diff --git a/config/options b/config/options index f0213dee08..c033f79bc4 100644 --- a/config/options +++ b/config/options @@ -119,7 +119,7 @@ WPA_SUPPLICANT=yes # X.org drivers to use (all/ati/geode/glint/i740/intel/mga/nv/openchrome/ # radeonhd/s3/s3virge/savage/sis/tdfx/trident/vesa/vmware) # Space separated list is supported, e.g. XORG_DRIVERS="ati s3" -XORG_DRIVERS="ati nv vesa openchrome intel" +XORG_DRIVERS="ati nouveau nv vesa openchrome intel" # LCD display support (yes/no) diff --git a/packages/graphics/Mesa/patches/20_libmesa-shared.diff b/packages/graphics/Mesa/20_libmesa-shared.diff similarity index 100% rename from packages/graphics/Mesa/patches/20_libmesa-shared.diff rename to packages/graphics/Mesa/20_libmesa-shared.diff diff --git a/packages/graphics/Mesa/23_mesa-no-mach64.diff b/packages/graphics/Mesa/23_mesa-no-mach64.diff new file mode 100644 index 0000000000..397531e749 --- /dev/null +++ b/packages/graphics/Mesa/23_mesa-no-mach64.diff @@ -0,0 +1,45 @@ +--- configure.ac.mach64 2008-09-05 13:53:24.000000000 +1000 ++++ configure.ac 2008-09-05 13:53:39.000000000 +1000 +@@ -656,7 +656,7 @@ + # because there is no x86-64 system where they could *ever* + # be used. + if test "x$DRI_DIRS" = "xyes"; then +- DRI_DIRS="i915 i965 mach64 mga r128 r200 r300 radeon \ ++ DRI_DIRS="i915 i965 mga r128 r200 r300 radeon \ + savage tdfx unichrome swrast" + fi + ;; +@@ -664,13 +664,13 @@ + # Build only the drivers for cards that exist on PowerPC. + # At some point MGA will be added, but not yet. + if test "x$DRI_DIRS" = "xyes"; then +- DRI_DIRS="mach64 r128 r200 r300 radeon tdfx swrast" ++ DRI_DIRS="r128 r200 r300 radeon tdfx swrast" + fi + ;; + sparc*) + # Build only the drivers for cards that exist on sparc` + if test "x$DRI_DIRS" = "xyes"; then +- DRI_DIRS="mach64 r128 r200 r300 radeon ffb swrast" ++ DRI_DIRS="r128 r200 r300 radeon ffb swrast" + fi + ;; + esac +@@ -689,7 +689,7 @@ + # ffb and gamma are missing because they have not been converted + # to use the new interface. + if test "x$DRI_DIRS" = "xyes"; then +- DRI_DIRS="i810 i915 i965 mach64 mga r128 r200 r300 radeon tdfx \ ++ DRI_DIRS="i810 i915 i965 mga r128 r200 r300 radeon tdfx \ + unichrome savage sis swrast" + fi + ;; +@@ -704,7 +704,7 @@ + + # default drivers + if test "x$DRI_DIRS" = "xyes"; then +- DRI_DIRS="i810 i915 i965 mach64 mga r128 r200 r300 radeon s3v \ ++ DRI_DIRS="i810 i915 i965 mga r128 r200 r300 radeon s3v \ + savage sis tdfx trident unichrome ffb swrast" + fi + diff --git a/packages/graphics/Mesa/24_radeon-rewrite.diff b/packages/graphics/Mesa/24_radeon-rewrite.diff new file mode 100644 index 0000000000..22f6dec57b --- /dev/null +++ b/packages/graphics/Mesa/24_radeon-rewrite.diff @@ -0,0 +1,37159 @@ +diff --git a/configs/autoconf.in b/configs/autoconf.in +index b61d7f3..0f9306d 100644 +--- a/configs/autoconf.in ++++ b/configs/autoconf.in +@@ -20,6 +20,8 @@ CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@ \ + $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) + LDFLAGS = @LDFLAGS@ + EXTRA_LIB_PATH = @EXTRA_LIB_PATH@ ++RADEON_CFLAGS = @RADEON_CFLAGS@ ++RADEON_LDFLAGS = @RADEON_LDFLAGS@ + + # Assembler + MESA_ASM_SOURCES = @MESA_ASM_SOURCES@ +diff --git a/configure.ac b/configure.ac +index 46070fd..4164d37 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -456,6 +456,8 @@ AC_SUBST([GALLIUM_WINSYS_DRM_DIRS]) + AC_SUBST([GALLIUM_DRIVERS_DIRS]) + AC_SUBST([GALLIUM_AUXILIARY_DIRS]) + AC_SUBST([GALLIUM_STATE_TRACKERS_DIRS]) ++AC_SUBST([RADEON_CFLAGS]) ++AC_SUBST([RADEON_LDFLAGS]) + + dnl + dnl User supplied program configuration +@@ -583,6 +585,13 @@ dri) + GL_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED dri2proto >= $DRI2PROTO_REQUIRED" + DRI_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED" + ++ PKG_CHECK_MODULES([LIBDRM_RADEON], [libdrm_radeon], HAVE_LIBDRM_RADEON=yes, HAVE_LIBDRM_RADEON=no) ++ ++ if test "$HAVE_LIBDRM_RADEON" = yes; then ++ RADEON_CFLAGS="-DHAVE_LIBDRM_RADEON=1 $LIBDRM_RADEON_CFLAGS" ++ RADEON_LDFLAGS=$LIBDRM_RADEON_LIBS ++ fi ++ + # find the DRI deps for libGL + if test "$x11_pkgconfig" = yes; then + # add xcb modules if necessary +diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile +index e9144ac..6a246ed 100644 +--- a/src/mesa/drivers/dri/r200/Makefile ++++ b/src/mesa/drivers/dri/r200/Makefile +@@ -3,6 +3,8 @@ + TOP = ../../../../.. + include $(TOP)/configs/current + ++CFLAGS += $(RADEON_CFLAGS) ++ + LIBNAME = r200_dri.so + + MINIGLX_SOURCES = server/radeon_dri.c +@@ -11,25 +13,36 @@ ifeq ($(USING_EGL), 1) + EGL_SOURCES = server/radeon_egl.c + endif + ++RADEON_COMMON_SOURCES = \ ++ radeon_texture.c \ ++ radeon_common_context.c \ ++ radeon_common.c \ ++ radeon_dma.c \ ++ radeon_lock.c \ ++ radeon_bo_legacy.c \ ++ radeon_cs_legacy.c \ ++ radeon_mipmap_tree.c \ ++ radeon_span.c \ ++ radeon_fbo.c ++ ++ + DRIVER_SOURCES = r200_context.c \ + r200_ioctl.c \ +- r200_lock.c \ + r200_state.c \ + r200_state_init.c \ + r200_cmdbuf.c \ + r200_pixel.c \ + r200_tex.c \ +- r200_texmem.c \ + r200_texstate.c \ + r200_tcl.c \ + r200_swtcl.c \ +- r200_span.c \ + r200_maos.c \ + r200_sanity.c \ + r200_fragshader.c \ + r200_vertprog.c \ + radeon_screen.c \ +- $(EGL_SOURCES) ++ $(EGL_SOURCES) \ ++ $(RADEON_COMMON_SOURCES) + + C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) + +@@ -48,7 +61,30 @@ SYMLINKS = \ + COMMON_SYMLINKS = \ + radeon_chipset.h \ + radeon_screen.c \ +- radeon_screen.h ++ radeon_screen.h \ ++ radeon_bo_legacy.c \ ++ radeon_cs_legacy.c \ ++ radeon_bo_legacy.h \ ++ radeon_cs_legacy.h \ ++ radeon_bocs_wrapper.h \ ++ radeon_span.h \ ++ radeon_span.c \ ++ radeon_lock.c \ ++ radeon_lock.h \ ++ radeon_common.c \ ++ radeon_common_context.c \ ++ radeon_common_context.h \ ++ radeon_common.h \ ++ radeon_cmdbuf.h \ ++ radeon_mipmap_tree.c \ ++ radeon_mipmap_tree.h \ ++ radeon_texture.c \ ++ radeon_texture.h \ ++ radeon_dma.c \ ++ radeon_dma.h \ ++ radeon_fbo.c ++ ++DRI_LIB_DEPS += $(RADEON_LDFLAGS) + + ##### TARGETS ##### + +diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c +index e163377..3a11a44 100644 +--- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c ++++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c +@@ -38,6 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "swrast/swrast.h" + #include "main/simple_list.h" + ++#include "radeon_common.h" + #include "r200_context.h" + #include "r200_state.h" + #include "r200_ioctl.h" +@@ -45,18 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r200_sanity.h" + #include "radeon_reg.h" + +-static void print_state_atom( struct r200_state_atom *state ) +-{ +- int i; +- +- fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); +- +- if (0 & R200_DEBUG & DEBUG_VERBOSE) +- for (i = 0 ; i < state->cmd_size ; i++) +- fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); +- +-} +- + /* The state atoms will be emitted in the order they appear in the atom list, + * so this step is important. + */ +@@ -64,141 +53,56 @@ void r200SetUpAtomList( r200ContextPtr rmesa ) + { + int i, mtu; + +- mtu = rmesa->glCtx->Const.MaxTextureUnits; +- +- make_empty_list(&rmesa->hw.atomlist); +- rmesa->hw.atomlist.name = "atom-list"; +- +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.ctx ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.set ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.lin ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.msk ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpt ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vtx ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vap ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vte ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.msc ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.cst ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.zbs ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tcl ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.msl ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tcg ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.grd ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.fog ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tam ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tf ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.atf ); ++ mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits; ++ ++ make_empty_list(&rmesa->radeon.hw.atomlist); ++ rmesa->radeon.hw.atomlist.name = "atom-list"; ++ ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.ctx ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.set ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.lin ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.msk ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpt ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vtx ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vap ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vte ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.msc ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.cst ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.zbs ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcl ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.msl ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcg ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.grd ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.fog ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tam ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tf ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.atf ); + for (i = 0; i < mtu; ++i) +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tex[i] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i] ); + for (i = 0; i < mtu; ++i) +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.cube[i] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i] ); + for (i = 0; i < 6; ++i) +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pix[i] ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.afs[0] ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.afs[1] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.pix[i] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[0] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[1] ); + for (i = 0; i < 8; ++i) +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.lit[i] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i] ); + for (i = 0; i < 3 + mtu; ++i) +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.mat[i] ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.eye ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.glt ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.eye ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.glt ); + for (i = 0; i < 2; ++i) +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.mtl[i] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.mtl[i] ); + for (i = 0; i < 6; ++i) +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.ucp[i] ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.spr ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.ptp ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.prf ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pvs ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpp[0] ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpp[1] ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpi[0] ); +- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpi[1] ); +-} +- +-static void r200SaveHwState( r200ContextPtr rmesa ) +-{ +- struct r200_state_atom *atom; +- char * dest = rmesa->backup_store.cmd_buf; +- +- if (R200_DEBUG & DEBUG_STATE) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- rmesa->backup_store.cmd_used = 0; +- +- foreach( atom, &rmesa->hw.atomlist ) { +- if ( atom->check( rmesa->glCtx, atom->idx ) ) { +- int size = atom->cmd_size * 4; +- memcpy( dest, atom->cmd, size); +- dest += size; +- rmesa->backup_store.cmd_used += size; +- if (R200_DEBUG & DEBUG_STATE) +- print_state_atom( atom ); +- } +- } +- +- assert( rmesa->backup_store.cmd_used <= R200_CMD_BUF_SZ ); +- if (R200_DEBUG & DEBUG_STATE) +- fprintf(stderr, "Returning to r200EmitState\n"); +-} +- +-void r200EmitState( r200ContextPtr rmesa ) +-{ +- char *dest; +- int mtu; +- struct r200_state_atom *atom; +- +- if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- if (rmesa->save_on_next_emit) { +- r200SaveHwState(rmesa); +- rmesa->save_on_next_emit = GL_FALSE; +- } +- +- if (!rmesa->hw.is_dirty && !rmesa->hw.all_dirty) +- return; +- +- mtu = rmesa->glCtx->Const.MaxTextureUnits; +- +- /* To avoid going across the entire set of states multiple times, just check +- * for enough space for the case of emitting all state, and inline the +- * r200AllocCmdBuf code here without all the checks. +- */ +- r200EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size ); +- +- /* we need to calculate dest after EnsureCmdBufSpace +- as we may flush the buffer - airlied */ +- dest = rmesa->store.cmd_buf + rmesa->store.cmd_used; +- if (R200_DEBUG & DEBUG_STATE) { +- foreach( atom, &rmesa->hw.atomlist ) { +- if ( atom->dirty || rmesa->hw.all_dirty ) { +- if ( atom->check( rmesa->glCtx, atom->idx ) ) +- print_state_atom( atom ); +- else +- fprintf(stderr, "skip state %s\n", atom->name); +- } +- } +- } +- +- foreach( atom, &rmesa->hw.atomlist ) { +- if ( rmesa->hw.all_dirty ) +- atom->dirty = GL_TRUE; +- if ( atom->dirty ) { +- if ( atom->check( rmesa->glCtx, atom->idx ) ) { +- int size = atom->cmd_size * 4; +- memcpy( dest, atom->cmd, size); +- dest += size; +- rmesa->store.cmd_used += size; +- atom->dirty = GL_FALSE; +- } +- } +- } +- +- assert( rmesa->store.cmd_used <= R200_CMD_BUF_SZ ); +- +- rmesa->hw.is_dirty = GL_FALSE; +- rmesa->hw.all_dirty = GL_FALSE; ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.spr ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.ptp ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.prf ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.pvs ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[0] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[1] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[0] ); ++ insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[1] ); + } + + /* Fire a section of the retained (indexed_verts) buffer as a regular +@@ -208,51 +112,80 @@ void r200EmitVbufPrim( r200ContextPtr rmesa, + GLuint primitive, + GLuint vertex_nr ) + { +- drm_radeon_cmd_header_t *cmd; ++ BATCH_LOCALS(&rmesa->radeon); + + assert(!(primitive & R200_VF_PRIM_WALK_IND)); + +- r200EmitState( rmesa ); ++ radeonEmitState(&rmesa->radeon); + + if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS)) + fprintf(stderr, "%s cmd_used/4: %d prim %x nr %d\n", __FUNCTION__, + rmesa->store.cmd_used/4, primitive, vertex_nr); +- +- cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, VBUF_BUFSZ, +- __FUNCTION__ ); +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; +- cmd[1].i = R200_CP_CMD_3D_DRAW_VBUF_2; +- cmd[2].i = (primitive | +- R200_VF_PRIM_WALK_LIST | +- R200_VF_COLOR_ORDER_RGBA | +- (vertex_nr << R200_VF_VERTEX_NUMBER_SHIFT)); ++ ++ BEGIN_BATCH(3); ++ OUT_BATCH_PACKET3_CLIP(R200_CP_CMD_3D_DRAW_VBUF_2, 0); ++ OUT_BATCH(primitive | R200_VF_PRIM_WALK_LIST | R200_VF_COLOR_ORDER_RGBA | ++ (vertex_nr << R200_VF_VERTEX_NUMBER_SHIFT)); ++ END_BATCH(); + } + ++static void r200FireEB(r200ContextPtr rmesa, int vertex_count, int type) ++{ ++ BATCH_LOCALS(&rmesa->radeon); ++ ++ if (vertex_count > 0) { ++ BEGIN_BATCH(8+2); ++ OUT_BATCH_PACKET3(R200_CP_CMD_3D_DRAW_INDX_2, 0); ++ OUT_BATCH(R200_VF_PRIM_WALK_IND | ++ ((vertex_count + 0) << 16) | ++ type); ++ ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ OUT_BATCH_PACKET3(R200_CP_CMD_INDX_BUFFER, 2); ++ OUT_BATCH((0x80 << 24) | (0 << 16) | 0x810); ++ OUT_BATCH_RELOC(rmesa->radeon.tcl.elt_dma_offset, ++ rmesa->radeon.tcl.elt_dma_bo, ++ rmesa->radeon.tcl.elt_dma_offset, ++ RADEON_GEM_DOMAIN_GTT, 0, 0); ++ OUT_BATCH(vertex_count/2); ++ } else { ++ OUT_BATCH_PACKET3(R200_CP_CMD_INDX_BUFFER, 2); ++ OUT_BATCH((0x80 << 24) | (0 << 16) | 0x810); ++ OUT_BATCH(rmesa->radeon.tcl.elt_dma_offset); ++ OUT_BATCH(vertex_count/2); ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.elt_dma_bo, ++ RADEON_GEM_DOMAIN_GTT, 0, 0); ++ } ++ END_BATCH(); ++ } ++} + +-void r200FlushElts( r200ContextPtr rmesa ) ++void r200FlushElts(GLcontext *ctx) + { +- int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start); +- int dwords; +- int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 12)) / 2; ++ r200ContextPtr rmesa = R200_CONTEXT(ctx); ++ int nr, elt_used = rmesa->tcl.elt_used; + + if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS)) +- fprintf(stderr, "%s\n", __FUNCTION__); ++ fprintf(stderr, "%s %x %d\n", __FUNCTION__, rmesa->tcl.hw_primitive, elt_used); ++ ++ assert( rmesa->radeon.dma.flush == r200FlushElts ); ++ rmesa->radeon.dma.flush = NULL; ++ ++ elt_used = (elt_used + 2) & ~2; + +- assert( rmesa->dma.flush == r200FlushElts ); +- rmesa->dma.flush = NULL; ++ nr = elt_used / 2; + +- /* Cope with odd number of elts: +- */ +- rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2; +- dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4; ++ radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo); + +- cmd[1] |= (dwords - 3) << 16; +- cmd[2] |= nr << R200_VF_VERTEX_NUMBER_SHIFT; ++ r200FireEB(rmesa, nr, rmesa->tcl.hw_primitive); ++ ++ radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo); ++ rmesa->radeon.tcl.elt_dma_bo = NULL; + + if (R200_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "%s: Syncing\n", __FUNCTION__); +- r200Finish( rmesa->glCtx ); ++ radeonFinish( rmesa->radeon.glCtx ); + } + } + +@@ -261,7 +194,6 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, + GLuint primitive, + GLuint min_nr ) + { +- drm_radeon_cmd_header_t *cmd; + GLushort *retval; + + if (R200_DEBUG & DEBUG_IOCTL) +@@ -269,30 +201,25 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, + + assert((primitive & R200_VF_PRIM_WALK_IND)); + +- r200EmitState( rmesa ); +- +- cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, ELTS_BUFSZ(min_nr), +- __FUNCTION__ ); +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; +- cmd[1].i = R200_CP_CMD_3D_DRAW_INDX_2; +- cmd[2].i = (primitive | +- R200_VF_PRIM_WALK_IND | +- R200_VF_COLOR_ORDER_RGBA); ++ radeonEmitState(&rmesa->radeon); ++ ++ rmesa->radeon.tcl.elt_dma_bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, ++ 0, R200_ELT_BUF_SZ, 4, ++ RADEON_GEM_DOMAIN_GTT, 0); ++ rmesa->radeon.tcl.elt_dma_offset = 0; ++ rmesa->tcl.elt_used = min_nr * 2; + ++ radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1); ++ retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset; + +- retval = (GLushort *)(cmd+3); + + if (R200_DEBUG & DEBUG_PRIMS) +- fprintf(stderr, "%s: header 0x%x prim %x \n", +- __FUNCTION__, +- cmd[1].i, primitive); ++ fprintf(stderr, "%s: header prim %x \n", ++ __FUNCTION__, primitive); + +- assert(!rmesa->dma.flush); +- rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; +- rmesa->dma.flush = r200FlushElts; +- +- rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf; ++ assert(!rmesa->radeon.dma.flush); ++ rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; ++ rmesa->radeon.dma.flush = r200FlushElts; + + return retval; + } +@@ -300,129 +227,119 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, + + + void r200EmitVertexAOS( r200ContextPtr rmesa, +- GLuint vertex_size, +- GLuint offset ) ++ GLuint vertex_size, ++ struct radeon_bo *bo, ++ GLuint offset ) + { +- drm_radeon_cmd_header_t *cmd; ++ BATCH_LOCALS(&rmesa->radeon); + + if (R200_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL)) + fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n", + __FUNCTION__, vertex_size, offset); + +- cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, VERT_AOS_BUFSZ, +- __FUNCTION__ ); + +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3; +- cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | (2 << 16); +- cmd[2].i = 1; +- cmd[3].i = vertex_size | (vertex_size << 8); +- cmd[4].i = offset; ++ BEGIN_BATCH(5); ++ OUT_BATCH_PACKET3(R200_CP_CMD_3D_LOAD_VBPNTR, 2); ++ OUT_BATCH(1); ++ OUT_BATCH(vertex_size | (vertex_size << 8)); ++ OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0); ++ END_BATCH(); + } +- + +-void r200EmitAOS( r200ContextPtr rmesa, +- struct r200_dma_region **component, +- GLuint nr, +- GLuint offset ) ++void r200EmitAOS(r200ContextPtr rmesa, GLuint nr, GLuint offset) + { +- drm_radeon_cmd_header_t *cmd; +- int sz = AOS_BUFSZ(nr); ++ BATCH_LOCALS(&rmesa->radeon); ++ uint32_t voffset; ++ int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2; + int i; +- int *tmp; +- +- if (R200_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s nr arrays: %d\n", __FUNCTION__, nr); +- +- cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, sz, __FUNCTION__ ); +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3; +- cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | (((sz / sizeof(int)) - 3) << 16); +- cmd[2].i = nr; +- tmp = &cmd[0].i; +- cmd += 3; +- +- for (i = 0 ; i < nr ; i++) { +- if (i & 1) { +- cmd[0].i |= ((component[i]->aos_stride << 24) | +- (component[i]->aos_size << 16)); +- cmd[2].i = (component[i]->aos_start + +- offset * component[i]->aos_stride * 4); +- cmd += 3; ++ ++ if (RADEON_DEBUG & DEBUG_VERTS) ++ fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr, ++ offset); ++ ++ BEGIN_BATCH(sz+2+ (nr*2)); ++ OUT_BATCH_PACKET3(R200_CP_CMD_3D_LOAD_VBPNTR, sz - 1); ++ OUT_BATCH(nr); ++ ++ ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ for (i = 0; i + 1 < nr; i += 2) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) | ++ (rmesa->radeon.tcl.aos[i].stride << 8) | ++ (rmesa->radeon.tcl.aos[i + 1].components << 16) | ++ (rmesa->radeon.tcl.aos[i + 1].stride << 24)); ++ ++ voffset = rmesa->radeon.tcl.aos[i + 0].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->radeon.tcl.aos[i].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ voffset = rmesa->radeon.tcl.aos[i + 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->radeon.tcl.aos[i+1].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); + } +- else { +- cmd[0].i = ((component[i]->aos_stride << 8) | +- (component[i]->aos_size << 0)); +- cmd[1].i = (component[i]->aos_start + +- offset * component[i]->aos_stride * 4); ++ ++ if (nr & 1) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | ++ (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); ++ voffset = rmesa->radeon.tcl.aos[nr - 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->radeon.tcl.aos[nr - 1].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++ } else { ++ for (i = 0; i + 1 < nr; i += 2) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) | ++ (rmesa->radeon.tcl.aos[i].stride << 8) | ++ (rmesa->radeon.tcl.aos[i + 1].components << 16) | ++ (rmesa->radeon.tcl.aos[i + 1].stride << 24)); ++ ++ voffset = rmesa->radeon.tcl.aos[i + 0].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; ++ OUT_BATCH(voffset); ++ voffset = rmesa->radeon.tcl.aos[i + 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; ++ OUT_BATCH(voffset); ++ } ++ ++ if (nr & 1) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | ++ (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); ++ voffset = rmesa->radeon.tcl.aos[nr - 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; ++ OUT_BATCH(voffset); ++ } ++ for (i = 0; i + 1 < nr; i += 2) { ++ voffset = rmesa->radeon.tcl.aos[i + 0].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.aos[i+0].bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ voffset = rmesa->radeon.tcl.aos[i + 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.aos[i+1].bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++ if (nr & 1) { ++ voffset = rmesa->radeon.tcl.aos[nr - 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.aos[nr-1].bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); + } + } +- +- if (R200_DEBUG & DEBUG_VERTS) { +- fprintf(stderr, "%s:\n", __FUNCTION__); +- for (i = 0 ; i < sz ; i++) +- fprintf(stderr, " %d: %x\n", i, tmp[i]); +- } +-} +- +-void r200EmitBlit( r200ContextPtr rmesa, +- GLuint color_fmt, +- GLuint src_pitch, +- GLuint src_offset, +- GLuint dst_pitch, +- GLuint dst_offset, +- GLint srcx, GLint srcy, +- GLint dstx, GLint dsty, +- GLuint w, GLuint h ) +-{ +- drm_radeon_cmd_header_t *cmd; +- +- if (R200_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n", +- __FUNCTION__, +- src_pitch, src_offset, srcx, srcy, +- dst_pitch, dst_offset, dstx, dsty, +- w, h); +- +- assert( (src_pitch & 63) == 0 ); +- assert( (dst_pitch & 63) == 0 ); +- assert( (src_offset & 1023) == 0 ); +- assert( (dst_offset & 1023) == 0 ); +- assert( w < (1<<16) ); +- assert( h < (1<<16) ); +- +- cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 8 * sizeof(int), +- __FUNCTION__ ); +- +- +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3; +- cmd[1].i = R200_CP_CMD_BITBLT_MULTI | (5 << 16); +- cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | +- RADEON_GMC_DST_PITCH_OFFSET_CNTL | +- RADEON_GMC_BRUSH_NONE | +- (color_fmt << 8) | +- RADEON_GMC_SRC_DATATYPE_COLOR | +- RADEON_ROP3_S | +- RADEON_DP_SRC_SOURCE_MEMORY | +- RADEON_GMC_CLR_CMP_CNTL_DIS | +- RADEON_GMC_WR_MSK_DIS ); +- +- cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10); +- cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10); +- cmd[5].i = (srcx << 16) | srcy; +- cmd[6].i = (dstx << 16) | dsty; /* dst */ +- cmd[7].i = (w << 16) | h; +-} +- +- +-void r200EmitWait( r200ContextPtr rmesa, GLuint flags ) +-{ +- drm_radeon_cmd_header_t *cmd; +- +- assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) ); +- +- cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 1 * sizeof(int), +- __FUNCTION__ ); +- cmd[0].i = 0; +- cmd[0].wait.cmd_type = RADEON_CMD_WAIT; +- cmd[0].wait.flags = flags; ++ END_BATCH(); + } +diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c +index c067515..f80f0d8 100644 +--- a/src/mesa/drivers/dri/r200/r200_context.c ++++ b/src/mesa/drivers/dri/r200/r200_context.c +@@ -54,7 +54,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r200_context.h" + #include "r200_ioctl.h" + #include "r200_state.h" +-#include "r200_span.h" + #include "r200_pixel.h" + #include "r200_tex.h" + #include "r200_swtcl.h" +@@ -62,6 +61,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r200_maos.h" + #include "r200_vertprog.h" + ++#include "radeon_span.h" ++ + #define need_GL_ARB_vertex_program + #define need_GL_ATI_fragment_shader + #define need_GL_EXT_blend_minmax +@@ -71,6 +72,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define need_GL_EXT_blend_func_separate + #define need_GL_NV_vertex_program + #define need_GL_ARB_point_parameters ++#define need_GL_EXT_framebuffer_object + #include "extension_helper.h" + + #define DRIVER_DATE "20060602" +@@ -78,9 +80,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "vblank.h" + #include "utils.h" + #include "xmlpool.h" /* for symbolic values of enum-type options */ +-#ifndef R200_DEBUG +-int R200_DEBUG = (0); +-#endif + + /* Return various strings for glGetString(). + */ +@@ -89,8 +88,8 @@ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name ) + r200ContextPtr rmesa = R200_CONTEXT(ctx); + static char buffer[128]; + unsigned offset; +- GLuint agp_mode = (rmesa->r200Screen->card_type == RADEON_CARD_PCI)? 0 : +- rmesa->r200Screen->AGPMode; ++ GLuint agp_mode = (rmesa->radeon.radeonScreen->card_type == RADEON_CARD_PCI)? 0 : ++ rmesa->radeon.radeonScreen->AGPMode; + + switch ( name ) { + case GL_VENDOR: +@@ -101,7 +100,7 @@ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name ) + agp_mode ); + + sprintf( & buffer[ offset ], " %sTCL", +- !(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) ++ !(rmesa->radeon.TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) + ? "" : "NO-" ); + + return (GLubyte *)buffer; +@@ -126,6 +125,7 @@ const struct dri_extension card_extensions[] = + { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, + { "GL_EXT_blend_subtract", NULL }, + { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, ++ { "GL_EXT_packed_depth_stencil", NULL}, + { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, + { "GL_EXT_stencil_wrap", NULL }, + { "GL_EXT_texture_edge_clamp", NULL }, +@@ -167,6 +167,11 @@ const struct dri_extension point_extensions[] = { + { NULL, NULL } + }; + ++const struct dri_extension mm_extensions[] = { ++ { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, ++ { NULL, NULL } ++}; ++ + extern const struct tnl_pipeline_stage _r200_render_stage; + extern const struct tnl_pipeline_stage _r200_tcl_stage; + +@@ -234,6 +239,39 @@ static const struct dri_debug_control debug_control[] = + { NULL, 0 } + }; + ++static void r200_get_lock(radeonContextPtr radeon) ++{ ++ r200ContextPtr rmesa = (r200ContextPtr)radeon; ++ drm_radeon_sarea_t *sarea = radeon->sarea; ++ ++ R200_STATECHANGE( rmesa, ctx ); ++ if (rmesa->radeon.sarea->tiling_enabled) { ++ rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; ++ } ++ else rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ~R200_COLOR_TILE_ENABLE; ++ ++ if ( sarea->ctx_owner != rmesa->radeon.dri.hwContext ) { ++ sarea->ctx_owner = rmesa->radeon.dri.hwContext; ++ if (!radeon->radeonScreen->kernel_mm) ++ radeon_bo_legacy_texture_age(radeon->radeonScreen->bom); ++ } ++ ++} ++ ++static void r200_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa) ++{ ++} ++ ++ ++static void r200_init_vtbl(radeonContextPtr radeon) ++{ ++ radeon->vtbl.get_lock = r200_get_lock; ++ radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset; ++ radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header; ++ radeon->vtbl.swtcl_flush = r200_swtcl_flush; ++ radeon->vtbl.fallback = r200Fallback; ++} ++ + + /* Create the device specific rendering context. + */ +@@ -245,9 +283,9 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, + radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private); + struct dd_function_table functions; + r200ContextPtr rmesa; +- GLcontext *ctx, *shareCtx; ++ GLcontext *ctx; + int i; +- int tcl_mode, fthrottle_mode; ++ int tcl_mode; + + assert(glVisual); + assert(driContextPriv); +@@ -257,7 +295,8 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, + rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) ); + if ( !rmesa ) + return GL_FALSE; +- ++ ++ r200_init_vtbl(&rmesa->radeon); + /* init exp fog table data */ + r200InitStaticFogData(); + +@@ -265,12 +304,12 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, + * Do this here so that initialMaxAnisotropy is set before we create + * the default textures. + */ +- driParseConfigFiles (&rmesa->optionCache, &screen->optionCache, ++ driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache, + screen->driScreen->myNum, "r200"); +- rmesa->initialMaxAnisotropy = driQueryOptionf(&rmesa->optionCache, +- "def_max_anisotropy"); ++ rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache, ++ "def_max_anisotropy"); + +- if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) { ++ if ( driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) { + if ( sPriv->drm_version.minor < 13 ) + fprintf( stderr, "DRM version 1.%d too old to support HyperZ, " + "disabling.\n", sPriv->drm_version.minor ); +@@ -291,59 +330,15 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, + r200InitTextureFuncs(&functions); + r200InitShaderFuncs(&functions); + +- /* Allocate and initialize the Mesa context */ +- if (sharedContextPrivate) +- shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx; +- else +- shareCtx = NULL; +- rmesa->glCtx = _mesa_create_context(glVisual, shareCtx, +- &functions, (void *) rmesa); +- if (!rmesa->glCtx) { +- FREE(rmesa); +- return GL_FALSE; +- } +- driContextPriv->driverPrivate = rmesa; +- +- /* Init r200 context data */ +- rmesa->dri.context = driContextPriv; +- rmesa->dri.screen = sPriv; +- rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */ +- rmesa->dri.hwContext = driContextPriv->hHWContext; +- rmesa->dri.hwLock = &sPriv->pSAREA->lock; +- rmesa->dri.fd = sPriv->fd; +- rmesa->dri.drmMinor = sPriv->drm_version.minor; +- +- rmesa->r200Screen = screen; +- rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA + +- screen->sarea_priv_offset); +- +- +- rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address; +- +- (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) ); +- make_empty_list( & rmesa->swapped ); +- +- rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ; +- assert(rmesa->nr_heaps < RADEON_NR_TEX_HEAPS); +- for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { +- rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa, +- screen->texSize[i], +- 12, +- RADEON_NR_TEX_REGIONS, +- (drmTextureRegionPtr)rmesa->sarea->tex_list[i], +- & rmesa->sarea->tex_age[i], +- & rmesa->swapped, +- sizeof( r200TexObj ), +- (destroy_texture_object_t *) r200DestroyTexObj ); ++ if (!radeonInitContext(&rmesa->radeon, &functions, ++ glVisual, driContextPriv, ++ sharedContextPrivate)) { ++ FREE(rmesa); ++ return GL_FALSE; + } +- rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache, +- "texture_depth"); +- if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) +- rmesa->texture_depth = ( screen->cpp == 4 ) ? +- DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; + +- rmesa->swtcl.RenderIndex = ~0; +- rmesa->hw.all_dirty = 1; ++ rmesa->radeon.swtcl.RenderIndex = ~0; ++ rmesa->radeon.hw.all_dirty = 1; + + /* Set the maximum texture size small enough that we can guarentee that + * all texture units can bind a maximal texture and have all of them in +@@ -351,29 +346,13 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, + * setting allow larger textures. + */ + +- ctx = rmesa->glCtx; +- ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->optionCache, ++ ctx = rmesa->radeon.glCtx; ++ ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache, + "texture_units"); + ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + +- i = driQueryOptioni( &rmesa->optionCache, "allow_large_textures"); +- +- driCalculateMaxTextureLevels( rmesa->texture_heaps, +- rmesa->nr_heaps, +- & ctx->Const, +- 4, +- 11, /* max 2D texture size is 2048x2048 */ +-#if ENABLE_HW_3D_TEXTURE +- 8, /* max 3D texture size is 256^3 */ +-#else +- 0, /* 3D textures unsupported */ +-#endif +- 11, /* max cube texture size is 2048x2048 */ +- 11, /* max texture rectangle size is 2048x2048 */ +- 12, +- GL_FALSE, +- i ); ++ i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures"); + + ctx->Const.MaxTextureMaxAnisotropy = 16.0; + +@@ -383,7 +362,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSizeAA = 1.0; + ctx->Const.PointSizeGranularity = 0.0625; +- if (rmesa->r200Screen->drmSupportsPointSprites) ++ if (rmesa->radeon.radeonScreen->drmSupportsPointSprites) + ctx->Const.MaxPointSize = 2047.0; + else + ctx->Const.MaxPointSize = 1.0; +@@ -439,32 +418,35 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, + _math_matrix_set_identity( &rmesa->tmpmat ); + + driInitExtensions( ctx, card_extensions, GL_TRUE ); +- if (!(rmesa->r200Screen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) { ++ ++ if (rmesa->radeon.radeonScreen->kernel_mm) ++ driInitExtensions(ctx, mm_extensions, GL_FALSE); ++ if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) { + /* yuv textures don't work with some chips - R200 / rv280 okay so far + others get the bit ordering right but don't actually do YUV-RGB conversion */ + _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" ); + } +- if (rmesa->glCtx->Mesa_DXTn) { ++ if (rmesa->radeon.glCtx->Mesa_DXTn) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + _mesa_enable_extension( ctx, "GL_S3_s3tc" ); + } +- else if (driQueryOptionb (&rmesa->optionCache, "force_s3tc_enable")) { ++ else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + } + +- if (rmesa->r200Screen->drmSupportsCubeMapsR200) ++ if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR200) + _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" ); +- if (rmesa->r200Screen->drmSupportsBlendColor) { ++ if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) { + driInitExtensions( ctx, blend_extensions, GL_FALSE ); + } +- if(rmesa->r200Screen->drmSupportsVertexProgram) ++ if(rmesa->radeon.radeonScreen->drmSupportsVertexProgram) + driInitSingleExtension( ctx, ARB_vp_extension ); +- if(driQueryOptionb(&rmesa->optionCache, "nv_vertex_program")) ++ if(driQueryOptionb(&rmesa->radeon.optionCache, "nv_vertex_program")) + driInitSingleExtension( ctx, NV_vp_extension ); + +- if ((ctx->Const.MaxTextureUnits == 6) && rmesa->r200Screen->drmSupportsFragShader) ++ if ((ctx->Const.MaxTextureUnits == 6) && rmesa->radeon.radeonScreen->drmSupportsFragShader) + driInitSingleExtension( ctx, ATI_fs_extension ); +- if (rmesa->r200Screen->drmSupportsPointSprites) ++ if (rmesa->radeon.radeonScreen->drmSupportsPointSprites) + driInitExtensions( ctx, point_extensions, GL_FALSE ); + #if 0 + r200InitDriverFuncs( ctx ); +@@ -474,33 +456,16 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, + #endif + /* plug in a few more device driver functions */ + /* XXX these should really go right after _mesa_init_driver_functions() */ ++ radeon_fbo_init(&rmesa->radeon); ++ radeonInitSpanFuncs( ctx ); + r200InitPixelFuncs( ctx ); +- r200InitSpanFuncs( ctx ); + r200InitTnlFuncs( ctx ); + r200InitState( rmesa ); + r200InitSwtcl( ctx ); + +- fthrottle_mode = driQueryOptioni(&rmesa->optionCache, "fthrottle_mode"); +- rmesa->iw.irq_seq = -1; +- rmesa->irqsEmitted = 0; +- rmesa->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && +- rmesa->r200Screen->irq); +- +- rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); +- +- if (!rmesa->do_irqs) +- fprintf(stderr, +- "IRQ's not enabled, falling back to %s: %d %d\n", +- rmesa->do_usleeps ? "usleeps" : "busy waits", +- fthrottle_mode, +- rmesa->r200Screen->irq); +- + rmesa->prefer_gart_client_texturing = + (getenv("R200_GART_CLIENT_TEXTURES") != 0); + +- (*sPriv->systemTime->getUST)( & rmesa->swap_ust ); +- +- + #if DO_DEBUG + R200_DEBUG = driParseDebugString( getenv( "R200_DEBUG" ), + debug_control ); +@@ -508,202 +473,21 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, + debug_control ); + #endif + +- tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode"); +- if (driQueryOptionb(&rmesa->optionCache, "no_rast")) { ++ tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode"); ++ if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) { + fprintf(stderr, "disabling 3D acceleration\n"); + FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1); + } + else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") || +- !(rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL)) { +- if (rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL) { +- rmesa->r200Screen->chip_flags &= ~RADEON_CHIPSET_TCL; ++ !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { ++ if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { ++ rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL; + fprintf(stderr, "Disabling HW TCL support\n"); + } +- TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1); +- } +- +- return GL_TRUE; +-} +- +- +-/* Destroy the device specific context. +- */ +-/* Destroy the Mesa and driver specific context data. +- */ +-void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) +-{ +- GET_CURRENT_CONTEXT(ctx); +- r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate; +- r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL; +- +- /* check if we're deleting the currently bound context */ +- if (rmesa == current) { +- R200_FIREVERTICES( rmesa ); +- _mesa_make_current(NULL, NULL, NULL); +- } +- +- /* Free r200 context resources */ +- assert(rmesa); /* should never be null */ +- if ( rmesa ) { +- GLboolean release_texture_heaps; +- +- +- release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); +- _swsetup_DestroyContext( rmesa->glCtx ); +- _tnl_DestroyContext( rmesa->glCtx ); +- _vbo_DestroyContext( rmesa->glCtx ); +- _swrast_DestroyContext( rmesa->glCtx ); +- +- r200DestroySwtcl( rmesa->glCtx ); +- r200ReleaseArrays( rmesa->glCtx, ~0 ); +- +- if (rmesa->dma.current.buf) { +- r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); +- r200FlushCmdBuf( rmesa, __FUNCTION__ ); +- } +- +- if (rmesa->state.scissor.pClipRects) { +- FREE(rmesa->state.scissor.pClipRects); +- rmesa->state.scissor.pClipRects = NULL; +- } +- +- if ( release_texture_heaps ) { +- /* This share group is about to go away, free our private +- * texture object data. +- */ +- int i; +- +- for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { +- driDestroyTextureHeap( rmesa->texture_heaps[ i ] ); +- rmesa->texture_heaps[ i ] = NULL; +- } +- +- assert( is_empty_list( & rmesa->swapped ) ); +- } +- +- /* free the Mesa context */ +- rmesa->glCtx->DriverCtx = NULL; +- _mesa_destroy_context( rmesa->glCtx ); +- +- /* free the option cache */ +- driDestroyOptionCache (&rmesa->optionCache); +- +- FREE( rmesa ); ++ TCL_FALLBACK(rmesa->radeon.glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1); + } +-} +- + +- +- +-void +-r200SwapBuffers( __DRIdrawablePrivate *dPriv ) +-{ +- if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { +- r200ContextPtr rmesa; +- GLcontext *ctx; +- rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; +- ctx = rmesa->glCtx; +- if (ctx->Visual.doubleBufferMode) { +- _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ +- if ( rmesa->doPageFlip ) { +- r200PageFlip( dPriv ); +- } +- else { +- r200CopyBuffer( dPriv, NULL ); +- } +- } +- } +- else { +- /* XXX this shouldn't be an error but we can't handle it for now */ +- _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__); +- } +-} +- +-void +-r200CopySubBuffer( __DRIdrawablePrivate *dPriv, +- int x, int y, int w, int h ) +-{ +- if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { +- r200ContextPtr rmesa; +- GLcontext *ctx; +- rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; +- ctx = rmesa->glCtx; +- if (ctx->Visual.doubleBufferMode) { +- drm_clip_rect_t rect; +- rect.x1 = x + dPriv->x; +- rect.y1 = (dPriv->h - y - h) + dPriv->y; +- rect.x2 = rect.x1 + w; +- rect.y2 = rect.y1 + h; +- _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ +- r200CopyBuffer( dPriv, &rect ); +- } +- } +- else { +- /* XXX this shouldn't be an error but we can't handle it for now */ +- _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__); +- } +-} +- +-/* Force the context `c' to be the current context and associate with it +- * buffer `b'. +- */ +-GLboolean +-r200MakeCurrent( __DRIcontextPrivate *driContextPriv, +- __DRIdrawablePrivate *driDrawPriv, +- __DRIdrawablePrivate *driReadPriv ) +-{ +- if ( driContextPriv ) { +- r200ContextPtr newCtx = +- (r200ContextPtr) driContextPriv->driverPrivate; +- +- if (R200_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx); +- +- newCtx->dri.readable = driReadPriv; +- +- if ( newCtx->dri.drawable != driDrawPriv || +- newCtx->lastStamp != driDrawPriv->lastStamp ) { +- if (driDrawPriv->swap_interval == (unsigned)-1) { +- driDrawPriv->vblFlags = (newCtx->r200Screen->irq != 0) +- ? driGetDefaultVBlankFlags(&newCtx->optionCache) +- : VBLANK_FLAG_NO_IRQ; +- +- driDrawableInitVBlank( driDrawPriv ); +- } +- +- newCtx->dri.drawable = driDrawPriv; +- +- r200SetCliprects(newCtx); +- r200UpdateViewportOffset( newCtx->glCtx ); +- } +- +- _mesa_make_current( newCtx->glCtx, +- (GLframebuffer *) driDrawPriv->driverPrivate, +- (GLframebuffer *) driReadPriv->driverPrivate ); +- +- _mesa_update_state( newCtx->glCtx ); +- r200ValidateState( newCtx->glCtx ); +- +- } else { +- if (R200_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s ctx is null\n", __FUNCTION__); +- _mesa_make_current( NULL, NULL, NULL ); +- } +- +- if (R200_DEBUG & DEBUG_DRI) +- fprintf(stderr, "End %s\n", __FUNCTION__); + return GL_TRUE; + } + +-/* Force the context `c' to be unbound from its buffer. +- */ +-GLboolean +-r200UnbindContext( __DRIcontextPrivate *driContextPriv ) +-{ +- r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate; +- +- if (R200_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx); + +- return GL_TRUE; +-} +diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h +index 14a1dda..6267293 100644 +--- a/src/mesa/drivers/dri/r200/r200_context.h ++++ b/src/mesa/drivers/dri/r200/r200_context.h +@@ -53,51 +53,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #error This driver requires a newer libdrm to compile + #endif + ++#include "radeon_screen.h" ++#include "radeon_common.h" ++ ++#include "radeon_lock.h" ++ + struct r200_context; + typedef struct r200_context r200ContextRec; + typedef struct r200_context *r200ContextPtr; + +-/* This union is used to avoid warnings/miscompilation +- with float to uint32_t casts due to strict-aliasing */ +-typedef union { GLfloat f; uint32_t ui32; } float_ui32_type; +- +-#include "r200_lock.h" +-#include "radeon_screen.h" + #include "main/mm.h" + +-/* Flags for software fallback cases */ +-/* See correponding strings in r200_swtcl.c */ +-#define R200_FALLBACK_TEXTURE 0x01 +-#define R200_FALLBACK_DRAW_BUFFER 0x02 +-#define R200_FALLBACK_STENCIL 0x04 +-#define R200_FALLBACK_RENDER_MODE 0x08 +-#define R200_FALLBACK_DISABLE 0x10 +-#define R200_FALLBACK_BORDER_MODE 0x20 +- +-/* The blit width for texture uploads +- */ +-#define BLIT_WIDTH_BYTES 1024 +- +-/* Use the templated vertex format: +- */ +-#define COLOR_IS_RGBA +-#define TAG(x) r200##x +-#include "tnl_dd/t_dd_vertex.h" +-#undef TAG +- +-typedef void (*r200_tri_func)( r200ContextPtr, +- r200Vertex *, +- r200Vertex *, +- r200Vertex * ); +- +-typedef void (*r200_line_func)( r200ContextPtr, +- r200Vertex *, +- r200Vertex * ); +- +-typedef void (*r200_point_func)( r200ContextPtr, +- r200Vertex * ); +- +- + struct r200_vertex_program { + struct gl_vertex_program mesa_program; /* Must be first */ + int translated; +@@ -112,93 +78,11 @@ struct r200_vertex_program { + int fogmode; + }; + +-struct r200_colorbuffer_state { +- GLuint clear; +-#if 000 +- GLint drawOffset, drawPitch; +-#endif +- int roundEnable; +-}; +- +- +-struct r200_depthbuffer_state { +- GLuint clear; +- GLfloat scale; +-}; +- +-#if 000 +-struct r200_pixel_state { +- GLint readOffset, readPitch; +-}; +-#endif +- +-struct r200_scissor_state { +- drm_clip_rect_t rect; +- GLboolean enabled; +- +- GLuint numClipRects; /* Cliprects active */ +- GLuint numAllocedClipRects; /* Cliprects available */ +- drm_clip_rect_t *pClipRects; +-}; +- +-struct r200_stencilbuffer_state { +- GLboolean hwBuffer; +- GLuint clear; /* rb3d_stencilrefmask value */ +-}; +- +-struct r200_stipple_state { +- GLuint mask[32]; +-}; +- +- +- +-#define TEX_0 0x1 +-#define TEX_1 0x2 +-#define TEX_2 0x4 +-#define TEX_3 0x8 +-#define TEX_4 0x10 +-#define TEX_5 0x20 +-#define TEX_ALL 0x3f +- +-typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr; +- +-/* Texture object in locally shared texture space. +- */ +-struct r200_tex_obj { +- driTextureObject base; +- +- GLuint bufAddr; /* Offset to start of locally +- shared texture block */ +- +- GLuint dirty_state; /* Flags (1 per texunit) for +- whether or not this texobj +- has dirty hardware state +- (pp_*) that needs to be +- brought into the +- texunit. */ +- +- drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; +- /* Six, for the cube faces */ +- GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ +- +- GLuint pp_txfilter; /* hardware register values */ +- GLuint pp_txformat; +- GLuint pp_txformat_x; +- GLuint pp_txoffset; /* Image location in texmem. +- All cube faces follow. */ +- GLuint pp_txsize; /* npot only */ +- GLuint pp_txpitch; /* npot only */ +- GLuint pp_border_color; +- GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ +- +- GLboolean border_fallback; +- +- GLuint tile_bits; /* hw texture tile bits used on this texture */ +-}; ++#define R200_TEX_ALL 0x3f + + + struct r200_texture_env_state { +- r200TexObjPtr texobj; ++ radeonTexObjPtr texobj; + GLuint outputreg; + GLuint unitneeded; + }; +@@ -210,19 +94,6 @@ struct r200_texture_state { + }; + + +-struct r200_state_atom { +- struct r200_state_atom *next, *prev; +- const char *name; /* for debug */ +- int cmd_size; /* size in bytes */ +- GLuint idx; +- int *cmd; /* one or more cmd's */ +- int *lastcmd; /* one or more cmd's */ +- GLboolean dirty; +- GLboolean (*check)( GLcontext *, int ); /* is this state active? */ +-}; +- +- +- + /* Trying to keep these relatively short as the variables are becoming + * extravagently long. Drop the driver name prefix off the front of + * everything - I think we know which driver we're in by now, and keep the +@@ -597,181 +468,79 @@ struct r200_state_atom { + + + struct r200_hw_state { +- /* Head of the linked list of state atoms. */ +- struct r200_state_atom atomlist; +- + /* Hardware state, stored as cmdbuf commands: + * -- Need to doublebuffer for + * - reviving state after loss of context + * - eliding noop statechange loops? (except line stipple count) + */ +- struct r200_state_atom ctx; +- struct r200_state_atom set; +- struct r200_state_atom vte; +- struct r200_state_atom lin; +- struct r200_state_atom msk; +- struct r200_state_atom vpt; +- struct r200_state_atom vap; +- struct r200_state_atom vtx; +- struct r200_state_atom tcl; +- struct r200_state_atom msl; +- struct r200_state_atom tcg; +- struct r200_state_atom msc; +- struct r200_state_atom cst; +- struct r200_state_atom tam; +- struct r200_state_atom tf; +- struct r200_state_atom tex[6]; +- struct r200_state_atom cube[6]; +- struct r200_state_atom zbs; +- struct r200_state_atom mtl[2]; +- struct r200_state_atom mat[9]; +- struct r200_state_atom lit[8]; /* includes vec, scl commands */ +- struct r200_state_atom ucp[6]; +- struct r200_state_atom pix[6]; /* pixshader stages */ +- struct r200_state_atom eye; /* eye pos */ +- struct r200_state_atom grd; /* guard band clipping */ +- struct r200_state_atom fog; +- struct r200_state_atom glt; +- struct r200_state_atom prf; +- struct r200_state_atom afs[2]; +- struct r200_state_atom pvs; +- struct r200_state_atom vpi[2]; +- struct r200_state_atom vpp[2]; +- struct r200_state_atom atf; +- struct r200_state_atom spr; +- struct r200_state_atom ptp; +- +- int max_state_size; /* Number of bytes necessary for a full state emit. */ +- GLboolean is_dirty, all_dirty; ++ struct radeon_state_atom ctx; ++ struct radeon_state_atom set; ++ struct radeon_state_atom vte; ++ struct radeon_state_atom lin; ++ struct radeon_state_atom msk; ++ struct radeon_state_atom vpt; ++ struct radeon_state_atom vap; ++ struct radeon_state_atom vtx; ++ struct radeon_state_atom tcl; ++ struct radeon_state_atom msl; ++ struct radeon_state_atom tcg; ++ struct radeon_state_atom msc; ++ struct radeon_state_atom cst; ++ struct radeon_state_atom tam; ++ struct radeon_state_atom tf; ++ struct radeon_state_atom tex[6]; ++ struct radeon_state_atom cube[6]; ++ struct radeon_state_atom zbs; ++ struct radeon_state_atom mtl[2]; ++ struct radeon_state_atom mat[9]; ++ struct radeon_state_atom lit[8]; /* includes vec, scl commands */ ++ struct radeon_state_atom ucp[6]; ++ struct radeon_state_atom pix[6]; /* pixshader stages */ ++ struct radeon_state_atom eye; /* eye pos */ ++ struct radeon_state_atom grd; /* guard band clipping */ ++ struct radeon_state_atom fog; ++ struct radeon_state_atom glt; ++ struct radeon_state_atom prf; ++ struct radeon_state_atom afs[2]; ++ struct radeon_state_atom pvs; ++ struct radeon_state_atom vpi[2]; ++ struct radeon_state_atom vpp[2]; ++ struct radeon_state_atom atf; ++ struct radeon_state_atom spr; ++ struct radeon_state_atom ptp; + }; + + struct r200_state { + /* Derived state for internal purposes: + */ +- struct r200_colorbuffer_state color; +- struct r200_depthbuffer_state depth; +-#if 00 +- struct r200_pixel_state pixel; +-#endif +- struct r200_scissor_state scissor; +- struct r200_stencilbuffer_state stencil; +- struct r200_stipple_state stipple; ++ struct radeon_stipple_state stipple; + struct r200_texture_state texture; + GLuint envneeded; + }; + +-/* Need refcounting on dma buffers: +- */ +-struct r200_dma_buffer { +- int refcount; /* the number of retained regions in buf */ +- drmBufPtr buf; +-}; +- +-#define GET_START(rvb) (rmesa->r200Screen->gart_buffer_offset + \ +- (rvb)->address - rmesa->dma.buf0_address + \ +- (rvb)->start) +- +-/* A retained region, eg vertices for indexed vertices. +- */ +-struct r200_dma_region { +- struct r200_dma_buffer *buf; +- char *address; /* == buf->address */ +- int start, end, ptr; /* offsets from start of buf */ +- int aos_start; +- int aos_stride; +- int aos_size; +-}; +- +- +-struct r200_dma { +- /* Active dma region. Allocations for vertices and retained +- * regions come from here. Also used for emitting random vertices, +- * these may be flushed by calling flush_current(); +- */ +- struct r200_dma_region current; +- +- void (*flush)( r200ContextPtr ); +- +- char *buf0_address; /* start of buf[0], for index calcs */ +- GLuint nr_released_bufs; /* flush after so many buffers released */ +-}; +- +-struct r200_dri_mirror { +- __DRIcontextPrivate *context; /* DRI context */ +- __DRIscreenPrivate *screen; /* DRI screen */ +- __DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */ +- __DRIdrawablePrivate *readable; /* DRI readable bound to this ctx */ +- +- drm_context_t hwContext; +- drm_hw_lock_t *hwLock; +- int fd; +- int drmMinor; +-}; +- +- + #define R200_CMD_BUF_SZ (16*1024) + +-struct r200_store { +- GLuint statenr; +- GLuint primnr; +- char cmd_buf[R200_CMD_BUF_SZ]; +- int cmd_used; +- int elts_start; +-}; +- +- ++#define R200_ELT_BUF_SZ (16*1024) + /* r200_tcl.c + */ + struct r200_tcl_info { + GLuint hw_primitive; + +-/* hw can handle 12 components max */ +- struct r200_dma_region *aos_components[12]; +- GLuint nr_aos_components; +- + GLuint *Elts; + +- struct r200_dma_region indexed_verts; +- struct r200_dma_region vertex_data[15]; ++ int elt_used; ++ + }; + + + /* r200_swtcl.c + */ + struct r200_swtcl_info { +- GLuint RenderIndex; +- +- /** +- * Size of a hardware vertex. This is calculated when \c ::vertex_attrs is +- * installed in the Mesa state vector. +- */ +- GLuint vertex_size; + +- /** +- * Attributes instructing the Mesa TCL pipeline where / how to put vertex +- * data in the hardware buffer. +- */ +- struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + +- /** +- * Number of elements of \c ::vertex_attrs that are actually used. +- */ +- GLuint vertex_attr_count; +- +- /** +- * Cached pointer to the buffer where Mesa will store vertex data. +- */ +- GLubyte *verts; +- +- /* Fallback rasterization functions +- */ +- r200_point_func draw_point; +- r200_line_func draw_line; +- r200_tri_func draw_tri; +- +- GLuint hw_primitive; +- GLenum render_primitive; +- GLuint numverts; ++ radeon_point_func draw_point; ++ radeon_line_func draw_line; ++ radeon_tri_func draw_tri; + + /** + * Offset of the 4UB color data within a hardware (swtcl) vertex. +@@ -787,27 +556,10 @@ struct r200_swtcl_info { + * Should Mesa project vertex data or will the hardware do it? + */ + GLboolean needproj; +- +- struct r200_dma_region indexed_verts; +-}; +- +- +-struct r200_ioctl { +- GLuint vertex_offset; +- GLuint vertex_size; + }; + + + +-#define R200_MAX_PRIMS 64 +- +- +- +-struct r200_prim { +- GLuint start; +- GLuint end; +- GLuint prim; +-}; + + /* A maximum total of 29 elements per vertex: 3 floats for position, 3 + * floats for normal, 4 floats for color, 4 bytes for secondary color, +@@ -822,9 +574,8 @@ struct r200_prim { + + #define R200_MAX_VERTEX_SIZE ((3*6)+11) + +- + struct r200_context { +- GLcontext *glCtx; /* Mesa context */ ++ struct radeon_context radeon; + + /* Driver and hardware state management + */ +@@ -832,56 +583,15 @@ struct r200_context { + struct r200_state state; + struct r200_vertex_program *curr_vp_hw; + +- /* Texture object bookkeeping +- */ +- unsigned nr_heaps; +- driTexHeap * texture_heaps[ RADEON_NR_TEX_HEAPS ]; +- driTextureObject swapped; +- int texture_depth; +- float initialMaxAnisotropy; +- +- /* Rasterization and vertex state: +- */ +- GLuint TclFallback; +- GLuint Fallback; +- GLuint NewGLState; +- DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ +- + /* Vertex buffers + */ +- struct r200_ioctl ioctl; +- struct r200_dma dma; +- struct r200_store store; +- /* A full state emit as of the first state emit in the main store, in case +- * the context is lost. +- */ +- struct r200_store backup_store; +- +- /* Page flipping +- */ +- GLuint doPageFlip; +- +- /* Busy waiting +- */ +- GLuint do_usleeps; +- GLuint do_irqs; +- GLuint irqsEmitted; +- drm_radeon_irq_wait_t iw; ++ struct radeon_ioctl ioctl; ++ struct radeon_store store; + + /* Clientdata textures; + */ + GLuint prefer_gart_client_texturing; + +- /* Drawable, cliprect and scissor information +- */ +- GLuint numClipRects; /* Cliprects for the draw buffer */ +- drm_clip_rect_t *pClipRects; +- unsigned int lastStamp; +- GLboolean lost_context; +- GLboolean save_on_next_emit; +- radeonScreenPtr r200Screen; /* Screen private DRI data */ +- drm_radeon_sarea_t *sarea; /* Private SAREA data */ +- + /* TCL stuff + */ + GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS]; +@@ -893,15 +603,6 @@ struct r200_context { + GLuint TexGenCompSel; + GLmatrix tmpmat; + +- /* buffer swap +- */ +- int64_t swap_ust; +- int64_t swap_missed_ust; +- +- GLuint swap_count; +- GLuint swap_missed_count; +- +- + /* r200_tcl.c + */ + struct r200_tcl_info tcl; +@@ -910,14 +611,6 @@ struct r200_context { + */ + struct r200_swtcl_info swtcl; + +- /* Mirrors of some DRI state +- */ +- struct r200_dri_mirror dri; +- +- /* Configuration cache +- */ +- driOptionCache optionCache; +- + GLboolean using_hyperz; + GLboolean texmicrotile; + +@@ -927,28 +620,10 @@ struct r200_context { + #define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx)) + + +-static INLINE GLuint r200PackColor( GLuint cpp, +- GLubyte r, GLubyte g, +- GLubyte b, GLubyte a ) +-{ +- switch ( cpp ) { +- case 2: +- return PACK_COLOR_565( r, g, b ); +- case 4: +- return PACK_COLOR_8888( a, r, g, b ); +- default: +- return 0; +- } +-} +- +- + extern void r200DestroyContext( __DRIcontextPrivate *driContextPriv ); + extern GLboolean r200CreateContext( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate); +-extern void r200SwapBuffers( __DRIdrawablePrivate *dPriv ); +-extern void r200CopySubBuffer( __DRIdrawablePrivate * dPriv, +- int x, int y, int w, int h ); + extern GLboolean r200MakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ); +@@ -957,28 +632,9 @@ extern GLboolean r200UnbindContext( __DRIcontextPrivate *driContextPriv ); + /* ================================================================ + * Debugging: + */ +-#define DO_DEBUG 1 + +-#if DO_DEBUG +-extern int R200_DEBUG; +-#else +-#define R200_DEBUG 0 +-#endif ++#define R200_DEBUG RADEON_DEBUG ++ + +-#define DEBUG_TEXTURE 0x001 +-#define DEBUG_STATE 0x002 +-#define DEBUG_IOCTL 0x004 +-#define DEBUG_PRIMS 0x008 +-#define DEBUG_VERTS 0x010 +-#define DEBUG_FALLBACKS 0x020 +-#define DEBUG_VFMT 0x040 +-#define DEBUG_CODEGEN 0x080 +-#define DEBUG_VERBOSE 0x100 +-#define DEBUG_DRI 0x200 +-#define DEBUG_DMA 0x400 +-#define DEBUG_SANITY 0x800 +-#define DEBUG_SYNC 0x1000 +-#define DEBUG_PIXEL 0x2000 +-#define DEBUG_MEMORY 0x4000 + + #endif /* __R200_CONTEXT_H__ */ +diff --git a/src/mesa/drivers/dri/r200/r200_fragshader.c b/src/mesa/drivers/dri/r200/r200_fragshader.c +index d514b28..85c1b7b 100644 +--- a/src/mesa/drivers/dri/r200/r200_fragshader.c ++++ b/src/mesa/drivers/dri/r200/r200_fragshader.c +@@ -522,7 +522,7 @@ static void r200UpdateFSConstants( GLcontext *ctx ) + CLAMPED_FLOAT_TO_UBYTE(con_byte[2], ctx->ATIFragmentShader.GlobalConstants[i][2]); + CLAMPED_FLOAT_TO_UBYTE(con_byte[3], ctx->ATIFragmentShader.GlobalConstants[i][3]); + } +- rmesa->hw.atf.cmd[ATF_TFACTOR_0 + i] = r200PackColor ( ++ rmesa->hw.atf.cmd[ATF_TFACTOR_0 + i] = radeonPackColor ( + 4, con_byte[0], con_byte[1], con_byte[2], con_byte[3] ); + } + } +diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c +index 0741e57..0262aea 100644 +--- a/src/mesa/drivers/dri/r200/r200_ioctl.c ++++ b/src/mesa/drivers/dri/r200/r200_ioctl.c +@@ -41,6 +41,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/context.h" + #include "swrast/swrast.h" + ++ ++ ++#include "radeon_common.h" ++#include "radeon_lock.h" + #include "r200_context.h" + #include "r200_state.h" + #include "r200_ioctl.h" +@@ -54,635 +58,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define R200_TIMEOUT 512 + #define R200_IDLE_RETRY 16 + +- +-static void r200WaitForIdle( r200ContextPtr rmesa ); +- +- +-/* At this point we were in FlushCmdBufLocked but we had lost our context, so +- * we need to unwire our current cmdbuf, hook the one with the saved state in +- * it, flush it, and then put the current one back. This is so commands at the +- * start of a cmdbuf can rely on the state being kept from the previous one. +- */ +-static void r200BackUpAndEmitLostStateLocked( r200ContextPtr rmesa ) +-{ +- GLuint nr_released_bufs; +- struct r200_store saved_store; +- +- if (rmesa->backup_store.cmd_used == 0) +- return; +- +- if (R200_DEBUG & DEBUG_STATE) +- fprintf(stderr, "Emitting backup state on lost context\n"); +- +- rmesa->lost_context = GL_FALSE; +- +- nr_released_bufs = rmesa->dma.nr_released_bufs; +- saved_store = rmesa->store; +- rmesa->dma.nr_released_bufs = 0; +- rmesa->store = rmesa->backup_store; +- r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); +- rmesa->dma.nr_released_bufs = nr_released_bufs; +- rmesa->store = saved_store; +-} +- +-int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ) +-{ +- int ret, i; +- drm_radeon_cmd_buffer_t cmd; +- +- if (rmesa->lost_context) +- r200BackUpAndEmitLostStateLocked( rmesa ); +- +- if (R200_DEBUG & DEBUG_IOCTL) { +- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); +- +- if (0 & R200_DEBUG & DEBUG_VERBOSE) +- for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 ) +- fprintf(stderr, "%d: %x\n", i/4, +- *(int *)(&rmesa->store.cmd_buf[i])); +- } +- +- if (R200_DEBUG & DEBUG_DMA) +- fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__, +- rmesa->dma.nr_released_bufs); +- +- +- if (R200_DEBUG & DEBUG_SANITY) { +- if (rmesa->state.scissor.enabled) +- ret = r200SanityCmdBuffer( rmesa, +- rmesa->state.scissor.numClipRects, +- rmesa->state.scissor.pClipRects); +- else +- ret = r200SanityCmdBuffer( rmesa, +- rmesa->numClipRects, +- rmesa->pClipRects); +- if (ret) { +- fprintf(stderr, "drmSanityCommandWrite: %d\n", ret); +- goto out; +- } +- } +- +- +- if (R200_DEBUG & DEBUG_MEMORY) { +- if (! driValidateTextureHeaps( rmesa->texture_heaps, rmesa->nr_heaps, +- & rmesa->swapped ) ) { +- fprintf( stderr, "%s: texture memory is inconsistent - expect " +- "mangled textures\n", __FUNCTION__ ); +- } +- } +- +- +- cmd.bufsz = rmesa->store.cmd_used; +- cmd.buf = rmesa->store.cmd_buf; +- +- if (rmesa->state.scissor.enabled) { +- cmd.nbox = rmesa->state.scissor.numClipRects; +- cmd.boxes = (drm_clip_rect_t *)rmesa->state.scissor.pClipRects; +- } else { +- cmd.nbox = rmesa->numClipRects; +- cmd.boxes = (drm_clip_rect_t *)rmesa->pClipRects; +- } +- +- ret = drmCommandWrite( rmesa->dri.fd, +- DRM_RADEON_CMDBUF, +- &cmd, sizeof(cmd) ); +- +- if (ret) +- fprintf(stderr, "drmCommandWrite: %d\n", ret); +- +- if (R200_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); +- r200WaitForIdleLocked( rmesa ); +- } +- +- +- out: +- rmesa->store.primnr = 0; +- rmesa->store.statenr = 0; +- rmesa->store.cmd_used = 0; +- rmesa->dma.nr_released_bufs = 0; +- rmesa->save_on_next_emit = 1; +- +- return ret; +-} +- +- +-/* Note: does not emit any commands to avoid recursion on +- * r200AllocCmdBuf. +- */ +-void r200FlushCmdBuf( r200ContextPtr rmesa, const char *caller ) +-{ +- int ret; +- +- LOCK_HARDWARE( rmesa ); +- +- ret = r200FlushCmdBufLocked( rmesa, caller ); +- +- UNLOCK_HARDWARE( rmesa ); +- +- if (ret) { +- fprintf(stderr, "drmRadeonCmdBuffer: %d (exiting)\n", ret); +- exit(ret); +- } +-} +- +- +-/* ============================================================= +- * Hardware vertex buffer handling +- */ +- +- +-void r200RefillCurrentDmaRegion( r200ContextPtr rmesa ) +-{ +- struct r200_dma_buffer *dmabuf; +- int fd = rmesa->dri.fd; +- int index = 0; +- int size = 0; +- drmDMAReq dma; +- int ret; +- +- if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- if (rmesa->dma.flush) { +- rmesa->dma.flush( rmesa ); +- } +- +- if (rmesa->dma.current.buf) +- r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); +- +- if (rmesa->dma.nr_released_bufs > 4) +- r200FlushCmdBuf( rmesa, __FUNCTION__ ); +- +- dma.context = rmesa->dri.hwContext; +- dma.send_count = 0; +- dma.send_list = NULL; +- dma.send_sizes = NULL; +- dma.flags = 0; +- dma.request_count = 1; +- dma.request_size = RADEON_BUFFER_SIZE; +- dma.request_list = &index; +- dma.request_sizes = &size; +- dma.granted_count = 0; +- +- LOCK_HARDWARE(rmesa); /* no need to validate */ +- +- while (1) { +- ret = drmDMA( fd, &dma ); +- if (ret == 0) +- break; +- +- if (rmesa->dma.nr_released_bufs) { +- r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); +- } +- +- if (rmesa->do_usleeps) { +- UNLOCK_HARDWARE( rmesa ); +- DO_USLEEP( 1 ); +- LOCK_HARDWARE( rmesa ); +- } +- } +- +- UNLOCK_HARDWARE(rmesa); +- +- if (R200_DEBUG & DEBUG_DMA) +- fprintf(stderr, "Allocated buffer %d\n", index); +- +- dmabuf = CALLOC_STRUCT( r200_dma_buffer ); +- dmabuf->buf = &rmesa->r200Screen->buffers->list[index]; +- dmabuf->refcount = 1; +- +- rmesa->dma.current.buf = dmabuf; +- rmesa->dma.current.address = dmabuf->buf->address; +- rmesa->dma.current.end = dmabuf->buf->total; +- rmesa->dma.current.start = 0; +- rmesa->dma.current.ptr = 0; +-} +- +-void r200ReleaseDmaRegion( r200ContextPtr rmesa, +- struct r200_dma_region *region, +- const char *caller ) +-{ +- if (R200_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); +- +- if (!region->buf) +- return; +- +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); +- +- if (--region->buf->refcount == 0) { +- drm_radeon_cmd_header_t *cmd; +- +- if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) +- fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__, +- region->buf->buf->idx); +- +- cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, sizeof(*cmd), +- __FUNCTION__ ); +- cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD; +- cmd->dma.buf_idx = region->buf->buf->idx; +- FREE(region->buf); +- rmesa->dma.nr_released_bufs++; +- } +- +- region->buf = NULL; +- region->start = 0; +-} +- +-/* Allocates a region from rmesa->dma.current. If there isn't enough +- * space in current, grab a new buffer (and discard what was left of current) +- */ +-void r200AllocDmaRegion( r200ContextPtr rmesa, +- struct r200_dma_region *region, +- int bytes, +- int alignment ) ++static void r200UserClear(GLcontext *ctx, GLuint mask) + { +- if (R200_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); +- +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); +- +- if (region->buf) +- r200ReleaseDmaRegion( rmesa, region, __FUNCTION__ ); +- +- alignment--; +- rmesa->dma.current.start = rmesa->dma.current.ptr = +- (rmesa->dma.current.ptr + alignment) & ~alignment; +- +- if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) +- r200RefillCurrentDmaRegion( rmesa ); +- +- region->start = rmesa->dma.current.start; +- region->ptr = rmesa->dma.current.start; +- region->end = rmesa->dma.current.start + bytes; +- region->address = rmesa->dma.current.address; +- region->buf = rmesa->dma.current.buf; +- region->buf->refcount++; +- +- rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ +- rmesa->dma.current.start = +- rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7; +- +- assert( rmesa->dma.current.ptr <= rmesa->dma.current.end ); ++ radeon_clear_tris(ctx, mask); + } + +-/* ================================================================ +- * SwapBuffers with client-side throttling +- */ +- +-static uint32_t r200GetLastFrame(r200ContextPtr rmesa) +-{ +- drm_radeon_getparam_t gp; +- int ret; +- uint32_t frame; +- +- gp.param = RADEON_PARAM_LAST_FRAME; +- gp.value = (int *)&frame; +- ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM, +- &gp, sizeof(gp) ); +- if ( ret ) { +- fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret ); +- exit(1); +- } +- +- return frame; +-} +- +-static void r200EmitIrqLocked( r200ContextPtr rmesa ) +-{ +- drm_radeon_irq_emit_t ie; +- int ret; +- +- ie.irq_seq = &rmesa->iw.irq_seq; +- ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_IRQ_EMIT, +- &ie, sizeof(ie) ); +- if ( ret ) { +- fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret ); +- exit(1); +- } +-} +- +- +-static void r200WaitIrq( r200ContextPtr rmesa ) +-{ +- int ret; +- +- do { +- ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_IRQ_WAIT, +- &rmesa->iw, sizeof(rmesa->iw) ); +- } while (ret && (errno == EINTR || errno == EBUSY)); +- +- if ( ret ) { +- fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret ); +- exit(1); +- } +-} +- +- +-static void r200WaitForFrameCompletion( r200ContextPtr rmesa ) +-{ +- drm_radeon_sarea_t *sarea = rmesa->sarea; +- +- if (rmesa->do_irqs) { +- if (r200GetLastFrame(rmesa) < sarea->last_frame) { +- if (!rmesa->irqsEmitted) { +- while (r200GetLastFrame (rmesa) < sarea->last_frame) +- ; +- } +- else { +- UNLOCK_HARDWARE( rmesa ); +- r200WaitIrq( rmesa ); +- LOCK_HARDWARE( rmesa ); +- } +- rmesa->irqsEmitted = 10; +- } +- +- if (rmesa->irqsEmitted) { +- r200EmitIrqLocked( rmesa ); +- rmesa->irqsEmitted--; +- } +- } +- else { +- while (r200GetLastFrame (rmesa) < sarea->last_frame) { +- UNLOCK_HARDWARE( rmesa ); +- if (rmesa->do_usleeps) +- DO_USLEEP( 1 ); +- LOCK_HARDWARE( rmesa ); +- } +- } +-} +- +- +- +-/* Copy the back color buffer to the front color buffer. +- */ +-void r200CopyBuffer( __DRIdrawablePrivate *dPriv, +- const drm_clip_rect_t *rect) +-{ +- r200ContextPtr rmesa; +- GLint nbox, i, ret; +- GLboolean missed_target; +- int64_t ust; +- __DRIscreenPrivate *psp = dPriv->driScreenPriv; +- +- assert(dPriv); +- assert(dPriv->driContextPriv); +- assert(dPriv->driContextPriv->driverPrivate); +- +- rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; +- +- if ( R200_DEBUG & DEBUG_IOCTL ) { +- fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *)rmesa->glCtx ); +- } +- +- R200_FIREVERTICES( rmesa ); +- +- LOCK_HARDWARE( rmesa ); +- +- +- /* Throttle the frame rate -- only allow one pending swap buffers +- * request at a time. +- */ +- r200WaitForFrameCompletion( rmesa ); +- if (!rect) +- { +- UNLOCK_HARDWARE( rmesa ); +- driWaitForVBlank( dPriv, & missed_target ); +- LOCK_HARDWARE( rmesa ); +- } +- +- nbox = dPriv->numClipRects; /* must be in locked region */ +- +- for ( i = 0 ; i < nbox ; ) { +- GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); +- drm_clip_rect_t *box = dPriv->pClipRects; +- drm_clip_rect_t *b = rmesa->sarea->boxes; +- GLint n = 0; +- +- for ( ; i < nr ; i++ ) { +- +- *b = box[i]; +- +- if (rect) +- { +- if (rect->x1 > b->x1) +- b->x1 = rect->x1; +- if (rect->y1 > b->y1) +- b->y1 = rect->y1; +- if (rect->x2 < b->x2) +- b->x2 = rect->x2; +- if (rect->y2 < b->y2) +- b->y2 = rect->y2; +- +- if (b->x1 >= b->x2 || b->y1 >= b->y2) +- continue; +- } +- +- b++; +- n++; +- } +- rmesa->sarea->nbox = n; +- +- if (!n) +- continue; +- +- ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP ); +- +- if ( ret ) { +- fprintf( stderr, "DRM_R200_SWAP_BUFFERS: return = %d\n", ret ); +- UNLOCK_HARDWARE( rmesa ); +- exit( 1 ); +- } +- } +- +- UNLOCK_HARDWARE( rmesa ); +- if (!rect) +- { +- rmesa->hw.all_dirty = GL_TRUE; +- +- rmesa->swap_count++; +- (*psp->systemTime->getUST)( & ust ); +- if ( missed_target ) { +- rmesa->swap_missed_count++; +- rmesa->swap_missed_ust = ust - rmesa->swap_ust; +- } +- +- rmesa->swap_ust = ust; +- +- sched_yield(); +- } +-} +- +-void r200PageFlip( __DRIdrawablePrivate *dPriv ) +-{ +- r200ContextPtr rmesa; +- GLint ret; +- GLboolean missed_target; +- __DRIscreenPrivate *psp = dPriv->driScreenPriv; +- +- assert(dPriv); +- assert(dPriv->driContextPriv); +- assert(dPriv->driContextPriv->driverPrivate); +- +- rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; +- +- if ( R200_DEBUG & DEBUG_IOCTL ) { +- fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, +- rmesa->sarea->pfCurrentPage); +- } +- +- R200_FIREVERTICES( rmesa ); +- LOCK_HARDWARE( rmesa ); +- +- if (!dPriv->numClipRects) { +- UNLOCK_HARDWARE( rmesa ); +- usleep( 10000 ); /* throttle invisible client 10ms */ +- return; +- } +- +- /* Need to do this for the perf box placement: +- */ +- { +- drm_clip_rect_t *box = dPriv->pClipRects; +- drm_clip_rect_t *b = rmesa->sarea->boxes; +- b[0] = box[0]; +- rmesa->sarea->nbox = 1; +- } +- +- /* Throttle the frame rate -- only allow a few pending swap buffers +- * request at a time. +- */ +- r200WaitForFrameCompletion( rmesa ); +- UNLOCK_HARDWARE( rmesa ); +- driWaitForVBlank( dPriv, & missed_target ); +- if ( missed_target ) { +- rmesa->swap_missed_count++; +- (void) (*psp->systemTime->getUST)( & rmesa->swap_missed_ust ); +- } +- LOCK_HARDWARE( rmesa ); +- +- ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); +- +- UNLOCK_HARDWARE( rmesa ); +- +- if ( ret ) { +- fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); +- exit( 1 ); +- } +- +- rmesa->swap_count++; +- (void) (*psp->systemTime->getUST)( & rmesa->swap_ust ); +- +-#if 000 +- if ( rmesa->sarea->pfCurrentPage == 1 ) { +- rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; +- rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch; +- } else { +- rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; +- rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch; +- } +- +- R200_STATECHANGE( rmesa, ctx ); +- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset +- + rmesa->r200Screen->fbLocation; +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; +- if (rmesa->sarea->tiling_enabled) { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; +- } +-#else +- /* Get ready for drawing next frame. Update the renderbuffers' +- * flippedOffset/Pitch fields so we draw into the right place. +- */ +- driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, +- rmesa->sarea->pfCurrentPage); +- +- +- r200UpdateDrawBuffer(rmesa->glCtx); +-#endif +-} +- +- +-/* ================================================================ +- * Buffer clear +- */ +-static void r200Clear( GLcontext *ctx, GLbitfield mask ) ++static void r200KernelClear(GLcontext *ctx, GLuint flags) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; +- GLuint flags = 0; +- GLuint color_mask = 0; +- GLint ret, i; +- GLint cx, cy, cw, ch; +- +- if ( R200_DEBUG & DEBUG_IOCTL ) { +- fprintf( stderr, "r200Clear\n"); +- } +- +- { +- LOCK_HARDWARE( rmesa ); +- UNLOCK_HARDWARE( rmesa ); +- if ( dPriv->numClipRects == 0 ) +- return; +- } +- +- r200Flush( ctx ); +- +- if ( mask & BUFFER_BIT_FRONT_LEFT ) { +- flags |= RADEON_FRONT; +- color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; +- mask &= ~BUFFER_BIT_FRONT_LEFT; +- } +- +- if ( mask & BUFFER_BIT_BACK_LEFT ) { +- flags |= RADEON_BACK; +- color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; +- mask &= ~BUFFER_BIT_BACK_LEFT; +- } ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; ++ GLint cx, cy, cw, ch, ret; ++ GLuint i; + +- if ( mask & BUFFER_BIT_DEPTH ) { +- flags |= RADEON_DEPTH; +- mask &= ~BUFFER_BIT_DEPTH; +- } +- +- if ( (mask & BUFFER_BIT_STENCIL) && rmesa->state.stencil.hwBuffer ) { +- flags |= RADEON_STENCIL; +- mask &= ~BUFFER_BIT_STENCIL; +- } +- +- if ( mask ) { +- if (R200_DEBUG & DEBUG_FALLBACKS) +- fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); +- _swrast_Clear( ctx, mask ); +- } +- +- if ( !flags ) +- return; +- +- if (rmesa->using_hyperz) { +- flags |= RADEON_USE_COMP_ZBUF; +-/* if (rmesa->r200Screen->chip_family == CHIP_FAMILY_R200) +- flags |= RADEON_USE_HIERZ; */ +- if (!(rmesa->state.stencil.hwBuffer) || +- ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && +- ((rmesa->state.stencil.clear & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) { +- flags |= RADEON_CLEAR_FASTZ; +- } +- } +- +- LOCK_HARDWARE( rmesa ); +- +- /* compute region after locking: */ +- cx = ctx->DrawBuffer->_Xmin; +- cy = ctx->DrawBuffer->_Ymin; +- cw = ctx->DrawBuffer->_Xmax - cx; +- ch = ctx->DrawBuffer->_Ymax - cy; +- +- /* Flip top to bottom */ +- cx += dPriv->x; +- cy = dPriv->y + dPriv->h - cy - ch; ++ LOCK_HARDWARE( &rmesa->radeon ); + + /* Throttle the number of clear ioctls we do. + */ +@@ -693,7 +81,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) + + gp.param = RADEON_PARAM_LAST_CLEAR; + gp.value = (int *)&clear; +- ret = drmCommandWriteRead( rmesa->dri.fd, ++ ret = drmCommandWriteRead( rmesa->radeon.dri.fd, + DRM_RADEON_GETPARAM, &gp, sizeof(gp) ); + + if ( ret ) { +@@ -703,24 +91,34 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) + + /* Clear throttling needs more thought. + */ +- if ( rmesa->sarea->last_clear - clear <= 25 ) { ++ if ( rmesa->radeon.sarea->last_clear - clear <= 25 ) { + break; + } + +- if (rmesa->do_usleeps) { +- UNLOCK_HARDWARE( rmesa ); ++ if (rmesa->radeon.do_usleeps) { ++ UNLOCK_HARDWARE( &rmesa->radeon ); + DO_USLEEP( 1 ); +- LOCK_HARDWARE( rmesa ); ++ LOCK_HARDWARE( &rmesa->radeon ); + } + } + + /* Send current state to the hardware */ +- r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); ++ rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ ); ++ ++ ++ /* compute region after locking: */ ++ cx = ctx->DrawBuffer->_Xmin; ++ cy = ctx->DrawBuffer->_Ymin; ++ cw = ctx->DrawBuffer->_Xmax - cx; ++ ch = ctx->DrawBuffer->_Ymax - cy; + ++ /* Flip top to bottom */ ++ cx += dPriv->x; ++ cy = dPriv->y + dPriv->h - cy - ch; + for ( i = 0 ; i < dPriv->numClipRects ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects ); + drm_clip_rect_t *box = dPriv->pClipRects; +- drm_clip_rect_t *b = rmesa->sarea->boxes; ++ drm_clip_rect_t *b = rmesa->radeon.sarea->boxes; + drm_radeon_clear_t clear; + drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; + GLint n = 0; +@@ -755,17 +153,17 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) + } + } + +- rmesa->sarea->nbox = n; ++ rmesa->radeon.sarea->nbox = n; + + clear.flags = flags; +- clear.clear_color = rmesa->state.color.clear; +- clear.clear_depth = rmesa->state.depth.clear; /* needed for hyperz */ ++ clear.clear_color = rmesa->radeon.state.color.clear; ++ clear.clear_depth = rmesa->radeon.state.depth.clear; /* needed for hyperz */ + clear.color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; +- clear.depth_mask = rmesa->state.stencil.clear; ++ clear.depth_mask = rmesa->radeon.state.stencil.clear; + clear.depth_boxes = depth_boxes; + + n--; +- b = rmesa->sarea->boxes; ++ b = rmesa->radeon.sarea->boxes; + for ( ; n >= 0 ; n-- ) { + depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1; + depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1; +@@ -774,84 +172,91 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) + depth_boxes[n].f[CLEAR_DEPTH] = ctx->Depth.Clear; + } + +- ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR, ++ ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_CLEAR, + &clear, sizeof(clear)); + + + if ( ret ) { +- UNLOCK_HARDWARE( rmesa ); ++ UNLOCK_HARDWARE( &rmesa->radeon ); + fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret ); + exit( 1 ); + } + } +- +- UNLOCK_HARDWARE( rmesa ); +- rmesa->hw.all_dirty = GL_TRUE; ++ UNLOCK_HARDWARE( &rmesa->radeon ); + } ++/* ================================================================ ++ * Buffer clear ++ */ ++static void r200Clear( GLcontext *ctx, GLbitfield mask ) ++{ ++ r200ContextPtr rmesa = R200_CONTEXT(ctx); ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; ++ GLuint flags = 0; ++ GLuint color_mask = 0; ++ GLuint orig_mask = mask; + ++ if ( R200_DEBUG & DEBUG_IOCTL ) { ++ fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage); ++ } + +-void r200WaitForIdleLocked( r200ContextPtr rmesa ) +-{ +- int ret; +- int i = 0; +- +- do { +- ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_CP_IDLE); +- if (ret) +- DO_USLEEP( 1 ); +- } while (ret && ++i < 100); +- +- if ( ret < 0 ) { +- UNLOCK_HARDWARE( rmesa ); +- fprintf( stderr, "Error: R200 timed out... exiting\n" ); +- exit( -1 ); +- } +-} ++ { ++ LOCK_HARDWARE( &rmesa->radeon ); ++ UNLOCK_HARDWARE( &rmesa->radeon ); ++ if ( dPriv->numClipRects == 0 ) ++ return; ++ } + ++ radeonFlush( ctx ); + +-static void r200WaitForIdle( r200ContextPtr rmesa ) +-{ +- LOCK_HARDWARE(rmesa); +- r200WaitForIdleLocked( rmesa ); +- UNLOCK_HARDWARE(rmesa); +-} ++ if ( mask & BUFFER_BIT_FRONT_LEFT ) { ++ flags |= RADEON_FRONT; ++ color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; ++ mask &= ~BUFFER_BIT_FRONT_LEFT; ++ } + ++ if ( mask & BUFFER_BIT_BACK_LEFT ) { ++ flags |= RADEON_BACK; ++ color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; ++ mask &= ~BUFFER_BIT_BACK_LEFT; ++ } + +-void r200Flush( GLcontext *ctx ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT( ctx ); ++ if ( mask & BUFFER_BIT_DEPTH ) { ++ flags |= RADEON_DEPTH; ++ mask &= ~BUFFER_BIT_DEPTH; ++ } + +- if (R200_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s\n", __FUNCTION__); ++ if ( (mask & BUFFER_BIT_STENCIL) ) { ++ flags |= RADEON_STENCIL; ++ mask &= ~BUFFER_BIT_STENCIL; ++ } + +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); ++ if ( mask ) { ++ if (R200_DEBUG & DEBUG_FALLBACKS) ++ fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); ++ _swrast_Clear( ctx, mask ); ++ } + +- r200EmitState( rmesa ); +- +- if (rmesa->store.cmd_used) +- r200FlushCmdBuf( rmesa, __FUNCTION__ ); +-} ++ if ( !flags ) ++ return; + +-/* Make sure all commands have been sent to the hardware and have +- * completed processing. +- */ +-void r200Finish( GLcontext *ctx ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- r200Flush( ctx ); ++ if (rmesa->using_hyperz) { ++ flags |= RADEON_USE_COMP_ZBUF; ++/* if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) ++ flags |= RADEON_USE_HIERZ; */ ++ if (!((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && ++ ((rmesa->radeon.state.stencil.clear & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) { ++ flags |= RADEON_CLEAR_FASTZ; ++ } ++ } + +- if (rmesa->do_irqs) { +- LOCK_HARDWARE( rmesa ); +- r200EmitIrqLocked( rmesa ); +- UNLOCK_HARDWARE( rmesa ); +- r200WaitIrq( rmesa ); ++ if (rmesa->radeon.radeonScreen->kernel_mm) ++ r200UserClear(ctx, orig_mask); ++ else { ++ r200KernelClear(ctx, flags); ++ rmesa->radeon.hw.all_dirty = GL_TRUE; + } +- else +- r200WaitForIdle( rmesa ); + } + +- + /* This version of AllocateMemoryMESA allocates only GART memory, and + * only does so after the point at which the driver has been + * initialized. +@@ -875,7 +280,7 @@ void *r200AllocateMemoryMESA(__DRIscreen *screen, GLsizei size, + fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq, + writefreq, priority); + +- if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->r200Screen->gartTextures.map) ++ if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->radeon.radeonScreen->gartTextures.map) + return NULL; + + if (getenv("R200_NO_ALLOC")) +@@ -886,7 +291,7 @@ void *r200AllocateMemoryMESA(__DRIscreen *screen, GLsizei size, + alloc.size = size; + alloc.region_offset = ®ion_offset; + +- ret = drmCommandWriteRead( rmesa->r200Screen->driScreen->fd, ++ ret = drmCommandWriteRead( rmesa->radeon.radeonScreen->driScreen->fd, + DRM_RADEON_ALLOC, + &alloc, sizeof(alloc)); + +@@ -896,7 +301,7 @@ void *r200AllocateMemoryMESA(__DRIscreen *screen, GLsizei size, + } + + { +- char *region_start = (char *)rmesa->r200Screen->gartTextures.map; ++ char *region_start = (char *)rmesa->radeon.radeonScreen->gartTextures.map; + return (void *)(region_start + region_offset); + } + } +@@ -914,24 +319,24 @@ void r200FreeMemoryMESA(__DRIscreen *screen, GLvoid *pointer) + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %p\n", __FUNCTION__, pointer); + +- if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->r200Screen->gartTextures.map) { ++ if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->radeon.radeonScreen->gartTextures.map) { + fprintf(stderr, "%s: no context\n", __FUNCTION__); + return; + } + +- region_offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map; ++ region_offset = (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map; + + if (region_offset < 0 || +- region_offset > rmesa->r200Screen->gartTextures.size) { ++ region_offset > rmesa->radeon.radeonScreen->gartTextures.size) { + fprintf(stderr, "offset %d outside range 0..%d\n", region_offset, +- rmesa->r200Screen->gartTextures.size); ++ rmesa->radeon.radeonScreen->gartTextures.size); + return; + } + + memfree.region = RADEON_MEM_REGION_GART; + memfree.region_offset = region_offset; + +- ret = drmCommandWrite( rmesa->r200Screen->driScreen->fd, ++ ret = drmCommandWrite( rmesa->radeon.radeonScreen->driScreen->fd, + DRM_RADEON_FREE, + &memfree, sizeof(memfree)); + +@@ -956,16 +361,16 @@ GLuint r200GetMemoryOffsetMESA(__DRIscreen *screen, const GLvoid *pointer) + + card_offset = r200GartOffsetFromVirtual( rmesa, pointer ); + +- return card_offset - rmesa->r200Screen->gart_base; ++ return card_offset - rmesa->radeon.radeonScreen->gart_base; + } + + GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer, + GLint size ) + { +- ptrdiff_t offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map; ++ ptrdiff_t offset = (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map; + int valid = (size >= 0 && + offset >= 0 && +- offset + size < rmesa->r200Screen->gartTextures.size); ++ offset + size < rmesa->radeon.radeonScreen->gartTextures.size); + + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "r200IsGartMemory( %p ) : %d\n", pointer, valid ); +@@ -976,12 +381,12 @@ GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer, + + GLuint r200GartOffsetFromVirtual( r200ContextPtr rmesa, const GLvoid *pointer ) + { +- ptrdiff_t offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map; ++ ptrdiff_t offset = (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map; + +- if (offset < 0 || offset > rmesa->r200Screen->gartTextures.size) ++ if (offset < 0 || offset > rmesa->radeon.radeonScreen->gartTextures.size) + return ~0; + else +- return rmesa->r200Screen->gart_texture_offset + offset; ++ return rmesa->radeon.radeonScreen->gart_texture_offset + offset; + } + + +@@ -989,7 +394,7 @@ GLuint r200GartOffsetFromVirtual( r200ContextPtr rmesa, const GLvoid *pointer ) + void r200InitIoctlFuncs( struct dd_function_table *functions ) + { + functions->Clear = r200Clear; +- functions->Finish = r200Finish; +- functions->Flush = r200Flush; ++ functions->Finish = radeonFinish; ++ functions->Flush = radeonFlush; + } + +diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h +index f7458e4..2a4b8a1 100644 +--- a/src/mesa/drivers/dri/r200/r200_ioctl.h ++++ b/src/mesa/drivers/dri/r200/r200_ioctl.h +@@ -37,65 +37,30 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #include "main/simple_list.h" + #include "radeon_dri.h" +-#include "r200_lock.h" ++ ++#include "radeon_bocs_wrapper.h" + + #include "xf86drm.h" + #include "drm.h" + #include "radeon_drm.h" + +-extern void r200EmitState( r200ContextPtr rmesa ); + extern void r200EmitVertexAOS( r200ContextPtr rmesa, +- GLuint vertex_size, +- GLuint offset ); ++ GLuint vertex_size, ++ struct radeon_bo *bo, ++ GLuint offset ); + + extern void r200EmitVbufPrim( r200ContextPtr rmesa, + GLuint primitive, + GLuint vertex_nr ); + +-extern void r200FlushElts( r200ContextPtr rmesa ); ++extern void r200FlushElts(GLcontext *ctx); + + extern GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, + GLuint primitive, + GLuint min_nr ); + +-extern void r200EmitAOS( r200ContextPtr rmesa, +- struct r200_dma_region **regions, +- GLuint n, +- GLuint offset ); +- +-extern void r200EmitBlit( r200ContextPtr rmesa, +- GLuint color_fmt, +- GLuint src_pitch, +- GLuint src_offset, +- GLuint dst_pitch, +- GLuint dst_offset, +- GLint srcx, GLint srcy, +- GLint dstx, GLint dsty, +- GLuint w, GLuint h ); +- +-extern void r200EmitWait( r200ContextPtr rmesa, GLuint flags ); +- +-extern void r200FlushCmdBuf( r200ContextPtr rmesa, const char * ); +-extern int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ); +- +-extern void r200RefillCurrentDmaRegion( r200ContextPtr rmesa ); +- +-extern void r200AllocDmaRegion( r200ContextPtr rmesa, +- struct r200_dma_region *region, +- int bytes, +- int alignment ); +- +-extern void r200ReleaseDmaRegion( r200ContextPtr rmesa, +- struct r200_dma_region *region, +- const char *caller ); +- +-extern void r200CopyBuffer( __DRIdrawablePrivate *drawable, +- const drm_clip_rect_t *rect); +-extern void r200PageFlip( __DRIdrawablePrivate *drawable ); +-extern void r200Flush( GLcontext *ctx ); +-extern void r200Finish( GLcontext *ctx ); +-extern void r200WaitForIdleLocked( r200ContextPtr rmesa ); +-extern void r200WaitForVBlank( r200ContextPtr rmesa ); ++extern void r200EmitAOS(r200ContextPtr rmesa, GLuint nr, GLuint offset); ++ + extern void r200InitIoctlFuncs( struct dd_function_table *functions ); + + extern void *r200AllocateMemoryMESA( __DRIscreen *screen, GLsizei size, GLfloat readfreq, +@@ -119,8 +84,8 @@ void r200SetUpAtomList( r200ContextPtr rmesa ); + */ + #define R200_NEWPRIM( rmesa ) \ + do { \ +- if ( rmesa->dma.flush ) \ +- rmesa->dma.flush( rmesa ); \ ++ if ( rmesa->radeon.dma.flush ) \ ++ rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); \ + } while (0) + + /* Can accomodate several state changes and primitive changes without +@@ -130,7 +95,7 @@ do { \ + do { \ + R200_NEWPRIM( rmesa ); \ + rmesa->hw.ATOM.dirty = GL_TRUE; \ +- rmesa->hw.is_dirty = GL_TRUE; \ ++ rmesa->radeon.hw.is_dirty = GL_TRUE; \ + } while (0) + + #define R200_DB_STATE( ATOM ) \ +@@ -139,13 +104,13 @@ do { \ + + static INLINE int R200_DB_STATECHANGE( + r200ContextPtr rmesa, +- struct r200_state_atom *atom ) ++ struct radeon_state_atom *atom ) + { + if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size*4)) { +- int *tmp; ++ GLuint *tmp; + R200_NEWPRIM( rmesa ); + atom->dirty = GL_TRUE; +- rmesa->hw.is_dirty = GL_TRUE; ++ rmesa->radeon.hw.is_dirty = GL_TRUE; + tmp = atom->cmd; + atom->cmd = atom->lastcmd; + atom->lastcmd = tmp; +@@ -156,15 +121,6 @@ static INLINE int R200_DB_STATECHANGE( + } + + +-/* Fire the buffered vertices no matter what. +- */ +-#define R200_FIREVERTICES( rmesa ) \ +-do { \ +- if ( rmesa->store.cmd_used || rmesa->dma.flush ) { \ +- r200Flush( rmesa->glCtx ); \ +- } \ +-} while (0) +- + /* Command lengths. Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ + * are available, you will also be adding an rmesa->state.max_state_size because + * r200EmitState is called from within r200EmitVbufPrim and r200FlushElts. +@@ -174,36 +130,36 @@ do { \ + #define ELTS_BUFSZ(nr) (12 + nr * 2) + #define VBUF_BUFSZ (3 * sizeof(int)) + +-/* Ensure that a minimum amount of space is available in the command buffer. +- * This is used to ensure atomicity of state updates with the rendering requests +- * that rely on them. +- * +- * An alternative would be to implement a "soft lock" such that when the buffer +- * wraps at an inopportune time, we grab the lock, flush the current buffer, +- * and hang on to the lock until the critical section is finished and we flush +- * the buffer again and unlock. +- */ +-static INLINE void r200EnsureCmdBufSpace( r200ContextPtr rmesa, int bytes ) ++static inline uint32_t cmdpacket3(int cmd_type) + { +- if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) +- r200FlushCmdBuf( rmesa, __FUNCTION__ ); +- assert( bytes <= R200_CMD_BUF_SZ ); +-} ++ drm_radeon_cmd_header_t cmd; + +-/* Alloc space in the command buffer +- */ +-static INLINE char *r200AllocCmdBuf( r200ContextPtr rmesa, +- int bytes, const char *where ) +-{ +- char * head; ++ cmd.i = 0; ++ cmd.header.cmd_type = cmd_type; + +- if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) +- r200FlushCmdBuf( rmesa, where ); ++ return (uint32_t)cmd.i; + +- head = rmesa->store.cmd_buf + rmesa->store.cmd_used; +- rmesa->store.cmd_used += bytes; +- assert( rmesa->store.cmd_used <= R200_CMD_BUF_SZ ); +- return head; + } + ++#define OUT_BATCH_PACKET3(packet, num_extra) do { \ ++ if (!b_l_rmesa->radeonScreen->kernel_mm) { \ ++ OUT_BATCH(cmdpacket3(RADEON_CMD_PACKET3)); \ ++ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ ++ } else { \ ++ OUT_BATCH(CP_PACKET2); \ ++ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ ++ } \ ++ } while(0) ++ ++#define OUT_BATCH_PACKET3_CLIP(packet, num_extra) do { \ ++ if (!b_l_rmesa->radeonScreen->kernel_mm) { \ ++ OUT_BATCH(cmdpacket3(RADEON_CMD_PACKET3_CLIP)); \ ++ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ ++ } else { \ ++ OUT_BATCH(CP_PACKET2); \ ++ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ ++ } \ ++ } while(0) ++ ++ + #endif /* __R200_IOCTL_H__ */ +diff --git a/src/mesa/drivers/dri/r200/r200_lock.c b/src/mesa/drivers/dri/r200/r200_lock.c +deleted file mode 100644 +index 99661a4..0000000 +--- a/src/mesa/drivers/dri/r200/r200_lock.c ++++ /dev/null +@@ -1,116 +0,0 @@ +-/* +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Keith Whitwell +- */ +- +-#include "r200_context.h" +-#include "r200_lock.h" +-#include "r200_tex.h" +-#include "r200_state.h" +-#include "r200_ioctl.h" +- +-#include "drirenderbuffer.h" +- +- +-#if DEBUG_LOCKING +-char *prevLockFile = NULL; +-int prevLockLine = 0; +-#endif +- +-/* Turn on/off page flipping according to the flags in the sarea: +- */ +-static void +-r200UpdatePageFlipping( r200ContextPtr rmesa ) +-{ +- rmesa->doPageFlip = rmesa->sarea->pfState; +- if (rmesa->glCtx->WinSysDrawBuffer) { +- driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, +- rmesa->sarea->pfCurrentPage); +- } +-} +- +- +- +-/* Update the hardware state. This is called if another main/context.has +- * grabbed the hardware lock, which includes the X server. This +- * function also updates the driver's window state after the X server +- * moves, resizes or restacks a window -- the change will be reflected +- * in the drawable position and clip rects. Since the X server grabs +- * the hardware lock when it changes the window state, this routine will +- * automatically be called after such a change. +- */ +-void r200GetLock( r200ContextPtr rmesa, GLuint flags ) +-{ +- __DRIdrawablePrivate *drawable = rmesa->dri.drawable; +- __DRIdrawablePrivate *readable = rmesa->dri.readable; +- __DRIscreenPrivate *sPriv = rmesa->dri.screen; +- drm_radeon_sarea_t *sarea = rmesa->sarea; +- int i; +- +- drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags ); +- +- /* The window might have moved, so we might need to get new clip +- * rects. +- * +- * NOTE: This releases and regrabs the hw lock to allow the X server +- * to respond to the DRI protocol request for new drawable info. +- * Since the hardware state depends on having the latest drawable +- * clip rects, all state checking must be done _after_ this call. +- */ +- DRI_VALIDATE_DRAWABLE_INFO( sPriv, drawable ); +- if (drawable != readable) { +- DRI_VALIDATE_DRAWABLE_INFO( sPriv, readable ); +- } +- +- if ( rmesa->lastStamp != drawable->lastStamp ) { +- r200UpdatePageFlipping( rmesa ); +- r200SetCliprects( rmesa ); +- r200UpdateViewportOffset( rmesa->glCtx ); +- driUpdateFramebufferSize(rmesa->glCtx, drawable); +- } +- +- R200_STATECHANGE( rmesa, ctx ); +- if (rmesa->sarea->tiling_enabled) { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; +- } +- else rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ~R200_COLOR_TILE_ENABLE; +- +- if ( sarea->ctx_owner != rmesa->dri.hwContext ) { +- sarea->ctx_owner = rmesa->dri.hwContext; +- } +- +- for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { +- DRI_AGE_TEXTURES( rmesa->texture_heaps[ i ] ); +- } +- +- rmesa->lost_context = GL_TRUE; +-} +diff --git a/src/mesa/drivers/dri/r200/r200_lock.h b/src/mesa/drivers/dri/r200/r200_lock.h +deleted file mode 100644 +index 4ff9890..0000000 +--- a/src/mesa/drivers/dri/r200/r200_lock.h ++++ /dev/null +@@ -1,106 +0,0 @@ +-/* +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Keith Whitwell +- */ +- +-#ifndef __R200_LOCK_H__ +-#define __R200_LOCK_H__ +- +-extern void r200GetLock( r200ContextPtr rmesa, GLuint flags ); +- +-/* Turn DEBUG_LOCKING on to find locking conflicts. +- */ +-#define DEBUG_LOCKING 0 +- +-#if DEBUG_LOCKING +-extern char *prevLockFile; +-extern int prevLockLine; +- +-#define DEBUG_LOCK() \ +- do { \ +- prevLockFile = (__FILE__); \ +- prevLockLine = (__LINE__); \ +- } while (0) +- +-#define DEBUG_RESET() \ +- do { \ +- prevLockFile = 0; \ +- prevLockLine = 0; \ +- } while (0) +- +-#define DEBUG_CHECK_LOCK() \ +- do { \ +- if ( prevLockFile ) { \ +- fprintf( stderr, \ +- "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ +- prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ +- exit( 1 ); \ +- } \ +- } while (0) +- +-#else +- +-#define DEBUG_LOCK() +-#define DEBUG_RESET() +-#define DEBUG_CHECK_LOCK() +- +-#endif +- +-/* +- * !!! We may want to separate locks from locks with validation. This +- * could be used to improve performance for those things commands that +- * do not do any drawing !!! +- */ +- +- +-/* Lock the hardware and validate our state. +- */ +-#define LOCK_HARDWARE( rmesa ) \ +- do { \ +- char __ret = 0; \ +- DEBUG_CHECK_LOCK(); \ +- DRM_CAS( rmesa->dri.hwLock, rmesa->dri.hwContext, \ +- (DRM_LOCK_HELD | rmesa->dri.hwContext), __ret ); \ +- if ( __ret ) \ +- r200GetLock( rmesa, 0 ); \ +- DEBUG_LOCK(); \ +- } while (0) +- +-#define UNLOCK_HARDWARE( rmesa ) \ +- do { \ +- DRM_UNLOCK( rmesa->dri.fd, \ +- rmesa->dri.hwLock, \ +- rmesa->dri.hwContext ); \ +- DEBUG_RESET(); \ +- } while (0) +- +-#endif /* __R200_LOCK_H__ */ +diff --git a/src/mesa/drivers/dri/r200/r200_maos.h b/src/mesa/drivers/dri/r200/r200_maos.h +index d3ed06d..16a7047 100644 +--- a/src/mesa/drivers/dri/r200/r200_maos.h ++++ b/src/mesa/drivers/dri/r200/r200_maos.h +@@ -38,6 +38,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r200_context.h" + + extern void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ); +-extern void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ); + + #endif +diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c +index 8512b9a..383a0c4 100644 +--- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c ++++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c +@@ -50,110 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r200_maos.h" + #include "r200_tcl.h" + +- +-#if 0 +-/* Usage: +- * - from r200_tcl_render +- * - call r200EmitArrays to ensure uptodate arrays in dma +- * - emit primitives (new type?) which reference the data +- * -- need to use elts for lineloop, quads, quadstrip/flat +- * -- other primitives are all well-formed (need tristrip-1,fake-poly) +- * +- */ +-static void emit_ubyte_rgba3( GLcontext *ctx, +- struct r200_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- r200_color_t *out = (r200_color_t *)(rvb->start + rvb->address); +- +- if (R200_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d out %p\n", +- __FUNCTION__, count, stride, (void *)out); +- +- for (i = 0; i < count; i++) { +- out->red = *data; +- out->green = *(data+1); +- out->blue = *(data+2); +- out->alpha = 0xFF; +- out++; +- data += stride; +- } +-} +- +-static void emit_ubyte_rgba4( GLcontext *ctx, +- struct r200_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (R200_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d\n", +- __FUNCTION__, count, stride); +- +- if (stride == 4) { +- for (i = 0; i < count; i++) +- ((int *)out)[i] = LE32_TO_CPU(((int *)data)[i]); +- } else { +- for (i = 0; i < count; i++) { +- *(int *)out++ = LE32_TO_CPU(*(int *)data); +- data += stride; +- } +- } +-} +- +- +-static void emit_ubyte_rgba( GLcontext *ctx, +- struct r200_dma_region *rvb, +- char *data, +- int size, +- int stride, +- int count ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- +- if (R200_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); +- +- assert (!rvb->buf); +- +- if (stride == 0) { +- r200AllocDmaRegion( rmesa, rvb, 4, 4 ); +- count = 1; +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 0; +- rvb->aos_size = 1; +- } +- else { +- r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */ +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 1; +- rvb->aos_size = 1; +- } +- +- /* Emit the data +- */ +- switch (size) { +- case 3: +- emit_ubyte_rgba3( ctx, rvb, data, stride, count ); +- break; +- case 4: +- emit_ubyte_rgba4( ctx, rvb, data, stride, count ); +- break; +- default: +- assert(0); +- exit(1); +- break; +- } +-} +-#endif +- +- + #if defined(USE_X86_ASM) + #define COPY_DWORDS( dst, src, nr ) \ + do { \ +@@ -174,204 +70,34 @@ do { \ + } while (0) + #endif + +- +-static void emit_vecfog( GLcontext *ctx, +- struct r200_dma_region *rvb, +- char *data, +- int stride, +- int count ) ++static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, ++ GLvoid *data, int stride, int count) + { +- int i; +- GLfloat *out; +- +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- +- if (R200_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d\n", +- __FUNCTION__, count, stride); +- +- assert (!rvb->buf); +- +- if (stride == 0) { +- r200AllocDmaRegion( rmesa, rvb, 4, 4 ); +- count = 1; +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 0; +- rvb->aos_size = 1; +- } +- else { +- r200AllocDmaRegion( rmesa, rvb, count * 4, 4 ); /* alignment? */ +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 1; +- rvb->aos_size = 1; +- } +- +- /* Emit the data +- */ +- out = (GLfloat *)(rvb->address + rvb->start); +- for (i = 0; i < count; i++) { +- out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data ); +- out++; +- data += stride; +- } +- ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ uint32_t *out; ++ int i; ++ int size = 1; ++ ++ if (stride == 0) { ++ radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); ++ count = 1; ++ aos->stride = 0; ++ } else { ++ radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); ++ aos->stride = size; ++ } ++ ++ aos->components = size; ++ aos->count = count; ++ ++ out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); ++ for (i = 0; i < count; i++) { ++ out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data ); ++ out++; ++ data += stride; ++ } + } + +- +-static void emit_vec4( GLcontext *ctx, +- struct r200_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (R200_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d\n", +- __FUNCTION__, count, stride); +- +- if (stride == 4) +- COPY_DWORDS( out, data, count ); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out++; +- data += stride; +- } +-} +- +- +-static void emit_vec8( GLcontext *ctx, +- struct r200_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (R200_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d\n", +- __FUNCTION__, count, stride); +- +- if (stride == 8) +- COPY_DWORDS( out, data, count*2 ); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out[1] = *(int *)(data+4); +- out += 2; +- data += stride; +- } +-} +- +-static void emit_vec12( GLcontext *ctx, +- struct r200_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (R200_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d out %p data %p\n", +- __FUNCTION__, count, stride, (void *)out, (void *)data); +- +- if (stride == 12) +- COPY_DWORDS( out, data, count*3 ); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out[1] = *(int *)(data+4); +- out[2] = *(int *)(data+8); +- out += 3; +- data += stride; +- } +-} +- +-static void emit_vec16( GLcontext *ctx, +- struct r200_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (R200_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d\n", +- __FUNCTION__, count, stride); +- +- if (stride == 16) +- COPY_DWORDS( out, data, count*4 ); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out[1] = *(int *)(data+4); +- out[2] = *(int *)(data+8); +- out[3] = *(int *)(data+12); +- out += 4; +- data += stride; +- } +-} +- +- +-static void emit_vector( GLcontext *ctx, +- struct r200_dma_region *rvb, +- char *data, +- int size, +- int stride, +- int count ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- +- if (R200_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d size %d stride %d\n", +- __FUNCTION__, count, size, stride); +- +- assert (!rvb->buf); +- +- if (stride == 0) { +- r200AllocDmaRegion( rmesa, rvb, size * 4, 4 ); +- count = 1; +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 0; +- rvb->aos_size = size; +- } +- else { +- r200AllocDmaRegion( rmesa, rvb, size * count * 4, 4 ); /* alignment? */ +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = size; +- rvb->aos_size = size; +- } +- +- /* Emit the data +- */ +- switch (size) { +- case 1: +- emit_vec4( ctx, rvb, data, stride, count ); +- break; +- case 2: +- emit_vec8( ctx, rvb, data, stride, count ); +- break; +- case 3: +- emit_vec12( ctx, rvb, data, stride, count ); +- break; +- case 4: +- emit_vec16( ctx, rvb, data, stride, count ); +- break; +- default: +- assert(0); +- exit(1); +- break; +- } +- +-} +- +- +- + /* Emit any changed arrays to new GART memory, re-emit a packet to + * update the arrays. + */ +@@ -379,12 +105,12 @@ void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ) + { + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; +- struct r200_dma_region **component = rmesa->tcl.aos_components; + GLuint nr = 0; + GLuint vfmt0 = 0, vfmt1 = 0; + GLuint count = VB->Count; + GLuint i, emitsize; + ++ // fprintf(stderr,"emit arrays\n"); + for ( i = 0; i < 15; i++ ) { + GLubyte attrib = vimap_rev[i]; + if (attrib != 255) { +@@ -416,20 +142,20 @@ void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ) + case 3: + /* special handling to fix up fog. Will get us into trouble with vbos...*/ + assert(attrib == VERT_ATTRIB_FOG); +- if (!rmesa->tcl.vertex_data[i].buf) { ++ if (!rmesa->radeon.tcl.aos[i].bo) { + if (ctx->VertexProgram._Enabled) +- emit_vector( ctx, +- &(rmesa->tcl.vertex_data[i]), +- (char *)VB->AttribPtr[attrib]->data, +- 1, +- VB->AttribPtr[attrib]->stride, +- count); ++ rcommon_emit_vector( ctx, ++ &(rmesa->radeon.tcl.aos[nr]), ++ (char *)VB->AttribPtr[attrib]->data, ++ 1, ++ VB->AttribPtr[attrib]->stride, ++ count); + else +- emit_vecfog( ctx, +- &(rmesa->tcl.vertex_data[i]), +- (char *)VB->AttribPtr[attrib]->data, +- VB->AttribPtr[attrib]->stride, +- count); ++ r200_emit_vecfog( ctx, ++ &(rmesa->radeon.tcl.aos[nr]), ++ (char *)VB->AttribPtr[attrib]->data, ++ VB->AttribPtr[attrib]->stride, ++ count); + } + vfmt0 |= R200_VTX_DISCRETE_FOG; + goto after_emit; +@@ -473,17 +199,17 @@ void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ) + default: + assert(0); + } +- if (!rmesa->tcl.vertex_data[i].buf) { +- emit_vector( ctx, +- &(rmesa->tcl.vertex_data[i]), +- (char *)VB->AttribPtr[attrib]->data, +- emitsize, +- VB->AttribPtr[attrib]->stride, +- count ); ++ if (!rmesa->radeon.tcl.aos[nr].bo) { ++ rcommon_emit_vector( ctx, ++ &(rmesa->radeon.tcl.aos[nr]), ++ (char *)VB->AttribPtr[attrib]->data, ++ emitsize, ++ VB->AttribPtr[attrib]->stride, ++ count ); + } + after_emit: + assert(nr < 12); +- component[nr++] = &rmesa->tcl.vertex_data[i]; ++ nr++; + } + } + +@@ -494,19 +220,6 @@ after_emit: + rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1; + } + +- rmesa->tcl.nr_aos_components = nr; ++ rmesa->radeon.tcl.aos_count = nr; + } + +- +-void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT( ctx ); +- +- /* only do it for changed inputs ? */ +- int i; +- for (i = 0; i < 15; i++) { +- if (newinputs & (1 << i)) +- r200ReleaseDmaRegion( rmesa, +- &rmesa->tcl.vertex_data[i], __FUNCTION__ ); +- } +-} +diff --git a/src/mesa/drivers/dri/r200/r200_pixel.c b/src/mesa/drivers/dri/r200/r200_pixel.c +index 2797cbb..354daef 100644 +--- a/src/mesa/drivers/dri/r200/r200_pixel.c ++++ b/src/mesa/drivers/dri/r200/r200_pixel.c +@@ -51,7 +51,7 @@ check_color( const GLcontext *ctx, GLenum type, GLenum format, + const void *pixels, GLint sz, GLint pitch ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- GLuint cpp = rmesa->r200Screen->cpp; ++ GLuint cpp = rmesa->radeon.radeonScreen->cpp; + + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); +@@ -137,8 +137,8 @@ clip_pixelrect( const GLcontext *ctx, + if (*height <= 0) + return GL_FALSE; + +- *size = ((*y + *height - 1) * rmesa->r200Screen->frontPitch + +- (*x + *width - 1) * rmesa->r200Screen->cpp); ++ *size = ((*y + *height - 1) * rmesa->radeon.radeonScreen->frontPitch + ++ (*x + *width - 1) * rmesa->radeon.radeonScreen->cpp); + + return GL_TRUE; + } +@@ -153,19 +153,20 @@ r200TryReadPixels( GLcontext *ctx, + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLint pitch = pack->RowLength ? pack->RowLength : width; + GLint blit_format; +- GLuint cpp = rmesa->r200Screen->cpp; ++ GLuint cpp = rmesa->radeon.radeonScreen->cpp; + GLint size = width * height * cpp; + ++ return GL_FALSE; ++#if 0 + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* Only accelerate reading to GART buffers. + */ + if ( !r200IsGartMemory(rmesa, pixels, +- pitch * height * rmesa->r200Screen->cpp ) ) { ++ pitch * height * rmesa->radeon.radeonScreen->cpp ) ) { + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: dest not GART\n", __FUNCTION__); +- return GL_FALSE; + } + + /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from +@@ -180,7 +181,7 @@ r200TryReadPixels( GLcontext *ctx, + if (!check_color(ctx, type, format, pack, pixels, size, pitch)) + return GL_FALSE; + +- switch ( rmesa->r200Screen->cpp ) { ++ switch ( rmesa->radeon.radeonScreen->cpp ) { + case 4: + blit_format = R200_CP_COLOR_FORMAT_ARGB8888; + break; +@@ -197,14 +198,14 @@ r200TryReadPixels( GLcontext *ctx, + * a full command buffer expects to be called unlocked. As a + * workaround, immediately flush the buffer on aquiring the lock. + */ +- LOCK_HARDWARE( rmesa ); ++ LOCK_HARDWARE( &rmesa->radeon ); + + if (rmesa->store.cmd_used) +- r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); ++ rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ ); + + if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height, + &size)) { +- UNLOCK_HARDWARE( rmesa ); ++ UNLOCK_HARDWARE( &rmesa->radeon ); + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s totally clipped -- nothing to do\n", + __FUNCTION__); +@@ -212,14 +213,14 @@ r200TryReadPixels( GLcontext *ctx, + } + + { +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; + driRenderbuffer *drb = (driRenderbuffer *) ctx->ReadBuffer->_ColorReadBuffer; + int nbox = dPriv->numClipRects; + int src_offset = drb->offset +- + rmesa->r200Screen->fbLocation; ++ + rmesa->radeon.radeonScreen->fbLocation; + int src_pitch = drb->pitch * drb->cpp; + int dst_offset = r200GartOffsetFromVirtual( rmesa, pixels ); +- int dst_pitch = pitch * rmesa->r200Screen->cpp; ++ int dst_pitch = pitch * rmesa->radeon.radeonScreen->cpp; + drm_clip_rect_t *box = dPriv->pClipRects; + int i; + +@@ -257,12 +258,12 @@ r200TryReadPixels( GLcontext *ctx, + bw, bh ); + } + +- r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); ++ rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ ); + } +- UNLOCK_HARDWARE( rmesa ); +- +- r200Finish( ctx ); /* required by GL */ ++ UNLOCK_HARDWARE( &rmesa->radeon ); + ++ radeonFinish( ctx ); /* required by GL */ ++#endif + return GL_TRUE; + } + +@@ -292,7 +293,7 @@ static void do_draw_pix( GLcontext *ctx, + GLuint planemask) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; + drm_clip_rect_t *box = dPriv->pClipRects; + struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorDrawBuffers[0]; + driRenderbuffer *drb = (driRenderbuffer *) rb; +@@ -301,12 +302,12 @@ static void do_draw_pix( GLcontext *ctx, + int blit_format; + int size; + int src_offset = r200GartOffsetFromVirtual( rmesa, pixels ); +- int src_pitch = pitch * rmesa->r200Screen->cpp; ++ int src_pitch = pitch * rmesa->radeon.radeonScreen->cpp; + + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); +- +- switch ( rmesa->r200Screen->cpp ) { ++#if 0 ++ switch ( rmesa->radeon.radeonScreen->cpp ) { + case 2: + blit_format = R200_CP_COLOR_FORMAT_RGB565; + break; +@@ -318,17 +319,17 @@ static void do_draw_pix( GLcontext *ctx, + } + + +- LOCK_HARDWARE( rmesa ); ++ LOCK_HARDWARE( &rmesa->radeon ); + + if (rmesa->store.cmd_used) +- r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); ++ rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ ); + + y -= height; /* cope with pixel zoom */ + + if (!clip_pixelrect(ctx, ctx->DrawBuffer, + &x, &y, &width, &height, + &size)) { +- UNLOCK_HARDWARE( rmesa ); ++ UNLOCK_HARDWARE( &rmesa->radeon ); + return; + } + +@@ -357,15 +358,16 @@ static void do_draw_pix( GLcontext *ctx, + blit_format, + src_pitch, src_offset, + drb->pitch * drb->cpp, +- drb->offset + rmesa->r200Screen->fbLocation, ++ drb->offset + rmesa->radeon.radeonScreen->fbLocation, + bx - x, by - y, + bx, by, + bw, bh ); + } + +- r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); +- r200WaitForIdleLocked( rmesa ); /* required by GL */ +- UNLOCK_HARDWARE( rmesa ); ++ rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ ); ++ radeonWaitForIdleLocked( &rmesa->radeon ); /* required by GL */ ++ UNLOCK_HARDWARE( &rmesa->radeon ); ++#endif + } + + +@@ -381,7 +383,7 @@ r200TryDrawPixels( GLcontext *ctx, + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLint pitch = unpack->RowLength ? unpack->RowLength : width; + GLuint planemask; +- GLuint cpp = rmesa->r200Screen->cpp; ++ GLuint cpp = rmesa->radeon.radeonScreen->cpp; + GLint size = height * pitch * cpp; + + if (R200_DEBUG & DEBUG_PIXEL) +@@ -395,7 +397,7 @@ r200TryDrawPixels( GLcontext *ctx, + case GL_RGB: + case GL_RGBA: + case GL_BGRA: +- planemask = r200PackColor(cpp, ++ planemask = radeonPackColor(cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], +@@ -431,7 +433,7 @@ r200TryDrawPixels( GLcontext *ctx, + return GL_FALSE; + } + +- if ( r200IsGartMemory(rmesa, pixels, size) ) ++ if (0)// r200IsGartMemory(rmesa, pixels, size) ) + { + do_draw_pix( ctx, x, y, width, height, pitch, pixels, planemask ); + return GL_TRUE; +@@ -471,7 +473,7 @@ r200Bitmap( GLcontext *ctx, GLint px, GLint py, + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + +- if (rmesa->Fallback) ++ if (rmesa->radeon.Fallback) + _swrast_Bitmap( ctx, px, py, width, height, unpack, bitmap ); + else + r200PointsBitmap( ctx, px, py, width, height, unpack, bitmap ); +diff --git a/src/mesa/drivers/dri/r200/r200_reg.h b/src/mesa/drivers/dri/r200/r200_reg.h +index 5ce287f..526a624 100644 +--- a/src/mesa/drivers/dri/r200/r200_reg.h ++++ b/src/mesa/drivers/dri/r200/r200_reg.h +@@ -463,8 +463,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define R200_VSC_UPDATE_USER_COLOR_1_ENABLE 0x00020000 + /* gap */ + #define R200_SE_TCL_VECTOR_INDX_REG 0x2200 ++# define RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT 16 ++# define RADEON_VEC_INDX_DWORD_COUNT_SHIFT 28 + #define R200_SE_TCL_VECTOR_DATA_REG 0x2204 + #define R200_SE_TCL_SCALAR_INDX_REG 0x2208 ++# define RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT 16 + #define R200_SE_TCL_SCALAR_DATA_REG 0x220c + /* gap */ + #define R200_SE_TCL_MATRIX_SEL_0 0x2230 +@@ -949,6 +952,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define R200_LOD_BIAS_MASK (0xfff80000) + #define R200_LOD_BIAS_SHIFT 19 + #define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ ++#define R200_PP_TX_WIDTHMASK_SHIFT 0 ++#define R200_PP_TX_HEIGHTMASK_SHIFT 16 ++ + #define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */ + #define R200_PP_BORDER_COLOR_0 0x2c14 + #define R200_PP_CUBIC_FACES_0 0x2c18 +diff --git a/src/mesa/drivers/dri/r200/r200_span.c b/src/mesa/drivers/dri/r200/r200_span.c +deleted file mode 100644 +index 9783678..0000000 +--- a/src/mesa/drivers/dri/r200/r200_span.c ++++ /dev/null +@@ -1,307 +0,0 @@ +-/* +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Keith Whitwell +- */ +- +-#include "main/glheader.h" +-#include "main/imports.h" +-#include "main/colormac.h" +-#include "swrast/swrast.h" +- +-#include "r200_context.h" +-#include "r200_ioctl.h" +-#include "r200_state.h" +-#include "r200_span.h" +-#include "r200_tex.h" +- +-#define DBG 0 +- +-/* +- * Note that all information needed to access pixels in a renderbuffer +- * should be obtained through the gl_renderbuffer parameter, not per-context +- * information. +- */ +-#define LOCAL_VARS \ +- driRenderbuffer *drb = (driRenderbuffer *) rb; \ +- const __DRIdrawablePrivate *dPriv = drb->dPriv; \ +- const GLuint bottom = dPriv->h - 1; \ +- GLubyte *buf = (GLubyte *) drb->flippedData \ +- + (dPriv->y * drb->flippedPitch + dPriv->x) * drb->cpp; \ +- GLuint p; \ +- (void) p; +- +-#define LOCAL_DEPTH_VARS \ +- driRenderbuffer *drb = (driRenderbuffer *) rb; \ +- const __DRIdrawablePrivate *dPriv = drb->dPriv; \ +- const GLuint bottom = dPriv->h - 1; \ +- GLuint xo = dPriv->x; \ +- GLuint yo = dPriv->y; \ +- GLubyte *buf = (GLubyte *) drb->Base.Data; +- +-#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS +- +-#define Y_FLIP(Y) (bottom - (Y)) +- +-#define HW_LOCK() +- +-#define HW_UNLOCK() +- +- +- +-/* ================================================================ +- * Color buffer +- */ +- +-/* 16 bit, RGB565 color spanline and pixel functions +- */ +-#define SPANTMP_PIXEL_FMT GL_RGB +-#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 +- +-#define TAG(x) r200##x##_RGB565 +-#define TAG2(x,y) r200##x##_RGB565##y +-#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 2) +-#include "spantmp2.h" +- +-/* 32 bit, ARGB8888 color spanline and pixel functions +- */ +-#define SPANTMP_PIXEL_FMT GL_BGRA +-#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV +- +-#define TAG(x) r200##x##_ARGB8888 +-#define TAG2(x,y) r200##x##_ARGB8888##y +-#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 4) +-#include "spantmp2.h" +- +- +-/* ================================================================ +- * Depth buffer +- */ +- +-/* The Radeon family has depth tiling on all the time, so we have to convert +- * the x,y coordinates into the memory bus address (mba) in the same +- * manner as the engine. In each case, the linear block address (ba) +- * is calculated, and then wired with x and y to produce the final +- * memory address. +- * The chip will do address translation on its own if the surface registers +- * are set up correctly. It is not quite enough to get it working with hyperz too... +- */ +- +-/* extract bit 'b' of x, result is zero or one */ +-#define BIT(x,b) ((x & (1<>b) +- +-static GLuint +-r200_mba_z32( driRenderbuffer *drb, GLint x, GLint y ) +-{ +- GLuint pitch = drb->pitch; +- if (drb->depthHasSurface) { +- return 4 * (x + y * pitch); +- } +- else { +- GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x7FF) >> 5); +- GLuint a = +- (BIT(x,0) << 2) | +- (BIT(y,0) << 3) | +- (BIT(x,1) << 4) | +- (BIT(y,1) << 5) | +- (BIT(x,3) << 6) | +- (BIT(x,4) << 7) | +- (BIT(x,2) << 8) | +- (BIT(y,2) << 9) | +- (BIT(y,3) << 10) | +- (((pitch & 0x20) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) | +- ((b >> 1) << 12); +- return a; +- } +-} +- +-static GLuint +-r200_mba_z16( driRenderbuffer *drb, GLint x, GLint y ) +-{ +- GLuint pitch = drb->pitch; +- if (drb->depthHasSurface) { +- return 2 * (x + y * pitch); +- } +- else { +- GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x7FF) >> 6); +- GLuint a = +- (BIT(x,0) << 1) | +- (BIT(y,0) << 2) | +- (BIT(x,1) << 3) | +- (BIT(y,1) << 4) | +- (BIT(x,2) << 5) | +- (BIT(x,4) << 6) | +- (BIT(x,5) << 7) | +- (BIT(x,3) << 8) | +- (BIT(y,2) << 9) | +- (BIT(y,3) << 10) | +- (((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) | +- ((b >> 1) << 12); +- return a; +- } +-} +- +- +-/* 16-bit depth buffer functions +- */ +-#define VALUE_TYPE GLushort +- +-#define WRITE_DEPTH( _x, _y, d ) \ +- *(GLushort *)(buf + r200_mba_z16( drb, _x + xo, _y + yo )) = d; +- +-#define READ_DEPTH( d, _x, _y ) \ +- d = *(GLushort *)(buf + r200_mba_z16( drb, _x + xo, _y + yo )); +- +-#define TAG(x) r200##x##_z16 +-#include "depthtmp.h" +- +- +-/* 24 bit depth, 8 bit stencil depthbuffer functions +- */ +-#define VALUE_TYPE GLuint +- +-#define WRITE_DEPTH( _x, _y, d ) \ +-do { \ +- GLuint offset = r200_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ +- tmp &= 0xff000000; \ +- tmp |= ((d) & 0x00ffffff); \ +- *(GLuint *)(buf + offset) = tmp; \ +-} while (0) +- +-#define READ_DEPTH( d, _x, _y ) \ +- d = *(GLuint *)(buf + r200_mba_z32( drb, _x + xo, \ +- _y + yo )) & 0x00ffffff; +- +-#define TAG(x) r200##x##_z24_s8 +-#include "depthtmp.h" +- +- +-/* ================================================================ +- * Stencil buffer +- */ +- +-/* 24 bit depth, 8 bit stencil depthbuffer functions +- */ +-#define WRITE_STENCIL( _x, _y, d ) \ +-do { \ +- GLuint offset = r200_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ +- tmp &= 0x00ffffff; \ +- tmp |= (((d) & 0xff) << 24); \ +- *(GLuint *)(buf + offset) = tmp; \ +-} while (0) +- +-#define READ_STENCIL( d, _x, _y ) \ +-do { \ +- GLuint offset = r200_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ +- tmp &= 0xff000000; \ +- d = tmp >> 24; \ +-} while (0) +- +-#define TAG(x) r200##x##_z24_s8 +-#include "stenciltmp.h" +- +- +-/* Move locking out to get reasonable span performance (10x better +- * than doing this in HW_LOCK above). WaitForIdle() is the main +- * culprit. +- */ +- +-static void r200SpanRenderStart( GLcontext *ctx ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT( ctx ); +- +- R200_FIREVERTICES( rmesa ); +- LOCK_HARDWARE( rmesa ); +- r200WaitForIdleLocked( rmesa ); +- +- /* Read & rewrite the first pixel in the frame buffer. This should +- * be a noop, right? In fact without this conform fails as reading +- * from the framebuffer sometimes produces old results -- the +- * on-card read cache gets mixed up and doesn't notice that the +- * framebuffer has been updated. +- * +- * In the worst case this is buggy too as p might get the wrong +- * value first time, so really need a hidden pixel somewhere for this. +- */ +- { +- int p; +- driRenderbuffer *drb = +- (driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0]; +- volatile int *buf = +- (volatile int *)(rmesa->dri.screen->pFB + drb->offset); +- p = *buf; +- *buf = p; +- } +-} +- +-static void r200SpanRenderFinish( GLcontext *ctx ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT( ctx ); +- _swrast_flush( ctx ); +- UNLOCK_HARDWARE( rmesa ); +-} +- +-void r200InitSpanFuncs( GLcontext *ctx ) +-{ +- struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); +- swdd->SpanRenderStart = r200SpanRenderStart; +- swdd->SpanRenderFinish = r200SpanRenderFinish; +-} +- +- +- +-/** +- * Plug in the Get/Put routines for the given driRenderbuffer. +- */ +-void +-radeonSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis) +-{ +- if (drb->Base.InternalFormat == GL_RGBA) { +- if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) { +- r200InitPointers_RGB565(&drb->Base); +- } +- else { +- r200InitPointers_ARGB8888(&drb->Base); +- } +- } +- else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) { +- r200InitDepthPointers_z16(&drb->Base); +- } +- else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) { +- r200InitDepthPointers_z24_s8(&drb->Base); +- } +- else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) { +- r200InitStencilPointers_z24_s8(&drb->Base); +- } +-} +diff --git a/src/mesa/drivers/dri/r200/r200_span.h b/src/mesa/drivers/dri/r200/r200_span.h +deleted file mode 100644 +index bae5644..0000000 +--- a/src/mesa/drivers/dri/r200/r200_span.h ++++ /dev/null +@@ -1,45 +0,0 @@ +-/* +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Keith Whitwell +- */ +- +-#ifndef __R200_SPAN_H__ +-#define __R200_SPAN_H__ +- +-#include "drirenderbuffer.h" +- +-extern void r200InitSpanFuncs( GLcontext *ctx ); +- +-extern void +-radeonSetSpanFunctions(driRenderbuffer *rb, const GLvisual *vis); +- +-#endif +diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c +index 0eaaaf6..1b9724d 100644 +--- a/src/mesa/drivers/dri/r200/r200_state.c ++++ b/src/mesa/drivers/dri/r200/r200_state.c +@@ -47,6 +47,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "tnl/t_pipeline.h" + #include "swrast_setup/swrast_setup.h" + ++#include "radeon_common.h" ++#include "radeon_mipmap_tree.h" + #include "r200_context.h" + #include "r200_ioctl.h" + #include "r200_state.h" +@@ -114,8 +116,8 @@ static void r200BlendColor( GLcontext *ctx, const GLfloat cf[4] ) + CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]); + CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]); + CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]); +- if (rmesa->r200Screen->drmSupportsBlendColor) +- rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] = r200PackColor( 4, color[0], color[1], color[2], color[3] ); ++ if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) ++ rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] = radeonPackColor( 4, color[0], color[1], color[2], color[3] ); + } + + /** +@@ -213,7 +215,7 @@ static void r200_set_blend_state( GLcontext * ctx ) + + R200_STATECHANGE( rmesa, ctx ); + +- if (rmesa->r200Screen->drmSupportsBlendColor) { ++ if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) { + if (ctx->Color.ColorLogicOpEnabled) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R200_ROP_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func; +@@ -278,7 +280,7 @@ static void r200_set_blend_state( GLcontext * ctx ) + return; + } + +- if (!rmesa->r200Screen->drmSupportsBlendColor) { ++ if (!rmesa->radeon.radeonScreen->drmSupportsBlendColor) { + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func; + return; + } +@@ -383,10 +385,10 @@ static void r200ClearDepth( GLcontext *ctx, GLclampd d ) + + switch ( format ) { + case R200_DEPTH_FORMAT_16BIT_INT_Z: +- rmesa->state.depth.clear = d * 0x0000ffff; ++ rmesa->radeon.state.depth.clear = d * 0x0000ffff; + break; + case R200_DEPTH_FORMAT_24BIT_INT_Z: +- rmesa->state.depth.clear = d * 0x00ffffff; ++ rmesa->radeon.state.depth.clear = d * 0x00ffffff; + break; + } + } +@@ -480,7 +482,7 @@ static void r200Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) + case GL_FOG_COLOR: + R200_STATECHANGE( rmesa, ctx ); + UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color ); +- i = r200PackColor( 4, col[0], col[1], col[2], 0 ); ++ i = radeonPackColor( 4, col[0], col[1], col[2], 0 ); + rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_COLOR_MASK; + rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= i; + break; +@@ -521,102 +523,6 @@ static void r200Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) + } + } + +- +-/* ============================================================= +- * Scissoring +- */ +- +- +-static GLboolean intersect_rect( drm_clip_rect_t *out, +- drm_clip_rect_t *a, +- drm_clip_rect_t *b ) +-{ +- *out = *a; +- if ( b->x1 > out->x1 ) out->x1 = b->x1; +- if ( b->y1 > out->y1 ) out->y1 = b->y1; +- if ( b->x2 < out->x2 ) out->x2 = b->x2; +- if ( b->y2 < out->y2 ) out->y2 = b->y2; +- if ( out->x1 >= out->x2 ) return GL_FALSE; +- if ( out->y1 >= out->y2 ) return GL_FALSE; +- return GL_TRUE; +-} +- +- +-void r200RecalcScissorRects( r200ContextPtr rmesa ) +-{ +- drm_clip_rect_t *out; +- int i; +- +- /* Grow cliprect store? +- */ +- if (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { +- while (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { +- rmesa->state.scissor.numAllocedClipRects += 1; /* zero case */ +- rmesa->state.scissor.numAllocedClipRects *= 2; +- } +- +- if (rmesa->state.scissor.pClipRects) +- FREE(rmesa->state.scissor.pClipRects); +- +- rmesa->state.scissor.pClipRects = +- MALLOC( rmesa->state.scissor.numAllocedClipRects * +- sizeof(drm_clip_rect_t) ); +- +- if ( rmesa->state.scissor.pClipRects == NULL ) { +- rmesa->state.scissor.numAllocedClipRects = 0; +- return; +- } +- } +- +- out = rmesa->state.scissor.pClipRects; +- rmesa->state.scissor.numClipRects = 0; +- +- for ( i = 0 ; i < rmesa->numClipRects ; i++ ) { +- if ( intersect_rect( out, +- &rmesa->pClipRects[i], +- &rmesa->state.scissor.rect ) ) { +- rmesa->state.scissor.numClipRects++; +- out++; +- } +- } +-} +- +- +-static void r200UpdateScissor( GLcontext *ctx ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- +- if ( rmesa->dri.drawable ) { +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; +- +- int x = ctx->Scissor.X; +- int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; +- int w = ctx->Scissor.X + ctx->Scissor.Width - 1; +- int h = dPriv->h - ctx->Scissor.Y - 1; +- +- rmesa->state.scissor.rect.x1 = x + dPriv->x; +- rmesa->state.scissor.rect.y1 = y + dPriv->y; +- rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; +- rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; +- +- r200RecalcScissorRects( rmesa ); +- } +-} +- +- +-static void r200Scissor( GLcontext *ctx, +- GLint x, GLint y, GLsizei w, GLsizei h ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- +- if ( ctx->Scissor.Enabled ) { +- R200_FIREVERTICES( rmesa ); /* don't pipeline cliprect changes */ +- r200UpdateScissor( ctx ); +- } +- +-} +- +- + /* ============================================================= + * Culling + */ +@@ -803,7 +709,7 @@ static void r200ColorMask( GLcontext *ctx, + GLboolean b, GLboolean a ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- GLuint mask = r200PackColor( rmesa->r200Screen->cpp, ++ GLuint mask = radeonPackColor( rmesa->radeon.radeonScreen->cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], +@@ -834,7 +740,8 @@ static void r200PolygonOffset( GLcontext *ctx, + GLfloat factor, GLfloat units ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- float_ui32_type constant = { units * rmesa->state.depth.scale }; ++ const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; ++ float_ui32_type constant = { units * depthScale }; + float_ui32_type factoru = { factor }; + + /* factor *= 2; */ +@@ -861,15 +768,15 @@ static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask ) + + /* TODO: push this into cmd mechanism + */ +- R200_FIREVERTICES( rmesa ); +- LOCK_HARDWARE( rmesa ); ++ radeon_firevertices(&rmesa->radeon); ++ LOCK_HARDWARE( &rmesa->radeon ); + + /* FIXME: Use window x,y offsets into stipple RAM. + */ + stipple.mask = rmesa->state.stipple.mask; +- drmCommandWrite( rmesa->dri.fd, DRM_RADEON_STIPPLE, ++ drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE, + &stipple, sizeof(stipple) ); +- UNLOCK_HARDWARE( rmesa ); ++ UNLOCK_HARDWARE( &rmesa->radeon ); + } + + static void r200PolygonMode( GLcontext *ctx, GLenum face, GLenum mode ) +@@ -881,7 +788,7 @@ static void r200PolygonMode( GLcontext *ctx, GLenum face, GLenum mode ) + * cases work. + */ + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_UNFILLED, flag); +- if (rmesa->TclFallback) { ++ if (rmesa->radeon.TclFallback) { + r200ChooseRenderState( ctx ); + r200ChooseVertexState( ctx ); + } +@@ -958,7 +865,7 @@ static void r200UpdateSpecular( GLcontext *ctx ) + + /* Update vertex/render formats + */ +- if (rmesa->TclFallback) { ++ if (rmesa->radeon.TclFallback) { + r200ChooseRenderState( ctx ); + r200ChooseVertexState( ctx ); + } +@@ -1430,7 +1337,7 @@ static void r200LightModelfv( GLcontext *ctx, GLenum pname, + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHT_TWOSIDE; + else + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~(R200_LIGHT_TWOSIDE); +- if (rmesa->TclFallback) { ++ if (rmesa->radeon.TclFallback) { + r200ChooseRenderState( ctx ); + r200ChooseVertexState( ctx ); + } +@@ -1675,7 +1582,7 @@ static void r200ClearStencil( GLcontext *ctx, GLint s ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + +- rmesa->state.stencil.clear = ++ rmesa->radeon.state.stencil.clear = + ((GLuint) (ctx->Stencil.Clear & 0xff) | + (0xff << R200_STENCIL_MASK_SHIFT) | + ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT)); +@@ -1700,19 +1607,29 @@ static void r200ClearStencil( GLcontext *ctx, GLint s ) + void r200UpdateWindow( GLcontext *ctx ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; +- GLfloat xoffset = (GLfloat)dPriv->x; +- GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; ++ GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0; ++ GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0; + const GLfloat *v = ctx->Viewport._WindowMap.m; ++ const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0); ++ const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; ++ GLfloat y_scale, y_bias; ++ ++ if (render_to_fbo) { ++ y_scale = 1.0; ++ y_bias = 0; ++ } else { ++ y_scale = -1.0; ++ y_bias = yoffset; ++ } + + float_ui32_type sx = { v[MAT_SX] }; + float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X }; +- float_ui32_type sy = { - v[MAT_SY] }; +- float_ui32_type ty = { (- v[MAT_TY]) + yoffset + SUBPIXEL_Y }; +- float_ui32_type sz = { v[MAT_SZ] * rmesa->state.depth.scale }; +- float_ui32_type tz = { v[MAT_TZ] * rmesa->state.depth.scale }; ++ float_ui32_type sy = { v[MAT_SY] * y_scale }; ++ float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y }; ++ float_ui32_type sz = { v[MAT_SZ] * depthScale }; ++ float_ui32_type tz = { v[MAT_TZ] * depthScale }; + +- R200_FIREVERTICES( rmesa ); + R200_STATECHANGE( rmesa, vpt ); + + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32; +@@ -1733,6 +1650,8 @@ static void r200Viewport( GLcontext *ctx, GLint x, GLint y, + * values, or keep the originals hanging around. + */ + r200UpdateWindow( ctx ); ++ ++ radeon_viewport(ctx, x, y, width, height); + } + + static void r200DepthRange( GLcontext *ctx, GLclampd nearval, +@@ -1744,7 +1663,7 @@ static void r200DepthRange( GLcontext *ctx, GLclampd nearval, + void r200UpdateViewportOffset( GLcontext *ctx ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; + GLfloat xoffset = (GLfloat)dPriv->x; + GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; + const GLfloat *v = ctx->Viewport._WindowMap.m; +@@ -1774,8 +1693,8 @@ void r200UpdateViewportOffset( GLcontext *ctx ) + R200_STIPPLE_Y_OFFSET_MASK); + + /* add magic offsets, then invert */ +- stx = 31 - ((rmesa->dri.drawable->x - 1) & R200_STIPPLE_COORD_MASK); +- sty = 31 - ((rmesa->dri.drawable->y + rmesa->dri.drawable->h - 1) ++ stx = 31 - ((rmesa->radeon.dri.drawable->x - 1) & R200_STIPPLE_COORD_MASK); ++ sty = 31 - ((rmesa->radeon.dri.drawable->y + rmesa->radeon.dri.drawable->h - 1) + & R200_STIPPLE_COORD_MASK); + + m |= ((stx << R200_STIPPLE_X_OFFSET_SHIFT) | +@@ -1788,7 +1707,7 @@ void r200UpdateViewportOffset( GLcontext *ctx ) + } + } + +- r200UpdateScissor( ctx ); ++ radeonUpdateScissor( ctx ); + } + + +@@ -1805,7 +1724,7 @@ static void r200ClearColor( GLcontext *ctx, const GLfloat c[4] ) + CLAMPED_FLOAT_TO_UBYTE(color[1], c[1]); + CLAMPED_FLOAT_TO_UBYTE(color[2], c[2]); + CLAMPED_FLOAT_TO_UBYTE(color[3], c[3]); +- rmesa->state.color.clear = r200PackColor( rmesa->r200Screen->cpp, ++ rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp, + color[0], color[1], + color[2], color[3] ); + } +@@ -1848,96 +1767,6 @@ static void r200LogicOpCode( GLcontext *ctx, GLenum opcode ) + rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = r200_rop_tab[rop]; + } + +- +-/* +- * Set up the cliprects for either front or back-buffer drawing. +- */ +-void r200SetCliprects( r200ContextPtr rmesa ) +-{ +- __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; +- __DRIdrawablePrivate *const readable = rmesa->dri.readable; +- GLframebuffer *const draw_fb = (GLframebuffer*) drawable->driverPrivate; +- GLframebuffer *const read_fb = (GLframebuffer*) readable->driverPrivate; +- +- if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BIT_BACK_LEFT) { +- /* Can't ignore 2d windows if we are page flipping. +- */ +- if ( drawable->numBackClipRects == 0 || rmesa->doPageFlip ) { +- rmesa->numClipRects = drawable->numClipRects; +- rmesa->pClipRects = drawable->pClipRects; +- } +- else { +- rmesa->numClipRects = drawable->numBackClipRects; +- rmesa->pClipRects = drawable->pBackClipRects; +- } +- } +- else { +- /* front buffer (or none, or multiple buffers) */ +- rmesa->numClipRects = drawable->numClipRects; +- rmesa->pClipRects = drawable->pClipRects; +- } +- +- if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { +- _mesa_resize_framebuffer(rmesa->glCtx, draw_fb, +- drawable->w, drawable->h); +- draw_fb->Initialized = GL_TRUE; +- } +- +- if (drawable != readable) { +- if ((read_fb->Width != readable->w) || +- (read_fb->Height != readable->h)) { +- _mesa_resize_framebuffer(rmesa->glCtx, read_fb, +- readable->w, readable->h); +- read_fb->Initialized = GL_TRUE; +- } +- } +- +- if (rmesa->state.scissor.enabled) +- r200RecalcScissorRects( rmesa ); +- +- rmesa->lastStamp = drawable->lastStamp; +-} +- +- +-static void r200DrawBuffer( GLcontext *ctx, GLenum mode ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- +- if (R200_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s %s\n", __FUNCTION__, +- _mesa_lookup_enum_by_nr( mode )); +- +- R200_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */ +- +- if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { +- /* 0 (GL_NONE) buffers or multiple color drawing buffers */ +- FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE ); +- return; +- } +- +- switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) { +- case BUFFER_FRONT_LEFT: +- case BUFFER_BACK_LEFT: +- FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_FALSE ); +- break; +- default: +- FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE ); +- return; +- } +- +- r200SetCliprects( rmesa ); +- +- /* We'll set the drawing engine's offset/pitch parameters later +- * when we update other state. +- */ +-} +- +- +-static void r200ReadBuffer( GLcontext *ctx, GLenum mode ) +-{ +- /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ +-} +- + /* ============================================================= + * State enable/disable + */ +@@ -2013,10 +1842,10 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) + R200_STATECHANGE(rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_DITHER_ENABLE; +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->state.color.roundEnable; ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_DITHER_ENABLE; +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; + } + break; + +@@ -2031,7 +1860,7 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK; + } + r200UpdateSpecular( ctx ); /* for PK_SPEC */ +- if (rmesa->TclFallback) ++ if (rmesa->radeon.TclFallback) + r200ChooseVertexState( ctx ); + _mesa_allow_light_in_model( ctx, !state ); + break; +@@ -2068,7 +1897,7 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) + case GL_LIGHTING: + r200UpdateSpecular(ctx); + /* for reflection map fixup - might set recheck_texgen for all units too */ +- rmesa->NewGLState |= _NEW_TEXTURE; ++ rmesa->radeon.NewGLState |= _NEW_TEXTURE; + break; + + case GL_LINE_SMOOTH: +@@ -2181,21 +2010,30 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) + } + + case GL_SCISSOR_TEST: +- R200_FIREVERTICES( rmesa ); +- rmesa->state.scissor.enabled = state; +- r200UpdateScissor( ctx ); ++ radeon_firevertices(&rmesa->radeon); ++ rmesa->radeon.state.scissor.enabled = state; ++ radeonUpdateScissor( ctx ); + break; + + case GL_STENCIL_TEST: +- if ( rmesa->state.stencil.hwBuffer ) { +- R200_STATECHANGE( rmesa, ctx ); +- if ( state ) { +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_STENCIL_ENABLE; ++ { ++ GLboolean hw_stencil = GL_FALSE; ++ if (ctx->DrawBuffer) { ++ struct radeon_renderbuffer *rrbStencil ++ = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); ++ hw_stencil = (rrbStencil && rrbStencil->bo); ++ } ++ ++ if (hw_stencil) { ++ R200_STATECHANGE( rmesa, ctx ); ++ if ( state ) { ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_STENCIL_ENABLE; ++ } else { ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE; ++ } + } else { +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE; ++ FALLBACK( rmesa, R200_FALLBACK_STENCIL, state ); + } +- } else { +- FALLBACK( rmesa, R200_FALLBACK_STENCIL, state ); + } + break; + +@@ -2432,64 +2270,73 @@ static void update_texturematrix( GLcontext *ctx ) + } + } + +- +- +-/** +- * Tell the card where to render (offset, pitch). +- * Effected by glDrawBuffer, etc +- */ +-void +-r200UpdateDrawBuffer(GLcontext *ctx) ++static GLboolean r200ValidateBuffers(GLcontext *ctx) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- struct gl_framebuffer *fb = ctx->DrawBuffer; +- driRenderbuffer *drb; ++ struct radeon_renderbuffer *rrb; ++ int i; + +- if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { +- /* draw to front */ +- drb = (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; +- } +- else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { +- /* draw to back */ +- drb = (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; +- } +- else { +- /* drawing to multiple buffers, or none */ +- return; ++ radeon_validate_reset_bos(&rmesa->radeon); ++ ++ rrb = radeon_get_colorbuffer(&rmesa->radeon); ++ /* color buffer */ ++ if (rrb && rrb->bo) { ++ radeon_validate_bo(&rmesa->radeon, rrb->bo, ++ 0, RADEON_GEM_DOMAIN_VRAM); + } + +- assert(drb); +- assert(drb->flippedPitch); ++ /* depth buffer */ ++ rrb = radeon_get_depthbuffer(&rmesa->radeon); ++ /* color buffer */ ++ if (rrb && rrb->bo) { ++ radeon_validate_bo(&rmesa->radeon, rrb->bo, ++ 0, RADEON_GEM_DOMAIN_VRAM); ++ } + +- R200_STATECHANGE( rmesa, ctx ); ++ for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { ++ radeonTexObj *t; ++ ++ if (!ctx->Texture.Unit[i]._ReallyEnabled) ++ continue; + +- /* Note: we used the (possibly) page-flipped values */ +- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] +- = ((drb->flippedOffset + rmesa->r200Screen->fbLocation) +- & R200_COLOROFFSET_MASK); +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch; +- if (rmesa->sarea->tiling_enabled) { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; ++ t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); ++ if (t->image_override && t->bo) ++ radeon_validate_bo(&rmesa->radeon, t->bo, ++ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); ++ else if (t->mt->bo) ++ radeon_validate_bo(&rmesa->radeon, t->mt->bo, ++ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + } +-} + ++ if (rmesa->radeon.dma.current) ++ radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); + ++ return radeon_revalidate_bos(ctx); ++} + +-void r200ValidateState( GLcontext *ctx ) ++GLboolean r200ValidateState( GLcontext *ctx ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- GLuint new_state = rmesa->NewGLState; ++ GLuint new_state = rmesa->radeon.NewGLState; + + if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { +- r200UpdateDrawBuffer(ctx); ++ _mesa_update_framebuffer(ctx); ++ /* this updates the DrawBuffer's Width/Height if it's a FBO */ ++ _mesa_update_draw_buffer_bounds(ctx); ++ ++ R200_STATECHANGE(rmesa, ctx); + } + + if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM)) { + r200UpdateTextureState( ctx ); +- new_state |= rmesa->NewGLState; /* may add TEXTURE_MATRIX */ ++ new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */ + r200UpdateLocalViewer( ctx ); + } + ++ /* we need to do a space check here */ ++ if (!r200ValidateBuffers(ctx)) ++ return GL_FALSE; ++ + /* FIXME: don't really need most of these when vertex progs are enabled */ + + /* Need an event driven matrix update? +@@ -2533,7 +2380,8 @@ void r200ValidateState( GLcontext *ctx ) + else TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, 0); + } + +- rmesa->NewGLState = 0; ++ rmesa->radeon.NewGLState = 0; ++ return GL_TRUE; + } + + +@@ -2544,7 +2392,7 @@ static void r200InvalidateState( GLcontext *ctx, GLuint new_state ) + _vbo_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + _ae_invalidate_state( ctx, new_state ); +- R200_CONTEXT(ctx)->NewGLState |= new_state; ++ R200_CONTEXT(ctx)->radeon.NewGLState |= new_state; + } + + /* A hack. The r200 can actually cope just fine with materials +@@ -2573,12 +2421,13 @@ static void r200WrapRunPipeline( GLcontext *ctx ) + GLboolean has_material; + + if (0) +- fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->NewGLState); ++ fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState); + + /* Validate state: + */ +- if (rmesa->NewGLState) +- r200ValidateState( ctx ); ++ if (rmesa->radeon.NewGLState) ++ if (!r200ValidateState( ctx )) ++ FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE); + + has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx ); + +@@ -2603,8 +2452,8 @@ void r200InitStateFuncs( struct dd_function_table *functions ) + functions->UpdateState = r200InvalidateState; + functions->LightingSpaceChange = r200LightingSpaceChange; + +- functions->DrawBuffer = r200DrawBuffer; +- functions->ReadBuffer = r200ReadBuffer; ++ functions->DrawBuffer = radeonDrawBuffer; ++ functions->ReadBuffer = radeonReadBuffer; + + functions->AlphaFunc = r200AlphaFunc; + functions->BlendColor = r200BlendColor; +@@ -2636,7 +2485,7 @@ void r200InitStateFuncs( struct dd_function_table *functions ) + functions->PointParameterfv = r200PointParameter; + functions->PointSize = r200PointSize; + functions->RenderMode = r200RenderMode; +- functions->Scissor = r200Scissor; ++ functions->Scissor = radeonScissor; + functions->ShadeModel = r200ShadeModel; + functions->StencilFuncSeparate = r200StencilFuncSeparate; + functions->StencilMaskSeparate = r200StencilMaskSeparate; +diff --git a/src/mesa/drivers/dri/r200/r200_state.h b/src/mesa/drivers/dri/r200/r200_state.h +index a917163..23cf8ae 100644 +--- a/src/mesa/drivers/dri/r200/r200_state.h ++++ b/src/mesa/drivers/dri/r200/r200_state.h +@@ -43,23 +43,17 @@ extern void r200InitTnlFuncs( GLcontext *ctx ); + + extern void r200UpdateMaterial( GLcontext *ctx ); + +-extern void r200SetCliprects( r200ContextPtr rmesa ); +-extern void r200RecalcScissorRects( r200ContextPtr rmesa ); + extern void r200UpdateViewportOffset( GLcontext *ctx ); + extern void r200UpdateWindow( GLcontext *ctx ); + extern void r200UpdateDrawBuffer(GLcontext *ctx); + +-extern void r200ValidateState( GLcontext *ctx ); +- +-extern void r200PrintDirty( r200ContextPtr rmesa, +- const char *msg ); +- ++extern GLboolean r200ValidateState( GLcontext *ctx ); + + extern void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); + #define FALLBACK( rmesa, bit, mode ) do { \ + if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \ + __FUNCTION__, bit, mode ); \ +- r200Fallback( rmesa->glCtx, bit, mode ); \ ++ r200Fallback( rmesa->radeon.glCtx, bit, mode ); \ + } while (0) + + extern void r200LightingSpaceChange( GLcontext *ctx ); +diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c +index 9e4677e..75262e4 100644 +--- a/src/mesa/drivers/dri/r200/r200_state_init.c ++++ b/src/mesa/drivers/dri/r200/r200_state_init.c +@@ -43,6 +43,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "tnl/t_pipeline.h" + #include "swrast_setup/swrast_setup.h" + ++#include "radeon_common.h" ++#include "radeon_mipmap_tree.h" + #include "r200_context.h" + #include "r200_ioctl.h" + #include "r200_state.h" +@@ -52,31 +54,129 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #include "xmlpool.h" + ++/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in ++ * 1.3 cmdbuffers allow all previous state to be updated as well as ++ * the tcl scalar and vector areas. ++ */ ++static struct { ++ int start; ++ int len; ++ const char *name; ++} packet[RADEON_MAX_STATE_PACKETS] = { ++ {RADEON_PP_MISC, 7, "RADEON_PP_MISC"}, ++ {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"}, ++ {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"}, ++ {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"}, ++ {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"}, ++ {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"}, ++ {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"}, ++ {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"}, ++ {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"}, ++ {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"}, ++ {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"}, ++ {RADEON_RE_MISC, 1, "RADEON_RE_MISC"}, ++ {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"}, ++ {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"}, ++ {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"}, ++ {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"}, ++ {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"}, ++ {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"}, ++ {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"}, ++ {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"}, ++ {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17, ++ "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"}, ++ {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"}, ++ {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"}, ++ {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"}, ++ {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"}, ++ {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"}, ++ {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"}, ++ {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"}, ++ {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"}, ++ {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"}, ++ {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"}, ++ {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"}, ++ {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"}, ++ {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"}, ++ {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"}, ++ {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"}, ++ {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"}, ++ {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"}, ++ {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"}, ++ {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"}, ++ {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"}, ++ {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"}, ++ {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"}, ++ {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"}, ++ {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"}, ++ {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"}, ++ {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, ++ {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, ++ {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, ++ {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, ++ "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, ++ {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, ++ {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, ++ {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, ++ {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"}, ++ {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"}, ++ {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"}, ++ {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"}, ++ {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"}, ++ {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"}, ++ {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"}, ++ {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, ++ "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, ++ {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ ++ {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ ++ {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, ++ {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, ++ {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, ++ {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"}, ++ {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"}, ++ {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"}, ++ {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"}, ++ {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"}, ++ {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"}, ++ {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"}, ++ {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"}, ++ {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"}, ++ {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"}, ++ {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"}, ++ {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"}, ++ {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"}, ++ {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"}, ++ {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"}, ++ {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"}, ++ {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, ++ {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, ++ {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, ++ {R200_PP_TXCBLEND_8, 32, "R200_PP_AFS_0"}, /* 85 */ ++ {R200_PP_TXCBLEND_0, 32, "R200_PP_AFS_1"}, ++ {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, ++ {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, ++ {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"}, ++ {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"}, ++ {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, ++ {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, ++ {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, ++ {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"}, ++}; ++ + /* ============================================================= + * State initialization + */ +- +-void r200PrintDirty( r200ContextPtr rmesa, const char *msg ) ++static int cmdpkt( r200ContextPtr rmesa, int id ) + { +- struct r200_state_atom *l; +- +- fprintf(stderr, msg); +- fprintf(stderr, ": "); ++ drm_radeon_cmd_header_t h; + +- foreach(l, &rmesa->hw.atomlist) { +- if (l->dirty || rmesa->hw.all_dirty) +- fprintf(stderr, "%s, ", l->name); ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ return CP_PACKET0(packet[id].start, packet[id].len - 1); ++ } else { ++ h.i = 0; ++ h.packet.cmd_type = RADEON_CMD_PACKET; ++ h.packet.packet_id = id; + } +- +- fprintf(stderr, "\n"); +-} +- +-static int cmdpkt( int id ) +-{ +- drm_radeon_cmd_header_t h; +- h.i = 0; +- h.packet.cmd_type = RADEON_CMD_PACKET; +- h.packet.packet_id = id; + return h.i; + } + +@@ -127,150 +227,475 @@ static int cmdscl2( int offset, int stride, int count ) + } + + #define CHECK( NM, FLAG ) \ +-static GLboolean check_##NM( GLcontext *ctx, int idx ) \ ++static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom) \ + { \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ +- (void) idx; \ + (void) rmesa; \ +- return FLAG; \ ++ return (FLAG) ? atom->cmd_size : 0; \ + } + + #define TCL_CHECK( NM, FLAG ) \ +-static GLboolean check_##NM( GLcontext *ctx, int idx ) \ +-{ \ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); \ +- (void) idx; \ +- return !rmesa->TclFallback && !ctx->VertexProgram._Enabled && (FLAG); \ ++static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom) \ ++{ \ ++ r200ContextPtr rmesa = R200_CONTEXT(ctx); \ ++ return (!rmesa->radeon.TclFallback && !ctx->VertexProgram._Enabled && (FLAG)) ? atom->cmd_size : 0; \ + } + + #define TCL_OR_VP_CHECK( NM, FLAG ) \ +-static GLboolean check_##NM( GLcontext *ctx, int idx ) \ ++static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom ) \ + { \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ +- (void) idx; \ +- return !rmesa->TclFallback && (FLAG); \ ++ return (!rmesa->radeon.TclFallback && (FLAG)) ? atom->cmd_size : 0; \ + } + + #define VP_CHECK( NM, FLAG ) \ +-static GLboolean check_##NM( GLcontext *ctx, int idx ) \ +-{ \ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); \ +- (void) idx; \ +- return !rmesa->TclFallback && ctx->VertexProgram._Enabled && (FLAG); \ ++static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom ) \ ++{ \ ++ r200ContextPtr rmesa = R200_CONTEXT(ctx); \ ++ (void) atom; \ ++ return (!rmesa->radeon.TclFallback && ctx->VertexProgram._Enabled && (FLAG)) ? atom->cmd_size : 0; \ + } + +- + CHECK( always, GL_TRUE ) + CHECK( never, GL_FALSE ) + CHECK( tex_any, ctx->Texture._EnabledUnits ) + CHECK( tf, (ctx->Texture._EnabledUnits && !ctx->ATIFragmentShader._Enabled) ); +-CHECK( tex_pair, (rmesa->state.texture.unit[idx].unitneeded | rmesa->state.texture.unit[idx & ~1].unitneeded) ) +-CHECK( tex, rmesa->state.texture.unit[idx].unitneeded ) ++CHECK( tex_pair, (rmesa->state.texture.unit[atom->idx].unitneeded | rmesa->state.texture.unit[atom->idx & ~1].unitneeded) ) ++CHECK( tex, rmesa->state.texture.unit[atom->idx].unitneeded ) + CHECK( pix_zero, !ctx->ATIFragmentShader._Enabled ) +-CHECK( texenv, (rmesa->state.envneeded & (1 << idx) && !ctx->ATIFragmentShader._Enabled) ) ++ CHECK( texenv, (rmesa->state.envneeded & (1 << (atom->idx)) && !ctx->ATIFragmentShader._Enabled) ) + CHECK( afs_pass1, (ctx->ATIFragmentShader._Enabled && (ctx->ATIFragmentShader.Current->NumPasses > 1)) ) + CHECK( afs, ctx->ATIFragmentShader._Enabled ) +-CHECK( tex_cube, rmesa->state.texture.unit[idx].unitneeded & TEXTURE_CUBE_BIT ) ++CHECK( tex_cube, rmesa->state.texture.unit[atom->idx].unitneeded & TEXTURE_CUBE_BIT ) + TCL_CHECK( tcl_fog, ctx->Fog.Enabled ) + TCL_CHECK( tcl, GL_TRUE ) +-TCL_CHECK( tcl_tex, rmesa->state.texture.unit[idx].unitneeded ) ++TCL_CHECK( tcl_tex, rmesa->state.texture.unit[atom->idx].unitneeded ) + TCL_CHECK( tcl_lighting, ctx->Light.Enabled ) +-TCL_CHECK( tcl_light, ctx->Light.Enabled && ctx->Light.Light[idx].Enabled ) +-TCL_OR_VP_CHECK( tcl_ucp, (ctx->Transform.ClipPlanesEnabled & (1 << idx)) ) ++TCL_CHECK( tcl_light, ctx->Light.Enabled && ctx->Light.Light[atom->idx].Enabled ) ++TCL_OR_VP_CHECK( tcl_ucp, (ctx->Transform.ClipPlanesEnabled & (1 << (atom->idx))) ) + TCL_OR_VP_CHECK( tcl_or_vp, GL_TRUE ) + VP_CHECK( tcl_vp, GL_TRUE ) + VP_CHECK( tcl_vp_size, ctx->VertexProgram.Current->Base.NumNativeInstructions > 64 ) + VP_CHECK( tcl_vpp_size, ctx->VertexProgram.Current->Base.NumNativeParameters > 96 ) + ++#define OUT_VEC(hdr, data) do { \ ++ drm_radeon_cmd_header_t h; \ ++ h.i = hdr; \ ++ OUT_BATCH(CP_PACKET0(RADEON_SE_TCL_STATE_FLUSH, 0)); \ ++ OUT_BATCH(0); \ ++ OUT_BATCH(CP_PACKET0(R200_SE_TCL_VECTOR_INDX_REG, 0)); \ ++ OUT_BATCH(h.vectors.offset | (h.vectors.stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); \ ++ OUT_BATCH(CP_PACKET0_ONE(R200_SE_TCL_VECTOR_DATA_REG, h.vectors.count - 1)); \ ++ OUT_BATCH_TABLE((data), h.vectors.count); \ ++ } while(0) ++ ++#define OUT_VECLINEAR(hdr, data) do { \ ++ drm_radeon_cmd_header_t h; \ ++ uint32_t _start, _sz; \ ++ h.i = hdr; \ ++ _start = h.veclinear.addr_lo | (h.veclinear.addr_hi << 8); \ ++ _sz = h.veclinear.count * 4; \ ++ OUT_BATCH(CP_PACKET0(RADEON_SE_TCL_STATE_FLUSH, 0)); \ ++ OUT_BATCH(0); \ ++ OUT_BATCH(CP_PACKET0(R200_SE_TCL_VECTOR_INDX_REG, 0)); \ ++ OUT_BATCH(_start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); \ ++ OUT_BATCH(CP_PACKET0_ONE(R200_SE_TCL_VECTOR_DATA_REG, _sz - 1)); \ ++ OUT_BATCH_TABLE((data), _sz); \ ++ } while(0) ++ ++#define OUT_SCL(hdr, data) do { \ ++ drm_radeon_cmd_header_t h; \ ++ h.i = hdr; \ ++ OUT_BATCH(CP_PACKET0(R200_SE_TCL_SCALAR_INDX_REG, 0)); \ ++ OUT_BATCH((h.scalars.offset) | (h.scalars.stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); \ ++ OUT_BATCH(CP_PACKET0_ONE(R200_SE_TCL_SCALAR_DATA_REG, h.scalars.count - 1)); \ ++ OUT_BATCH_TABLE((data), h.scalars.count); \ ++ } while(0) ++ ++#define OUT_SCL2(hdr, data) do { \ ++ drm_radeon_cmd_header_t h; \ ++ h.i = hdr; \ ++ OUT_BATCH(CP_PACKET0(R200_SE_TCL_SCALAR_INDX_REG, 0)); \ ++ OUT_BATCH((h.scalars.offset + 0x100) | (h.scalars.stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); \ ++ OUT_BATCH(CP_PACKET0_ONE(R200_SE_TCL_SCALAR_DATA_REG, h.scalars.count - 1)); \ ++ OUT_BATCH_TABLE((data), h.scalars.count); \ ++ } while(0) ++ ++static void mtl_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ uint32_t dwords = atom->cmd_size; ++ ++ dwords += 6; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_VEC(atom->cmd[MTL_CMD_0], (atom->cmd+1)); ++ OUT_SCL2(atom->cmd[MTL_CMD_1], (atom->cmd + 18)); ++ END_BATCH(); ++} + +-/* Initialize the context's hardware state. +- */ +-void r200InitState( r200ContextPtr rmesa ) ++static void lit_emit(GLcontext *ctx, struct radeon_state_atom *atom) + { +- GLcontext *ctx = rmesa->glCtx; +- GLuint color_fmt, depth_fmt, i; +- GLint drawPitch, drawOffset; ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ uint32_t dwords = atom->cmd_size; ++ ++ dwords += 8; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_VEC(atom->cmd[LIT_CMD_0], atom->cmd+1); ++ OUT_VEC(atom->cmd[LIT_CMD_1], atom->cmd+LIT_CMD_1+1); ++ END_BATCH(); ++} + +- switch ( rmesa->r200Screen->cpp ) { +- case 2: +- color_fmt = R200_COLOR_FORMAT_RGB565; +- break; +- case 4: +- color_fmt = R200_COLOR_FORMAT_ARGB8888; +- break; +- default: +- fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); +- exit( -1 ); ++static void ptp_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ uint32_t dwords = atom->cmd_size; ++ ++ dwords += 8; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_VEC(atom->cmd[PTP_CMD_0], atom->cmd+1); ++ OUT_VEC(atom->cmd[PTP_CMD_1], atom->cmd+PTP_CMD_1+1); ++ END_BATCH(); ++} ++ ++static void veclinear_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ uint32_t dwords = atom->cmd_size; ++ ++ dwords += 4; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_VECLINEAR(atom->cmd[0], atom->cmd+1); ++ END_BATCH(); ++} ++ ++static void scl_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ uint32_t dwords = atom->cmd_size; ++ ++ dwords += 2; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_SCL(atom->cmd[0], atom->cmd+1); ++ END_BATCH(); ++} ++ ++ ++static void vec_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ uint32_t dwords = atom->cmd_size; ++ ++ dwords += 4; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_VEC(atom->cmd[0], atom->cmd+1); ++ END_BATCH(); ++} ++ ++static void ctx_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ struct radeon_renderbuffer *rrb; ++ uint32_t cbpitch; ++ uint32_t zbpitch, depth_fmt; ++ uint32_t dwords = atom->cmd_size; ++ ++ /* output the first 7 bytes of context */ ++ BEGIN_BATCH_NO_AUTOSTATE(dwords+2+2); ++ OUT_BATCH_TABLE(atom->cmd, 5); ++ ++ rrb = radeon_get_depthbuffer(&r200->radeon); ++ if (!rrb) { ++ OUT_BATCH(0); ++ OUT_BATCH(0); ++ } else { ++ zbpitch = (rrb->pitch / rrb->cpp); ++ if (r200->using_hyperz) ++ zbpitch |= RADEON_DEPTH_HYPERZ; ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ OUT_BATCH(zbpitch); ++ if (rrb->cpp == 4) ++ depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; ++ else ++ depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; ++ atom->cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_DEPTH_FORMAT_MASK; ++ atom->cmd[CTX_RB3D_ZSTENCILCNTL] |= depth_fmt; ++ } ++ ++ OUT_BATCH(atom->cmd[CTX_RB3D_ZSTENCILCNTL]); ++ OUT_BATCH(atom->cmd[CTX_CMD_1]); ++ OUT_BATCH(atom->cmd[CTX_PP_CNTL]); ++ ++ rrb = radeon_get_colorbuffer(&r200->radeon); ++ if (!rrb || !rrb->bo) { ++ OUT_BATCH(atom->cmd[CTX_RB3D_CNTL]); ++ OUT_BATCH(atom->cmd[CTX_RB3D_COLOROFFSET]); ++ } else { ++ atom->cmd[CTX_RB3D_CNTL] &= ~(0xf << 10); ++ if (rrb->cpp == 4) ++ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB8888; ++ else ++ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_RGB565; ++ ++ OUT_BATCH(atom->cmd[CTX_RB3D_CNTL]); ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); + } + +- rmesa->state.color.clear = 0x00000000; ++ OUT_BATCH(atom->cmd[CTX_CMD_2]); + +- switch ( ctx->Visual.depthBits ) { +- case 16: +- rmesa->state.depth.clear = 0x0000ffff; +- rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff; +- depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z; +- rmesa->state.stencil.clear = 0x00000000; +- break; +- case 24: +- rmesa->state.depth.clear = 0x00ffffff; +- rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff; +- depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z; +- rmesa->state.stencil.clear = 0xffff0000; +- break; +- default: +- fprintf( stderr, "Error: Unsupported depth %d... exiting\n", +- ctx->Visual.depthBits ); +- exit( -1 ); ++ if (!rrb || !rrb->bo) { ++ OUT_BATCH(atom->cmd[CTX_RB3D_COLORPITCH]); ++ } else { ++ cbpitch = (rrb->pitch / rrb->cpp); ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) ++ cbpitch |= R200_COLOR_TILE_ENABLE; ++ OUT_BATCH(cbpitch); + } + +- /* Only have hw stencil when depth buffer is 24 bits deep */ +- rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && +- ctx->Visual.depthBits == 24 ); ++ if (atom->cmd_size == CTX_STATE_SIZE_NEWDRM) ++ OUT_BATCH_TABLE((atom->cmd + 14), 4); + +- rmesa->Fallback = 0; ++ END_BATCH(); ++} + +- if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { +- drawOffset = rmesa->r200Screen->backOffset; +- drawPitch = rmesa->r200Screen->backPitch; +- } else { +- drawOffset = rmesa->r200Screen->frontOffset; +- drawPitch = rmesa->r200Screen->frontPitch; ++static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ struct radeon_renderbuffer *rrb, *drb; ++ uint32_t cbpitch = 0; ++ uint32_t zbpitch = 0; ++ uint32_t dwords = atom->cmd_size; ++ uint32_t depth_fmt; ++ ++ rrb = radeon_get_colorbuffer(&r200->radeon); ++ if (!rrb || !rrb->bo) { ++ return; + } +-#if 000 +- if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { +- rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; +- rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch; ++ ++ atom->cmd[CTX_RB3D_CNTL] &= ~(0xf << 10); ++ if (rrb->cpp == 4) ++ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB8888; ++ else ++ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_RGB565; ++ ++ cbpitch = (rrb->pitch / rrb->cpp); ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) ++ cbpitch |= R200_COLOR_TILE_ENABLE; ++ ++ drb = radeon_get_depthbuffer(&r200->radeon); ++ if (drb) { ++ zbpitch = (drb->pitch / drb->cpp); ++ if (drb->cpp == 4) ++ depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; ++ else ++ depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; ++ atom->cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_DEPTH_FORMAT_MASK; ++ atom->cmd[CTX_RB3D_ZSTENCILCNTL] |= depth_fmt; ++ } ++ ++ dwords = 10; ++ if (drb) ++ dwords += 6; ++ if (rrb) ++ dwords += 6; ++ ++ /* output the first 7 bytes of context */ ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ ++ /* In the CS case we need to split this up */ ++ OUT_BATCH(CP_PACKET0(packet[0].start, 3)); ++ OUT_BATCH_TABLE((atom->cmd + 1), 4); ++ ++ if (drb) { ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_DEPTHOFFSET, 0)); ++ OUT_BATCH_RELOC(0, drb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_DEPTHPITCH, 0)); ++ OUT_BATCH(zbpitch); ++ } ++ ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZSTENCILCNTL, 0)); ++ OUT_BATCH(atom->cmd[CTX_RB3D_ZSTENCILCNTL]); ++ OUT_BATCH(CP_PACKET0(RADEON_PP_CNTL, 1)); ++ OUT_BATCH(atom->cmd[CTX_PP_CNTL]); ++ OUT_BATCH(atom->cmd[CTX_RB3D_CNTL]); ++ ++ ++ if (rrb) { ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_COLOROFFSET, 0)); ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0)); ++ OUT_BATCH(cbpitch); ++ } ++ ++ if (atom->cmd_size == CTX_STATE_SIZE_NEWDRM) { ++ OUT_BATCH_TABLE((atom->cmd + 14), 4); ++ } ++ ++ END_BATCH(); ++} ++ ++static void tex_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ uint32_t dwords = atom->cmd_size; ++ int i = atom->idx; ++ radeonTexObj *t = r200->state.texture.unit[i].texobj; ++ radeon_mipmap_level *lvl; ++ ++ if (t && t->mt && !t->image_override) ++ dwords += 2; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_BATCH_TABLE(atom->cmd, 10); ++ ++ if (t && t->mt && !t->image_override) { ++ if ((ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT)) { ++ lvl = &t->mt->levels[0]; ++ OUT_BATCH_RELOC(lvl->faces[5].offset, t->mt->bo, lvl->faces[5].offset, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } else { ++ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } ++ } else if (!t) { ++ /* workaround for old CS mechanism */ ++ OUT_BATCH(r200->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]); + } else { +- rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; +- rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch; ++ OUT_BATCH(t->override_offset); + } + +- rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset; +- rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch; +-#endif ++ END_BATCH(); ++} ++ ++static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ uint32_t dwords = atom->cmd_size; ++ int i = atom->idx; ++ radeonTexObj *t = r200->state.texture.unit[i].texobj; ++ radeon_mipmap_level *lvl; ++ int hastexture = 1; ++ ++ if (!t) ++ hastexture = 0; ++ else { ++ if (!t->mt && !t->bo) ++ hastexture = 0; ++ } ++ ++ dwords += 2; ++ if (hastexture) ++ dwords += 2; ++ else ++ dwords -= 2; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ ++ OUT_BATCH(CP_PACKET0(R200_PP_TXFILTER_0 + (24 * i), 7)); ++ OUT_BATCH_TABLE((atom->cmd + 1), 8); ++ ++ if (hastexture) { ++ OUT_BATCH(CP_PACKET0(R200_PP_TXOFFSET_0 + (24 * i), 0)); ++ if (t->mt && !t->image_override) { ++ if ((ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT)) { ++ lvl = &t->mt->levels[0]; ++ OUT_BATCH_RELOC(lvl->faces[5].offset, t->mt->bo, lvl->faces[5].offset, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } else { ++ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } ++ } else { ++ if (t->bo) ++ OUT_BATCH_RELOC(t->tile_bits, t->bo, 0, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } ++ } ++ END_BATCH(); ++} ++ ++ ++static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r200ContextPtr r200 = R200_CONTEXT(ctx); ++ BATCH_LOCALS(&r200->radeon); ++ uint32_t dwords = atom->cmd_size; ++ int i = atom->idx; ++ radeonTexObj *t = r200->state.texture.unit[i].texobj; ++ GLuint size; ++ ++ BEGIN_BATCH_NO_AUTOSTATE(dwords + (2 * 5)); ++ OUT_BATCH_TABLE(atom->cmd, 3); ++ ++ if (t && !t->image_override) { ++ size = t->mt->totalsize / 6; ++ OUT_BATCH_RELOC(0, t->mt->bo, size, RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ OUT_BATCH_RELOC(0, t->mt->bo, size * 2, RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ OUT_BATCH_RELOC(0, t->mt->bo, size * 3, RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ OUT_BATCH_RELOC(0, t->mt->bo, size * 4, RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ OUT_BATCH_RELOC(0, t->mt->bo, size * 5, RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } ++ END_BATCH(); ++} ++ ++/* Initialize the context's hardware state. ++ */ ++void r200InitState( r200ContextPtr rmesa ) ++{ ++ GLcontext *ctx = rmesa->radeon.glCtx; ++ GLuint i; + +- rmesa->hw.max_state_size = 0; ++ rmesa->radeon.state.color.clear = 0x00000000; ++ ++ switch ( ctx->Visual.depthBits ) { ++ case 16: ++ rmesa->radeon.state.depth.clear = 0x0000ffff; ++ rmesa->radeon.state.stencil.clear = 0x00000000; ++ break; ++ case 24: ++ default: ++ rmesa->radeon.state.depth.clear = 0x00ffffff; ++ rmesa->radeon.state.stencil.clear = 0xffff0000; ++ break; ++ } ++ ++ rmesa->radeon.Fallback = 0; ++ ++ rmesa->radeon.hw.max_state_size = 0; + + #define ALLOC_STATE( ATOM, CHK, SZ, NM, IDX ) \ + do { \ + rmesa->hw.ATOM.cmd_size = SZ; \ +- rmesa->hw.ATOM.cmd = (int *)CALLOC(SZ * sizeof(int)); \ +- rmesa->hw.ATOM.lastcmd = (int *)CALLOC(SZ * sizeof(int)); \ ++ rmesa->hw.ATOM.cmd = (GLuint *)CALLOC(SZ * sizeof(int)); \ ++ rmesa->hw.ATOM.lastcmd = (GLuint *)CALLOC(SZ * sizeof(int)); \ + rmesa->hw.ATOM.name = NM; \ + rmesa->hw.ATOM.idx = IDX; \ + rmesa->hw.ATOM.check = check_##CHK; \ + rmesa->hw.ATOM.dirty = GL_FALSE; \ +- rmesa->hw.max_state_size += SZ * sizeof(int); \ ++ rmesa->radeon.hw.max_state_size += SZ * sizeof(int); \ + } while (0) + + + /* Allocate state buffers: + */ +- if (rmesa->r200Screen->drmSupportsBlendColor) ++ if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) + ALLOC_STATE( ctx, always, CTX_STATE_SIZE_NEWDRM, "CTX/context", 0 ); + else + ALLOC_STATE( ctx, always, CTX_STATE_SIZE_OLDDRM, "CTX/context", 0 ); ++ ++ if (rmesa->radeon.radeonScreen->kernel_mm) ++ rmesa->hw.ctx.emit = ctx_emit_cs; ++ else ++ rmesa->hw.ctx.emit = ctx_emit; + ALLOC_STATE( set, always, SET_STATE_SIZE, "SET/setup", 0 ); + ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 ); + ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 ); +@@ -282,8 +707,8 @@ void r200InitState( r200ContextPtr rmesa ) + ALLOC_STATE( cst, always, CST_STATE_SIZE, "CST/constant", 0 ); + ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 ); + ALLOC_STATE( tf, tf, TF_STATE_SIZE, "TF/tfactor", 0 ); +- if (rmesa->r200Screen->drmSupportsFragShader) { +- if (rmesa->r200Screen->chip_family == CHIP_FAMILY_R200) { ++ if (rmesa->radeon.radeonScreen->drmSupportsFragShader) { ++ if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) { + /* make sure texture units 0/1 are emitted pair-wise for r200 t0 hang workaround */ + ALLOC_STATE( tex[0], tex_pair, TEX_STATE_SIZE_NEWDRM, "TEX/tex-0", 0 ); + ALLOC_STATE( tex[1], tex_pair, TEX_STATE_SIZE_NEWDRM, "TEX/tex-1", 1 ); +@@ -303,7 +728,7 @@ void r200InitState( r200ContextPtr rmesa ) + ALLOC_STATE( afs[1], afs, AFS_STATE_SIZE, "AFS/afsinst-1", 1 ); + } + else { +- if (rmesa->r200Screen->chip_family == CHIP_FAMILY_R200) { ++ if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) { + ALLOC_STATE( tex[0], tex_pair, TEX_STATE_SIZE_OLDDRM, "TEX/tex-0", 0 ); + ALLOC_STATE( tex[1], tex_pair, TEX_STATE_SIZE_OLDDRM, "TEX/tex-1", 1 ); + ALLOC_STATE( tam, tex_any, TAM_STATE_SIZE, "TAM/tam", 0 ); +@@ -321,13 +746,21 @@ void r200InitState( r200ContextPtr rmesa ) + ALLOC_STATE( afs[0], never, AFS_STATE_SIZE, "AFS/afsinst-0", 0 ); + ALLOC_STATE( afs[1], never, AFS_STATE_SIZE, "AFS/afsinst-1", 1 ); + } +- if (rmesa->r200Screen->drmSupportsCubeMapsR200) { ++ ++ for (i = 0; i < 5; i++) ++ if (rmesa->radeon.radeonScreen->kernel_mm) ++ rmesa->hw.tex[i].emit = tex_emit_cs; ++ else ++ rmesa->hw.tex[i].emit = tex_emit; ++ if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR200) { + ALLOC_STATE( cube[0], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-0", 0 ); + ALLOC_STATE( cube[1], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-1", 1 ); + ALLOC_STATE( cube[2], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-2", 2 ); + ALLOC_STATE( cube[3], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-3", 3 ); + ALLOC_STATE( cube[4], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-4", 4 ); + ALLOC_STATE( cube[5], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-5", 5 ); ++ for (i = 0; i < 5; i++) ++ rmesa->hw.cube[i].emit = cube_emit; + } + else { + ALLOC_STATE( cube[0], never, CUBE_STATE_SIZE, "CUBE/tex-0", 0 ); +@@ -337,7 +770,8 @@ void r200InitState( r200ContextPtr rmesa ) + ALLOC_STATE( cube[4], never, CUBE_STATE_SIZE, "CUBE/tex-4", 4 ); + ALLOC_STATE( cube[5], never, CUBE_STATE_SIZE, "CUBE/tex-5", 5 ); + } +- if (rmesa->r200Screen->drmSupportsVertexProgram) { ++ ++ if (rmesa->radeon.radeonScreen->drmSupportsVertexProgram) { + ALLOC_STATE( pvs, tcl_vp, PVS_STATE_SIZE, "PVS/pvscntl", 0 ); + ALLOC_STATE( vpi[0], tcl_vp, VPI_STATE_SIZE, "VP/vertexprog-0", 0 ); + ALLOC_STATE( vpi[1], tcl_vp_size, VPI_STATE_SIZE, "VP/vertexprog-1", 1 ); +@@ -390,13 +824,13 @@ void r200InitState( r200ContextPtr rmesa ) + ALLOC_STATE( pix[3], texenv, PIX_STATE_SIZE, "PIX/pixstage-3", 3 ); + ALLOC_STATE( pix[4], texenv, PIX_STATE_SIZE, "PIX/pixstage-4", 4 ); + ALLOC_STATE( pix[5], texenv, PIX_STATE_SIZE, "PIX/pixstage-5", 5 ); +- if (rmesa->r200Screen->drmSupportsTriPerf) { ++ if (rmesa->radeon.radeonScreen->drmSupportsTriPerf) { + ALLOC_STATE( prf, always, PRF_STATE_SIZE, "PRF/performance-tri", 0 ); + } + else { + ALLOC_STATE( prf, never, PRF_STATE_SIZE, "PRF/performance-tri", 0 ); + } +- if (rmesa->r200Screen->drmSupportsPointSprites) { ++ if (rmesa->radeon.radeonScreen->drmSupportsPointSprites) { + ALLOC_STATE( spr, always, SPR_STATE_SIZE, "SPR/pointsprite", 0 ); + ALLOC_STATE( ptp, tcl, PTP_STATE_SIZE, "PTP/pointparams", 0 ); + } +@@ -409,87 +843,115 @@ void r200InitState( r200ContextPtr rmesa ) + + /* Fill in the packet headers: + */ +- rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(RADEON_EMIT_PP_MISC); +- rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(RADEON_EMIT_PP_CNTL); +- rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(RADEON_EMIT_RB3D_COLORPITCH); +- if (rmesa->r200Screen->drmSupportsBlendColor) +- rmesa->hw.ctx.cmd[CTX_CMD_3] = cmdpkt(R200_EMIT_RB3D_BLENDCOLOR); +- rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(RADEON_EMIT_RE_LINE_PATTERN); +- rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(RADEON_EMIT_SE_LINE_WIDTH); +- rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(RADEON_EMIT_RB3D_STENCILREFMASK); +- rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(RADEON_EMIT_SE_VPORT_XSCALE); +- rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(RADEON_EMIT_SE_CNTL); +- rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(RADEON_EMIT_RE_MISC); +- rmesa->hw.cst.cmd[CST_CMD_0] = cmdpkt(R200_EMIT_PP_CNTL_X); +- rmesa->hw.cst.cmd[CST_CMD_1] = cmdpkt(R200_EMIT_RB3D_DEPTHXY_OFFSET); +- rmesa->hw.cst.cmd[CST_CMD_2] = cmdpkt(R200_EMIT_RE_AUX_SCISSOR_CNTL); +- rmesa->hw.cst.cmd[CST_CMD_3] = cmdpkt(R200_EMIT_RE_SCISSOR_TL_0); +- rmesa->hw.cst.cmd[CST_CMD_4] = cmdpkt(R200_EMIT_SE_VAP_CNTL_STATUS); +- rmesa->hw.cst.cmd[CST_CMD_5] = cmdpkt(R200_EMIT_RE_POINTSIZE); +- rmesa->hw.cst.cmd[CST_CMD_6] = cmdpkt(R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0); +- rmesa->hw.tam.cmd[TAM_CMD_0] = cmdpkt(R200_EMIT_PP_TAM_DEBUG3); +- rmesa->hw.tf.cmd[TF_CMD_0] = cmdpkt(R200_EMIT_TFACTOR_0); +- if (rmesa->r200Screen->drmSupportsFragShader) { +- rmesa->hw.atf.cmd[ATF_CMD_0] = cmdpkt(R200_EMIT_ATF_TFACTOR); +- rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCTLALL_0); +- rmesa->hw.tex[0].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_0); +- rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCTLALL_1); +- rmesa->hw.tex[1].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_1); +- rmesa->hw.tex[2].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCTLALL_2); +- rmesa->hw.tex[2].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_2); +- rmesa->hw.tex[3].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCTLALL_3); +- rmesa->hw.tex[3].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_3); +- rmesa->hw.tex[4].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCTLALL_4); +- rmesa->hw.tex[4].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_4); +- rmesa->hw.tex[5].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCTLALL_5); +- rmesa->hw.tex[5].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_5); ++ rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_MISC); ++ rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_CNTL); ++ rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(rmesa, RADEON_EMIT_RB3D_COLORPITCH); ++ if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) ++ rmesa->hw.ctx.cmd[CTX_CMD_3] = cmdpkt(rmesa, R200_EMIT_RB3D_BLENDCOLOR); ++ rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_RE_LINE_PATTERN); ++ rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_SE_LINE_WIDTH); ++ rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_RB3D_STENCILREFMASK); ++ rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_VPORT_XSCALE); ++ rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_CNTL); ++ rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_RE_MISC); ++ rmesa->hw.cst.cmd[CST_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_CNTL_X); ++ rmesa->hw.cst.cmd[CST_CMD_1] = cmdpkt(rmesa, R200_EMIT_RB3D_DEPTHXY_OFFSET); ++ rmesa->hw.cst.cmd[CST_CMD_2] = cmdpkt(rmesa, R200_EMIT_RE_AUX_SCISSOR_CNTL); ++ rmesa->hw.cst.cmd[CST_CMD_3] = cmdpkt(rmesa, R200_EMIT_RE_SCISSOR_TL_0); ++ rmesa->hw.cst.cmd[CST_CMD_4] = cmdpkt(rmesa, R200_EMIT_SE_VAP_CNTL_STATUS); ++ rmesa->hw.cst.cmd[CST_CMD_5] = cmdpkt(rmesa, R200_EMIT_RE_POINTSIZE); ++ rmesa->hw.cst.cmd[CST_CMD_6] = cmdpkt(rmesa, R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0); ++ rmesa->hw.tam.cmd[TAM_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TAM_DEBUG3); ++ rmesa->hw.tf.cmd[TF_CMD_0] = cmdpkt(rmesa, R200_EMIT_TFACTOR_0); ++ if (rmesa->radeon.radeonScreen->drmSupportsFragShader) { ++ rmesa->hw.atf.cmd[ATF_CMD_0] = cmdpkt(rmesa, R200_EMIT_ATF_TFACTOR); ++ rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCTLALL_0); ++ rmesa->hw.tex[0].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_0); ++ rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCTLALL_1); ++ rmesa->hw.tex[1].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_1); ++ rmesa->hw.tex[2].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCTLALL_2); ++ rmesa->hw.tex[2].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_2); ++ rmesa->hw.tex[3].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCTLALL_3); ++ rmesa->hw.tex[3].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_3); ++ rmesa->hw.tex[4].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCTLALL_4); ++ rmesa->hw.tex[4].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_4); ++ rmesa->hw.tex[5].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCTLALL_5); ++ rmesa->hw.tex[5].cmd[TEX_CMD_1_NEWDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_5); + } else { +- rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_0); +- rmesa->hw.tex[0].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_0); +- rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_1); +- rmesa->hw.tex[1].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_1); +- rmesa->hw.tex[2].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_2); +- rmesa->hw.tex[2].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_2); +- rmesa->hw.tex[3].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_3); +- rmesa->hw.tex[3].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_3); +- rmesa->hw.tex[4].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_4); +- rmesa->hw.tex[4].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_4); +- rmesa->hw.tex[5].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_5); +- rmesa->hw.tex[5].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(R200_EMIT_PP_TXOFFSET_5); +- } +- rmesa->hw.afs[0].cmd[AFS_CMD_0] = cmdpkt(R200_EMIT_PP_AFS_0); +- rmesa->hw.afs[1].cmd[AFS_CMD_0] = cmdpkt(R200_EMIT_PP_AFS_1); +- rmesa->hw.pvs.cmd[PVS_CMD_0] = cmdpkt(R200_EMIT_VAP_PVS_CNTL); +- rmesa->hw.cube[0].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_0); +- rmesa->hw.cube[0].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_0); +- rmesa->hw.cube[1].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_1); +- rmesa->hw.cube[1].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_1); +- rmesa->hw.cube[2].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_2); +- rmesa->hw.cube[2].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_2); +- rmesa->hw.cube[3].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_3); +- rmesa->hw.cube[3].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_3); +- rmesa->hw.cube[4].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_4); +- rmesa->hw.cube[4].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_4); +- rmesa->hw.cube[5].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_5); +- rmesa->hw.cube[5].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_5); +- rmesa->hw.pix[0].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_0); +- rmesa->hw.pix[1].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_1); +- rmesa->hw.pix[2].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_2); +- rmesa->hw.pix[3].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_3); +- rmesa->hw.pix[4].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_4); +- rmesa->hw.pix[5].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_5); +- rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(RADEON_EMIT_SE_ZBIAS_FACTOR); +- rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(R200_EMIT_TCL_LIGHT_MODEL_CTL_0); +- rmesa->hw.tcl.cmd[TCL_CMD_1] = cmdpkt(R200_EMIT_TCL_UCP_VERT_BLEND_CTL); +- rmesa->hw.tcg.cmd[TCG_CMD_0] = cmdpkt(R200_EMIT_TEX_PROC_CTL_2); +- rmesa->hw.msl.cmd[MSL_CMD_0] = cmdpkt(R200_EMIT_MATRIX_SELECT_0); +- rmesa->hw.vap.cmd[VAP_CMD_0] = cmdpkt(R200_EMIT_VAP_CTL); +- rmesa->hw.vtx.cmd[VTX_CMD_0] = cmdpkt(R200_EMIT_VTX_FMT_0); +- rmesa->hw.vtx.cmd[VTX_CMD_1] = cmdpkt(R200_EMIT_OUTPUT_VTX_COMP_SEL); +- rmesa->hw.vtx.cmd[VTX_CMD_2] = cmdpkt(R200_EMIT_SE_VTX_STATE_CNTL); +- rmesa->hw.vte.cmd[VTE_CMD_0] = cmdpkt(R200_EMIT_VTE_CNTL); +- rmesa->hw.prf.cmd[PRF_CMD_0] = cmdpkt(R200_EMIT_PP_TRI_PERF_CNTL); +- rmesa->hw.spr.cmd[SPR_CMD_0] = cmdpkt(R200_EMIT_TCL_POINT_SPRITE_CNTL); ++ rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXFILTER_0); ++ rmesa->hw.tex[0].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_0); ++ rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXFILTER_1); ++ rmesa->hw.tex[1].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_1); ++ rmesa->hw.tex[2].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXFILTER_2); ++ rmesa->hw.tex[2].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_2); ++ rmesa->hw.tex[3].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXFILTER_3); ++ rmesa->hw.tex[3].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_3); ++ rmesa->hw.tex[4].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXFILTER_4); ++ rmesa->hw.tex[4].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_4); ++ rmesa->hw.tex[5].cmd[TEX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXFILTER_5); ++ rmesa->hw.tex[5].cmd[TEX_CMD_1_OLDDRM] = cmdpkt(rmesa, R200_EMIT_PP_TXOFFSET_5); ++ } ++ rmesa->hw.afs[0].cmd[AFS_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_AFS_0); ++ rmesa->hw.afs[1].cmd[AFS_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_AFS_1); ++ rmesa->hw.pvs.cmd[PVS_CMD_0] = cmdpkt(rmesa, R200_EMIT_VAP_PVS_CNTL); ++ rmesa->hw.cube[0].cmd[CUBE_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_FACES_0); ++ rmesa->hw.cube[0].cmd[CUBE_CMD_1] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_OFFSETS_0); ++ rmesa->hw.cube[1].cmd[CUBE_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_FACES_1); ++ rmesa->hw.cube[1].cmd[CUBE_CMD_1] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_OFFSETS_1); ++ rmesa->hw.cube[2].cmd[CUBE_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_FACES_2); ++ rmesa->hw.cube[2].cmd[CUBE_CMD_1] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_OFFSETS_2); ++ rmesa->hw.cube[3].cmd[CUBE_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_FACES_3); ++ rmesa->hw.cube[3].cmd[CUBE_CMD_1] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_OFFSETS_3); ++ rmesa->hw.cube[4].cmd[CUBE_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_FACES_4); ++ rmesa->hw.cube[4].cmd[CUBE_CMD_1] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_OFFSETS_4); ++ rmesa->hw.cube[5].cmd[CUBE_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_FACES_5); ++ rmesa->hw.cube[5].cmd[CUBE_CMD_1] = cmdpkt(rmesa, R200_EMIT_PP_CUBIC_OFFSETS_5); ++ rmesa->hw.pix[0].cmd[PIX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCBLEND_0); ++ rmesa->hw.pix[1].cmd[PIX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCBLEND_1); ++ rmesa->hw.pix[2].cmd[PIX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCBLEND_2); ++ rmesa->hw.pix[3].cmd[PIX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCBLEND_3); ++ rmesa->hw.pix[4].cmd[PIX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCBLEND_4); ++ rmesa->hw.pix[5].cmd[PIX_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TXCBLEND_5); ++ rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_ZBIAS_FACTOR); ++ rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(rmesa, R200_EMIT_TCL_LIGHT_MODEL_CTL_0); ++ rmesa->hw.tcl.cmd[TCL_CMD_1] = cmdpkt(rmesa, R200_EMIT_TCL_UCP_VERT_BLEND_CTL); ++ rmesa->hw.tcg.cmd[TCG_CMD_0] = cmdpkt(rmesa, R200_EMIT_TEX_PROC_CTL_2); ++ rmesa->hw.msl.cmd[MSL_CMD_0] = cmdpkt(rmesa, R200_EMIT_MATRIX_SELECT_0); ++ rmesa->hw.vap.cmd[VAP_CMD_0] = cmdpkt(rmesa, R200_EMIT_VAP_CTL); ++ rmesa->hw.vtx.cmd[VTX_CMD_0] = cmdpkt(rmesa, R200_EMIT_VTX_FMT_0); ++ rmesa->hw.vtx.cmd[VTX_CMD_1] = cmdpkt(rmesa, R200_EMIT_OUTPUT_VTX_COMP_SEL); ++ rmesa->hw.vtx.cmd[VTX_CMD_2] = cmdpkt(rmesa, R200_EMIT_SE_VTX_STATE_CNTL); ++ rmesa->hw.vte.cmd[VTE_CMD_0] = cmdpkt(rmesa, R200_EMIT_VTE_CNTL); ++ rmesa->hw.prf.cmd[PRF_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TRI_PERF_CNTL); ++ rmesa->hw.spr.cmd[SPR_CMD_0] = cmdpkt(rmesa, R200_EMIT_TCL_POINT_SPRITE_CNTL); ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ rmesa->hw.mtl[0].emit = mtl_emit; ++ rmesa->hw.mtl[1].emit = mtl_emit; ++ ++ rmesa->hw.vpi[0].emit = veclinear_emit; ++ rmesa->hw.vpi[1].emit = veclinear_emit; ++ rmesa->hw.vpp[0].emit = veclinear_emit; ++ rmesa->hw.vpp[1].emit = veclinear_emit; ++ ++ rmesa->hw.grd.emit = scl_emit; ++ rmesa->hw.fog.emit = vec_emit; ++ rmesa->hw.glt.emit = vec_emit; ++ rmesa->hw.eye.emit = vec_emit; ++ ++ for (i = R200_MTX_MV; i <= R200_MTX_TEX5; i++) ++ rmesa->hw.mat[i].emit = vec_emit; ++ ++ for (i = 0; i < 8; i++) ++ rmesa->hw.lit[i].emit = lit_emit; ++ ++ for (i = 0; i < 6; i++) ++ rmesa->hw.ucp[i].emit = vec_emit; ++ ++ rmesa->hw.ptp.emit = ptp_emit; ++ } ++ ++ ++ + rmesa->hw.mtl[0].cmd[MTL_CMD_0] = + cmdvec( R200_VS_MAT_0_EMISS, 1, 16 ); + rmesa->hw.mtl[0].cmd[MTL_CMD_1] = +@@ -567,7 +1029,7 @@ void r200InitState( r200ContextPtr rmesa ) + (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) | + (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT)); + +- if (rmesa->r200Screen->drmSupportsBlendColor) { ++ if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) { + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] = 0x00000000; + rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = (R200_COMB_FCN_ADD_CLAMP | + (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) | +@@ -578,18 +1040,17 @@ void r200InitState( r200ContextPtr rmesa ) + } + + rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHOFFSET] = +- rmesa->r200Screen->depthOffset + rmesa->r200Screen->fbLocation; ++ rmesa->radeon.radeonScreen->depthOffset + rmesa->radeon.radeonScreen->fbLocation; + + rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHPITCH] = +- ((rmesa->r200Screen->depthPitch & ++ ((rmesa->radeon.radeonScreen->depthPitch & + R200_DEPTHPITCH_MASK) | + R200_DEPTH_ENDIAN_NO_SWAP); + + if (rmesa->using_hyperz) + rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHPITCH] |= R200_DEPTH_HYPERZ; + +- rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (depth_fmt | +- R200_Z_TEST_LESS | ++ rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (R200_Z_TEST_LESS | + R200_STENCIL_TEST_ALWAYS | + R200_STENCIL_FAIL_KEEP | + R200_STENCIL_ZPASS_KEEP | +@@ -599,15 +1060,14 @@ void r200InitState( r200ContextPtr rmesa ) + if (rmesa->using_hyperz) { + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_COMPRESSION_ENABLE | + R200_Z_DECOMPRESSION_ENABLE; +-/* if (rmesa->r200Screen->chip_family == CHIP_FAMILY_R200) ++/* if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_HIERARCHY_ENABLE;*/ + } + + rmesa->hw.ctx.cmd[CTX_PP_CNTL] = (R200_ANTI_ALIAS_NONE + | R200_TEX_BLEND_0_ENABLE); + +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = color_fmt; +- switch ( driQueryOptioni( &rmesa->optionCache, "dither_mode" ) ) { ++ switch ( driQueryOptioni( &rmesa->radeon.optionCache, "dither_mode" ) ) { + case DRI_CONF_DITHER_XERRORDIFFRESET: + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_DITHER_INIT; + break; +@@ -615,41 +1075,19 @@ void r200InitState( r200ContextPtr rmesa ) + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_SCALE_DITHER_ENABLE; + break; + } +- if ( driQueryOptioni( &rmesa->optionCache, "round_mode" ) == ++ if ( driQueryOptioni( &rmesa->radeon.optionCache, "round_mode" ) == + DRI_CONF_ROUND_ROUND ) +- rmesa->state.color.roundEnable = R200_ROUND_ENABLE; ++ rmesa->radeon.state.color.roundEnable = R200_ROUND_ENABLE; + else +- rmesa->state.color.roundEnable = 0; +- if ( driQueryOptioni (&rmesa->optionCache, "color_reduction" ) == ++ rmesa->radeon.state.color.roundEnable = 0; ++ if ( driQueryOptioni (&rmesa->radeon.optionCache, "color_reduction" ) == + DRI_CONF_COLOR_REDUCTION_DITHER ) + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_DITHER_ENABLE; + else +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; +- +-#if 000 +- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((rmesa->state.color.drawOffset + +- rmesa->r200Screen->fbLocation) +- & R200_COLOROFFSET_MASK); +- +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch & +- R200_COLORPITCH_MASK) | +- R200_COLOR_ENDIAN_NO_SWAP); +-#else +- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((drawOffset + +- rmesa->r200Screen->fbLocation) +- & R200_COLOROFFSET_MASK); +- +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((drawPitch & +- R200_COLORPITCH_MASK) | +- R200_COLOR_ENDIAN_NO_SWAP); +-#endif +- /* (fixed size) sarea is initialized to zero afaics so can omit version check. Phew! */ +- if (rmesa->sarea->tiling_enabled) { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; +- } ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; + + rmesa->hw.prf.cmd[PRF_PP_TRI_PERF] = R200_TRI_CUTOFF_MASK - R200_TRI_CUTOFF_MASK * +- driQueryOptionf (&rmesa->optionCache,"texture_blend_quality"); ++ driQueryOptionf (&rmesa->radeon.optionCache,"texture_blend_quality"); + rmesa->hw.prf.cmd[PRF_PP_PERF_CNTL] = 0; + + rmesa->hw.set.cmd[SET_SE_CNTL] = (R200_FFACE_CULL_CCW | +@@ -704,7 +1142,7 @@ void r200InitState( r200ContextPtr rmesa ) + R200_VC_NO_SWAP; + #endif + +- if (!(rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL)) { ++ if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { + /* Bypass TCL */ + rmesa->hw.cst.cmd[CST_SE_VAP_CNTL_STATUS] |= (1<<8); + } +@@ -743,28 +1181,28 @@ void r200InitState( r200ContextPtr rmesa ) + rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT_X] = + (/* R200_TEXCOORD_PROJ | */ + 0x100000); /* Small default bias */ +- if (rmesa->r200Screen->drmSupportsFragShader) { ++ if (rmesa->radeon.radeonScreen->drmSupportsFragShader) { + rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET_NEWDRM] = +- rmesa->r200Screen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + rmesa->hw.tex[i].cmd[TEX_PP_CUBIC_FACES] = 0; + rmesa->hw.tex[i].cmd[TEX_PP_TXMULTI_CTL] = 0; + } + else { + rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET_OLDDRM] = +- rmesa->r200Screen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + } + + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_FACES] = 0; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F1] = +- rmesa->r200Screen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F2] = +- rmesa->r200Screen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F3] = +- rmesa->r200Screen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F4] = +- rmesa->r200Screen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F5] = +- rmesa->r200Screen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + + rmesa->hw.pix[i].cmd[PIX_PP_TXCBLEND] = + (R200_TXC_ARG_A_ZERO | +@@ -967,5 +1405,7 @@ void r200InitState( r200ContextPtr rmesa ) + + r200LightingSpaceChange( ctx ); + +- rmesa->hw.all_dirty = GL_TRUE; ++ rmesa->radeon.hw.all_dirty = GL_TRUE; ++ ++ rcommonInitCmdBuf(&rmesa->radeon); + } +diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c +index b25f028..712da98 100644 +--- a/src/mesa/drivers/dri/r200/r200_swtcl.c ++++ b/src/mesa/drivers/dri/r200/r200_swtcl.c +@@ -55,27 +55,24 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r200_tcl.h" + + +-static void flush_last_swtcl_prim( r200ContextPtr rmesa ); +- +- + /*********************************************************************** + * Initialization + ***********************************************************************/ + + #define EMIT_ATTR( ATTR, STYLE, F0 ) \ + do { \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR); \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = (STYLE); \ +- rmesa->swtcl.vertex_attr_count++; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \ ++ rmesa->radeon.swtcl.vertex_attr_count++; \ + fmt_0 |= F0; \ + } while (0) + + #define EMIT_PAD( N ) \ + do { \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = 0; \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = EMIT_PAD; \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].offset = (N); \ +- rmesa->swtcl.vertex_attr_count++; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = 0; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = EMIT_PAD; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].offset = (N); \ ++ rmesa->radeon.swtcl.vertex_attr_count++; \ + } while (0) + + static void r200SetVertexFormat( GLcontext *ctx ) +@@ -100,7 +97,7 @@ static void r200SetVertexFormat( GLcontext *ctx ) + } + + assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL ); +- rmesa->swtcl.vertex_attr_count = 0; ++ rmesa->radeon.swtcl.vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. +@@ -185,7 +182,7 @@ static void r200SetVertexFormat( GLcontext *ctx ) + rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_SPEC_ALPHA; + } + +- if (!RENDERINPUTS_EQUAL( rmesa->tnl_index_bitset, index_bitset ) || ++ if (!RENDERINPUTS_EQUAL( rmesa->radeon.tnl_index_bitset, index_bitset ) || + (rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0) || + (rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) { + R200_NEWPRIM(rmesa); +@@ -193,26 +190,20 @@ static void r200SetVertexFormat( GLcontext *ctx ) + rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = fmt_0; + rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = fmt_1; + +- rmesa->swtcl.vertex_size = ++ rmesa->radeon.swtcl.vertex_size = + _tnl_install_attrs( ctx, +- rmesa->swtcl.vertex_attrs, +- rmesa->swtcl.vertex_attr_count, ++ rmesa->radeon.swtcl.vertex_attrs, ++ rmesa->radeon.swtcl.vertex_attr_count, + NULL, 0 ); +- rmesa->swtcl.vertex_size /= 4; +- RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset ); ++ rmesa->radeon.swtcl.vertex_size /= 4; ++ RENDERINPUTS_COPY( rmesa->radeon.tnl_index_bitset, index_bitset ); + } + } + + + static void r200RenderStart( GLcontext *ctx ) + { +- r200ContextPtr rmesa = R200_CONTEXT( ctx ); +- + r200SetVertexFormat( ctx ); +- +- if (rmesa->dma.flush != 0 && +- rmesa->dma.flush != flush_last_swtcl_prim) +- rmesa->dma.flush( rmesa ); + } + + +@@ -232,7 +223,7 @@ void r200ChooseVertexState( GLcontext *ctx ) + * rasterization fallback. As this function will be called again when we + * leave a rasterization fallback, we can just skip it for now. + */ +- if (rmesa->Fallback != 0) ++ if (rmesa->radeon.Fallback != 0) + return; + + vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]; +@@ -273,78 +264,27 @@ void r200ChooseVertexState( GLcontext *ctx ) + } + } + +- +-/* Flush vertices in the current dma region. +- */ +-static void flush_last_swtcl_prim( r200ContextPtr rmesa ) ++void r200_swtcl_flush(GLcontext *ctx, uint32_t current_offset) + { +- if (R200_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- rmesa->dma.flush = NULL; +- +- if (rmesa->dma.current.buf) { +- struct r200_dma_region *current = &rmesa->dma.current; +- GLuint current_offset = (rmesa->r200Screen->gart_buffer_offset + +- current->buf->buf->idx * RADEON_BUFFER_SIZE + +- current->start); +- +- assert (!(rmesa->swtcl.hw_primitive & R200_VF_PRIM_WALK_IND)); +- +- assert (current->start + +- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == +- current->ptr); +- +- if (rmesa->dma.current.start != rmesa->dma.current.ptr) { +- r200EnsureCmdBufSpace( rmesa, VERT_AOS_BUFSZ + +- rmesa->hw.max_state_size + VBUF_BUFSZ ); +- r200EmitVertexAOS( rmesa, +- rmesa->swtcl.vertex_size, +- current_offset); +- +- r200EmitVbufPrim( rmesa, +- rmesa->swtcl.hw_primitive, +- rmesa->swtcl.numverts); +- } +- +- rmesa->swtcl.numverts = 0; +- current->start = current->ptr; +- } +-} +- +- +-/* Alloc space in the current dma region. +- */ +-static INLINE void * +-r200AllocDmaLowVerts( r200ContextPtr rmesa, int nverts, int vsize ) +-{ +- GLuint bytes = vsize * nverts; +- +- if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) +- r200RefillCurrentDmaRegion( rmesa ); +- +- if (!rmesa->dma.flush) { +- rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; +- rmesa->dma.flush = flush_last_swtcl_prim; +- } ++ r200ContextPtr rmesa = R200_CONTEXT(ctx); ++ rcommonEnsureCmdBufSpace(&rmesa->radeon, ++ rmesa->radeon.hw.max_state_size + (12*sizeof(int)), ++ __FUNCTION__); + +- ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); +- ASSERT( rmesa->dma.flush == flush_last_swtcl_prim ); +- ASSERT( rmesa->dma.current.start + +- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == +- rmesa->dma.current.ptr ); + ++ radeonEmitState(&rmesa->radeon); ++ r200EmitVertexAOS( rmesa, ++ rmesa->radeon.swtcl.vertex_size, ++ rmesa->radeon.dma.current, ++ current_offset); + +- { +- GLubyte *head = (GLubyte *) (rmesa->dma.current.address + rmesa->dma.current.ptr); +- rmesa->dma.current.ptr += bytes; +- rmesa->swtcl.numverts += nverts; +- return head; +- } ++ ++ r200EmitVbufPrim( rmesa, ++ rmesa->radeon.swtcl.hw_primitive, ++ rmesa->radeon.swtcl.numverts); + + } + +- + /**************************************************************************/ + + +@@ -392,13 +332,13 @@ static void r200ResetLineStipple( GLcontext *ctx ); + #undef LOCAL_VARS + #undef ALLOC_VERTS + #define CTX_ARG r200ContextPtr rmesa +-#define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size +-#define ALLOC_VERTS( n, size ) r200AllocDmaLowVerts( rmesa, n, size * 4 ) ++#define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size ++#define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 ) + #define LOCAL_VARS \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ +- const char *r200verts = (char *)rmesa->swtcl.verts; +-#define VERT(x) (r200Vertex *)(r200verts + ((x) * vertsize * sizeof(int))) +-#define VERTEX r200Vertex ++ const char *r200verts = (char *)rmesa->radeon.swtcl.verts; ++#define VERT(x) (radeonVertex *)(r200verts + ((x) * vertsize * sizeof(int))) ++#define VERTEX radeonVertex + #define DO_DEBUG_VERTS (1 && (R200_DEBUG & DEBUG_VERTS)) + + #undef TAG +@@ -456,11 +396,11 @@ static struct { + #define VERT_Y(_v) _v->v.y + #define VERT_Z(_v) _v->v.z + #define AREA_IS_CCW( a ) (a < 0) +-#define GET_VERTEX(e) (rmesa->swtcl.verts + (e*rmesa->swtcl.vertex_size*sizeof(int))) ++#define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int))) + + #define VERT_SET_RGBA( v, c ) \ + do { \ +- r200_color_t *color = (r200_color_t *)&((v)->ui[coloroffset]); \ ++ radeon_color_t *color = (radeon_color_t *)&((v)->ui[coloroffset]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \ +@@ -472,7 +412,7 @@ do { \ + #define VERT_SET_SPEC( v, c ) \ + do { \ + if (specoffset) { \ +- r200_color_t *spec = (r200_color_t *)&((v)->ui[specoffset]); \ ++ radeon_color_t *spec = (radeon_color_t *)&((v)->ui[specoffset]); \ + UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]); \ +@@ -481,8 +421,8 @@ do { \ + #define VERT_COPY_SPEC( v0, v1 ) \ + do { \ + if (specoffset) { \ +- r200_color_t *spec0 = (r200_color_t *)&((v0)->ui[specoffset]); \ +- r200_color_t *spec1 = (r200_color_t *)&((v1)->ui[specoffset]); \ ++ radeon_color_t *spec0 = (radeon_color_t *)&((v0)->ui[specoffset]); \ ++ radeon_color_t *spec1 = (radeon_color_t *)&((v1)->ui[specoffset]); \ + spec0->red = spec1->red; \ + spec0->green = spec1->green; \ + spec0->blue = spec1->blue; \ +@@ -513,7 +453,7 @@ do { \ + ***********************************************************************/ + + #define RASTERIZE(x) r200RasterPrimitive( ctx, reduced_hw_prim(ctx, x) ) +-#define RENDER_PRIMITIVE rmesa->swtcl.render_primitive ++#define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive + #undef TAG + #define TAG(x) x + #include "tnl_dd/t_dd_unfilled.h" +@@ -569,8 +509,8 @@ static void init_rast_tab( void ) + #undef LOCAL_VARS + #define LOCAL_VARS \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ +- const GLuint vertsize = rmesa->swtcl.vertex_size; \ +- const char *r200verts = (char *)rmesa->swtcl.verts; \ ++ const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \ ++ const char *r200verts = (char *)rmesa->radeon.swtcl.verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) elt; (void) stipple; +@@ -599,13 +539,13 @@ void r200ChooseRenderState( GLcontext *ctx ) + GLuint index = 0; + GLuint flags = ctx->_TriangleCaps; + +- if (!rmesa->TclFallback || rmesa->Fallback) ++ if (!rmesa->radeon.TclFallback || rmesa->radeon.Fallback) + return; + + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R200_TWOSIDE_BIT; + if (flags & DD_TRI_UNFILLED) index |= R200_UNFILLED_BIT; + +- if (index != rmesa->swtcl.RenderIndex) { ++ if (index != rmesa->radeon.swtcl.RenderIndex) { + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; +@@ -622,7 +562,7 @@ void r200ChooseRenderState( GLcontext *ctx ) + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + } + +- rmesa->swtcl.RenderIndex = index; ++ rmesa->radeon.swtcl.RenderIndex = index; + } + } + +@@ -636,7 +576,7 @@ static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + +- if (rmesa->swtcl.hw_primitive != hwprim) { ++ if (rmesa->radeon.swtcl.hw_primitive != hwprim) { + /* need to disable perspective-correct texturing for point sprites */ + if ((hwprim & 0xf) == R200_VF_PRIM_POINT_SPRITES && ctx->Point.PointSprite) { + if (rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE) { +@@ -649,14 +589,14 @@ static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim ) + rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PERSPECTIVE_ENABLE; + } + R200_NEWPRIM( rmesa ); +- rmesa->swtcl.hw_primitive = hwprim; ++ rmesa->radeon.swtcl.hw_primitive = hwprim; + } + } + + static void r200RenderPrimitive( GLcontext *ctx, GLenum prim ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- rmesa->swtcl.render_primitive = prim; ++ rmesa->radeon.swtcl.render_primitive = prim; + if (prim < GL_TRIANGLES || !(ctx->_TriangleCaps & DD_TRI_UNFILLED)) + r200RasterPrimitive( ctx, reduced_hw_prim(ctx, prim) ); + } +@@ -701,15 +641,15 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); +- GLuint oldfallback = rmesa->Fallback; ++ GLuint oldfallback = rmesa->radeon.Fallback; + + if (mode) { +- rmesa->Fallback |= bit; ++ rmesa->radeon.Fallback |= bit; + if (oldfallback == 0) { +- R200_FIREVERTICES( rmesa ); ++ radeon_firevertices(&rmesa->radeon); + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_TRUE ); + _swsetup_Wakeup( ctx ); +- rmesa->swtcl.RenderIndex = ~0; ++ rmesa->radeon.swtcl.RenderIndex = ~0; + if (R200_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "R200 begin rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); +@@ -717,7 +657,7 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + } + } + else { +- rmesa->Fallback &= ~bit; ++ rmesa->radeon.Fallback &= ~bit; + if (oldfallback == bit) { + + _swrast_flush( ctx ); +@@ -731,14 +671,14 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + + tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple; + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_FALSE ); +- if (rmesa->TclFallback) { +- /* These are already done if rmesa->TclFallback goes to ++ if (rmesa->radeon.TclFallback) { ++ /* These are already done if rmesa->radeon.TclFallback goes to + * zero above. But not if it doesn't (R200_NO_TCL for + * example?) + */ + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); +- RENDERINPUTS_ZERO( rmesa->tnl_index_bitset ); ++ RENDERINPUTS_ZERO( rmesa->radeon.tnl_index_bitset ); + r200ChooseVertexState( ctx ); + r200ChooseRenderState( ctx ); + } +@@ -772,7 +712,7 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, + r200ContextPtr rmesa = R200_CONTEXT(ctx); + const GLfloat *rc = ctx->Current.RasterColor; + GLint row, col; +- r200Vertex vert; ++ radeonVertex vert; + GLuint orig_vte; + GLuint h; + +@@ -794,7 +734,7 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, + vte |= R200_VTX_W0_FMT; + vap &= ~R200_VAP_FORCE_W_TO_ONE; + +- rmesa->swtcl.vertex_size = 5; ++ rmesa->radeon.swtcl.vertex_size = 5; + + if ( (rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0) + || (rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) { +@@ -871,10 +811,10 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, + + /* Update window height + */ +- LOCK_HARDWARE( rmesa ); +- UNLOCK_HARDWARE( rmesa ); +- h = rmesa->dri.drawable->h + rmesa->dri.drawable->y; +- px += rmesa->dri.drawable->x; ++ LOCK_HARDWARE( &rmesa->radeon ); ++ UNLOCK_HARDWARE( &rmesa->radeon ); ++ h = rmesa->radeon.dri.drawable->h + rmesa->radeon.dri.drawable->y; ++ px += rmesa->radeon.dri.drawable->x; + + /* Clipping handled by existing mechansims in r200_ioctl.c? + */ +@@ -929,7 +869,7 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, + + /* Need to restore vertexformat? + */ +- if (rmesa->TclFallback) ++ if (rmesa->radeon.TclFallback) + r200ChooseVertexState( ctx ); + } + +@@ -962,17 +902,9 @@ void r200InitSwtcl( GLcontext *ctx ) + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, + 36 * sizeof(GLfloat) ); + +- rmesa->swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf; +- rmesa->swtcl.RenderIndex = ~0; +- rmesa->swtcl.render_primitive = GL_TRIANGLES; +- rmesa->swtcl.hw_primitive = 0; ++ rmesa->radeon.swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf; ++ rmesa->radeon.swtcl.RenderIndex = ~0; ++ rmesa->radeon.swtcl.render_primitive = GL_TRIANGLES; ++ rmesa->radeon.swtcl.hw_primitive = 0; + } + +- +-void r200DestroySwtcl( GLcontext *ctx ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- +- if (rmesa->swtcl.indexed_verts.buf) +- r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ ); +-} +diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.h b/src/mesa/drivers/dri/r200/r200_swtcl.h +index 8c29fd0..b090587 100644 +--- a/src/mesa/drivers/dri/r200/r200_swtcl.h ++++ b/src/mesa/drivers/dri/r200/r200_swtcl.h +@@ -39,7 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r200_context.h" + + extern void r200InitSwtcl( GLcontext *ctx ); +-extern void r200DestroySwtcl( GLcontext *ctx ); + + extern void r200ChooseRenderState( GLcontext *ctx ); + extern void r200ChooseVertexState( GLcontext *ctx ); +@@ -52,15 +51,11 @@ extern void r200BuildVertices( GLcontext *ctx, GLuint start, GLuint count, + extern void r200PrintSetupFlags(char *msg, GLuint flags ); + + +-extern void r200_emit_indexed_verts( GLcontext *ctx, +- GLuint start, +- GLuint count ); +- + extern void r200_translate_vertex( GLcontext *ctx, +- const r200Vertex *src, ++ const radeonVertex *src, + SWvertex *dst ); + +-extern void r200_print_vertex( GLcontext *ctx, const r200Vertex *v ); ++extern void r200_print_vertex( GLcontext *ctx, const radeonVertex *v ); + + extern void r200_import_float_colors( GLcontext *ctx ); + extern void r200_import_float_spec_colors( GLcontext *ctx ); +@@ -70,5 +65,5 @@ extern void r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ); + +- ++void r200_swtcl_flush(GLcontext *ctx, uint32_t current_offset); + #endif +diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c +index 99aecfe..5803709 100644 +--- a/src/mesa/drivers/dri/r200/r200_tcl.c ++++ b/src/mesa/drivers/dri/r200/r200_tcl.c +@@ -123,7 +123,7 @@ static GLboolean discrete_prim[0x10] = { + + #define RESET_STIPPLE() do { \ + R200_STATECHANGE( rmesa, lin ); \ +- r200EmitState( rmesa ); \ ++ radeonEmitState(&rmesa->radeon); \ + } while (0) + + #define AUTO_STIPPLE( mode ) do { \ +@@ -134,7 +134,7 @@ static GLboolean discrete_prim[0x10] = { + else \ + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \ + ~R200_LINE_PATTERN_AUTO_RESET; \ +- r200EmitState( rmesa ); \ ++ radeonEmitState(&rmesa->radeon); \ + } while (0) + + +@@ -142,26 +142,24 @@ static GLboolean discrete_prim[0x10] = { + + static GLushort *r200AllocElts( r200ContextPtr rmesa, GLuint nr ) + { +- if (rmesa->dma.flush == r200FlushElts && +- rmesa->store.cmd_used + nr*2 < R200_CMD_BUF_SZ) { ++ if (rmesa->radeon.dma.flush == r200FlushElts && ++ rmesa->tcl.elt_used + nr*2 < R200_ELT_BUF_SZ) { + +- GLushort *dest = (GLushort *)(rmesa->store.cmd_buf + +- rmesa->store.cmd_used); ++ GLushort *dest = (GLushort *)(rmesa->radeon.tcl.elt_dma_bo->ptr + ++ rmesa->tcl.elt_used); + +- rmesa->store.cmd_used += nr*2; ++ rmesa->tcl.elt_used += nr*2; + + return dest; + } + else { +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); ++ if (rmesa->radeon.dma.flush) ++ rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); + +- r200EnsureCmdBufSpace( rmesa, AOS_BUFSZ(rmesa->tcl.nr_aos_components) + +- rmesa->hw.max_state_size + ELTS_BUFSZ(nr) ); ++ rcommonEnsureCmdBufSpace(&rmesa->radeon, AOS_BUFSZ(rmesa->radeon.tcl.aos_count), __FUNCTION__); + + r200EmitAOS( rmesa, +- rmesa->tcl.aos_components, +- rmesa->tcl.nr_aos_components, 0 ); ++ rmesa->radeon.tcl.aos_count, 0 ); + + return r200AllocEltsOpenEnded( rmesa, rmesa->tcl.hw_primitive, nr ); + } +@@ -188,13 +186,14 @@ static void r200EmitPrim( GLcontext *ctx, + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + r200TclPrimitive( ctx, prim, hwprim ); + +- r200EnsureCmdBufSpace( rmesa, AOS_BUFSZ(rmesa->tcl.nr_aos_components) + +- rmesa->hw.max_state_size + VBUF_BUFSZ ); ++ // fprintf(stderr,"Emit prim %d\n", rmesa->radeon.tcl.aos_count); ++ rcommonEnsureCmdBufSpace( &rmesa->radeon, ++ AOS_BUFSZ(rmesa->radeon.tcl.aos_count) + ++ rmesa->radeon.hw.max_state_size + VBUF_BUFSZ, __FUNCTION__ ); + + r200EmitAOS( rmesa, +- rmesa->tcl.aos_components, +- rmesa->tcl.nr_aos_components, +- start ); ++ rmesa->radeon.tcl.aos_count, ++ start ); + + /* Why couldn't this packet have taken an offset param? + */ +@@ -394,7 +393,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, + + /* TODO: separate this from the swtnl pipeline + */ +- if (rmesa->TclFallback) ++ if (rmesa->radeon.TclFallback) + return GL_TRUE; /* fallback to software t&l */ + + if (R200_DEBUG & DEBUG_PRIMS) +@@ -405,8 +404,9 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, + + /* Validate state: + */ +- if (rmesa->NewGLState) +- r200ValidateState( ctx ); ++ if (rmesa->radeon.NewGLState) ++ if (!r200ValidateState( ctx )) ++ return GL_TRUE; /* fallback to sw t&l */ + + if (!ctx->VertexProgram._Enabled) { + /* NOTE: inputs != tnl->render_inputs - these are the untransformed +@@ -481,7 +481,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, + + /* Do the actual work: + */ +- r200ReleaseArrays( ctx, ~0 /* stage->changed_inputs */ ); ++ radeonReleaseArrays( ctx, ~0 /* stage->changed_inputs */ ); + r200EmitArrays( ctx, vimap_rev ); + + rmesa->tcl.Elts = VB->Elts; +@@ -545,7 +545,7 @@ static void transition_to_swtnl( GLcontext *ctx ) + tnl->Driver.NotifyMaterialChange = + _mesa_validate_all_lighting_tables; + +- r200ReleaseArrays( ctx, ~0 ); ++ radeonReleaseArrays( ctx, ~0 ); + + /* Still using the D3D based hardware-rasterizer from the radeon; + * need to put the card into D3D mode to make it work: +@@ -565,15 +565,11 @@ static void transition_to_hwtnl( GLcontext *ctx ) + + tnl->Driver.NotifyMaterialChange = r200UpdateMaterial; + +- if ( rmesa->dma.flush ) +- rmesa->dma.flush( rmesa ); ++ if ( rmesa->radeon.dma.flush ) ++ rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); + +- rmesa->dma.flush = NULL; ++ rmesa->radeon.dma.flush = NULL; + +- if (rmesa->swtcl.indexed_verts.buf) +- r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, +- __FUNCTION__ ); +- + R200_STATECHANGE( rmesa, vap ); + rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE; + rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE; +@@ -631,10 +627,10 @@ static char *getFallbackString(GLuint bit) + void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- GLuint oldfallback = rmesa->TclFallback; ++ GLuint oldfallback = rmesa->radeon.TclFallback; + + if (mode) { +- rmesa->TclFallback |= bit; ++ rmesa->radeon.TclFallback |= bit; + if (oldfallback == 0) { + if (R200_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "R200 begin tcl fallback %s\n", +@@ -643,7 +639,7 @@ void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + } + } + else { +- rmesa->TclFallback &= ~bit; ++ rmesa->radeon.TclFallback &= ~bit; + if (oldfallback == bit) { + if (R200_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "R200 end tcl fallback %s\n", +diff --git a/src/mesa/drivers/dri/r200/r200_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c +index 5a4db33..fc2caab 100644 +--- a/src/mesa/drivers/dri/r200/r200_tex.c ++++ b/src/mesa/drivers/dri/r200/r200_tex.c +@@ -43,8 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/teximage.h" + #include "main/texobj.h" + +-#include "texmem.h" +- ++#include "radeon_mipmap_tree.h" + #include "r200_context.h" + #include "r200_state.h" + #include "r200_ioctl.h" +@@ -63,10 +62,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * \param twrap Wrap mode for the \a t texture coordinate + */ + +-static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum rwrap ) ++static void r200SetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap, GLenum rwrap ) + { + GLboolean is_clamp = GL_FALSE; + GLboolean is_clamp_to_border = GL_FALSE; ++ struct gl_texture_object *tObj = &t->base; + + t->pp_txfilter &= ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK | R200_BORDER_MODE_D3D); + +@@ -103,7 +103,7 @@ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum + _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__); + } + +- if (t->base.tObj->Target != GL_TEXTURE_1D) { ++ if (tObj->Target != GL_TEXTURE_1D) { + switch ( twrap ) { + case GL_REPEAT: + t->pp_txfilter |= R200_CLAMP_T_WRAP; +@@ -180,7 +180,7 @@ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum + t->border_fallback = (is_clamp && is_clamp_to_border); + } + +-static void r200SetTexMaxAnisotropy( r200TexObjPtr t, GLfloat max ) ++static void r200SetTexMaxAnisotropy( radeonTexObjPtr t, GLfloat max ) + { + t->pp_txfilter &= ~R200_MAX_ANISO_MASK; + +@@ -205,10 +205,13 @@ static void r200SetTexMaxAnisotropy( r200TexObjPtr t, GLfloat max ) + * \param magf Texture magnification mode + */ + +-static void r200SetTexFilter( r200TexObjPtr t, GLenum minf, GLenum magf ) ++static void r200SetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf ) + { + GLuint anisotropy = (t->pp_txfilter & R200_MAX_ANISO_MASK); + ++ /* Force revalidation to account for switches from/to mipmapping. */ ++ t->validated = GL_FALSE; ++ + t->pp_txfilter &= ~(R200_MIN_FILTER_MASK | R200_MAG_FILTER_MASK); + t->pp_txformat_x &= ~R200_VOLUME_FILTER_MASK; + +@@ -267,693 +270,12 @@ static void r200SetTexFilter( r200TexObjPtr t, GLenum minf, GLenum magf ) + } + } + +-static void r200SetTexBorderColor( r200TexObjPtr t, GLubyte c[4] ) +-{ +- t->pp_border_color = r200PackColor( 4, c[0], c[1], c[2], c[3] ); +-} +- +- +-/** +- * Allocate space for and load the mesa images into the texture memory block. +- * This will happen before drawing with a new texture, or drawing with a +- * texture after it was swapped out or teximaged again. +- */ +- +-static r200TexObjPtr r200AllocTexObj( struct gl_texture_object *texObj ) +-{ +- r200TexObjPtr t; +- +- t = CALLOC_STRUCT( r200_tex_obj ); +- texObj->DriverData = t; +- if ( t != NULL ) { +- if ( R200_DEBUG & DEBUG_TEXTURE ) { +- fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, (void *)texObj, +- (void *)t ); +- } +- +- /* Initialize non-image-dependent parts of the state: +- */ +- t->base.tObj = texObj; +- t->border_fallback = GL_FALSE; +- +- make_empty_list( & t->base ); +- +- r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR ); +- r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); +- r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); +- r200SetTexBorderColor( t, texObj->_BorderChan ); +- } +- +- return t; +-} +- +-/* try to find a format which will only need a memcopy */ +-static const struct gl_texture_format * +-r200Choose8888TexFormat( GLenum srcFormat, GLenum srcType ) +-{ +- const GLuint ui = 1; +- const GLubyte littleEndian = *((const GLubyte *) &ui); +- +- if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || +- (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || +- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || +- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { +- return &_mesa_texformat_rgba8888; +- } +- else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || +- (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || +- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || +- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { +- return &_mesa_texformat_rgba8888_rev; +- } +- else return _dri_texformat_argb8888; +-} +- +-static const struct gl_texture_format * +-r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, +- GLenum format, GLenum type ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- const GLboolean do32bpt = +- ( rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32 ); +- const GLboolean force16bpt = +- ( rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16 ); +- (void) format; +- +- switch ( internalFormat ) { +- case 4: +- case GL_RGBA: +- case GL_COMPRESSED_RGBA: +- switch ( type ) { +- case GL_UNSIGNED_INT_10_10_10_2: +- case GL_UNSIGNED_INT_2_10_10_10_REV: +- return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_argb1555; +- case GL_UNSIGNED_SHORT_4_4_4_4: +- case GL_UNSIGNED_SHORT_4_4_4_4_REV: +- return _dri_texformat_argb4444; +- case GL_UNSIGNED_SHORT_5_5_5_1: +- case GL_UNSIGNED_SHORT_1_5_5_5_REV: +- return _dri_texformat_argb1555; +- default: +- return do32bpt ? +- r200Choose8888TexFormat(format, type) : _dri_texformat_argb4444; +- } +- +- case 3: +- case GL_RGB: +- case GL_COMPRESSED_RGB: +- switch ( type ) { +- case GL_UNSIGNED_SHORT_4_4_4_4: +- case GL_UNSIGNED_SHORT_4_4_4_4_REV: +- return _dri_texformat_argb4444; +- case GL_UNSIGNED_SHORT_5_5_5_1: +- case GL_UNSIGNED_SHORT_1_5_5_5_REV: +- return _dri_texformat_argb1555; +- case GL_UNSIGNED_SHORT_5_6_5: +- case GL_UNSIGNED_SHORT_5_6_5_REV: +- return _dri_texformat_rgb565; +- default: +- return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565; +- } +- +- case GL_RGBA8: +- case GL_RGB10_A2: +- case GL_RGBA12: +- case GL_RGBA16: +- return !force16bpt ? +- r200Choose8888TexFormat(format, type) : _dri_texformat_argb4444; +- +- case GL_RGBA4: +- case GL_RGBA2: +- return _dri_texformat_argb4444; +- +- case GL_RGB5_A1: +- return _dri_texformat_argb1555; +- +- case GL_RGB8: +- case GL_RGB10: +- case GL_RGB12: +- case GL_RGB16: +- return !force16bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565; +- +- case GL_RGB5: +- case GL_RGB4: +- case GL_R3_G3_B2: +- return _dri_texformat_rgb565; +- +- case GL_ALPHA: +- case GL_ALPHA4: +- case GL_ALPHA8: +- case GL_ALPHA12: +- case GL_ALPHA16: +- case GL_COMPRESSED_ALPHA: +- /* can't use a8 format since interpreting hw I8 as a8 would result +- in wrong rgb values (same as alpha value instead of 0). */ +- return _dri_texformat_al88; +- +- case 1: +- case GL_LUMINANCE: +- case GL_LUMINANCE4: +- case GL_LUMINANCE8: +- case GL_LUMINANCE12: +- case GL_LUMINANCE16: +- case GL_COMPRESSED_LUMINANCE: +- return _dri_texformat_l8; +- +- case 2: +- case GL_LUMINANCE_ALPHA: +- case GL_LUMINANCE4_ALPHA4: +- case GL_LUMINANCE6_ALPHA2: +- case GL_LUMINANCE8_ALPHA8: +- case GL_LUMINANCE12_ALPHA4: +- case GL_LUMINANCE12_ALPHA12: +- case GL_LUMINANCE16_ALPHA16: +- case GL_COMPRESSED_LUMINANCE_ALPHA: +- return _dri_texformat_al88; +- +- case GL_INTENSITY: +- case GL_INTENSITY4: +- case GL_INTENSITY8: +- case GL_INTENSITY12: +- case GL_INTENSITY16: +- case GL_COMPRESSED_INTENSITY: +- return _dri_texformat_i8; +- +- case GL_YCBCR_MESA: +- if (type == GL_UNSIGNED_SHORT_8_8_APPLE || +- type == GL_UNSIGNED_BYTE) +- return &_mesa_texformat_ycbcr; +- else +- return &_mesa_texformat_ycbcr_rev; +- +- case GL_RGB_S3TC: +- case GL_RGB4_S3TC: +- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: +- return &_mesa_texformat_rgb_dxt1; +- +- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: +- return &_mesa_texformat_rgba_dxt1; +- +- case GL_RGBA_S3TC: +- case GL_RGBA4_S3TC: +- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: +- return &_mesa_texformat_rgba_dxt3; +- +- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: +- return &_mesa_texformat_rgba_dxt5; +- +- default: +- _mesa_problem(ctx, +- "unexpected internalFormat 0x%x in r200ChooseTextureFormat", +- (int) internalFormat); +- return NULL; +- } +- +- return NULL; /* never get here */ +-} +- +- +-static GLboolean +-r200ValidateClientStorage( GLcontext *ctx, GLenum target, +- GLint internalFormat, +- GLint srcWidth, GLint srcHeight, +- GLenum format, GLenum type, const void *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +- +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- +- if ( R200_DEBUG & DEBUG_TEXTURE ) +- fprintf(stderr, "intformat %s format %s type %s\n", +- _mesa_lookup_enum_by_nr( internalFormat ), +- _mesa_lookup_enum_by_nr( format ), +- _mesa_lookup_enum_by_nr( type )); +- +- if (!ctx->Unpack.ClientStorage) +- return 0; +- +- if (ctx->_ImageTransferState || +- texImage->IsCompressed || +- texObj->GenerateMipmap) +- return 0; +- +- +- /* This list is incomplete, may be different on ppc??? +- */ +- switch ( internalFormat ) { +- case GL_RGBA: +- if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) { +- texImage->TexFormat = _dri_texformat_argb8888; +- } +- else +- return 0; +- break; +- +- case GL_RGB: +- if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { +- texImage->TexFormat = _dri_texformat_rgb565; +- } +- else +- return 0; +- break; +- +- case GL_YCBCR_MESA: +- if ( format == GL_YCBCR_MESA && +- type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) { +- texImage->TexFormat = &_mesa_texformat_ycbcr_rev; +- } +- else if ( format == GL_YCBCR_MESA && +- (type == GL_UNSIGNED_SHORT_8_8_APPLE || +- type == GL_UNSIGNED_BYTE)) { +- texImage->TexFormat = &_mesa_texformat_ycbcr; +- } +- else +- return 0; +- break; +- +- default: +- return 0; +- } +- +- /* Could deal with these packing issues, but currently don't: +- */ +- if (packing->SkipPixels || +- packing->SkipRows || +- packing->SwapBytes || +- packing->LsbFirst) { +- return 0; +- } +- +- { +- GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth, +- format, type); +- +- +- if ( R200_DEBUG & DEBUG_TEXTURE ) +- fprintf(stderr, "%s: srcRowStride %d/%x\n", +- __FUNCTION__, srcRowStride, srcRowStride); +- +- /* Could check this later in upload, pitch restrictions could be +- * relaxed, but would need to store the image pitch somewhere, +- * as packing details might change before image is uploaded: +- */ +- if (!r200IsGartMemory( rmesa, pixels, srcHeight * srcRowStride ) || +- (srcRowStride & 63)) +- return 0; +- +- +- /* Have validated that _mesa_transfer_teximage would be a straight +- * memcpy at this point. NOTE: future calls to TexSubImage will +- * overwrite the client data. This is explicitly mentioned in the +- * extension spec. +- */ +- texImage->Data = (void *)pixels; +- texImage->IsClientData = GL_TRUE; +- texImage->RowStride = srcRowStride / texImage->TexFormat->TexelBytes; +- +- return 1; +- } +-} +- +- +-static void r200TexImage1D( GLcontext *ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint border, +- GLenum format, GLenum type, const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) r200AllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); +- return; +- } +- } +- +- /* Note, this will call ChooseTextureFormat */ +- _mesa_store_teximage1d(ctx, target, level, internalFormat, +- width, border, format, type, pixels, +- &ctx->Unpack, texObj, texImage); +- +- t->dirty_images[0] |= (1 << level); +-} +- +- +-static void r200TexSubImage1D( GLcontext *ctx, GLenum target, GLint level, +- GLint xoffset, +- GLsizei width, +- GLenum format, GLenum type, +- const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- +- assert( t ); /* this _should_ be true */ +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) r200AllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); +- return; +- } +- } +- +- _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, +- format, type, pixels, packing, texObj, +- texImage); +- +- t->dirty_images[0] |= (1 << level); +-} +- +- +-static void r200TexImage2D( GLcontext *ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint height, GLint border, +- GLenum format, GLenum type, const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- if ( t != NULL ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) r200AllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); +- return; +- } +- } +- +- texImage->IsClientData = GL_FALSE; +- +- if (r200ValidateClientStorage( ctx, target, +- internalFormat, +- width, height, +- format, type, pixels, +- packing, texObj, texImage)) { +- if (R200_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using client storage\n", __FUNCTION__); +- } +- else { +- if (R200_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__); +- +- /* Normal path: copy (to cached memory) and eventually upload +- * via another copy to GART memory and then a blit... Could +- * eliminate one copy by going straight to (permanent) GART. +- * +- * Note, this will call r200ChooseTextureFormat. +- */ +- _mesa_store_teximage2d(ctx, target, level, internalFormat, +- width, height, border, format, type, pixels, +- &ctx->Unpack, texObj, texImage); +- +- t->dirty_images[face] |= (1 << level); +- } +-} +- +- +-static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, +- GLint xoffset, GLint yoffset, +- GLsizei width, GLsizei height, +- GLenum format, GLenum type, +- const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- assert( t ); /* this _should_ be true */ +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) r200AllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); +- return; +- } +- } +- +- _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, +- height, format, type, pixels, packing, texObj, +- texImage); +- +- t->dirty_images[face] |= (1 << level); +-} +- +- +-static void r200CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint height, GLint border, +- GLsizei imageSize, const GLvoid *data, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) ++static void r200SetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] ) + { +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- if ( t != NULL ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) r200AllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); +- return; +- } +- } +- +- texImage->IsClientData = GL_FALSE; +-/* can't call this, different parameters. Would never evaluate to true anyway currently +- if (r200ValidateClientStorage( ctx, target, +- internalFormat, +- width, height, +- format, type, pixels, +- packing, texObj, texImage)) { +- if (R200_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using client storage\n", __FUNCTION__); +- } +- else */{ +- if (R200_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__); +- +- /* Normal path: copy (to cached memory) and eventually upload +- * via another copy to GART memory and then a blit... Could +- * eliminate one copy by going straight to (permanent) GART. +- * +- * Note, this will call r200ChooseTextureFormat. +- */ +- _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width, +- height, border, imageSize, data, texObj, texImage); +- +- t->dirty_images[face] |= (1 << level); +- } +-} +- +- +-static void r200CompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, +- GLint xoffset, GLint yoffset, +- GLsizei width, GLsizei height, +- GLenum format, +- GLsizei imageSize, const GLvoid *data, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- assert( t ); /* this _should_ be true */ +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) r200AllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D"); +- return; +- } +- } +- +- _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width, +- height, format, imageSize, data, texObj, texImage); +- +- t->dirty_images[face] |= (1 << level); +-} +- +- +-#if ENABLE_HW_3D_TEXTURE +-static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint height, GLint depth, +- GLint border, +- GLenum format, GLenum type, const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) r200AllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); +- return; +- } +- } +- +- texImage->IsClientData = GL_FALSE; +- +-#if 0 +- if (r200ValidateClientStorage( ctx, target, +- internalFormat, +- width, height, +- format, type, pixels, +- packing, texObj, texImage)) { +- if (R200_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using client storage\n", __FUNCTION__); +- } +- else +-#endif +- { +- if (R200_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__); +- +- /* Normal path: copy (to cached memory) and eventually upload +- * via another copy to GART memory and then a blit... Could +- * eliminate one copy by going straight to (permanent) GART. +- * +- * Note, this will call r200ChooseTextureFormat. +- */ +- _mesa_store_teximage3d(ctx, target, level, internalFormat, +- width, height, depth, border, +- format, type, pixels, +- &ctx->Unpack, texObj, texImage); +- +- t->dirty_images[0] |= (1 << level); +- } ++ t->pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); + } +-#endif +- + +-#if ENABLE_HW_3D_TEXTURE +-static void +-r200TexSubImage3D( GLcontext *ctx, GLenum target, GLint level, +- GLint xoffset, GLint yoffset, GLint zoffset, +- GLsizei width, GLsizei height, GLsizei depth, +- GLenum format, GLenum type, +- const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- +-/* fprintf(stderr, "%s\n", __FUNCTION__); */ +- +- assert( t ); /* this _should_ be true */ +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) r200AllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D"); +- return; +- } +- texObj->DriverData = t; +- } + +- _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset, +- width, height, depth, +- format, type, pixels, packing, texObj, texImage); +- +- t->dirty_images[0] |= (1 << level); +-} +-#endif + + + +@@ -978,7 +300,7 @@ static void r200TexEnv( GLcontext *ctx, GLenum target, + GLubyte c[4]; + GLuint envColor; + UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor ); +- envColor = r200PackColor( 4, c[0], c[1], c[2], c[3] ); ++ envColor = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); + if ( rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] != envColor ) { + R200_STATECHANGE( rmesa, tf ); + rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] = envColor; +@@ -997,7 +319,7 @@ static void r200TexEnv( GLcontext *ctx, GLenum target, + * NOTE: Add a small bias to the bias for conform mipsel.c test. + */ + bias = *param + .01; +- min = driQueryOptionb (&rmesa->optionCache, "no_neg_lod_bias") ? ++ min = driQueryOptionb (&rmesa->radeon.optionCache, "no_neg_lod_bias") ? + 0.0 : -16.0; + bias = CLAMP( bias, min, 16.0 ); + b = (int)(bias * fixed_one) & R200_LOD_BIAS_MASK; +@@ -1034,7 +356,7 @@ static void r200TexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params ) + { +- r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; ++ radeonTexObj* t = radeon_tex_obj(texObj); + + if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { + fprintf( stderr, "%s( %s )\n", __FUNCTION__, +@@ -1068,59 +390,46 @@ static void r200TexParameter( GLcontext *ctx, GLenum target, + * we just have to rely on loading the right subset of mipmap levels + * to simulate a clamped LOD. + */ +- driSwapOutTextureObject( (driTextureObject *) t ); ++ if (t->mt) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = 0; ++ t->validated = GL_FALSE; ++ } + break; + + default: + return; + } +- +- /* Mark this texobj as dirty (one bit per tex unit) +- */ +- t->dirty_state = TEX_ALL; + } + + +- +-static void r200BindTexture( GLcontext *ctx, GLenum target, +- struct gl_texture_object *texObj ) +-{ +- if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { +- fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, (void *)texObj, +- ctx->Texture.CurrentUnit ); +- } +- +- if ( (target == GL_TEXTURE_1D) +- || (target == GL_TEXTURE_2D) +-#if ENABLE_HW_3D_TEXTURE +- || (target == GL_TEXTURE_3D) +-#endif +- || (target == GL_TEXTURE_CUBE_MAP) +- || (target == GL_TEXTURE_RECTANGLE_NV) ) { +- assert( texObj->DriverData != NULL ); +- } +-} +- +- +-static void r200DeleteTexture( GLcontext *ctx, +- struct gl_texture_object *texObj ) ++static void r200DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- +- if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { +- fprintf( stderr, "%s( %p (target = %s) )\n", __FUNCTION__, (void *)texObj, +- _mesa_lookup_enum_by_nr( texObj->Target ) ); ++ radeonTexObj* t = radeon_tex_obj(texObj); ++ ++ if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { ++ fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, ++ (void *)texObj, ++ _mesa_lookup_enum_by_nr(texObj->Target)); ++ } ++ ++ if (rmesa) { ++ int i; ++ radeon_firevertices(&rmesa->radeon); ++ for ( i = 0 ; i < rmesa->radeon.glCtx->Const.MaxTextureUnits ; i++ ) { ++ if ( t == rmesa->state.texture.unit[i].texobj ) { ++ rmesa->state.texture.unit[i].texobj = NULL; ++ rmesa->hw.tex[i].dirty = GL_FALSE; ++ rmesa->hw.cube[i].dirty = GL_FALSE; ++ } ++ } + } +- +- if ( t != NULL ) { +- if ( rmesa ) { +- R200_FIREVERTICES( rmesa ); +- } +- +- driDestroyTextureObject( t ); ++ ++ if (t->mt) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = 0; + } +- /* Free mipmap images and the texture object itself */ + _mesa_delete_texture_object(ctx, texObj); + } + +@@ -1150,46 +459,59 @@ static void r200TexGen( GLcontext *ctx, + * Called via ctx->Driver.NewTextureObject. + * Note: this function will be called during context creation to + * allocate the default texture objects. +- * Note: we could use containment here to 'derive' the driver-specific +- * texture object from the core mesa gl_texture_object. Not done at this time. + * Fixup MaxAnisotropy according to user preference. + */ +-static struct gl_texture_object * +-r200NewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) ++static struct gl_texture_object *r200NewTextureObject(GLcontext * ctx, ++ GLuint name, ++ GLenum target) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- struct gl_texture_object *obj; +- obj = _mesa_new_texture_object(ctx, name, target); +- if (!obj) +- return NULL; +- obj->MaxAnisotropy = rmesa->initialMaxAnisotropy; +- r200AllocTexObj( obj ); +- return obj; ++ radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj); ++ ++ ++ if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { ++ fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, ++ t, _mesa_lookup_enum_by_nr(target)); ++ } ++ ++ _mesa_initialize_texture_object(&t->base, name, target); ++ t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy; ++ ++ /* Initialize hardware state */ ++ r200SetTexWrap( t, t->base.WrapS, t->base.WrapT, t->base.WrapR ); ++ r200SetTexMaxAnisotropy( t, t->base.MaxAnisotropy ); ++ r200SetTexFilter(t, t->base.MinFilter, t->base.MagFilter); ++ r200SetTexBorderColor(t, t->base._BorderChan); ++ ++ return &t->base; + } + + ++ + void r200InitTextureFuncs( struct dd_function_table *functions ) + { + /* Note: we only plug in the functions we implement in the driver + * since _mesa_init_driver_functions() was already called. + */ +- functions->ChooseTextureFormat = r200ChooseTextureFormat; +- functions->TexImage1D = r200TexImage1D; +- functions->TexImage2D = r200TexImage2D; ++ functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; ++ functions->TexImage1D = radeonTexImage1D; ++ functions->TexImage2D = radeonTexImage2D; + #if ENABLE_HW_3D_TEXTURE +- functions->TexImage3D = r200TexImage3D; ++ functions->TexImage3D = radeonTexImage3D; + #else + functions->TexImage3D = _mesa_store_teximage3d; + #endif +- functions->TexSubImage1D = r200TexSubImage1D; +- functions->TexSubImage2D = r200TexSubImage2D; ++ functions->TexSubImage1D = radeonTexSubImage1D; ++ functions->TexSubImage2D = radeonTexSubImage2D; + #if ENABLE_HW_3D_TEXTURE +- functions->TexSubImage3D = r200TexSubImage3D; ++ functions->TexSubImage3D = radeonTexSubImage3D; + #else + functions->TexSubImage3D = _mesa_store_texsubimage3d; + #endif ++ functions->GetTexImage = radeonGetTexImage; ++ functions->GetCompressedTexImage = radeonGetCompressedTexImage; + functions->NewTextureObject = r200NewTextureObject; +- functions->BindTexture = r200BindTexture; ++ // functions->BindTexture = r200BindTexture; + functions->DeleteTexture = r200DeleteTexture; + functions->IsTextureResident = driIsTextureResident; + +@@ -1197,22 +519,16 @@ void r200InitTextureFuncs( struct dd_function_table *functions ) + functions->TexParameter = r200TexParameter; + functions->TexGen = r200TexGen; + +- functions->CompressedTexImage2D = r200CompressedTexImage2D; +- functions->CompressedTexSubImage2D = r200CompressedTexSubImage2D; ++ functions->CompressedTexImage2D = radeonCompressedTexImage2D; ++ functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; ++ ++ functions->GenerateMipmap = radeonGenerateMipmap; ++ ++ functions->NewTextureImage = radeonNewTextureImage; ++ functions->FreeTexImageData = radeonFreeTexImageData; ++ functions->MapTexture = radeonMapTexture; ++ functions->UnmapTexture = radeonUnmapTexture; + + driInitTextureFormats(); + +-#if 000 +- /* moved or obsolete code */ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- driInitTextureObjects( ctx, & rmesa->swapped, +- DRI_TEXMGR_DO_TEXTURE_1D +- | DRI_TEXMGR_DO_TEXTURE_2D ); +- +- /* Hack: r200NewTextureObject is not yet installed when the +- * default textures are created. Therefore set MaxAnisotropy of the +- * default 2D texture now. */ +- ctx->Shared->Default2D->MaxAnisotropy = driQueryOptionf (&rmesa->optionCache, +- "def_max_anisotropy"); +-#endif + } +diff --git a/src/mesa/drivers/dri/r200/r200_tex.h b/src/mesa/drivers/dri/r200/r200_tex.h +index 10ff8e8..e122de6 100644 +--- a/src/mesa/drivers/dri/r200/r200_tex.h ++++ b/src/mesa/drivers/dri/r200/r200_tex.h +@@ -35,15 +35,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #ifndef __R200_TEX_H__ + #define __R200_TEX_H__ + ++extern void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv); ++extern void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, ++ __DRIdrawable *dPriv); + extern void r200SetTexOffset(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, + GLuint pitch); + + extern void r200UpdateTextureState( GLcontext *ctx ); + +-extern int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ); ++extern int r200UploadTexImages( r200ContextPtr rmesa, radeonTexObjPtr t, GLuint face ); + +-extern void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ); ++extern void r200DestroyTexObj( r200ContextPtr rmesa, radeonTexObjPtr t ); + + extern void r200InitTextureFuncs( struct dd_function_table *functions ); + +diff --git a/src/mesa/drivers/dri/r200/r200_texmem.c b/src/mesa/drivers/dri/r200/r200_texmem.c +deleted file mode 100644 +index 3b81ac0..0000000 +--- a/src/mesa/drivers/dri/r200/r200_texmem.c ++++ /dev/null +@@ -1,530 +0,0 @@ +-/************************************************************************** +- +-Copyright (C) Tungsten Graphics 2002. All Rights Reserved. +-The Weather Channel, Inc. funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 +-license. This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation on the rights to use, copy, modify, merge, publish, +-distribute, sub license, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +-NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR THEIR +-SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Kevin E. Martin +- * Gareth Hughes +- * +- */ +- +-#include +- +-#include "main/glheader.h" +-#include "main/imports.h" +-#include "main/context.h" +-#include "main/colormac.h" +-#include "main/macros.h" +-#include "r200_context.h" +-#include "r200_ioctl.h" +-#include "r200_tex.h" +-#include "radeon_reg.h" +- +-#include /* for usleep() */ +- +- +-/** +- * Destroy any device-dependent state associated with the texture. This may +- * include NULLing out hardware state that points to the texture. +- */ +-void +-r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) +-{ +- if ( R200_DEBUG & DEBUG_TEXTURE ) { +- fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, +- (void *)t, (void *)t->base.tObj ); +- } +- +- if ( rmesa != NULL ) { +- unsigned i; +- +- +- for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) { +- if ( t == rmesa->state.texture.unit[i].texobj ) { +- rmesa->state.texture.unit[i].texobj = NULL; +- rmesa->hw.tex[i].dirty = GL_FALSE; +- rmesa->hw.cube[i].dirty = GL_FALSE; +- } +- } +- } +-} +- +- +-/* ------------------------------------------------------------ +- * Texture image conversions +- */ +- +- +-static void r200UploadGARTClientSubImage( r200ContextPtr rmesa, +- r200TexObjPtr t, +- struct gl_texture_image *texImage, +- GLint hwlevel, +- GLint x, GLint y, +- GLint width, GLint height ) +-{ +- const struct gl_texture_format *texFormat = texImage->TexFormat; +- GLuint srcPitch, dstPitch; +- int blit_format; +- int srcOffset; +- +- /* +- * XXX it appears that we always upload the full image, not a subimage. +- * I.e. x==0, y==0, width=texWidth, height=texWidth. If this is ever +- * changed, the src pitch will have to change. +- */ +- switch ( texFormat->TexelBytes ) { +- case 1: +- blit_format = R200_CP_COLOR_FORMAT_CI8; +- srcPitch = t->image[0][0].width * texFormat->TexelBytes; +- dstPitch = t->image[0][0].width * texFormat->TexelBytes; +- break; +- case 2: +- blit_format = R200_CP_COLOR_FORMAT_RGB565; +- srcPitch = t->image[0][0].width * texFormat->TexelBytes; +- dstPitch = t->image[0][0].width * texFormat->TexelBytes; +- break; +- case 4: +- blit_format = R200_CP_COLOR_FORMAT_ARGB8888; +- srcPitch = t->image[0][0].width * texFormat->TexelBytes; +- dstPitch = t->image[0][0].width * texFormat->TexelBytes; +- break; +- default: +- return; +- } +- +- t->image[0][hwlevel].data = texImage->Data; +- srcOffset = r200GartOffsetFromVirtual( rmesa, texImage->Data ); +- +- assert( srcOffset != ~0 ); +- +- /* Don't currently need to cope with small pitches? +- */ +- width = texImage->Width; +- height = texImage->Height; +- +- r200EmitWait( rmesa, RADEON_WAIT_3D ); +- +- r200EmitBlit( rmesa, blit_format, +- srcPitch, +- srcOffset, +- dstPitch, +- t->bufAddr, +- x, +- y, +- t->image[0][hwlevel].x + x, +- t->image[0][hwlevel].y + y, +- width, +- height ); +- +- r200EmitWait( rmesa, RADEON_WAIT_2D ); +-} +- +-static void r200UploadRectSubImage( r200ContextPtr rmesa, +- r200TexObjPtr t, +- struct gl_texture_image *texImage, +- GLint x, GLint y, +- GLint width, GLint height ) +-{ +- const struct gl_texture_format *texFormat = texImage->TexFormat; +- int blit_format, dstPitch, done; +- +- switch ( texFormat->TexelBytes ) { +- case 1: +- blit_format = R200_CP_COLOR_FORMAT_CI8; +- break; +- case 2: +- blit_format = R200_CP_COLOR_FORMAT_RGB565; +- break; +- case 4: +- blit_format = R200_CP_COLOR_FORMAT_ARGB8888; +- break; +- default: +- return; +- } +- +- t->image[0][0].data = texImage->Data; +- +- /* Currently don't need to cope with small pitches. +- */ +- width = texImage->Width; +- height = texImage->Height; +- dstPitch = t->pp_txpitch + 32; +- +- if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) { +- /* In this case, could also use GART texturing. This is +- * currently disabled, but has been tested & works. +- */ +- if ( !t->image_override ) +- t->pp_txoffset = r200GartOffsetFromVirtual( rmesa, texImage->Data ); +- t->pp_txpitch = texImage->RowStride * texFormat->TexelBytes - 32; +- +- if (R200_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, +- "Using GART texturing for rectangular client texture\n"); +- +- /* Release FB memory allocated for this image: +- */ +- /* FIXME This may not be correct as driSwapOutTextureObject sets +- * FIXME dirty_images. It may be fine, though. +- */ +- if ( t->base.memBlock ) { +- driSwapOutTextureObject( (driTextureObject *) t ); +- } +- } +- else if (texImage->IsClientData) { +- /* Data already in GART memory, with usable pitch. +- */ +- GLuint srcPitch; +- srcPitch = texImage->RowStride * texFormat->TexelBytes; +- r200EmitBlit( rmesa, +- blit_format, +- srcPitch, +- r200GartOffsetFromVirtual( rmesa, texImage->Data ), +- dstPitch, t->bufAddr, +- 0, 0, +- 0, 0, +- width, height ); +- } +- else { +- /* Data not in GART memory, or bad pitch. +- */ +- for (done = 0; done < height ; ) { +- struct r200_dma_region region; +- int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch ); +- int src_pitch; +- char *tex; +- +- src_pitch = texImage->RowStride * texFormat->TexelBytes; +- +- tex = (char *)texImage->Data + done * src_pitch; +- +- memset(®ion, 0, sizeof(region)); +- r200AllocDmaRegion( rmesa, ®ion, lines * dstPitch, 1024 ); +- +- /* Copy texdata to dma: +- */ +- if (0) +- fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n", +- __FUNCTION__, src_pitch, dstPitch); +- +- if (src_pitch == dstPitch) { +- memcpy( region.address + region.start, tex, lines * src_pitch ); +- } +- else { +- char *buf = region.address + region.start; +- int i; +- for (i = 0 ; i < lines ; i++) { +- memcpy( buf, tex, src_pitch ); +- buf += dstPitch; +- tex += src_pitch; +- } +- } +- +- r200EmitWait( rmesa, RADEON_WAIT_3D ); +- +- /* Blit to framebuffer +- */ +- r200EmitBlit( rmesa, +- blit_format, +- dstPitch, GET_START( ®ion ), +- dstPitch | (t->tile_bits >> 16), +- t->bufAddr, +- 0, 0, +- 0, done, +- width, lines ); +- +- r200EmitWait( rmesa, RADEON_WAIT_2D ); +- +- r200ReleaseDmaRegion( rmesa, ®ion, __FUNCTION__ ); +- done += lines; +- } +- } +-} +- +- +-/** +- * Upload the texture image associated with texture \a t at the specified +- * level at the address relative to \a start. +- */ +-static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t, +- GLint hwlevel, +- GLint x, GLint y, GLint width, GLint height, +- GLuint face ) +-{ +- struct gl_texture_image *texImage = NULL; +- GLuint offset; +- GLint imageWidth, imageHeight; +- GLint ret; +- drm_radeon_texture_t tex; +- drm_radeon_tex_image_t tmp; +- const int level = hwlevel + t->base.firstLevel; +- +- if ( R200_DEBUG & DEBUG_TEXTURE ) { +- fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n", +- __FUNCTION__, (void *)t, (void *)t->base.tObj, +- level, width, height, face ); +- } +- +- ASSERT(face < 6); +- +- /* Ensure we have a valid texture to upload */ +- if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) { +- _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__); +- return; +- } +- +- texImage = t->base.tObj->Image[face][level]; +- +- if ( !texImage ) { +- if ( R200_DEBUG & DEBUG_TEXTURE ) +- fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level ); +- return; +- } +- if ( !texImage->Data ) { +- if ( R200_DEBUG & DEBUG_TEXTURE ) +- fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ ); +- return; +- } +- +- +- if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) { +- assert(level == 0); +- assert(hwlevel == 0); +- if ( R200_DEBUG & DEBUG_TEXTURE ) +- fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__); +- r200UploadRectSubImage( rmesa, t, texImage, x, y, width, height ); +- return; +- } +- else if (texImage->IsClientData) { +- if ( R200_DEBUG & DEBUG_TEXTURE ) +- fprintf( stderr, "%s: image data is in GART client storage\n", +- __FUNCTION__); +- r200UploadGARTClientSubImage( rmesa, t, texImage, hwlevel, +- x, y, width, height ); +- return; +- } +- else if ( R200_DEBUG & DEBUG_TEXTURE ) +- fprintf( stderr, "%s: image data is in normal memory\n", +- __FUNCTION__); +- +- +- imageWidth = texImage->Width; +- imageHeight = texImage->Height; +- +- offset = t->bufAddr + t->base.totalSize / 6 * face; +- +- if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { +- GLint imageX = 0; +- GLint imageY = 0; +- GLint blitX = t->image[face][hwlevel].x; +- GLint blitY = t->image[face][hwlevel].y; +- GLint blitWidth = t->image[face][hwlevel].width; +- GLint blitHeight = t->image[face][hwlevel].height; +- fprintf( stderr, " upload image: %d,%d at %d,%d\n", +- imageWidth, imageHeight, imageX, imageY ); +- fprintf( stderr, " upload blit: %d,%d at %d,%d\n", +- blitWidth, blitHeight, blitX, blitY ); +- fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n", +- (GLuint)offset, hwlevel, level ); +- } +- +- t->image[face][hwlevel].data = texImage->Data; +- +- /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct. +- * NOTE: we're always use a 1KB-wide blit and I8 texture format. +- * We used to use 1, 2 and 4-byte texels and used to use the texture +- * width to dictate the blit width - but that won't work for compressed +- * textures. (Brian) +- * NOTE: can't do that with texture tiling. (sroland) +- */ +- tex.offset = offset; +- tex.image = &tmp; +- /* copy (x,y,width,height,data) */ +- memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) ); +- +- if (texImage->TexFormat->TexelBytes) { +- /* use multi-byte upload scheme */ +- tex.height = imageHeight; +- tex.width = imageWidth; +- tex.format = t->pp_txformat & R200_TXFORMAT_FORMAT_MASK; +- if (tex.format == R200_TXFORMAT_ABGR8888) { +- /* drm will refuse abgr8888 textures. */ +- tex.format = R200_TXFORMAT_ARGB8888; +- } +- tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1); +- tex.offset += tmp.x & ~1023; +- tmp.x = tmp.x % 1024; +- if (t->tile_bits & R200_TXO_MICRO_TILE) { +- /* need something like "tiled coordinates" ? */ +- tmp.y = tmp.x / (tex.pitch * 128) * 2; +- tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes; +- tex.pitch |= RADEON_DST_TILE_MICRO >> 22; +- } +- else { +- tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1); +- } +- if ((t->tile_bits & R200_TXO_MACRO_TILE) && +- (texImage->Width * texImage->TexFormat->TexelBytes >= 256) && +- ((!(t->tile_bits & R200_TXO_MICRO_TILE) && (texImage->Height >= 8)) || +- (texImage->Height >= 16))) { +- /* weird: R200 disables macro tiling if mip width is smaller than 256 bytes, +- OR if height is smaller than 8 automatically, but if micro tiling is active +- the limit is height 16 instead ? */ +- tex.pitch |= RADEON_DST_TILE_MACRO >> 22; +- } +- } +- else { +- /* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is +- needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */ +- /* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed +- so the kernel module reads the right amount of data. */ +- tex.format = R200_TXFORMAT_I8; /* any 1-byte texel format */ +- tex.pitch = (BLIT_WIDTH_BYTES / 64); +- tex.height = (imageHeight + 3) / 4; +- tex.width = (imageWidth + 3) / 4; +- switch (t->pp_txformat & R200_TXFORMAT_FORMAT_MASK) { +- case R200_TXFORMAT_DXT1: +- tex.width *= 8; +- break; +- case R200_TXFORMAT_DXT23: +- case R200_TXFORMAT_DXT45: +- tex.width *= 16; +- break; +- default: +- fprintf(stderr, "unknown compressed tex format in uploadSubImage\n"); +- } +- } +- +- LOCK_HARDWARE( rmesa ); +- do { +- ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE, +- &tex, sizeof(drm_radeon_texture_t) ); +- if (ret) { +- if (R200_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n"); +- usleep(1); +- } +- } while ( ret == -EAGAIN ); +- +- UNLOCK_HARDWARE( rmesa ); +- +- if ( ret ) { +- fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret ); +- fprintf( stderr, " offset=0x%08x\n", +- offset ); +- fprintf( stderr, " image width=%d height=%d\n", +- imageWidth, imageHeight ); +- fprintf( stderr, " blit width=%d height=%d data=%p\n", +- t->image[face][hwlevel].width, t->image[face][hwlevel].height, +- t->image[face][hwlevel].data ); +- exit( 1 ); +- } +-} +- +- +-/** +- * Upload the texture images associated with texture \a t. This might +- * require the allocation of texture memory. +- * +- * \param rmesa Context pointer +- * \param t Texture to be uploaded +- * \param face Cube map face to be uploaded. Zero for non-cube maps. +- */ +- +-int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ) +-{ +- const int numLevels = t->base.lastLevel - t->base.firstLevel + 1; +- +- if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { +- fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, +- (void *)rmesa->glCtx, (void *)t->base.tObj, t->base.totalSize, +- t->base.firstLevel, t->base.lastLevel ); +- } +- +- if ( !t || t->base.totalSize == 0 || t->image_override ) +- return 0; +- +- if (R200_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "%s: Syncing\n", __FUNCTION__ ); +- r200Finish( rmesa->glCtx ); +- } +- +- LOCK_HARDWARE( rmesa ); +- +- if ( t->base.memBlock == NULL ) { +- int heap; +- +- heap = driAllocateTexture( rmesa->texture_heaps, rmesa->nr_heaps, +- (driTextureObject *) t ); +- if ( heap == -1 ) { +- UNLOCK_HARDWARE( rmesa ); +- return -1; +- } +- +- /* Set the base offset of the texture image */ +- t->bufAddr = rmesa->r200Screen->texOffset[heap] +- + t->base.memBlock->ofs; +- t->pp_txoffset = t->bufAddr; +- +- if (!(t->base.tObj->Image[0][0]->IsClientData)) { +- /* hope it's safe to add that here... */ +- t->pp_txoffset |= t->tile_bits; +- } +- +- /* Mark this texobj as dirty on all units: +- */ +- t->dirty_state = TEX_ALL; +- } +- +- /* Let the world know we've used this memory recently. +- */ +- driUpdateTextureLRU( (driTextureObject *) t ); +- UNLOCK_HARDWARE( rmesa ); +- +- /* Upload any images that are new */ +- if (t->base.dirty_images[face]) { +- int i; +- for ( i = 0 ; i < numLevels ; i++ ) { +- if ( (t->base.dirty_images[face] & (1 << (i+t->base.firstLevel))) != 0 ) { +- uploadSubImage( rmesa, t, i, 0, 0, t->image[face][i].width, +- t->image[face][i].height, face ); +- } +- } +- t->base.dirty_images[face] = 0; +- } +- +- +- if (R200_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "%s: Syncing\n", __FUNCTION__ ); +- r200Finish( rmesa->glCtx ); +- } +- +- return 0; +-} +diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c +index 0ad5651..9797f77 100644 +--- a/src/mesa/drivers/dri/r200/r200_texstate.c ++++ b/src/mesa/drivers/dri/r200/r200_texstate.c +@@ -37,9 +37,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/context.h" + #include "main/macros.h" + #include "main/texformat.h" ++#include "main/teximage.h" + #include "main/texobj.h" + #include "main/enums.h" + ++#include "radeon_common.h" ++#include "radeon_mipmap_tree.h" + #include "r200_context.h" + #include "r200_state.h" + #include "r200_ioctl.h" +@@ -139,257 +142,6 @@ static const struct tx_table tx_table_le[] = + #undef _ALPHA + #undef _INVALID + +-/** +- * This function computes the number of bytes of storage needed for +- * the given texture object (all mipmap levels, all cube faces). +- * The \c image[face][level].x/y/width/height parameters for upload/blitting +- * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here +- * too. +- * +- * \param rmesa Context pointer +- * \param tObj GL texture object whose images are to be posted to +- * hardware state. +- */ +-static void r200SetTexImages( r200ContextPtr rmesa, +- struct gl_texture_object *tObj ) +-{ +- r200TexObjPtr t = (r200TexObjPtr)tObj->DriverData; +- const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; +- GLint curOffset, blitWidth; +- GLint i, texelBytes; +- GLint numLevels; +- GLint log2Width, log2Height, log2Depth; +- +- /* Set the hardware texture format +- */ +- if ( !t->image_override ) { +- if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { +- const struct tx_table *table = _mesa_little_endian() ? tx_table_le : +- tx_table_be; +- +- t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK | +- R200_TXFORMAT_ALPHA_IN_MAP); +- t->pp_txfilter &= ~R200_YUV_TO_RGB; +- +- t->pp_txformat |= table[ baseImage->TexFormat->MesaFormat ].format; +- t->pp_txfilter |= table[ baseImage->TexFormat->MesaFormat ].filter; +- } +- else { +- _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); +- return; +- } +- } +- +- texelBytes = baseImage->TexFormat->TexelBytes; +- +- /* Compute which mipmap levels we really want to send to the hardware. +- */ +- +- driCalculateTextureFirstLastLevel( (driTextureObject *) t ); +- log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2; +- log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2; +- log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2; +- +- numLevels = t->base.lastLevel - t->base.firstLevel + 1; +- +- assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS); +- +- /* Calculate mipmap offsets and dimensions for blitting (uploading) +- * The idea is that we lay out the mipmap levels within a block of +- * memory organized as a rectangle of width BLIT_WIDTH_BYTES. +- */ +- curOffset = 0; +- blitWidth = BLIT_WIDTH_BYTES; +- t->tile_bits = 0; +- +- /* figure out if this texture is suitable for tiling. */ +- if (texelBytes) { +- if (rmesa->texmicrotile && (tObj->Target != GL_TEXTURE_RECTANGLE_NV) && +- /* texrect might be able to use micro tiling too in theory? */ +- (baseImage->Height > 1)) { +- /* allow 32 (bytes) x 1 mip (which will use two times the space +- the non-tiled version would use) max if base texture is large enough */ +- if ((numLevels == 1) || +- (((baseImage->Width * texelBytes / baseImage->Height) <= 32) && +- (baseImage->Width * texelBytes > 64)) || +- ((baseImage->Width * texelBytes / baseImage->Height) <= 16)) { +- t->tile_bits |= R200_TXO_MICRO_TILE; +- } +- } +- if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) { +- /* we can set macro tiling even for small textures, they will be untiled anyway */ +- t->tile_bits |= R200_TXO_MACRO_TILE; +- } +- } +- +- for (i = 0; i < numLevels; i++) { +- const struct gl_texture_image *texImage; +- GLuint size; +- +- texImage = tObj->Image[0][i + t->base.firstLevel]; +- if ( !texImage ) +- break; +- +- /* find image size in bytes */ +- if (texImage->IsCompressed) { +- /* need to calculate the size AFTER padding even though the texture is +- submitted without padding. +- Only handle pot textures currently - don't know if npot is even possible, +- size calculation would certainly need (trivial) adjustments. +- Align (and later pad) to 32byte, not sure what that 64byte blit width is +- good for? */ +- if ((t->pp_txformat & R200_TXFORMAT_FORMAT_MASK) == R200_TXFORMAT_DXT1) { +- /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */ +- if ((texImage->Width + 3) < 8) /* width one block */ +- size = texImage->CompressedSize * 4; +- else if ((texImage->Width + 3) < 16) +- size = texImage->CompressedSize * 2; +- else size = texImage->CompressedSize; +- } +- else /* DXT3/5, 16 bytes per block */ +- if ((texImage->Width + 3) < 8) +- size = texImage->CompressedSize * 2; +- else size = texImage->CompressedSize; +- } +- else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { +- size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height; +- } +- else if (t->tile_bits & R200_TXO_MICRO_TILE) { +- /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, +- though the actual offset may be different (if texture is less than +- 32 bytes width) to the untiled case */ +- int w = (texImage->Width * texelBytes * 2 + 31) & ~31; +- size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth; +- blitWidth = MAX2(texImage->Width, 64 / texelBytes); +- } +- else { +- int w = (texImage->Width * texelBytes + 31) & ~31; +- size = w * texImage->Height * texImage->Depth; +- blitWidth = MAX2(texImage->Width, 64 / texelBytes); +- } +- assert(size > 0); +- +- /* Align to 32-byte offset. It is faster to do this unconditionally +- * (no branch penalty). +- */ +- +- curOffset = (curOffset + 0x1f) & ~0x1f; +- +- if (texelBytes) { +- t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */ +- t->image[0][i].y = 0; +- t->image[0][i].width = MIN2(size / texelBytes, blitWidth); +- t->image[0][i].height = (size / texelBytes) / t->image[0][i].width; +- } +- else { +- t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES; +- t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES; +- t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES); +- t->image[0][i].height = size / t->image[0][i].width; +- } +- +-#if 0 +- /* for debugging only and only applicable to non-rectangle targets */ +- assert(size % t->image[0][i].width == 0); +- assert(t->image[0][i].x == 0 +- || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1)); +-#endif +- +- if (0) +- fprintf(stderr, +- "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n", +- i, texImage->Width, texImage->Height, +- t->image[0][i].x, t->image[0][i].y, +- t->image[0][i].width, t->image[0][i].height, size, curOffset); +- +- curOffset += size; +- +- } +- +- /* Align the total size of texture memory block. +- */ +- t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; +- +- /* Setup remaining cube face blits, if needed */ +- if (tObj->Target == GL_TEXTURE_CUBE_MAP) { +- const GLuint faceSize = t->base.totalSize; +- GLuint face; +- /* reuse face 0 x/y/width/height - just update the offset when uploading */ +- for (face = 1; face < 6; face++) { +- for (i = 0; i < numLevels; i++) { +- t->image[face][i].x = t->image[0][i].x; +- t->image[face][i].y = t->image[0][i].y; +- t->image[face][i].width = t->image[0][i].width; +- t->image[face][i].height = t->image[0][i].height; +- } +- } +- t->base.totalSize = 6 * faceSize; /* total texmem needed */ +- } +- +- +- /* Hardware state: +- */ +- t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK; +- t->pp_txfilter |= (numLevels - 1) << R200_MAX_MIP_LEVEL_SHIFT; +- +- t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK | +- R200_TXFORMAT_HEIGHT_MASK | +- R200_TXFORMAT_CUBIC_MAP_ENABLE | +- R200_TXFORMAT_F5_WIDTH_MASK | +- R200_TXFORMAT_F5_HEIGHT_MASK); +- t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) | +- (log2Height << R200_TXFORMAT_HEIGHT_SHIFT)); +- +- t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK); +- if (tObj->Target == GL_TEXTURE_3D) { +- t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT); +- t->pp_txformat_x |= R200_TEXCOORD_VOLUME; +- } +- else if (tObj->Target == GL_TEXTURE_CUBE_MAP) { +- ASSERT(log2Width == log2Height); +- t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) | +- (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) | +-/* don't think we need this bit, if it exists at all - fglrx does not set it */ +- (R200_TXFORMAT_CUBIC_MAP_ENABLE)); +- t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV; +- t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) | +- (log2Height << R200_FACE_HEIGHT_1_SHIFT) | +- (log2Width << R200_FACE_WIDTH_2_SHIFT) | +- (log2Height << R200_FACE_HEIGHT_2_SHIFT) | +- (log2Width << R200_FACE_WIDTH_3_SHIFT) | +- (log2Height << R200_FACE_HEIGHT_3_SHIFT) | +- (log2Width << R200_FACE_WIDTH_4_SHIFT) | +- (log2Height << R200_FACE_HEIGHT_4_SHIFT)); +- } +- else { +- /* If we don't in fact send enough texture coordinates, q will be 1, +- * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?) +- */ +- t->pp_txformat_x |= R200_TEXCOORD_PROJ; +- } +- +- t->pp_txsize = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << 0) | +- ((tObj->Image[0][t->base.firstLevel]->Height - 1) << 16)); +- +- /* Only need to round to nearest 32 for textures, but the blitter +- * requires 64-byte aligned pitches, and we may/may not need the +- * blitter. NPOT only! +- */ +- if ( !t->image_override ) { +- if (baseImage->IsCompressed) +- t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63); +- else +- t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63); +- t->pp_txpitch -= 32; +- } +- +- t->dirty_state = TEX_ALL; +- +- /* FYI: r200UploadTexImages( rmesa, t ) used to be called here */ +-} +- +- +- + /* ================================================================ + * Texture combine functions + */ +@@ -981,20 +733,19 @@ void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname, + { + r200ContextPtr rmesa = pDRICtx->driverPrivate; + struct gl_texture_object *tObj = +- _mesa_lookup_texture(rmesa->glCtx, texname); +- r200TexObjPtr t; ++ _mesa_lookup_texture(rmesa->radeon.glCtx, texname); ++ radeonTexObjPtr t = radeon_tex_obj(tObj); + + if (!tObj) + return; + +- t = (r200TexObjPtr) tObj->DriverData; +- + t->image_override = GL_TRUE; + + if (!offset) + return; + +- t->pp_txoffset = offset; ++ t->bo = NULL; ++ t->override_offset = offset; + t->pp_txpitch = pitch - 32; + + switch (depth) { +@@ -1014,6 +765,123 @@ void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname, + } + } + ++void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, ++ __DRIdrawable *dPriv) ++{ ++ struct gl_texture_unit *texUnit; ++ struct gl_texture_object *texObj; ++ struct gl_texture_image *texImage; ++ struct radeon_renderbuffer *rb; ++ radeon_texture_image *rImage; ++ radeonContextPtr radeon; ++ r200ContextPtr rmesa; ++ struct radeon_framebuffer *rfb; ++ radeonTexObjPtr t; ++ uint32_t pitch_val; ++ uint32_t internalFormat, type, format; ++ ++ type = GL_BGRA; ++ format = GL_UNSIGNED_BYTE; ++ internalFormat = (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT ? 3 : 4); ++ ++ radeon = pDRICtx->driverPrivate; ++ rmesa = pDRICtx->driverPrivate; ++ ++ rfb = dPriv->driverPrivate; ++ texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit]; ++ texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target); ++ texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0); ++ ++ rImage = get_radeon_texture_image(texImage); ++ t = radeon_tex_obj(texObj); ++ if (t == NULL) { ++ return; ++ } ++ ++ radeon_update_renderbuffers(pDRICtx, dPriv); ++ /* back & depth buffer are useless free them right away */ ++ rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = rfb->color_rb[0]; ++ if (rb->bo == NULL) { ++ /* Failed to BO for the buffer */ ++ return; ++ } ++ ++ _mesa_lock_texture(radeon->glCtx, texObj); ++ if (t->bo) { ++ radeon_bo_unref(t->bo); ++ t->bo = NULL; ++ } ++ if (rImage->bo) { ++ radeon_bo_unref(rImage->bo); ++ rImage->bo = NULL; ++ } ++ if (t->mt) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = NULL; ++ } ++ if (rImage->mt) { ++ radeon_miptree_unreference(rImage->mt); ++ rImage->mt = NULL; ++ } ++ fprintf(stderr,"settexbuf %d %dx%d@%d\n", rb->pitch, rb->width, rb->height, rb->cpp); ++ _mesa_init_teximage_fields(radeon->glCtx, target, texImage, ++ rb->width, rb->height, 1, 0, rb->cpp); ++ texImage->RowStride = rb->pitch / rb->cpp; ++ texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx, ++ internalFormat, ++ type, format, 0); ++ rImage->bo = rb->bo; ++ radeon_bo_ref(rImage->bo); ++ t->bo = rb->bo; ++ radeon_bo_ref(t->bo); ++ t->tile_bits = 0; ++ t->image_override = GL_TRUE; ++ t->override_offset = 0; ++ t->pp_txpitch &= (1 << 13) -1; ++ pitch_val = rb->pitch; ++ switch (rb->cpp) { ++ case 4: ++ t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format; ++ t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter; ++ break; ++ case 3: ++ default: ++ t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format; ++ t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter; ++ break; ++ case 2: ++ t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format; ++ t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter; ++ break; ++ } ++ t->pp_txsize = ((rb->width - 1) << RADEON_TEX_USIZE_SHIFT) ++ | ((rb->height - 1) << RADEON_TEX_VSIZE_SHIFT); ++ t->pp_txformat |= R200_TXFORMAT_NON_POWER2; ++ t->pp_txpitch = pitch_val; ++ t->pp_txpitch -= 32; ++ ++ t->validated = GL_TRUE; ++ _mesa_unlock_texture(radeon->glCtx, texObj); ++ return; ++} ++ ++ ++void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) ++{ ++ r200SetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); ++} ++ ++ + #define REF_COLOR 1 + #define REF_ALPHA 2 + +@@ -1207,12 +1075,41 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx ) + R200_VOLUME_FILTER_MASK) + + ++static void disable_tex_obj_state( r200ContextPtr rmesa, ++ int unit ) ++{ ++ ++ R200_STATECHANGE( rmesa, vtx ); ++ rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); ++ ++ if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<2 texunits. ++ */ ++ ++ { ++ GLuint tmp = rmesa->TexGenEnabled; ++ ++ rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<TexGenNeedNormals[unit] = GL_FALSE; ++ rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); ++ ++ if (tmp != rmesa->TexGenEnabled) { ++ rmesa->recheck_texgen[unit] = GL_TRUE; ++ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; ++ } ++ } ++} + static void import_tex_obj_state( r200ContextPtr rmesa, + int unit, +- r200TexObjPtr texobj ) ++ radeonTexObjPtr texobj ) + { + /* do not use RADEON_DB_STATE to avoid stale texture caches */ +- int *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0]; ++ GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0]; + + R200_STATECHANGE( rmesa, tex[unit] ); + +@@ -1225,36 +1122,21 @@ static void import_tex_obj_state( r200ContextPtr rmesa, + cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */ + cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */ + cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; +- if (rmesa->r200Screen->drmSupportsFragShader) { +- cmd[TEX_PP_TXOFFSET_NEWDRM] = texobj->pp_txoffset; +- } +- else { +- cmd[TEX_PP_TXOFFSET_OLDDRM] = texobj->pp_txoffset; +- } + +- if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) { +- int *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0]; +- GLuint bytesPerFace = texobj->base.totalSize / 6; +- ASSERT(texobj->base.totalSize % 6 == 0); ++ if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) { ++ GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0]; + + R200_STATECHANGE( rmesa, cube[unit] ); + cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces; +- if (rmesa->r200Screen->drmSupportsFragShader) { ++ if (rmesa->radeon.radeonScreen->drmSupportsFragShader) { + /* that value is submitted twice. could change cube atom + to not include that command when new drm is used */ + cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces; + } +- cube_cmd[CUBE_PP_CUBIC_OFFSET_F1] = texobj->pp_txoffset + 1 * bytesPerFace; +- cube_cmd[CUBE_PP_CUBIC_OFFSET_F2] = texobj->pp_txoffset + 2 * bytesPerFace; +- cube_cmd[CUBE_PP_CUBIC_OFFSET_F3] = texobj->pp_txoffset + 3 * bytesPerFace; +- cube_cmd[CUBE_PP_CUBIC_OFFSET_F4] = texobj->pp_txoffset + 4 * bytesPerFace; +- cube_cmd[CUBE_PP_CUBIC_OFFSET_F5] = texobj->pp_txoffset + 5 * bytesPerFace; + } + +- texobj->dirty_state &= ~(1<TexGenEnabled & R_BIT) { + if (texUnit->GenR.Mode != mode) + mixed_fallback = GL_TRUE; +@@ -1517,52 +1398,6 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit ) + return GL_TRUE; + } + +- +-static void disable_tex( GLcontext *ctx, int unit ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- +- if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<state.texture.unit[unit].texobj != NULL ) { +- /* The old texture is no longer bound to this texture unit. +- * Mark it as such. +- */ +- +- rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit); +- rmesa->state.texture.unit[unit].texobj = NULL; +- } +- +- R200_STATECHANGE( rmesa, ctx ); +- rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit); +- +- R200_STATECHANGE( rmesa, vtx ); +- rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); +- +- if (rmesa->TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<2 texunits. +- */ +- +- { +- GLuint tmp = rmesa->TexGenEnabled; +- +- rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<TexGenNeedNormals[unit] = GL_FALSE; +- rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); +- +- if (tmp != rmesa->TexGenEnabled) { +- rmesa->recheck_texgen[unit] = GL_TRUE; +- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; +- } +- } +- } +-} +- + void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +@@ -1579,237 +1414,169 @@ void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d ) + } + } + +-static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) ++/** ++ * Compute the cached hardware register values for the given texture object. ++ * ++ * \param rmesa Context pointer ++ * \param t the r300 texture object ++ */ ++static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) + { +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; +- +- /* Need to load the 2d images associated with this unit. +- */ +- if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { +- t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; +- t->base.dirty_images[0] = ~0; ++ const struct gl_texture_image *firstImage = ++ t->base.Image[0][t->mt->firstLevel]; ++ GLint log2Width, log2Height, log2Depth, texelBytes; ++ ++ if ( t->bo ) { ++ return; + } + +- ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D); ++ log2Width = firstImage->WidthLog2; ++ log2Height = firstImage->HeightLog2; ++ log2Depth = firstImage->DepthLog2; ++ texelBytes = firstImage->TexFormat->TexelBytes; + +- if ( t->base.dirty_images[0] ) { +- R200_FIREVERTICES( rmesa ); +- r200SetTexImages( rmesa, tObj ); +- r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); +- if ( !t->base.memBlock && !t->image_override ) +- return GL_FALSE; +- } + +- set_re_cntl_d3d( ctx, unit, GL_FALSE ); +- +- return GL_TRUE; +-} +- +-#if ENABLE_HW_3D_TEXTURE +-static GLboolean enable_tex_3d( GLcontext *ctx, int unit ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; +- +- /* Need to load the 3d images associated with this unit. +- */ +- if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { +- t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; +- t->base.dirty_images[0] = ~0; ++ if (!t->image_override) { ++ if (VALID_FORMAT(firstImage->TexFormat->MesaFormat)) { ++ const struct tx_table *table = _mesa_little_endian() ? tx_table_le : ++ tx_table_be; ++ ++ t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK | ++ R200_TXFORMAT_ALPHA_IN_MAP); ++ t->pp_txfilter &= ~R200_YUV_TO_RGB; ++ ++ t->pp_txformat |= table[ firstImage->TexFormat->MesaFormat ].format; ++ t->pp_txfilter |= table[ firstImage->TexFormat->MesaFormat ].filter; ++ } else { ++ _mesa_problem(NULL, "unexpected texture format in %s", ++ __FUNCTION__); ++ return; ++ } + } ++ ++ t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK; ++ t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << R200_MAX_MIP_LEVEL_SHIFT; ++ ++ t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK | ++ R200_TXFORMAT_HEIGHT_MASK | ++ R200_TXFORMAT_CUBIC_MAP_ENABLE | ++ R200_TXFORMAT_F5_WIDTH_MASK | ++ R200_TXFORMAT_F5_HEIGHT_MASK); ++ t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) | ++ (log2Height << R200_TXFORMAT_HEIGHT_SHIFT)); ++ ++ t->tile_bits = 0; ++ ++ t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK); ++ if (t->base.Target == GL_TEXTURE_3D) { ++ t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT); ++ t->pp_txformat_x |= R200_TEXCOORD_VOLUME; + +- ASSERT(tObj->Target == GL_TEXTURE_3D); +- +- /* R100 & R200 do not support mipmaps for 3D textures. +- */ +- if ( (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR) ) { +- return GL_FALSE; + } +- +- if ( t->base.dirty_images[0] ) { +- R200_FIREVERTICES( rmesa ); +- r200SetTexImages( rmesa, tObj ); +- r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); +- if ( !t->base.memBlock ) +- return GL_FALSE; ++ else if (t->base.Target == GL_TEXTURE_CUBE_MAP) { ++ ASSERT(log2Width == log2Height); ++ t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) | ++ (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) | ++ /* don't think we need this bit, if it exists at all - fglrx does not set it */ ++ (R200_TXFORMAT_CUBIC_MAP_ENABLE)); ++ t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV; ++ t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) | ++ (log2Height << R200_FACE_HEIGHT_1_SHIFT) | ++ (log2Width << R200_FACE_WIDTH_2_SHIFT) | ++ (log2Height << R200_FACE_HEIGHT_2_SHIFT) | ++ (log2Width << R200_FACE_WIDTH_3_SHIFT) | ++ (log2Height << R200_FACE_HEIGHT_3_SHIFT) | ++ (log2Width << R200_FACE_WIDTH_4_SHIFT) | ++ (log2Height << R200_FACE_HEIGHT_4_SHIFT)); + } +- +- set_re_cntl_d3d( ctx, unit, GL_TRUE ); +- +- return GL_TRUE; +-} +-#endif +- +-static GLboolean enable_tex_cube( GLcontext *ctx, int unit ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; +- GLuint face; +- +- /* Need to load the 2d images associated with this unit. +- */ +- if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { +- t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; +- for (face = 0; face < 6; face++) +- t->base.dirty_images[face] = ~0; ++ else { ++ /* If we don't in fact send enough texture coordinates, q will be 1, ++ * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?) ++ */ ++ t->pp_txformat_x |= R200_TEXCOORD_PROJ; + } + +- ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP); ++ t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT) ++ | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT)); + +- if ( t->base.dirty_images[0] || t->base.dirty_images[1] || +- t->base.dirty_images[2] || t->base.dirty_images[3] || +- t->base.dirty_images[4] || t->base.dirty_images[5] ) { +- /* flush */ +- R200_FIREVERTICES( rmesa ); +- /* layout memory space, once for all faces */ +- r200SetTexImages( rmesa, tObj ); +- } +- +- /* upload (per face) */ +- for (face = 0; face < 6; face++) { +- if (t->base.dirty_images[face]) { +- r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, face ); +- } +- } +- +- if ( !t->base.memBlock ) { +- /* texmem alloc failed, use s/w fallback */ +- return GL_FALSE; ++ if ( !t->image_override ) { ++ if (firstImage->IsCompressed) ++ t->pp_txpitch = (firstImage->Width + 63) & ~(63); ++ else ++ t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63); ++ t->pp_txpitch -= 32; + } + +- set_re_cntl_d3d( ctx, unit, GL_TRUE ); +- +- return GL_TRUE; +-} +- +-static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) +-{ +- r200ContextPtr rmesa = R200_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; +- +- if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) { ++ if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) { + t->pp_txformat |= R200_TXFORMAT_NON_POWER2; +- t->base.dirty_images[0] = ~0; +- } +- +- ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV); +- +- if ( t->base.dirty_images[0] ) { +- R200_FIREVERTICES( rmesa ); +- r200SetTexImages( rmesa, tObj ); +- r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); +- if ( !t->base.memBlock && +- !t->image_override && +- !rmesa->prefer_gart_client_texturing ) +- return GL_FALSE; + } + +- set_re_cntl_d3d( ctx, unit, GL_FALSE ); +- +- return GL_TRUE; + } + +- +-static GLboolean update_tex_common( GLcontext *ctx, int unit ) ++static GLboolean r200_validate_texture(GLcontext *ctx, struct gl_texture_object *texObj, int unit) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; +- +- /* Fallback if there's a texture border */ +- if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) +- return GL_FALSE; +- +- /* Update state if this is a different texture object to last +- * time. +- */ +- if ( rmesa->state.texture.unit[unit].texobj != t ) { +- if ( rmesa->state.texture.unit[unit].texobj != NULL ) { +- /* The old texture is no longer bound to this texture unit. +- * Mark it as such. +- */ ++ radeonTexObj *t = radeon_tex_obj(texObj); + +- rmesa->state.texture.unit[unit].texobj->base.bound &= +- ~(1UL << unit); +- } +- +- rmesa->state.texture.unit[unit].texobj = t; +- t->base.bound |= (1UL << unit); +- t->dirty_state |= 1<hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit; +- +- R200_STATECHANGE( rmesa, vtx ); +- rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); +- rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3); ++ if (!radeon_validate_texture_miptree(ctx, texObj)) ++ return GL_FALSE; + +- rmesa->recheck_texgen[unit] = GL_TRUE; +- } ++ r200_validate_texgen(ctx, unit); ++ /* Configure the hardware registers (more precisely, the cached version ++ * of the hardware registers). */ ++ setup_hardware_state(rmesa, t); ++ ++ if (texObj->Target == GL_TEXTURE_RECTANGLE_NV || ++ texObj->Target == GL_TEXTURE_2D || ++ texObj->Target == GL_TEXTURE_1D) ++ set_re_cntl_d3d( ctx, unit, GL_FALSE ); ++ else ++ set_re_cntl_d3d( ctx, unit, GL_TRUE ); ++ R200_STATECHANGE( rmesa, ctx ); ++ rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit; ++ ++ R200_STATECHANGE( rmesa, vtx ); ++ rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); ++ rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3); + +- if (t->dirty_state & (1<recheck_texgen[unit] = GL_TRUE; ++ import_tex_obj_state( rmesa, unit, t ); + + if (rmesa->recheck_texgen[unit]) { + GLboolean fallback = !r200_validate_texgen( ctx, unit ); + TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<recheck_texgen[unit] = 0; +- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; ++ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; + } + +- FALLBACK( rmesa, R200_FALLBACK_BORDER_MODE, t->border_fallback ); +- return !t->border_fallback; +-} ++ t->validated = GL_TRUE; + ++ FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback ); + ++ return !t->border_fallback; ++} + +-static GLboolean r200UpdateTextureUnit( GLcontext *ctx, int unit ) ++static GLboolean r200UpdateTextureUnit(GLcontext *ctx, int unit) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded; + +- if ( unitneeded & (TEXTURE_RECT_BIT) ) { +- return (enable_tex_rect( ctx, unit ) && +- update_tex_common( ctx, unit )); +- } +- else if ( unitneeded & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) { +- return (enable_tex_2d( ctx, unit ) && +- update_tex_common( ctx, unit )); +- } +-#if ENABLE_HW_3D_TEXTURE +- else if ( unitneeded & (TEXTURE_3D_BIT) ) { +- return (enable_tex_3d( ctx, unit ) && +- update_tex_common( ctx, unit )); +- } +-#endif +- else if ( unitneeded & (TEXTURE_CUBE_BIT) ) { +- return (enable_tex_cube( ctx, unit ) && +- update_tex_common( ctx, unit )); +- } +- else if ( unitneeded ) { +- return GL_FALSE; +- } +- else { +- disable_tex( ctx, unit ); +- return GL_TRUE; ++ if (!unitneeded) { ++ /* disable the unit */ ++ disable_tex_obj_state(rmesa, unit); ++ return GL_TRUE; + } ++ ++ if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) { ++ _mesa_warning(ctx, ++ "failed to validate texture for unit %d.\n", ++ unit); ++ rmesa->state.texture.unit[unit].texobj = NULL; ++ return GL_FALSE; ++ } ++ ++ rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current); ++ return GL_TRUE; + } + + +@@ -1850,11 +1617,11 @@ void r200UpdateTextureState( GLcontext *ctx ) + + FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok ); + +- if (rmesa->TclFallback) ++ if (rmesa->radeon.TclFallback) + r200ChooseVertexState( ctx ); + + +- if (rmesa->r200Screen->chip_family == CHIP_FAMILY_R200) { ++ if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) { + + /* + * T0 hang workaround ------------- +@@ -1867,7 +1634,7 @@ void r200UpdateTextureState( GLcontext *ctx ) + R200_STATECHANGE(rmesa, tex[1]); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE; + if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE)) +- rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; ++ rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; + rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE; + } + else if (!ctx->ATIFragmentShader._Enabled) { +diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c +index a2561df..aadd144 100644 +--- a/src/mesa/drivers/dri/r200/r200_vertprog.c ++++ b/src/mesa/drivers/dri/r200/r200_vertprog.c +@@ -1110,9 +1110,9 @@ void r200SetupVertexProg( GLcontext *ctx ) { + } + /* could optimize setting up vertex progs away for non-tcl hw */ + fallback = !(vp->native && r200VertexProgUpdateParams(ctx, vp) && +- rmesa->r200Screen->drmSupportsVertexProgram); ++ rmesa->radeon.radeonScreen->drmSupportsVertexProgram); + TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, fallback); +- if (rmesa->TclFallback) return; ++ if (rmesa->radeon.TclFallback) return; + + R200_STATECHANGE( rmesa, vap ); + /* FIXME: fglrx sets R200_VAP_SINGLE_BUF_STATE_ENABLE too. Do we need it? +diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile +index 6ca9342..0dff9a1 100644 +--- a/src/mesa/drivers/dri/r300/Makefile ++++ b/src/mesa/drivers/dri/r300/Makefile +@@ -3,6 +3,8 @@ + TOP = ../../../../.. + include $(TOP)/configs/current + ++CFLAGS += $(RADEON_CFLAGS) ++ + LIBNAME = r300_dri.so + + MINIGLX_SOURCES = server/radeon_dri.c +@@ -20,20 +22,25 @@ COMMON_SOURCES = \ + ../common/xmlconfig.c \ + ../common/dri_util.c + ++RADEON_COMMON_SOURCES = \ ++ radeon_texture.c \ ++ radeon_common_context.c \ ++ radeon_common.c \ ++ radeon_dma.c \ ++ radeon_lock.c \ ++ radeon_bo_legacy.c \ ++ radeon_cs_legacy.c \ ++ radeon_mipmap_tree.c \ ++ radeon_span.c \ ++ radeon_fbo.c ++ + DRIVER_SOURCES = \ + radeon_screen.c \ +- radeon_context.c \ +- radeon_ioctl.c \ +- radeon_lock.c \ +- radeon_span.c \ +- radeon_state.c \ +- r300_mem.c \ + r300_context.c \ + r300_ioctl.c \ + r300_cmdbuf.c \ + r300_state.c \ + r300_render.c \ +- r300_texmem.c \ + r300_tex.c \ + r300_texstate.c \ + radeon_program.c \ +@@ -49,12 +56,15 @@ DRIVER_SOURCES = \ + r300_shader.c \ + r300_emit.c \ + r300_swtcl.c \ ++ $(RADEON_COMMON_SOURCES) \ + $(EGL_SOURCES) + + C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) + + DRIVER_DEFINES = -DCOMPILE_R300 -DR200_MERGED=0 \ +- -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300 ++ -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300 \ ++# -DRADEON_BO_TRACK \ ++ -Wall + + SYMLINKS = \ + server/radeon_dri.c \ +@@ -68,7 +78,29 @@ COMMON_SYMLINKS = \ + radeon_chipset.h \ + radeon_screen.c \ + radeon_screen.h \ +- radeon_span.h ++ radeon_span.h \ ++ radeon_span.c \ ++ radeon_bo_legacy.c \ ++ radeon_cs_legacy.c \ ++ radeon_bo_legacy.h \ ++ radeon_cs_legacy.h \ ++ radeon_bocs_wrapper.h \ ++ radeon_lock.c \ ++ radeon_lock.h \ ++ radeon_common.c \ ++ radeon_common.h \ ++ radeon_common_context.c \ ++ radeon_common_context.h \ ++ radeon_cmdbuf.h \ ++ radeon_dma.c \ ++ radeon_dma.h \ ++ radeon_mipmap_tree.c \ ++ radeon_mipmap_tree.h \ ++ radeon_texture.c \ ++ radeon_texture.h \ ++ radeon_fbo.c ++ ++DRI_LIB_DEPS += $(RADEON_LDFLAGS) + + ##### TARGETS ##### + +diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c +index 3eb2dc8..2dd2c6a 100644 +--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c ++++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c +@@ -44,245 +44,306 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "drm.h" + #include "radeon_drm.h" + +-#include "radeon_ioctl.h" + #include "r300_context.h" + #include "r300_ioctl.h" + #include "radeon_reg.h" + #include "r300_reg.h" + #include "r300_cmdbuf.h" + #include "r300_emit.h" ++#include "radeon_bocs_wrapper.h" ++#include "radeon_mipmap_tree.h" + #include "r300_state.h" ++#include "radeon_reg.h" + +-// Set this to 1 for extremely verbose debugging of command buffers +-#define DEBUG_CMDBUF 0 ++#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 ++# define RADEON_ONE_REG_WR (1 << 15) + +-/** +- * Send the current command buffer via ioctl to the hardware. ++/** # of dwords reserved for additional instructions that may need to be written ++ * during flushing. + */ +-int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller) ++#define SPACE_FOR_FLUSHING 4 ++ ++static unsigned packet0_count(r300ContextPtr r300, uint32_t *pkt) + { +- int ret; +- int i; +- drm_radeon_cmd_buffer_t cmd; +- int start; +- +- if (r300->radeon.lost_context) { +- start = 0; +- r300->radeon.lost_context = GL_FALSE; +- } else +- start = r300->cmdbuf.count_reemit; +- +- if (RADEON_DEBUG & DEBUG_IOCTL) { +- fprintf(stderr, "%s from %s - %i cliprects\n", +- __FUNCTION__, caller, r300->radeon.numClipRects); +- +- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_VERBOSE) +- for (i = start; i < r300->cmdbuf.count_used; ++i) +- fprintf(stderr, "%d: %08x\n", i, +- r300->cmdbuf.cmd_buf[i]); +- } ++ if (r300->radeon.radeonScreen->kernel_mm) { ++ return ((((*pkt) >> 16) & 0x3FFF) + 1); ++ } else { ++ drm_r300_cmd_header_t *t = (drm_r300_cmd_header_t*)pkt; ++ return t->packet0.count; ++ } ++ return 0; ++} + +- cmd.buf = (char *)(r300->cmdbuf.cmd_buf + start); +- cmd.bufsz = (r300->cmdbuf.count_used - start) * 4; ++#define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count) ++#define r500fp_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->r500fp.count) + +- if (r300->radeon.state.scissor.enabled) { +- cmd.nbox = r300->radeon.state.scissor.numClipRects; +- cmd.boxes = +- (drm_clip_rect_t *) r300->radeon.state.scissor.pClipRects; +- } else { +- cmd.nbox = r300->radeon.numClipRects; +- cmd.boxes = (drm_clip_rect_t *) r300->radeon.pClipRects; ++void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom) ++{ ++ r300ContextPtr r300 = R300_CONTEXT(ctx); ++ BATCH_LOCALS(&r300->radeon); ++ drm_r300_cmd_header_t cmd; ++ uint32_t addr, ndw, i; ++ ++ if (!r300->radeon.radeonScreen->kernel_mm) { ++ uint32_t dwords; ++ dwords = (*atom->check) (ctx, atom); ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_BATCH_TABLE(atom->cmd, dwords); ++ END_BATCH(); ++ return; + } +- +- ret = drmCommandWrite(r300->radeon.dri.fd, +- DRM_RADEON_CMDBUF, &cmd, sizeof(cmd)); +- +- if (RADEON_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "Syncing in %s (from %s)\n\n", +- __FUNCTION__, caller); +- radeonWaitForIdleLocked(&r300->radeon); ++ ++ cmd.u = atom->cmd[0]; ++ addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo; ++ ndw = cmd.vpu.count * 4; ++ if (ndw) { ++ ++ if (r300->vap_flush_needed) { ++ BEGIN_BATCH_NO_AUTOSTATE(15 + ndw); ++ ++ /* flush processing vertices */ ++ OUT_BATCH_REGVAL(R300_SC_SCREENDOOR, 0); ++ OUT_BATCH_REGVAL(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); ++ OUT_BATCH_REGVAL(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); ++ OUT_BATCH_REGVAL(R300_SC_SCREENDOOR, 0xffffff); ++ OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0); ++ r300->vap_flush_needed = GL_FALSE; ++ } else { ++ BEGIN_BATCH_NO_AUTOSTATE(5 + ndw); ++ } ++ OUT_BATCH_REGVAL(R300_VAP_PVS_UPLOAD_ADDRESS, addr); ++ OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, ndw-1) | RADEON_ONE_REG_WR); ++ for (i = 0; i < ndw; i++) { ++ OUT_BATCH(atom->cmd[i+1]); ++ } ++ OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0); ++ END_BATCH(); + } +- +- r300->dma.nr_released_bufs = 0; +- r300->cmdbuf.count_used = 0; +- r300->cmdbuf.count_reemit = 0; +- +- return ret; + } + +-int r300FlushCmdBuf(r300ContextPtr r300, const char *caller) ++void emit_r500fp(GLcontext *ctx, struct radeon_state_atom * atom) + { +- int ret; ++ r300ContextPtr r300 = R300_CONTEXT(ctx); ++ BATCH_LOCALS(&r300->radeon); ++ drm_r300_cmd_header_t cmd; ++ uint32_t addr, ndw, i, sz; ++ int type, clamp, stride; ++ ++ if (!r300->radeon.radeonScreen->kernel_mm) { ++ uint32_t dwords; ++ dwords = (*atom->check) (ctx, atom); ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_BATCH_TABLE(atom->cmd, dwords); ++ END_BATCH(); ++ return; ++ } + +- LOCK_HARDWARE(&r300->radeon); ++ cmd.u = atom->cmd[0]; ++ sz = cmd.r500fp.count; ++ addr = ((cmd.r500fp.adrhi_flags & 1) << 8) | cmd.r500fp.adrlo; ++ type = !!(cmd.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE); ++ clamp = !!(cmd.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP); + +- ret = r300FlushCmdBufLocked(r300, caller); ++ addr |= (type << 16); ++ addr |= (clamp << 17); + +- UNLOCK_HARDWARE(&r300->radeon); ++ stride = type ? 4 : 6; + +- if (ret) { +- fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); +- _mesa_exit(ret); +- } ++ ndw = sz * stride; ++ if (ndw) { + +- return ret; ++ BEGIN_BATCH_NO_AUTOSTATE(3 + ndw); ++ OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_INDEX, 0)); ++ OUT_BATCH(addr); ++ OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_DATA, ndw-1) | RADEON_ONE_REG_WR); ++ for (i = 0; i < ndw; i++) { ++ OUT_BATCH(atom->cmd[i+1]); ++ } ++ END_BATCH(); ++ } + } + +-static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *state) ++static void emit_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom) + { +- int i, j, reg; +- int dwords = (*state->check) (r300, state); +- drm_r300_cmd_header_t cmd; ++ r300ContextPtr r300 = R300_CONTEXT(ctx); ++ BATCH_LOCALS(&r300->radeon); ++ int numtmus = packet0_count(r300, r300->hw.tex.offset.cmd); ++ int notexture = 0; ++ ++ if (numtmus) { ++ int i; ++ ++ for(i = 0; i < numtmus; ++i) { ++ radeonTexObj *t = r300->hw.textures[i]; ++ ++ if (!t) ++ notexture = 1; ++ } + +- fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, +- state->cmd_size); +- +- if (RADEON_DEBUG & DEBUG_VERBOSE) { +- for (i = 0; i < dwords;) { +- cmd = (drm_r300_cmd_header_t) state->cmd[i]; +- reg = (cmd.packet0.reghi << 8) | cmd.packet0.reglo; +- fprintf(stderr, " %s[%d]: cmdpacket0 (first reg=0x%04x, count=%d)\n", +- state->name, i, reg, cmd.packet0.count); +- ++i; +- for (j = 0; j < cmd.packet0.count; j++) { +- fprintf(stderr, " %s[%d]: 0x%04x = %08x\n", +- state->name, i, reg, state->cmd[i]); +- reg += 4; +- ++i; +- } ++ if (r300->radeon.radeonScreen->kernel_mm && notexture) { ++ return; + } ++ BEGIN_BATCH_NO_AUTOSTATE(4 * numtmus); ++ for(i = 0; i < numtmus; ++i) { ++ radeonTexObj *t = r300->hw.textures[i]; ++ OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1); ++ if (t && !t->image_override) { ++ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } else if (!t) { ++ OUT_BATCH(r300->radeon.radeonScreen->texOffset[0]); ++ } else { /* override cases */ ++ if (t->bo) { ++ OUT_BATCH_RELOC(t->tile_bits, t->bo, 0, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } else if (!r300->radeon.radeonScreen->kernel_mm) { ++ OUT_BATCH(t->override_offset); ++ } ++ else ++ OUT_BATCH(r300->radeon.radeonScreen->texOffset[0]); ++ } ++ } ++ END_BATCH(); + } + } + +-/** +- * Emit all atoms with a dirty field equal to dirty. +- * +- * The caller must have ensured that there is enough space in the command +- * buffer. +- */ +-static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) ++static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) + { +- struct r300_state_atom *atom; +- uint32_t *dest; +- int dwords; +- +- dest = r300->cmdbuf.cmd_buf + r300->cmdbuf.count_used; +- +- /* Emit WAIT */ +- *dest = cmdwait(R300_WAIT_3D | R300_WAIT_3D_CLEAN); +- dest++; +- r300->cmdbuf.count_used++; +- +- /* Emit cache flush */ +- *dest = cmdpacket0(R300_TX_INVALTAGS, 1); +- dest++; +- r300->cmdbuf.count_used++; +- +- *dest = R300_TX_FLUSH; +- dest++; +- r300->cmdbuf.count_used++; +- +- /* Emit END3D */ +- *dest = cmdpacify(); +- dest++; +- r300->cmdbuf.count_used++; +- +- /* Emit actual atoms */ +- +- foreach(atom, &r300->hw.atomlist) { +- if ((atom->dirty || r300->hw.all_dirty) == dirty) { +- dwords = (*atom->check) (r300, atom); +- if (dwords) { +- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { +- r300PrintStateAtom(r300, atom); +- } +- memcpy(dest, atom->cmd, dwords * 4); +- dest += dwords; +- r300->cmdbuf.count_used += dwords; +- atom->dirty = GL_FALSE; +- } else { +- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { +- fprintf(stderr, " skip state %s\n", +- atom->name); +- } +- } +- } ++ r300ContextPtr r300 = R300_CONTEXT(ctx); ++ BATCH_LOCALS(&r300->radeon); ++ struct radeon_renderbuffer *rrb; ++ uint32_t cbpitch; ++ uint32_t offset = r300->radeon.state.color.draw_offset; ++ ++ rrb = radeon_get_colorbuffer(&r300->radeon); ++ if (!rrb || !rrb->bo) { ++ fprintf(stderr, "no rrb\n"); ++ return; + } ++ ++ cbpitch = (rrb->pitch / rrb->cpp); ++ if (rrb->cpp == 4) ++ cbpitch |= R300_COLOR_FORMAT_ARGB8888; ++ else ++ cbpitch |= R300_COLOR_FORMAT_RGB565; ++ ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) ++ cbpitch |= R300_COLOR_TILE_ENABLE; ++ ++ BEGIN_BATCH_NO_AUTOSTATE(8); ++ OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1); ++ OUT_BATCH_RELOC(offset, rrb->bo, offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ OUT_BATCH_REGSEQ(R300_RB3D_COLORPITCH0, 1); ++ OUT_BATCH_RELOC(cbpitch, rrb->bo, cbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ END_BATCH(); ++ if (r300->radeon.radeonScreen->driScreen->dri2.enabled) { ++ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { ++ BEGIN_BATCH_NO_AUTOSTATE(3); ++ OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2); ++ OUT_BATCH(0); ++ OUT_BATCH((rrb->width << R300_SCISSORS_X_SHIFT) | ++ (rrb->height << R300_SCISSORS_Y_SHIFT)); ++ END_BATCH(); ++ } else { ++ BEGIN_BATCH_NO_AUTOSTATE(3); ++ OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2); ++ OUT_BATCH((R300_SCISSORS_OFFSET << R300_SCISSORS_X_SHIFT) | ++ (R300_SCISSORS_OFFSET << R300_SCISSORS_Y_SHIFT)); ++ OUT_BATCH(((rrb->width + R300_SCISSORS_OFFSET) << R300_SCISSORS_X_SHIFT) | ++ ((rrb->height + R300_SCISSORS_OFFSET) << R300_SCISSORS_Y_SHIFT)); ++ END_BATCH(); ++ } ++ } + } + +-/** +- * Copy dirty hardware state atoms into the command buffer. +- * +- * We also copy out clean state if we're at the start of a buffer. That makes +- * it easy to recover from lost contexts. +- */ +-void r300EmitState(r300ContextPtr r300) ++static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom) + { +- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_PRIMS)) +- fprintf(stderr, "%s\n", __FUNCTION__); ++ r300ContextPtr r300 = R300_CONTEXT(ctx); ++ BATCH_LOCALS(&r300->radeon); ++ struct radeon_renderbuffer *rrb; ++ uint32_t zbpitch; + +- if (r300->cmdbuf.count_used && !r300->hw.is_dirty +- && !r300->hw.all_dirty) ++ rrb = radeon_get_depthbuffer(&r300->radeon); ++ if (!rrb) + return; + +- /* To avoid going across the entire set of states multiple times, just check +- * for enough space for the case of emitting all state, and inline the +- * r300AllocCmdBuf code here without all the checks. +- */ +- r300EnsureCmdBufSpace(r300, r300->hw.max_state_size, __FUNCTION__); +- +- if (!r300->cmdbuf.count_used) { +- if (RADEON_DEBUG & DEBUG_STATE) +- fprintf(stderr, "Begin reemit state\n"); +- +- r300EmitAtoms(r300, GL_FALSE); +- r300->cmdbuf.count_reemit = r300->cmdbuf.count_used; ++ zbpitch = (rrb->pitch / rrb->cpp); ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { ++ zbpitch |= R300_DEPTHMACROTILE_ENABLE; + } ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ ++ zbpitch |= R300_DEPTHMICROTILE_TILED; ++ } ++ ++ BEGIN_BATCH_NO_AUTOSTATE(6); ++ OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1); ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, zbpitch); ++ END_BATCH(); ++} + +- if (RADEON_DEBUG & DEBUG_STATE) +- fprintf(stderr, "Begin dirty state\n"); +- +- r300EmitAtoms(r300, GL_TRUE); +- +- assert(r300->cmdbuf.count_used < r300->cmdbuf.size); ++static void emit_zstencil_format(GLcontext *ctx, struct radeon_state_atom * atom) ++{ ++ r300ContextPtr r300 = R300_CONTEXT(ctx); ++ BATCH_LOCALS(&r300->radeon); ++ struct radeon_renderbuffer *rrb; ++ uint32_t format = 0; ++ ++ rrb = radeon_get_depthbuffer(&r300->radeon); ++ if (!rrb) ++ format = 0; ++ else { ++ if (rrb->cpp == 2) ++ format = R300_DEPTHFORMAT_16BIT_INT_Z; ++ else if (rrb->cpp == 4) ++ format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; ++ } + +- r300->hw.is_dirty = GL_FALSE; +- r300->hw.all_dirty = GL_FALSE; ++ OUT_BATCH(atom->cmd[0]); ++ atom->cmd[1] &= ~0xf; ++ atom->cmd[1] |= format; ++ OUT_BATCH(atom->cmd[1]); ++ OUT_BATCH(atom->cmd[2]); ++ OUT_BATCH(atom->cmd[3]); ++ OUT_BATCH(atom->cmd[4]); + } + +-#define packet0_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->packet0.count) +-#define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count) +-#define r500fp_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->r500fp.count) +- +-static int check_always(r300ContextPtr r300, struct r300_state_atom *atom) ++static int check_always(GLcontext *ctx, struct radeon_state_atom *atom) + { + return atom->cmd_size; + } + +-static int check_variable(r300ContextPtr r300, struct r300_state_atom *atom) ++static int check_variable(GLcontext *ctx, struct radeon_state_atom *atom) + { ++ r300ContextPtr r300 = R300_CONTEXT(ctx); + int cnt; +- cnt = packet0_count(atom->cmd); ++ if (atom->cmd[0] == CP_PACKET2) { ++ return 0; ++ } ++ cnt = packet0_count(r300, atom->cmd); + return cnt ? cnt + 1 : 0; + } + +-static int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom) ++int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom) + { + int cnt; ++ + cnt = vpu_count(atom->cmd); + return cnt ? (cnt * 4) + 1 : 0; + } + +-static int check_r500fp(r300ContextPtr r300, struct r300_state_atom *atom) ++int check_r500fp(GLcontext *ctx, struct radeon_state_atom *atom) + { + int cnt; ++ + cnt = r500fp_count(atom->cmd); + return cnt ? (cnt * 6) + 1 : 0; + } + +-static int check_r500fp_const(r300ContextPtr r300, struct r300_state_atom *atom) ++int check_r500fp_const(GLcontext *ctx, struct radeon_state_atom *atom) + { + int cnt; ++ + cnt = r500fp_count(atom->cmd); + return cnt ? (cnt * 4) + 1 : 0; + } +@@ -295,8 +356,8 @@ static int check_r500fp_const(r300ContextPtr r300, struct r300_state_atom *atom) + r300->hw.ATOM.idx = (IDX); \ + r300->hw.ATOM.check = check_##CHK; \ + r300->hw.ATOM.dirty = GL_FALSE; \ +- r300->hw.max_state_size += (SZ); \ +- insert_at_tail(&r300->hw.atomlist, &r300->hw.ATOM); \ ++ r300->radeon.hw.max_state_size += (SZ); \ ++ insert_at_tail(&r300->radeon.hw.atomlist, &r300->hw.ATOM); \ + } while (0) + /** + * Allocate memory for the command buffer and initialize the state atom +@@ -304,7 +365,7 @@ static int check_r500fp_const(r300ContextPtr r300, struct r300_state_atom *atom) + */ + void r300InitCmdBuf(r300ContextPtr r300) + { +- int size, mtu; ++ int mtu; + int has_tcl = 1; + int is_r500 = 0; + int i; +@@ -315,7 +376,7 @@ void r300InitCmdBuf(r300ContextPtr r300) + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + is_r500 = 1; + +- r300->hw.max_state_size = 2 + 2; /* reserve extra space for WAIT_IDLE and tex cache flush */ ++ r300->radeon.hw.max_state_size = 2 + 2; /* reserve extra space for WAIT_IDLE and tex cache flush */ + + mtu = r300->radeon.glCtx->Const.MaxTextureUnits; + if (RADEON_DEBUG & DEBUG_TEXTURE) { +@@ -323,97 +384,97 @@ void r300InitCmdBuf(r300ContextPtr r300) + } + + /* Setup the atom linked list */ +- make_empty_list(&r300->hw.atomlist); +- r300->hw.atomlist.name = "atom-list"; ++ make_empty_list(&r300->radeon.hw.atomlist); ++ r300->radeon.hw.atomlist.name = "atom-list"; + + /* Initialize state atoms */ + ALLOC_STATE(vpt, always, R300_VPT_CMDSIZE, 0); +- r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmdpacket0(R300_SE_VPORT_XSCALE, 6); ++ r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_SE_VPORT_XSCALE, 6); + ALLOC_STATE(vap_cntl, always, R300_VAP_CNTL_SIZE, 0); +- r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH] = cmdpacket0(R300_VAP_PVS_STATE_FLUSH_REG, 1); ++ r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_STATE_FLUSH_REG, 1); + r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH_1] = 0; +- r300->hw.vap_cntl.cmd[R300_VAP_CNTL_CMD] = cmdpacket0(R300_VAP_CNTL, 1); ++ r300->hw.vap_cntl.cmd[R300_VAP_CNTL_CMD] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CNTL, 1); + if (is_r500) { + ALLOC_STATE(vap_index_offset, always, 2, 0); +- r300->hw.vap_index_offset.cmd[0] = cmdpacket0(R500_VAP_INDEX_OFFSET, 1); ++ r300->hw.vap_index_offset.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_VAP_INDEX_OFFSET, 1); + r300->hw.vap_index_offset.cmd[1] = 0; + } + ALLOC_STATE(vte, always, 3, 0); +- r300->hw.vte.cmd[0] = cmdpacket0(R300_SE_VTE_CNTL, 2); ++ r300->hw.vte.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SE_VTE_CNTL, 2); + ALLOC_STATE(vap_vf_max_vtx_indx, always, 3, 0); +- r300->hw.vap_vf_max_vtx_indx.cmd[0] = cmdpacket0(R300_VAP_VF_MAX_VTX_INDX, 2); ++ r300->hw.vap_vf_max_vtx_indx.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_VF_MAX_VTX_INDX, 2); + ALLOC_STATE(vap_cntl_status, always, 2, 0); +- r300->hw.vap_cntl_status.cmd[0] = cmdpacket0(R300_VAP_CNTL_STATUS, 1); ++ r300->hw.vap_cntl_status.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CNTL_STATUS, 1); + ALLOC_STATE(vir[0], variable, R300_VIR_CMDSIZE, 0); + r300->hw.vir[0].cmd[R300_VIR_CMD_0] = +- cmdpacket0(R300_VAP_PROG_STREAM_CNTL_0, 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PROG_STREAM_CNTL_0, 1); + ALLOC_STATE(vir[1], variable, R300_VIR_CMDSIZE, 1); + r300->hw.vir[1].cmd[R300_VIR_CMD_0] = +- cmdpacket0(R300_VAP_PROG_STREAM_CNTL_EXT_0, 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PROG_STREAM_CNTL_EXT_0, 1); + ALLOC_STATE(vic, always, R300_VIC_CMDSIZE, 0); +- r300->hw.vic.cmd[R300_VIC_CMD_0] = cmdpacket0(R300_VAP_VTX_STATE_CNTL, 2); ++ r300->hw.vic.cmd[R300_VIC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_VTX_STATE_CNTL, 2); + ALLOC_STATE(vap_psc_sgn_norm_cntl, always, 2, 0); +- r300->hw.vap_psc_sgn_norm_cntl.cmd[0] = cmdpacket0(R300_VAP_PSC_SGN_NORM_CNTL, SGN_NORM_ZERO_CLAMP_MINUS_ONE); ++ r300->hw.vap_psc_sgn_norm_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PSC_SGN_NORM_CNTL, SGN_NORM_ZERO_CLAMP_MINUS_ONE); + + if (has_tcl) { + ALLOC_STATE(vap_clip_cntl, always, 2, 0); +- r300->hw.vap_clip_cntl.cmd[0] = cmdpacket0(R300_VAP_CLIP_CNTL, 1); ++ r300->hw.vap_clip_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CLIP_CNTL, 1); + ALLOC_STATE(vap_clip, always, 5, 0); +- r300->hw.vap_clip.cmd[0] = cmdpacket0(R300_VAP_GB_VERT_CLIP_ADJ, 4); ++ r300->hw.vap_clip.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_GB_VERT_CLIP_ADJ, 4); + ALLOC_STATE(vap_pvs_vtx_timeout_reg, always, 2, 0); +- r300->hw.vap_pvs_vtx_timeout_reg.cmd[0] = cmdpacket0(VAP_PVS_VTX_TIMEOUT_REG, 1); ++ r300->hw.vap_pvs_vtx_timeout_reg.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, VAP_PVS_VTX_TIMEOUT_REG, 1); + } + + ALLOC_STATE(vof, always, R300_VOF_CMDSIZE, 0); + r300->hw.vof.cmd[R300_VOF_CMD_0] = +- cmdpacket0(R300_VAP_OUTPUT_VTX_FMT_0, 2); ++ cmdpacket0(r300->radeon.radeonScreen, R300_VAP_OUTPUT_VTX_FMT_0, 2); + + if (has_tcl) { + ALLOC_STATE(pvs, always, R300_PVS_CMDSIZE, 0); + r300->hw.pvs.cmd[R300_PVS_CMD_0] = +- cmdpacket0(R300_VAP_PVS_CODE_CNTL_0, 3); ++ cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_CODE_CNTL_0, 3); + } + + ALLOC_STATE(gb_enable, always, 2, 0); +- r300->hw.gb_enable.cmd[0] = cmdpacket0(R300_GB_ENABLE, 1); ++ r300->hw.gb_enable.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_ENABLE, 1); + ALLOC_STATE(gb_misc, always, R300_GB_MISC_CMDSIZE, 0); +- r300->hw.gb_misc.cmd[0] = cmdpacket0(R300_GB_MSPOS0, 5); ++ r300->hw.gb_misc.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_MSPOS0, 5); + ALLOC_STATE(txe, always, R300_TXE_CMDSIZE, 0); +- r300->hw.txe.cmd[R300_TXE_CMD_0] = cmdpacket0(R300_TX_ENABLE, 1); ++ r300->hw.txe.cmd[R300_TXE_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_ENABLE, 1); + ALLOC_STATE(ga_point_s0, always, 5, 0); +- r300->hw.ga_point_s0.cmd[0] = cmdpacket0(R300_GA_POINT_S0, 4); ++ r300->hw.ga_point_s0.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POINT_S0, 4); + ALLOC_STATE(ga_triangle_stipple, always, 2, 0); +- r300->hw.ga_triangle_stipple.cmd[0] = cmdpacket0(R300_GA_TRIANGLE_STIPPLE, 1); ++ r300->hw.ga_triangle_stipple.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_TRIANGLE_STIPPLE, 1); + ALLOC_STATE(ps, always, R300_PS_CMDSIZE, 0); +- r300->hw.ps.cmd[0] = cmdpacket0(R300_GA_POINT_SIZE, 1); ++ r300->hw.ps.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POINT_SIZE, 1); + ALLOC_STATE(ga_point_minmax, always, 4, 0); +- r300->hw.ga_point_minmax.cmd[0] = cmdpacket0(R300_GA_POINT_MINMAX, 3); ++ r300->hw.ga_point_minmax.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POINT_MINMAX, 3); + ALLOC_STATE(lcntl, always, 2, 0); +- r300->hw.lcntl.cmd[0] = cmdpacket0(R300_GA_LINE_CNTL, 1); ++ r300->hw.lcntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_CNTL, 1); + ALLOC_STATE(ga_line_stipple, always, 4, 0); +- r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(R300_GA_LINE_STIPPLE_VALUE, 3); ++ r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_STIPPLE_VALUE, 3); + ALLOC_STATE(shade, always, 5, 0); +- r300->hw.shade.cmd[0] = cmdpacket0(R300_GA_ENHANCE, 4); ++ r300->hw.shade.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_ENHANCE, 4); + ALLOC_STATE(polygon_mode, always, 4, 0); +- r300->hw.polygon_mode.cmd[0] = cmdpacket0(R300_GA_POLY_MODE, 3); ++ r300->hw.polygon_mode.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POLY_MODE, 3); + ALLOC_STATE(fogp, always, 3, 0); +- r300->hw.fogp.cmd[0] = cmdpacket0(R300_GA_FOG_SCALE, 2); ++ r300->hw.fogp.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_FOG_SCALE, 2); + ALLOC_STATE(zbias_cntl, always, 2, 0); +- r300->hw.zbias_cntl.cmd[0] = cmdpacket0(R300_SU_TEX_WRAP, 1); ++ r300->hw.zbias_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_TEX_WRAP, 1); + ALLOC_STATE(zbs, always, R300_ZBS_CMDSIZE, 0); + r300->hw.zbs.cmd[R300_ZBS_CMD_0] = +- cmdpacket0(R300_SU_POLY_OFFSET_FRONT_SCALE, 4); ++ cmdpacket0(r300->radeon.radeonScreen, R300_SU_POLY_OFFSET_FRONT_SCALE, 4); + ALLOC_STATE(occlusion_cntl, always, 2, 0); +- r300->hw.occlusion_cntl.cmd[0] = cmdpacket0(R300_SU_POLY_OFFSET_ENABLE, 1); ++ r300->hw.occlusion_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_POLY_OFFSET_ENABLE, 1); + ALLOC_STATE(cul, always, R300_CUL_CMDSIZE, 0); +- r300->hw.cul.cmd[R300_CUL_CMD_0] = cmdpacket0(R300_SU_CULL_MODE, 1); ++ r300->hw.cul.cmd[R300_CUL_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_CULL_MODE, 1); + ALLOC_STATE(su_depth_scale, always, 3, 0); +- r300->hw.su_depth_scale.cmd[0] = cmdpacket0(R300_SU_DEPTH_SCALE, 2); ++ r300->hw.su_depth_scale.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_DEPTH_SCALE, 2); + ALLOC_STATE(rc, always, R300_RC_CMDSIZE, 0); +- r300->hw.rc.cmd[R300_RC_CMD_0] = cmdpacket0(R300_RS_COUNT, 2); ++ r300->hw.rc.cmd[R300_RC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_COUNT, 2); + if (is_r500) { + ALLOC_STATE(ri, always, R500_RI_CMDSIZE, 0); +- r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R500_RS_IP_0, 16); ++ r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_IP_0, 16); + for (i = 0; i < 8; i++) { + r300->hw.ri.cmd[R300_RI_CMD_0 + i +1] = + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | +@@ -422,133 +483,149 @@ void r300InitCmdBuf(r300ContextPtr r300) + (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT); + } + ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); +- r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R500_RS_INST_0, 1); ++ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_INST_0, 1); + } else { + ALLOC_STATE(ri, always, R300_RI_CMDSIZE, 0); +- r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R300_RS_IP_0, 8); ++ r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_IP_0, 8); + ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); +- r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, 1); ++ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_INST_0, 1); + } + ALLOC_STATE(sc_hyperz, always, 3, 0); +- r300->hw.sc_hyperz.cmd[0] = cmdpacket0(R300_SC_HYPERZ, 2); ++ r300->hw.sc_hyperz.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_HYPERZ, 2); + ALLOC_STATE(sc_screendoor, always, 2, 0); +- r300->hw.sc_screendoor.cmd[0] = cmdpacket0(R300_SC_SCREENDOOR, 1); ++ r300->hw.sc_screendoor.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_SCREENDOOR, 1); + ALLOC_STATE(us_out_fmt, always, 6, 0); +- r300->hw.us_out_fmt.cmd[0] = cmdpacket0(R300_US_OUT_FMT, 5); ++ r300->hw.us_out_fmt.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_OUT_FMT, 5); + + if (is_r500) { + ALLOC_STATE(fp, always, R500_FP_CMDSIZE, 0); +- r300->hw.fp.cmd[R500_FP_CMD_0] = cmdpacket0(R500_US_CONFIG, 2); ++ r300->hw.fp.cmd[R500_FP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_US_CONFIG, 2); + r300->hw.fp.cmd[R500_FP_CNTL] = R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO; +- r300->hw.fp.cmd[R500_FP_CMD_1] = cmdpacket0(R500_US_CODE_ADDR, 3); +- r300->hw.fp.cmd[R500_FP_CMD_2] = cmdpacket0(R500_US_FC_CTRL, 1); ++ r300->hw.fp.cmd[R500_FP_CMD_1] = cmdpacket0(r300->radeon.radeonScreen, R500_US_CODE_ADDR, 3); ++ r300->hw.fp.cmd[R500_FP_CMD_2] = cmdpacket0(r300->radeon.radeonScreen, R500_US_FC_CTRL, 1); + r300->hw.fp.cmd[R500_FP_FC_CNTL] = 0; /* FIXME when we add flow control */ + + ALLOC_STATE(r500fp, r500fp, R500_FPI_CMDSIZE, 0); +- r300->hw.r500fp.cmd[R300_FPI_CMD_0] = cmdr500fp(0, 0, 0, 0); ++ r300->hw.r500fp.cmd[R300_FPI_CMD_0] = ++ cmdr500fp(r300->radeon.radeonScreen, 0, 0, 0, 0); ++ r300->hw.r500fp.emit = emit_r500fp; + ALLOC_STATE(r500fp_const, r500fp_const, R500_FPP_CMDSIZE, 0); +- r300->hw.r500fp_const.cmd[R300_FPI_CMD_0] = cmdr500fp(0, 0, 1, 0); ++ r300->hw.r500fp_const.cmd[R300_FPI_CMD_0] = ++ cmdr500fp(r300->radeon.radeonScreen, 0, 0, 1, 0); ++ r300->hw.r500fp_const.emit = emit_r500fp; + } else { + ALLOC_STATE(fp, always, R300_FP_CMDSIZE, 0); +- r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(R300_US_CONFIG, 3); +- r300->hw.fp.cmd[R300_FP_CMD_1] = cmdpacket0(R300_US_CODE_ADDR_0, 4); ++ r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_CONFIG, 3); ++ r300->hw.fp.cmd[R300_FP_CMD_1] = cmdpacket0(r300->radeon.radeonScreen, R300_US_CODE_ADDR_0, 4); ++ + ALLOC_STATE(fpt, variable, R300_FPT_CMDSIZE, 0); +- r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(R300_US_TEX_INST_0, 0); ++ r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_TEX_INST_0, 0); + + ALLOC_STATE(fpi[0], variable, R300_FPI_CMDSIZE, 0); +- r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, 1); ++ r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_RGB_INST_0, 1); + ALLOC_STATE(fpi[1], variable, R300_FPI_CMDSIZE, 1); +- r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, 1); ++ r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_RGB_ADDR_0, 1); + ALLOC_STATE(fpi[2], variable, R300_FPI_CMDSIZE, 2); +- r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, 1); ++ r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_ALPHA_INST_0, 1); + ALLOC_STATE(fpi[3], variable, R300_FPI_CMDSIZE, 3); +- r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, 1); ++ r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_ALPHA_ADDR_0, 1); + ALLOC_STATE(fpp, variable, R300_FPP_CMDSIZE, 0); +- r300->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, 0); ++ r300->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_PFS_PARAM_0_X, 0); + } + ALLOC_STATE(fogs, always, R300_FOGS_CMDSIZE, 0); +- r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(R300_FG_FOG_BLEND, 1); ++ r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_FOG_BLEND, 1); + ALLOC_STATE(fogc, always, R300_FOGC_CMDSIZE, 0); +- r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(R300_FG_FOG_COLOR_R, 3); ++ r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_FOG_COLOR_R, 3); + ALLOC_STATE(at, always, R300_AT_CMDSIZE, 0); +- r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(R300_FG_ALPHA_FUNC, 2); ++ r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_ALPHA_FUNC, 2); + ALLOC_STATE(fg_depth_src, always, 2, 0); +- r300->hw.fg_depth_src.cmd[0] = cmdpacket0(R300_FG_DEPTH_SRC, 1); ++ r300->hw.fg_depth_src.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_DEPTH_SRC, 1); + ALLOC_STATE(rb3d_cctl, always, 2, 0); +- r300->hw.rb3d_cctl.cmd[0] = cmdpacket0(R300_RB3D_CCTL, 1); ++ r300->hw.rb3d_cctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_CCTL, 1); + ALLOC_STATE(bld, always, R300_BLD_CMDSIZE, 0); +- r300->hw.bld.cmd[R300_BLD_CMD_0] = cmdpacket0(R300_RB3D_CBLEND, 2); ++ r300->hw.bld.cmd[R300_BLD_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_CBLEND, 2); + ALLOC_STATE(cmk, always, R300_CMK_CMDSIZE, 0); +- r300->hw.cmk.cmd[R300_CMK_CMD_0] = cmdpacket0(RB3D_COLOR_CHANNEL_MASK, 1); ++ r300->hw.cmk.cmd[R300_CMK_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, RB3D_COLOR_CHANNEL_MASK, 1); + if (is_r500) { + ALLOC_STATE(blend_color, always, 3, 0); +- r300->hw.blend_color.cmd[0] = cmdpacket0(R500_RB3D_CONSTANT_COLOR_AR, 2); ++ r300->hw.blend_color.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_CONSTANT_COLOR_AR, 2); + } else { + ALLOC_STATE(blend_color, always, 2, 0); +- r300->hw.blend_color.cmd[0] = cmdpacket0(R300_RB3D_BLEND_COLOR, 1); ++ r300->hw.blend_color.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_BLEND_COLOR, 1); + } + ALLOC_STATE(rop, always, 2, 0); +- r300->hw.rop.cmd[0] = cmdpacket0(R300_RB3D_ROPCNTL, 1); ++ r300->hw.rop.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_ROPCNTL, 1); + ALLOC_STATE(cb, always, R300_CB_CMDSIZE, 0); +- r300->hw.cb.cmd[R300_CB_CMD_0] = cmdpacket0(R300_RB3D_COLOROFFSET0, 1); +- r300->hw.cb.cmd[R300_CB_CMD_1] = cmdpacket0(R300_RB3D_COLORPITCH0, 1); ++ r300->hw.cb.emit = &emit_cb_offset; + ALLOC_STATE(rb3d_dither_ctl, always, 10, 0); +- r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(R300_RB3D_DITHER_CTL, 9); ++ r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_DITHER_CTL, 9); + ALLOC_STATE(rb3d_aaresolve_ctl, always, 2, 0); +- r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(R300_RB3D_AARESOLVE_CTL, 1); ++ r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_AARESOLVE_CTL, 1); + ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold, always, 3, 0); +- r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); ++ r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); + ALLOC_STATE(zs, always, R300_ZS_CMDSIZE, 0); + r300->hw.zs.cmd[R300_ZS_CMD_0] = +- cmdpacket0(R300_ZB_CNTL, 3); ++ cmdpacket0(r300->radeon.radeonScreen, R300_ZB_CNTL, 3); ++ + ALLOC_STATE(zstencil_format, always, 5, 0); + r300->hw.zstencil_format.cmd[0] = +- cmdpacket0(R300_ZB_FORMAT, 4); ++ cmdpacket0(r300->radeon.radeonScreen, R300_ZB_FORMAT, 4); ++ r300->hw.zstencil_format.emit = emit_zstencil_format; ++ + ALLOC_STATE(zb, always, R300_ZB_CMDSIZE, 0); +- r300->hw.zb.cmd[R300_ZB_CMD_0] = cmdpacket0(R300_ZB_DEPTHOFFSET, 2); ++ r300->hw.zb.emit = emit_zb_offset; + ALLOC_STATE(zb_depthclearvalue, always, 2, 0); +- r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(R300_ZB_DEPTHCLEARVALUE, 1); ++ r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_DEPTHCLEARVALUE, 1); + ALLOC_STATE(unk4F30, always, 3, 0); +- r300->hw.unk4F30.cmd[0] = cmdpacket0(0x4F30, 2); ++ r300->hw.unk4F30.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, 0x4F30, 2); + ALLOC_STATE(zb_hiz_offset, always, 2, 0); +- r300->hw.zb_hiz_offset.cmd[0] = cmdpacket0(R300_ZB_HIZ_OFFSET, 1); ++ r300->hw.zb_hiz_offset.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_HIZ_OFFSET, 1); + ALLOC_STATE(zb_hiz_pitch, always, 2, 0); +- r300->hw.zb_hiz_pitch.cmd[0] = cmdpacket0(R300_ZB_HIZ_PITCH, 1); ++ r300->hw.zb_hiz_pitch.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_HIZ_PITCH, 1); + + /* VPU only on TCL */ + if (has_tcl) { + int i; + ALLOC_STATE(vpi, vpu, R300_VPI_CMDSIZE, 0); +- r300->hw.vpi.cmd[R300_VPI_CMD_0] = +- cmdvpu(R300_PVS_CODE_START, 0); ++ r300->hw.vpi.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R300_PVS_CODE_START, 0); ++ r300->hw.vpi.emit = emit_vpu; + + if (is_r500) { + ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); +- r300->hw.vpp.cmd[R300_VPP_CMD_0] = +- cmdvpu(R500_PVS_CONST_START, 0); ++ r300->hw.vpp.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R500_PVS_CONST_START, 0); ++ r300->hw.vpp.emit = emit_vpu; + + ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); +- r300->hw.vps.cmd[R300_VPS_CMD_0] = +- cmdvpu(R500_POINT_VPORT_SCALE_OFFSET, 1); ++ r300->hw.vps.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R500_POINT_VPORT_SCALE_OFFSET, 1); ++ r300->hw.vps.emit = emit_vpu; + + for (i = 0; i < 6; i++) { +- ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); +- r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = +- cmdvpu(R500_PVS_UCP_START + i, 1); ++ ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); ++ r300->hw.vpucp[i].cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, ++ R500_PVS_UCP_START + i, 1); ++ r300->hw.vpucp[i].emit = emit_vpu; + } + } else { + ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); +- r300->hw.vpp.cmd[R300_VPP_CMD_0] = +- cmdvpu(R300_PVS_CONST_START, 0); ++ r300->hw.vpp.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R300_PVS_CONST_START, 0); ++ r300->hw.vpp.emit = emit_vpu; + + ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); +- r300->hw.vps.cmd[R300_VPS_CMD_0] = +- cmdvpu(R300_POINT_VPORT_SCALE_OFFSET, 1); ++ r300->hw.vps.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R300_POINT_VPORT_SCALE_OFFSET, 1); ++ r300->hw.vps.emit = emit_vpu; + + for (i = 0; i < 6; i++) { + ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); +- r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = +- cmdvpu(R300_PVS_UCP_START + i, 1); ++ r300->hw.vpucp[i].cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, ++ R300_PVS_UCP_START + i, 1); ++ r300->hw.vpucp[i].emit = emit_vpu; + } + } + } +@@ -556,130 +633,37 @@ void r300InitCmdBuf(r300ContextPtr r300) + /* Textures */ + ALLOC_STATE(tex.filter, variable, mtu + 1, 0); + r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER0_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 0); + + ALLOC_STATE(tex.filter_1, variable, mtu + 1, 0); + r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER1_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER1_0, 0); + + ALLOC_STATE(tex.size, variable, mtu + 1, 0); +- r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_SIZE_0, 0); ++ r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_SIZE_0, 0); + + ALLOC_STATE(tex.format, variable, mtu + 1, 0); + r300->hw.tex.format.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FORMAT_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT_0, 0); + + ALLOC_STATE(tex.pitch, variable, mtu + 1, 0); +- r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FORMAT2_0, 0); ++ r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT2_0, 0); + +- ALLOC_STATE(tex.offset, variable, mtu + 1, 0); ++ ALLOC_STATE(tex.offset, variable, 1, 0); + r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_OFFSET_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_OFFSET_0, 0); ++ r300->hw.tex.offset.emit = &emit_tex_offsets; + + ALLOC_STATE(tex.chroma_key, variable, mtu + 1, 0); + r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_CHROMA_KEY_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_CHROMA_KEY_0, 0); + + ALLOC_STATE(tex.border_color, variable, mtu + 1, 0); + r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_BORDER_COLOR_0, 0); +- +- r300->hw.is_dirty = GL_TRUE; +- r300->hw.all_dirty = GL_TRUE; +- +- /* Initialize command buffer */ +- size = +- 256 * driQueryOptioni(&r300->radeon.optionCache, +- "command_buffer_size"); +- if (size < 2 * r300->hw.max_state_size) { +- size = 2 * r300->hw.max_state_size + 65535; +- } +- if (size > 64 * 256) +- size = 64 * 256; +- +- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { +- fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", +- sizeof(drm_r300_cmd_header_t)); +- fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", +- sizeof(drm_radeon_cmd_buffer_t)); +- fprintf(stderr, +- "Allocating %d bytes command buffer (max state is %d bytes)\n", +- size * 4, r300->hw.max_state_size * 4); +- } +- +- r300->cmdbuf.size = size; +- r300->cmdbuf.cmd_buf = (uint32_t *) CALLOC(size * 4); +- r300->cmdbuf.count_used = 0; +- r300->cmdbuf.count_reemit = 0; +-} +- +-/** +- * Destroy the command buffer and state atoms. +- */ +-void r300DestroyCmdBuf(r300ContextPtr r300) +-{ +- struct r300_state_atom *atom; +- +- FREE(r300->cmdbuf.cmd_buf); +- +- foreach(atom, &r300->hw.atomlist) { +- FREE(atom->cmd); +- } +-} +- +-void r300EmitBlit(r300ContextPtr rmesa, +- GLuint color_fmt, +- GLuint src_pitch, +- GLuint src_offset, +- GLuint dst_pitch, +- GLuint dst_offset, +- GLint srcx, GLint srcy, +- GLint dstx, GLint dsty, GLuint w, GLuint h) +-{ +- drm_r300_cmd_header_t *cmd; +- +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, +- "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n", +- __FUNCTION__, src_pitch, src_offset, srcx, srcy, +- dst_pitch, dst_offset, dstx, dsty, w, h); +- +- assert((src_pitch & 63) == 0); +- assert((dst_pitch & 63) == 0); +- assert((src_offset & 1023) == 0); +- assert((dst_offset & 1023) == 0); +- assert(w < (1 << 16)); +- assert(h < (1 << 16)); +- +- cmd = (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa, 8, __FUNCTION__); +- +- cmd[0].header.cmd_type = R300_CMD_PACKET3; +- cmd[0].header.pad0 = R300_CMD_PACKET3_RAW; +- cmd[1].u = R300_CP_CMD_BITBLT_MULTI | (5 << 16); +- cmd[2].u = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | +- RADEON_GMC_DST_PITCH_OFFSET_CNTL | +- RADEON_GMC_BRUSH_NONE | +- (color_fmt << 8) | +- RADEON_GMC_SRC_DATATYPE_COLOR | +- RADEON_ROP3_S | +- RADEON_DP_SRC_SOURCE_MEMORY | +- RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); +- +- cmd[3].u = ((src_pitch / 64) << 22) | (src_offset >> 10); +- cmd[4].u = ((dst_pitch / 64) << 22) | (dst_offset >> 10); +- cmd[5].u = (srcx << 16) | srcy; +- cmd[6].u = (dstx << 16) | dsty; /* dst */ +- cmd[7].u = (w << 16) | h; +-} +- +-void r300EmitWait(r300ContextPtr rmesa, GLuint flags) +-{ +- drm_r300_cmd_header_t *cmd; ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, 0); + +- assert(!(flags & ~(R300_WAIT_2D | R300_WAIT_3D))); ++ r300->radeon.hw.is_dirty = GL_TRUE; ++ r300->radeon.hw.all_dirty = GL_TRUE; + +- cmd = (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); +- cmd[0].u = 0; +- cmd[0].wait.cmd_type = R300_CMD_WAIT; +- cmd[0].wait.flags = flags; ++ rcommonInitCmdBuf(&r300->radeon); + } +diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h +index a8eaa58..3786813 100644 +--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h ++++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h +@@ -38,79 +38,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #include "r300_context.h" + +-extern int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller); +-extern int r300FlushCmdBuf(r300ContextPtr r300, const char *caller); +- +-extern void r300EmitState(r300ContextPtr r300); +- + extern void r300InitCmdBuf(r300ContextPtr r300); +-extern void r300DestroyCmdBuf(r300ContextPtr r300); +- +-/** +- * Make sure that enough space is available in the command buffer +- * by flushing if necessary. +- * +- * \param dwords The number of dwords we need to be free on the command buffer +- */ +-static INLINE void r300EnsureCmdBufSpace(r300ContextPtr r300, +- int dwords, const char *caller) +-{ +- assert(dwords < r300->cmdbuf.size); +- +- if (r300->cmdbuf.count_used + dwords > r300->cmdbuf.size) +- r300FlushCmdBuf(r300, caller); +-} +- +-/** +- * Allocate the given number of dwords in the command buffer and return +- * a pointer to the allocated area. +- * When necessary, these functions cause a flush. r300AllocCmdBuf() also +- * causes state reemission after a flush. This is necessary to ensure +- * correct hardware state after an unlock. +- */ +-static INLINE uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300, +- int dwords, const char *caller) +-{ +- uint32_t *ptr; +- +- r300EnsureCmdBufSpace(r300, dwords, caller); +- +- ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used]; +- r300->cmdbuf.count_used += dwords; +- return ptr; +-} +- +-static INLINE uint32_t *r300AllocCmdBuf(r300ContextPtr r300, +- int dwords, const char *caller) +-{ +- uint32_t *ptr; +- +- r300EnsureCmdBufSpace(r300, dwords, caller); +- +- if (!r300->cmdbuf.count_used) { +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, +- "Reemit state after flush (from %s)\n", caller); +- r300EmitState(r300); +- } +- +- ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used]; +- r300->cmdbuf.count_used += dwords; +- return ptr; +-} + +-extern void r300EmitBlit(r300ContextPtr rmesa, +- GLuint color_fmt, +- GLuint src_pitch, +- GLuint src_offset, +- GLuint dst_pitch, +- GLuint dst_offset, +- GLint srcx, GLint srcy, +- GLint dstx, GLint dsty, GLuint w, GLuint h); ++void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom); ++int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom); + +-extern void r300EmitWait(r300ContextPtr rmesa, GLuint flags); +-extern void r300EmitLOAD_VBPNTR(r300ContextPtr rmesa, int start); +-extern void r300EmitVertexShader(r300ContextPtr rmesa); +-extern void r300EmitPixelShader(r300ContextPtr rmesa); ++void emit_r500fp(GLcontext *ctx, struct radeon_state_atom * atom); ++int check_r500fp(GLcontext *ctx, struct radeon_state_atom *atom); ++int check_r500fp_const(GLcontext *ctx, struct radeon_state_atom *atom); + + #endif /* __R300_CMDBUF_H__ */ +diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c +index fddd87b..06db7ab 100644 +--- a/src/mesa/drivers/dri/r300/r300_context.c ++++ b/src/mesa/drivers/dri/r300/r300_context.c +@@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/extensions.h" + #include "main/state.h" + #include "main/bufferobj.h" ++#include "main/texobj.h" + + #include "swrast/swrast.h" + #include "swrast_setup/swrast_setup.h" +@@ -55,19 +56,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #include "drivers/common/driverfuncs.h" + +-#include "radeon_ioctl.h" +-#include "radeon_span.h" + #include "r300_context.h" ++#include "radeon_context.h" ++#include "radeon_span.h" + #include "r300_cmdbuf.h" + #include "r300_state.h" + #include "r300_ioctl.h" + #include "r300_tex.h" + #include "r300_emit.h" + #include "r300_swtcl.h" ++#include "radeon_bocs_wrapper.h" + +-#ifdef USER_BUFFERS +-#include "r300_mem.h" +-#endif + + #include "vblank.h" + #include "utils.h" +@@ -83,14 +82,17 @@ int hw_tcl_on = 1; + #define need_GL_EXT_blend_equation_separate + #define need_GL_EXT_blend_func_separate + #define need_GL_EXT_blend_minmax ++#define need_GL_EXT_framebuffer_object + #define need_GL_EXT_fog_coord + #define need_GL_EXT_gpu_program_parameters + #define need_GL_EXT_secondary_color + #define need_GL_EXT_stencil_two_side + #define need_GL_ATI_separate_stencil + #define need_GL_NV_vertex_program ++ + #include "extension_helper.h" + ++ + const struct dri_extension card_extensions[] = { + /* *INDENT-OFF* */ + {"GL_ARB_depth_texture", NULL}, +@@ -111,6 +113,7 @@ const struct dri_extension card_extensions[] = { + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, ++ {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, +@@ -138,6 +141,11 @@ const struct dri_extension card_extensions[] = { + }; + + ++const struct dri_extension mm_extensions[] = { ++ { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, ++ { NULL, NULL } ++}; ++ + /** + * The GL 2.0 functions are needed to make display lists work with + * functions added by GL_ATI_separate_stencil. +@@ -183,6 +191,91 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = { + 0, + }; + ++static void r300RunPipeline(GLcontext * ctx) ++{ ++ _mesa_lock_context_textures(ctx); ++ ++ if (ctx->NewState) ++ _mesa_update_state_locked(ctx); ++ ++ _tnl_run_pipeline(ctx); ++ _mesa_unlock_context_textures(ctx); ++} ++ ++static void r300_get_lock(radeonContextPtr rmesa) ++{ ++ drm_radeon_sarea_t *sarea = rmesa->sarea; ++ ++ if (sarea->ctx_owner != rmesa->dri.hwContext) { ++ sarea->ctx_owner = rmesa->dri.hwContext; ++ if (!rmesa->radeonScreen->kernel_mm) ++ radeon_bo_legacy_texture_age(rmesa->radeonScreen->bom); ++ } ++} ++ ++static void r300_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa) ++{ ++ /* please flush pipe do all pending work */ ++ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen, ++ R300_SC_SCREENDOOR, 1)); ++ radeon_cs_write_dword(cs, 0x0); ++ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen, ++ R300_SC_SCREENDOOR, 1)); ++ radeon_cs_write_dword(cs, 0x00FFFFFF); ++ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen, ++ R300_SC_HYPERZ, 1)); ++ radeon_cs_write_dword(cs, 0x0); ++ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen, ++ R300_US_CONFIG, 1)); ++ radeon_cs_write_dword(cs, 0x0); ++ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen, ++ R300_ZB_CNTL, 1)); ++ radeon_cs_write_dword(cs, 0x0); ++ radeon_cs_write_dword(cs, cmdwait(rmesa->radeonScreen, R300_WAIT_3D)); ++ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen, ++ R300_RB3D_DSTCACHE_CTLSTAT, 1)); ++ radeon_cs_write_dword(cs, R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); ++ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen, ++ R300_ZB_ZCACHE_CTLSTAT, 1)); ++ radeon_cs_write_dword(cs, R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE); ++ radeon_cs_write_dword(cs, cmdwait(rmesa->radeonScreen, ++ R300_WAIT_3D | R300_WAIT_3D_CLEAN)); ++} ++ ++static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon) ++{ ++ r300ContextPtr r300 = (r300ContextPtr)radeon; ++ BATCH_LOCALS(radeon); ++ ++ r300->vap_flush_needed = GL_TRUE; ++ ++ cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); ++ BEGIN_BATCH_NO_AUTOSTATE(2); ++ OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH); ++ END_BATCH(); ++ end_3d(radeon); ++} ++ ++static void r300_fallback(GLcontext *ctx, GLuint bit, GLboolean mode) ++{ ++ r300ContextPtr r300 = R300_CONTEXT(ctx); ++ if (mode) ++ r300->radeon.Fallback |= bit; ++ else ++ r300->radeon.Fallback &= ~bit; ++} ++ ++static void r300_init_vtbl(radeonContextPtr radeon) ++{ ++ radeon->vtbl.get_lock = r300_get_lock; ++ radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset; ++ radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header; ++ radeon->vtbl.swtcl_flush = r300_swtcl_flush; ++ radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms; ++ radeon->vtbl.fallback = r300_fallback; ++} ++ ++ + /* Create the device specific rendering context. + */ + GLboolean r300CreateContext(const __GLcontextModes * glVisual, +@@ -194,7 +287,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, + struct dd_function_table functions; + r300ContextPtr r300; + GLcontext *ctx; +- int tcl_mode, i; ++ int tcl_mode; + + assert(glVisual); + assert(driContextPriv); +@@ -208,13 +301,14 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, + if (!(screen->chip_flags & RADEON_CHIPSET_TCL)) + hw_tcl_on = future_hw_tcl_on = 0; + ++ r300_init_vtbl(&r300->radeon); + /* Parse configuration files. + * Do this here so that initialMaxAnisotropy is set before we create + * the default textures. + */ + driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache, + screen->driScreen->myNum, "r300"); +- r300->initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache, ++ r300->radeon.initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache, + "def_max_anisotropy"); + + /* Init default driver functions then plug in our R300-specific functions +@@ -226,10 +320,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, + r300InitTextureFuncs(&functions); + r300InitShaderFuncs(&functions); + +-#ifdef USER_BUFFERS +- r300_mem_init(r300); +-#endif +- + if (!radeonInitContext(&r300->radeon, &functions, + glVisual, driContextPriv, + sharedContextPrivate)) { +@@ -238,39 +328,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, + } + + /* Init r300 context data */ +- r300->dma.buf0_address = +- r300->radeon.radeonScreen->buffers->list[0].address; +- +- (void)memset(r300->texture_heaps, 0, sizeof(r300->texture_heaps)); +- make_empty_list(&r300->swapped); +- +- r300->nr_heaps = 1 /* screen->numTexHeaps */ ; +- assert(r300->nr_heaps < RADEON_NR_TEX_HEAPS); +- for (i = 0; i < r300->nr_heaps; i++) { +- /* *INDENT-OFF* */ +- r300->texture_heaps[i] = driCreateTextureHeap(i, r300, +- screen-> +- texSize[i], 12, +- RADEON_NR_TEX_REGIONS, +- (drmTextureRegionPtr) +- r300->radeon.sarea-> +- tex_list[i], +- &r300->radeon.sarea-> +- tex_age[i], +- &r300->swapped, +- sizeof +- (r300TexObj), +- (destroy_texture_object_t +- *) +- r300DestroyTexObj); +- /* *INDENT-ON* */ +- } +- r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache, +- "texture_depth"); +- if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) +- r300->texture_depth = (screen->cpp == 4) ? +- DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; +- + /* Set the maximum texture size small enough that we can guarentee that + * all texture units can bind a maximal texture and have them both in + * texturable memory at once. +@@ -303,13 +360,11 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, + ctx->Const.MaxLineWidth = R300_LINESIZE_MAX; + ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX; + +-#ifdef USER_BUFFERS + /* Needs further modifications */ + #if 0 + ctx->Const.MaxArrayLockSize = + ( /*512 */ RADEON_BUFFER_SIZE * 16 * 1024) / (4 * 4); + #endif +-#endif + + ctx->Const.MaxDrawBuffers = 1; + +@@ -365,6 +420,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; + + driInitExtensions(ctx, card_extensions, GL_TRUE); ++ if (r300->radeon.radeonScreen->kernel_mm) ++ driInitExtensions(ctx, mm_extensions, GL_FALSE); + + if (driQueryOptionb + (&r300->radeon.optionCache, "disable_stencil_two_side")) +@@ -383,14 +440,14 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, + r300->disable_lowimpact_fallback = + driQueryOptionb(&r300->radeon.optionCache, + "disable_lowimpact_fallback"); +- +- radeonInitSpanFuncs(ctx); ++ radeon_fbo_init(&r300->radeon); ++ radeonInitSpanFuncs( ctx ); + r300InitCmdBuf(r300); + r300InitState(r300); + if (!(screen->chip_flags & RADEON_CHIPSET_TCL)) + r300InitSwtcl(ctx); + +- TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; ++ TNL_CONTEXT(ctx)->Driver.RunPipeline = r300RunPipeline; + + tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode"); + if (driQueryOptionb(&r300->radeon.optionCache, "no_rast")) { +@@ -413,145 +470,3 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, + return GL_TRUE; + } + +-static void r300FreeGartAllocations(r300ContextPtr r300) +-{ +- int i, ret, tries = 0, done_age, in_use = 0; +- drm_radeon_mem_free_t memfree; +- +- memfree.region = RADEON_MEM_REGION_GART; +- +-#ifdef USER_BUFFERS +- for (i = r300->rmm->u_last; i > 0; i--) { +- if (r300->rmm->u_list[i].ptr == NULL) { +- continue; +- } +- +- /* check whether this buffer is still in use */ +- if (r300->rmm->u_list[i].pending) { +- in_use++; +- } +- } +- /* Cannot flush/lock if no context exists. */ +- if (in_use) +- r300FlushCmdBuf(r300, __FUNCTION__); +- +- done_age = radeonGetAge((radeonContextPtr) r300); +- +- for (i = r300->rmm->u_last; i > 0; i--) { +- if (r300->rmm->u_list[i].ptr == NULL) { +- continue; +- } +- +- /* check whether this buffer is still in use */ +- if (!r300->rmm->u_list[i].pending) { +- continue; +- } +- +- assert(r300->rmm->u_list[i].h_pending == 0); +- +- tries = 0; +- while (r300->rmm->u_list[i].age > done_age && tries++ < 1000) { +- usleep(10); +- done_age = radeonGetAge((radeonContextPtr) r300); +- } +- if (tries >= 1000) { +- WARN_ONCE("Failed to idle region!"); +- } +- +- memfree.region_offset = (char *)r300->rmm->u_list[i].ptr - +- (char *)r300->radeon.radeonScreen->gartTextures.map; +- +- ret = drmCommandWrite(r300->radeon.radeonScreen->driScreen->fd, +- DRM_RADEON_FREE, &memfree, +- sizeof(memfree)); +- if (ret) { +- fprintf(stderr, "Failed to free at %p\nret = %s\n", +- r300->rmm->u_list[i].ptr, strerror(-ret)); +- } else { +- if (i == r300->rmm->u_last) +- r300->rmm->u_last--; +- +- r300->rmm->u_list[i].pending = 0; +- r300->rmm->u_list[i].ptr = NULL; +- } +- } +- r300->rmm->u_head = i; +-#endif /* USER_BUFFERS */ +-} +- +-/* Destroy the device specific context. +- */ +-void r300DestroyContext(__DRIcontextPrivate * driContextPriv) +-{ +- GET_CURRENT_CONTEXT(ctx); +- r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate; +- radeonContextPtr radeon = (radeonContextPtr) r300; +- radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL; +- +- if (RADEON_DEBUG & DEBUG_DRI) { +- fprintf(stderr, "Destroying context !\n"); +- } +- +- /* check if we're deleting the currently bound context */ +- if (&r300->radeon == current) { +- radeonFlush(r300->radeon.glCtx); +- _mesa_make_current(NULL, NULL, NULL); +- } +- +- /* Free r300 context resources */ +- assert(r300); /* should never be null */ +- +- if (r300) { +- GLboolean release_texture_heaps; +- +- release_texture_heaps = +- (r300->radeon.glCtx->Shared->RefCount == 1); +- _swsetup_DestroyContext(r300->radeon.glCtx); +- _tnl_DestroyContext(r300->radeon.glCtx); +- _vbo_DestroyContext(r300->radeon.glCtx); +- _swrast_DestroyContext(r300->radeon.glCtx); +- +- if (r300->dma.current.buf) { +- r300ReleaseDmaRegion(r300, &r300->dma.current, +- __FUNCTION__); +-#ifndef USER_BUFFERS +- r300FlushCmdBuf(r300, __FUNCTION__); +-#endif +- } +- r300FreeGartAllocations(r300); +- r300DestroyCmdBuf(r300); +- +- if (radeon->state.scissor.pClipRects) { +- FREE(radeon->state.scissor.pClipRects); +- radeon->state.scissor.pClipRects = NULL; +- } +- +- if (release_texture_heaps) { +- /* This share group is about to go away, free our private +- * texture object data. +- */ +- int i; +- +- for (i = 0; i < r300->nr_heaps; i++) { +- driDestroyTextureHeap(r300->texture_heaps[i]); +- r300->texture_heaps[i] = NULL; +- } +- +- assert(is_empty_list(&r300->swapped)); +- } +- +- radeonCleanupContext(&r300->radeon); +- +-#ifdef USER_BUFFERS +- /* the memory manager might be accessed when Mesa frees the shared +- * state, so don't destroy it earlier +- */ +- r300_mem_destroy(r300); +-#endif +- +- /* free the option cache */ +- driDestroyOptionCache(&r300->radeon.optionCache); +- +- FREE(r300); +- } +-} +diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h +index c15e9fa..5ef59d2 100644 +--- a/src/mesa/drivers/dri/r300/r300_context.h ++++ b/src/mesa/drivers/dri/r300/r300_context.h +@@ -42,21 +42,20 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "radeon_drm.h" + #include "dri_util.h" + #include "texmem.h" ++#include "radeon_common.h" + + #include "main/macros.h" + #include "main/mtypes.h" + #include "main/colormac.h" + +-#define USER_BUFFERS +- + struct r300_context; + typedef struct r300_context r300ContextRec; + typedef struct r300_context *r300ContextPtr; + +-#include "radeon_lock.h" ++ + #include "main/mm.h" + +-/* From http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html . ++/* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html . + I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble + with other compilers ... GLUE! + */ +@@ -75,174 +74,19 @@ typedef struct r300_context *r300ContextPtr; + #include "r300_vertprog.h" + #include "r500_fragprog.h" + +-/** +- * This function takes a float and packs it into a uint32_t +- */ +-static INLINE uint32_t r300PackFloat32(float fl) +-{ +- union { +- float fl; +- uint32_t u; +- } u; +- +- u.fl = fl; +- return u.u; +-} +- +-/* This is probably wrong for some values, I need to test this +- * some more. Range checking would be a good idea also.. +- * +- * But it works for most things. I'll fix it later if someone +- * else with a better clue doesn't +- */ +-static INLINE uint32_t r300PackFloat24(float f) +-{ +- float mantissa; +- int exponent; +- uint32_t float24 = 0; +- +- if (f == 0.0) +- return 0; + +- mantissa = frexpf(f, &exponent); +- +- /* Handle -ve */ +- if (mantissa < 0) { +- float24 |= (1 << 23); +- mantissa = mantissa * -1.0; +- } +- /* Handle exponent, bias of 63 */ +- exponent += 62; +- float24 |= (exponent << 16); +- /* Kill 7 LSB of mantissa */ +- float24 |= (r300PackFloat32(mantissa) & 0x7FFFFF) >> 7; +- +- return float24; +-} + + /************ DMA BUFFERS **************/ + +-/* Need refcounting on dma buffers: +- */ +-struct r300_dma_buffer { +- int refcount; /**< the number of retained regions in buf */ +- drmBufPtr buf; +- int id; +-}; +-#undef GET_START +-#ifdef USER_BUFFERS +-#define GET_START(rvb) (r300GartOffsetFromVirtual(rmesa, (rvb)->address+(rvb)->start)) +-#else +-#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \ +- (rvb)->address - rmesa->dma.buf0_address + \ +- (rvb)->start) +-#endif +-/* A retained region, eg vertices for indexed vertices. +- */ +-struct r300_dma_region { +- struct r300_dma_buffer *buf; +- char *address; /* == buf->address */ +- int start, end, ptr; /* offsets from start of buf */ +- +- int aos_offset; /* address in GART memory */ +- int aos_stride; /* distance between elements, in dwords */ +- int aos_size; /* number of components (1-4) */ +-}; +- +-struct r300_dma { +- /* Active dma region. Allocations for vertices and retained +- * regions come from here. Also used for emitting random vertices, +- * these may be flushed by calling flush_current(); +- */ +- struct r300_dma_region current; +- +- void (*flush) (r300ContextPtr); +- +- char *buf0_address; /* start of buf[0], for index calcs */ +- +- /* Number of "in-flight" DMA buffers, i.e. the number of buffers +- * for which a DISCARD command is currently queued in the command buffer. +- */ +- GLuint nr_released_bufs; +-}; +- +- /* Texture related */ +- +-typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr; +- +-/* Texture object in locally shared texture space. +- */ +-struct r300_tex_obj { +- driTextureObject base; +- +- GLuint bufAddr; /* Offset to start of locally +- shared texture block */ +- +- drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; +- /* Six, for the cube faces */ +- +- GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ +- +- GLuint pitch; /* this isn't sent to hardware just used in calculations */ +- /* hardware register values */ +- /* Note that R200 has 8 registers per texture and R300 only 7 */ +- GLuint filter; +- GLuint filter_1; +- GLuint pitch_reg; +- GLuint size; /* npot only */ +- GLuint format; +- GLuint offset; /* Image location in the card's address space. +- All cube faces follow. */ +- GLuint unknown4; +- GLuint unknown5; +- /* end hardware registers */ +- +- /* registers computed by r200 code - keep them here to +- compare against what is actually written. +- +- to be removed later.. */ +- GLuint pp_border_color; +- GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ +- GLuint format_x; +- +- GLboolean border_fallback; +- +- GLuint tile_bits; /* hw texture tile bits used on this texture */ +-}; +- +-struct r300_texture_env_state { +- r300TexObjPtr texobj; +- GLenum format; +- GLenum envMode; +-}; +- + /* The blit width for texture uploads + */ + #define R300_BLIT_WIDTH_BYTES 1024 + #define R300_MAX_TEXTURE_UNITS 8 + + struct r300_texture_state { +- struct r300_texture_env_state unit[R300_MAX_TEXTURE_UNITS]; + int tc_count; /* number of incoming texture coordinates from VAP */ + }; + +-/** +- * A block of hardware state. +- * +- * When check returns non-zero, the returned number of dwords must be +- * copied verbatim into the command buffer in order to update a state atom +- * when it is dirty. +- */ +-struct r300_state_atom { +- struct r300_state_atom *next, *prev; +- const char *name; /* for debug */ +- int cmd_size; /* maximum size in dwords */ +- GLuint idx; /* index in an array (e.g. textures) */ +- uint32_t *cmd; +- GLboolean dirty; +- +- int (*check) (r300ContextPtr, struct r300_state_atom * atom); +-}; + + #define R300_VPT_CMD_0 0 + #define R300_VPT_XSCALE 1 +@@ -459,124 +303,98 @@ struct r300_state_atom { + * Cache for hardware register state. + */ + struct r300_hw_state { +- struct r300_state_atom atomlist; +- +- GLboolean is_dirty; +- GLboolean all_dirty; +- int max_state_size; /* in dwords */ +- +- struct r300_state_atom vpt; /* viewport (1D98) */ +- struct r300_state_atom vap_cntl; +- struct r300_state_atom vap_index_offset; /* 0x208c r5xx only */ +- struct r300_state_atom vof; /* VAP output format register 0x2090 */ +- struct r300_state_atom vte; /* (20B0) */ +- struct r300_state_atom vap_vf_max_vtx_indx; /* Maximum Vertex Indx Clamp (2134) */ +- struct r300_state_atom vap_cntl_status; +- struct r300_state_atom vir[2]; /* vap input route (2150/21E0) */ +- struct r300_state_atom vic; /* vap input control (2180) */ +- struct r300_state_atom vap_psc_sgn_norm_cntl; /* Programmable Stream Control Signed Normalize Control (21DC) */ +- struct r300_state_atom vap_clip_cntl; +- struct r300_state_atom vap_clip; +- struct r300_state_atom vap_pvs_vtx_timeout_reg; /* Vertex timeout register (2288) */ +- struct r300_state_atom pvs; /* pvs_cntl (22D0) */ +- struct r300_state_atom gb_enable; /* (4008) */ +- struct r300_state_atom gb_misc; /* Multisampling position shifts ? (4010) */ +- struct r300_state_atom ga_point_s0; /* S Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) (4200) */ +- struct r300_state_atom ga_triangle_stipple; /* (4214) */ +- struct r300_state_atom ps; /* pointsize (421C) */ +- struct r300_state_atom ga_point_minmax; /* (4230) */ +- struct r300_state_atom lcntl; /* line control */ +- struct r300_state_atom ga_line_stipple; /* (4260) */ +- struct r300_state_atom shade; +- struct r300_state_atom polygon_mode; +- struct r300_state_atom fogp; /* fog parameters (4294) */ +- struct r300_state_atom ga_soft_reset; /* (429C) */ +- struct r300_state_atom zbias_cntl; +- struct r300_state_atom zbs; /* zbias (42A4) */ +- struct r300_state_atom occlusion_cntl; +- struct r300_state_atom cul; /* cull cntl (42B8) */ +- struct r300_state_atom su_depth_scale; /* (42C0) */ +- struct r300_state_atom rc; /* rs control (4300) */ +- struct r300_state_atom ri; /* rs interpolators (4310) */ +- struct r300_state_atom rr; /* rs route (4330) */ +- struct r300_state_atom sc_hyperz; /* (43A4) */ +- struct r300_state_atom sc_screendoor; /* (43E8) */ +- struct r300_state_atom fp; /* fragment program cntl + nodes (4600) */ +- struct r300_state_atom fpt; /* texi - (4620) */ +- struct r300_state_atom us_out_fmt; /* (46A4) */ +- struct r300_state_atom r500fp; /* r500 fp instructions */ +- struct r300_state_atom r500fp_const; /* r500 fp constants */ +- struct r300_state_atom fpi[4]; /* fp instructions (46C0/47C0/48C0/49C0) */ +- struct r300_state_atom fogs; /* fog state (4BC0) */ +- struct r300_state_atom fogc; /* fog color (4BC8) */ +- struct r300_state_atom at; /* alpha test (4BD4) */ +- struct r300_state_atom fg_depth_src; /* (4BD8) */ +- struct r300_state_atom fpp; /* 0x4C00 and following */ +- struct r300_state_atom rb3d_cctl; /* (4E00) */ +- struct r300_state_atom bld; /* blending (4E04) */ +- struct r300_state_atom cmk; /* colormask (4E0C) */ +- struct r300_state_atom blend_color; /* constant blend color */ +- struct r300_state_atom rop; /* ropcntl */ +- struct r300_state_atom cb; /* colorbuffer (4E28) */ +- struct r300_state_atom rb3d_dither_ctl; /* (4E50) */ +- struct r300_state_atom rb3d_aaresolve_ctl; /* (4E88) */ +- struct r300_state_atom rb3d_discard_src_pixel_lte_threshold; /* (4E88) I saw it only written on RV350 hardware.. */ +- struct r300_state_atom zs; /* zstencil control (4F00) */ +- struct r300_state_atom zstencil_format; +- struct r300_state_atom zb; /* z buffer (4F20) */ +- struct r300_state_atom zb_depthclearvalue; /* (4F28) */ +- struct r300_state_atom unk4F30; /* (4F30) */ +- struct r300_state_atom zb_hiz_offset; /* (4F44) */ +- struct r300_state_atom zb_hiz_pitch; /* (4F54) */ +- +- struct r300_state_atom vpi; /* vp instructions */ +- struct r300_state_atom vpp; /* vp parameters */ +- struct r300_state_atom vps; /* vertex point size (?) */ +- struct r300_state_atom vpucp[6]; /* vp user clip plane - 6 */ ++ struct radeon_state_atom vpt; /* viewport (1D98) */ ++ struct radeon_state_atom vap_cntl; ++ struct radeon_state_atom vap_index_offset; /* 0x208c r5xx only */ ++ struct radeon_state_atom vof; /* VAP output format register 0x2090 */ ++ struct radeon_state_atom vte; /* (20B0) */ ++ struct radeon_state_atom vap_vf_max_vtx_indx; /* Maximum Vertex Indx Clamp (2134) */ ++ struct radeon_state_atom vap_cntl_status; ++ struct radeon_state_atom vir[2]; /* vap input route (2150/21E0) */ ++ struct radeon_state_atom vic; /* vap input control (2180) */ ++ struct radeon_state_atom vap_psc_sgn_norm_cntl; /* Programmable Stream Control Signed Normalize Control (21DC) */ ++ struct radeon_state_atom vap_clip_cntl; ++ struct radeon_state_atom vap_clip; ++ struct radeon_state_atom vap_pvs_vtx_timeout_reg; /* Vertex timeout register (2288) */ ++ struct radeon_state_atom pvs; /* pvs_cntl (22D0) */ ++ struct radeon_state_atom gb_enable; /* (4008) */ ++ struct radeon_state_atom gb_misc; /* Multisampling position shifts ? (4010) */ ++ struct radeon_state_atom ga_point_s0; /* S Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) (4200) */ ++ struct radeon_state_atom ga_triangle_stipple; /* (4214) */ ++ struct radeon_state_atom ps; /* pointsize (421C) */ ++ struct radeon_state_atom ga_point_minmax; /* (4230) */ ++ struct radeon_state_atom lcntl; /* line control */ ++ struct radeon_state_atom ga_line_stipple; /* (4260) */ ++ struct radeon_state_atom shade; ++ struct radeon_state_atom polygon_mode; ++ struct radeon_state_atom fogp; /* fog parameters (4294) */ ++ struct radeon_state_atom ga_soft_reset; /* (429C) */ ++ struct radeon_state_atom zbias_cntl; ++ struct radeon_state_atom zbs; /* zbias (42A4) */ ++ struct radeon_state_atom occlusion_cntl; ++ struct radeon_state_atom cul; /* cull cntl (42B8) */ ++ struct radeon_state_atom su_depth_scale; /* (42C0) */ ++ struct radeon_state_atom rc; /* rs control (4300) */ ++ struct radeon_state_atom ri; /* rs interpolators (4310) */ ++ struct radeon_state_atom rr; /* rs route (4330) */ ++ struct radeon_state_atom sc_hyperz; /* (43A4) */ ++ struct radeon_state_atom sc_screendoor; /* (43E8) */ ++ struct radeon_state_atom fp; /* fragment program cntl + nodes (4600) */ ++ struct radeon_state_atom fpt; /* texi - (4620) */ ++ struct radeon_state_atom us_out_fmt; /* (46A4) */ ++ struct radeon_state_atom r500fp; /* r500 fp instructions */ ++ struct radeon_state_atom r500fp_const; /* r500 fp constants */ ++ struct radeon_state_atom fpi[4]; /* fp instructions (46C0/47C0/48C0/49C0) */ ++ struct radeon_state_atom fogs; /* fog state (4BC0) */ ++ struct radeon_state_atom fogc; /* fog color (4BC8) */ ++ struct radeon_state_atom at; /* alpha test (4BD4) */ ++ struct radeon_state_atom fg_depth_src; /* (4BD8) */ ++ struct radeon_state_atom fpp; /* 0x4C00 and following */ ++ struct radeon_state_atom rb3d_cctl; /* (4E00) */ ++ struct radeon_state_atom bld; /* blending (4E04) */ ++ struct radeon_state_atom cmk; /* colormask (4E0C) */ ++ struct radeon_state_atom blend_color; /* constant blend color */ ++ struct radeon_state_atom rop; /* ropcntl */ ++ struct radeon_state_atom cb; /* colorbuffer (4E28) */ ++ struct radeon_state_atom rb3d_dither_ctl; /* (4E50) */ ++ struct radeon_state_atom rb3d_aaresolve_ctl; /* (4E88) */ ++ struct radeon_state_atom rb3d_discard_src_pixel_lte_threshold; /* (4E88) I saw it only written on RV350 hardware.. */ ++ struct radeon_state_atom zs; /* zstencil control (4F00) */ ++ struct radeon_state_atom zstencil_format; ++ struct radeon_state_atom zb; /* z buffer (4F20) */ ++ struct radeon_state_atom zb_depthclearvalue; /* (4F28) */ ++ struct radeon_state_atom unk4F30; /* (4F30) */ ++ struct radeon_state_atom zb_hiz_offset; /* (4F44) */ ++ struct radeon_state_atom zb_hiz_pitch; /* (4F54) */ ++ ++ struct radeon_state_atom vpi; /* vp instructions */ ++ struct radeon_state_atom vpp; /* vp parameters */ ++ struct radeon_state_atom vps; /* vertex point size (?) */ ++ struct radeon_state_atom vpucp[6]; /* vp user clip plane - 6 */ + /* 8 texture units */ + /* the state is grouped by function and not by + texture unit. This makes single unit updates + really awkward - we are much better off + updating the whole thing at once */ + struct { +- struct r300_state_atom filter; +- struct r300_state_atom filter_1; +- struct r300_state_atom size; +- struct r300_state_atom format; +- struct r300_state_atom pitch; +- struct r300_state_atom offset; +- struct r300_state_atom chroma_key; +- struct r300_state_atom border_color; ++ struct radeon_state_atom filter; ++ struct radeon_state_atom filter_1; ++ struct radeon_state_atom size; ++ struct radeon_state_atom format; ++ struct radeon_state_atom pitch; ++ struct radeon_state_atom offset; ++ struct radeon_state_atom chroma_key; ++ struct radeon_state_atom border_color; + } tex; +- struct r300_state_atom txe; /* tex enable (4104) */ +-}; ++ struct radeon_state_atom txe; /* tex enable (4104) */ + +-/** +- * This structure holds the command buffer while it is being constructed. +- * +- * The first batch of commands in the buffer is always the state that needs +- * to be re-emitted when the context is lost. This batch can be skipped +- * otherwise. +- */ +-struct r300_cmdbuf { +- int size; /* DWORDs allocated for buffer */ +- uint32_t *cmd_buf; +- int count_used; /* DWORDs filled so far */ +- int count_reemit; /* size of re-emission batch */ ++ radeonTexObj *textures[R300_MAX_TEXTURE_UNITS]; + }; + + /** + * State cache + */ + +-struct r300_depthbuffer_state { +- GLfloat scale; +-}; +- +-struct r300_stencilbuffer_state { +- GLboolean hw_stencil; +-}; +- + /* Vertex shader state */ + + /* Perhaps more if we store programs in vmem? */ +@@ -812,22 +630,14 @@ struct r500_fragment_program { + #define REG_TEX0 2 + + struct r300_state { +- struct r300_depthbuffer_state depth; + struct r300_texture_state texture; + int sw_tcl_inputs[VERT_ATTRIB_MAX]; + struct r300_vertex_shader_state vertex_shader; +- struct r300_dma_region aos[R300_MAX_AOS_ARRAYS]; +- int aos_count; + +- GLuint *Elts; +- struct r300_dma_region elt_dma; + +- struct r300_dma_region swtcl_dma; + DECLARE_RENDERINPUTS(render_inputs_bitset); /* actual render inputs that R300 was configured for. + They are the same as tnl->render_inputs for fixed pipeline */ + +- struct r300_stencilbuffer_state stencil; +- + }; + + #define R300_FALLBACK_NONE 0 +@@ -837,41 +647,7 @@ struct r300_state { + /* r300_swtcl.c + */ + struct r300_swtcl_info { +- GLuint RenderIndex; +- +- /** +- * Size of a hardware vertex. This is calculated when \c ::vertex_attrs is +- * installed in the Mesa state vector. +- */ +- GLuint vertex_size; +- +- /** +- * Attributes instructing the Mesa TCL pipeline where / how to put vertex +- * data in the hardware buffer. +- */ +- struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; +- +- /** +- * Number of elements of \c ::vertex_attrs that are actually used. +- */ +- GLuint vertex_attr_count; +- +- /** +- * Cached pointer to the buffer where Mesa will store vertex data. +- */ +- GLubyte *verts; +- +- /* Fallback rasterization functions +- */ +- // r200_point_func draw_point; +- // r200_line_func draw_line; +- // r200_tri_func draw_tri; +- +- GLuint hw_primitive; +- GLenum render_primitive; +- GLuint numverts; +- +- /** ++ /* + * Offset of the 4UB color data within a hardware (swtcl) vertex. + */ + GLuint coloroffset; +@@ -880,13 +656,6 @@ struct r300_swtcl_info { + * Offset of the 3UB specular color data within a hardware (swtcl) vertex. + */ + GLuint specoffset; +- +- /** +- * Should Mesa project vertex data or will the hardware do it? +- */ +- GLboolean needproj; +- +- struct r300_dma_region indexed_verts; + }; + + +@@ -897,40 +666,22 @@ struct r300_context { + struct radeon_context radeon; /* parent class, must be first */ + + struct r300_hw_state hw; +- struct r300_cmdbuf cmdbuf; ++ + struct r300_state state; + struct gl_vertex_program *curr_vp; + struct r300_vertex_program *selected_vp; + + /* Vertex buffers + */ +- struct r300_dma dma; +- GLboolean save_on_next_unlock; +- GLuint NewGLState; +- +- /* Texture object bookkeeping +- */ +- unsigned nr_heaps; +- driTexHeap *texture_heaps[RADEON_NR_TEX_HEAPS]; +- driTextureObject swapped; +- int texture_depth; +- float initialMaxAnisotropy; +- +- /* Clientdata textures; +- */ +- GLuint prefer_gart_client_texturing; +- +-#ifdef USER_BUFFERS +- struct r300_memory_manager *rmm; +-#endif +- + GLvector4f dummy_attrib[_TNL_ATTRIB_MAX]; + GLvector4f *temp_attrib[_TNL_ATTRIB_MAX]; + + GLboolean disable_lowimpact_fallback; + + DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ ++ + struct r300_swtcl_info swtcl; ++ GLboolean vap_flush_needed; + }; + + struct r300_buffer_object { +@@ -956,4 +707,7 @@ extern int r300VertexProgUpdateParams(GLcontext * ctx, + #define RADEON_D_PLAYBACK_RAW 2 + #define RADEON_D_T 3 + ++#define r300PackFloat32 radeonPackFloat32 ++#define r300PackFloat24 radeonPackFloat24 ++ + #endif /* __R300_CONTEXT_H__ */ +diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c +index 28c3157..bcf8803 100644 +--- a/src/mesa/drivers/dri/r300/r300_emit.c ++++ b/src/mesa/drivers/dri/r300/r300_emit.c +@@ -46,14 +46,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "tnl/t_context.h" + + #include "r300_context.h" +-#include "radeon_ioctl.h" + #include "r300_state.h" + #include "r300_emit.h" + #include "r300_ioctl.h" + +-#ifdef USER_BUFFERS +-#include "r300_mem.h" +-#endif + + #if SWIZZLE_X != R300_INPUT_ROUTE_SELECT_X || \ + SWIZZLE_Y != R300_INPUT_ROUTE_SELECT_Y || \ +@@ -66,147 +62,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #define DEBUG_ALL DEBUG_VERTS + +-#if defined(USE_X86_ASM) +-#define COPY_DWORDS( dst, src, nr ) \ +-do { \ +- int __tmp; \ +- __asm__ __volatile__( "rep ; movsl" \ +- : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ +- : "0" (nr), \ +- "D" ((long)dst), \ +- "S" ((long)src) ); \ +-} while (0) +-#else +-#define COPY_DWORDS( dst, src, nr ) \ +-do { \ +- int j; \ +- for ( j = 0 ; j < nr ; j++ ) \ +- dst[j] = ((int *)src)[j]; \ +- dst += nr; \ +-} while (0) +-#endif +- +-static void r300EmitVec4(GLcontext * ctx, struct r300_dma_region *rvb, +- GLvoid * data, int stride, int count) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d out %p data %p\n", +- __FUNCTION__, count, stride, (void *)out, (void *)data); +- +- if (stride == 4) +- COPY_DWORDS(out, data, count); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out++; +- data += stride; +- } +-} +- +-static void r300EmitVec8(GLcontext * ctx, struct r300_dma_region *rvb, +- GLvoid * data, int stride, int count) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d out %p data %p\n", +- __FUNCTION__, count, stride, (void *)out, (void *)data); +- +- if (stride == 8) +- COPY_DWORDS(out, data, count * 2); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out[1] = *(int *)(data + 4); +- out += 2; +- data += stride; +- } +-} +- +-static void r300EmitVec12(GLcontext * ctx, struct r300_dma_region *rvb, +- GLvoid * data, int stride, int count) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d out %p data %p\n", +- __FUNCTION__, count, stride, (void *)out, (void *)data); +- +- if (stride == 12) +- COPY_DWORDS(out, data, count * 3); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out[1] = *(int *)(data + 4); +- out[2] = *(int *)(data + 8); +- out += 3; +- data += stride; +- } +-} +- +-static void r300EmitVec16(GLcontext * ctx, struct r300_dma_region *rvb, +- GLvoid * data, int stride, int count) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d out %p data %p\n", +- __FUNCTION__, count, stride, (void *)out, (void *)data); +- +- if (stride == 16) +- COPY_DWORDS(out, data, count * 4); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out[1] = *(int *)(data + 4); +- out[2] = *(int *)(data + 8); +- out[3] = *(int *)(data + 12); +- out += 4; +- data += stride; +- } +-} +- +-static void r300EmitVec(GLcontext * ctx, struct r300_dma_region *rvb, +- GLvoid * data, int size, int stride, int count) +-{ +- r300ContextPtr rmesa = R300_CONTEXT(ctx); +- +- if (stride == 0) { +- r300AllocDmaRegion(rmesa, rvb, size * 4, 4); +- count = 1; +- rvb->aos_offset = GET_START(rvb); +- rvb->aos_stride = 0; +- } else { +- r300AllocDmaRegion(rmesa, rvb, size * count * 4, 4); +- rvb->aos_offset = GET_START(rvb); +- rvb->aos_stride = size; +- } +- +- switch (size) { +- case 1: +- r300EmitVec4(ctx, rvb, data, stride, count); +- break; +- case 2: +- r300EmitVec8(ctx, rvb, data, stride, count); +- break; +- case 3: +- r300EmitVec12(ctx, rvb, data, stride, count); +- break; +- case 4: +- r300EmitVec16(ctx, rvb, data, stride, count); +- break; +- default: +- assert(0); +- break; +- } +-} +- + #define DW_SIZE(x) ((inputs[tab[(x)]] << R300_DST_VEC_LOC_SHIFT) | \ + (attribptr[tab[(x)]]->size - 1) << R300_DATA_TYPE_0_SHIFT) + +@@ -376,7 +231,6 @@ int r300EmitArrays(GLcontext * ctx) + + assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)); + assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_NORMAL) == 0); +- //assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0)); + + if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)) { + InputsRead |= 1 << VERT_ATTRIB_POS; +@@ -438,7 +292,7 @@ int r300EmitArrays(GLcontext * ctx) + } + + for (i = 0; i < nr; i++) { +- int ci, fix, found = 0; ++ int ci; + + swizzle[i][0] = SWIZZLE_ZERO; + swizzle[i][1] = SWIZZLE_ZERO; +@@ -448,61 +302,35 @@ int r300EmitArrays(GLcontext * ctx) + for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++) { + swizzle[i][ci] = ci; + } +- +- if (r300IsGartMemory(rmesa, vb->AttribPtr[tab[i]]->data, 4)) { +- if (vb->AttribPtr[tab[i]]->stride % 4) { +- return R300_FALLBACK_TCL; +- } +- rmesa->state.aos[i].address = (void *)(vb->AttribPtr[tab[i]]->data); +- rmesa->state.aos[i].start = 0; +- rmesa->state.aos[i].aos_offset = r300GartOffsetFromVirtual(rmesa, vb->AttribPtr[tab[i]]->data); +- rmesa->state.aos[i].aos_stride = vb->AttribPtr[tab[i]]->stride / 4; +- rmesa->state.aos[i].aos_size = vb->AttribPtr[tab[i]]->size; +- } else { +- r300EmitVec(ctx, &rmesa->state.aos[i], ++ rcommon_emit_vector(ctx, &rmesa->radeon.tcl.aos[i], + vb->AttribPtr[tab[i]]->data, + vb->AttribPtr[tab[i]]->size, + vb->AttribPtr[tab[i]]->stride, count); +- } +- +- rmesa->state.aos[i].aos_size = vb->AttribPtr[tab[i]]->size; +- +- for (fix = 0; fix <= 4 - vb->AttribPtr[tab[i]]->size; fix++) { +- if ((rmesa->state.aos[i].aos_offset - _mesa_sizeof_type(GL_FLOAT) * fix) % 4) { +- continue; +- } +- found = 1; +- break; +- } +- +- if (found) { +- if (fix > 0) { +- WARN_ONCE("Feeling lucky?\n"); +- } +- rmesa->state.aos[i].aos_offset -= _mesa_sizeof_type(GL_FLOAT) * fix; +- for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++) { +- swizzle[i][ci] += fix; +- } +- } else { +- WARN_ONCE +- ("Cannot handle offset %x with stride %d, comp %d\n", +- rmesa->state.aos[i].aos_offset, +- rmesa->state.aos[i].aos_stride, +- vb->AttribPtr[tab[i]]->size); +- return R300_FALLBACK_TCL; +- } + } + + /* Setup INPUT_ROUTE. */ +- R300_STATECHANGE(rmesa, vir[0]); +- ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = +- r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], +- vb->AttribPtr, inputs, tab, nr); +- R300_STATECHANGE(rmesa, vir[1]); +- ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = +- r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, +- nr); +- ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ R300_STATECHANGE(rmesa, vir[0]); ++ rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF; ++ rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF; ++ rmesa->hw.vir[0].cmd[0] |= ++ (r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], ++ vb->AttribPtr, inputs, tab, nr) & 0x3FFF) << 16; ++ R300_STATECHANGE(rmesa, vir[1]); ++ rmesa->hw.vir[1].cmd[0] |= ++ (r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, ++ nr) & 0x3FFF) << 16; ++ } else { ++ R300_STATECHANGE(rmesa, vir[0]); ++ ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = ++ r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], ++ vb->AttribPtr, inputs, tab, nr); ++ R300_STATECHANGE(rmesa, vir[1]); ++ ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = ++ r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, ++ nr); ++ } ++ + /* Setup INPUT_CNTL. */ + R300_STATECHANGE(rmesa, vic); + rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead); +@@ -515,50 +343,22 @@ int r300EmitArrays(GLcontext * ctx) + rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = + r300VAPOutputCntl1(ctx, OutputsWritten); + +- rmesa->state.aos_count = nr; ++ rmesa->radeon.tcl.aos_count = nr; + + return R300_FALLBACK_NONE; + } + +-#ifdef USER_BUFFERS +-void r300UseArrays(GLcontext * ctx) +-{ +- r300ContextPtr rmesa = R300_CONTEXT(ctx); +- int i; +- +- if (rmesa->state.elt_dma.buf) +- r300_mem_use(rmesa, rmesa->state.elt_dma.buf->id); +- +- for (i = 0; i < rmesa->state.aos_count; i++) { +- if (rmesa->state.aos[i].buf) +- r300_mem_use(rmesa, rmesa->state.aos[i].buf->id); +- } +-} +-#endif +- +-void r300ReleaseArrays(GLcontext * ctx) +-{ +- r300ContextPtr rmesa = R300_CONTEXT(ctx); +- int i; +- +- r300ReleaseDmaRegion(rmesa, &rmesa->state.elt_dma, __FUNCTION__); +- for (i = 0; i < rmesa->state.aos_count; i++) { +- r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__); +- } +-} +- + void r300EmitCacheFlush(r300ContextPtr rmesa) + { +- int cmd_reserved = 0; +- int cmd_written = 0; +- +- drm_radeon_cmd_header_t *cmd = NULL; +- +- reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0); +- e32(R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | +- R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); +- +- reg_start(R300_ZB_ZCACHE_CTLSTAT, 0); +- e32(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | +- R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); ++ BATCH_LOCALS(&rmesa->radeon); ++ ++ BEGIN_BATCH_NO_AUTOSTATE(4); ++ OUT_BATCH_REGVAL(R300_RB3D_DSTCACHE_CTLSTAT, ++ R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | ++ R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); ++ OUT_BATCH_REGVAL(R300_ZB_ZCACHE_CTLSTAT, ++ R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | ++ R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); ++ END_BATCH(); ++ COMMIT_BATCH(); + } +diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h +index 89d7383..80c22d5 100644 +--- a/src/mesa/drivers/dri/r300/r300_emit.h ++++ b/src/mesa/drivers/dri/r300/r300_emit.h +@@ -44,28 +44,31 @@ + #include "r300_cmdbuf.h" + #include "radeon_reg.h" + +-/* TODO: move these defines (and the ones from DRM) into r300_reg.h and sync up +- * with DRM */ +-#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) +-#define CP_PACKET3( pkt, n ) \ +- (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) +- +-static INLINE uint32_t cmdpacket0(int reg, int count) ++static INLINE uint32_t cmdpacket0(struct radeon_screen *rscrn, ++ int reg, int count) + { +- drm_r300_cmd_header_t cmd; +- +- cmd.packet0.cmd_type = R300_CMD_PACKET0; +- cmd.packet0.count = count; +- cmd.packet0.reghi = ((unsigned int)reg & 0xFF00) >> 8; +- cmd.packet0.reglo = ((unsigned int)reg & 0x00FF); +- +- return cmd.u; ++ if (!rscrn->kernel_mm) { ++ drm_r300_cmd_header_t cmd; ++ ++ cmd.u = 0; ++ cmd.packet0.cmd_type = R300_CMD_PACKET0; ++ cmd.packet0.count = count; ++ cmd.packet0.reghi = ((unsigned int)reg & 0xFF00) >> 8; ++ cmd.packet0.reglo = ((unsigned int)reg & 0x00FF); ++ ++ return cmd.u; ++ } ++ if (count) { ++ return CP_PACKET0(reg, count - 1); ++ } ++ return CP_PACKET2; + } + +-static INLINE uint32_t cmdvpu(int addr, int count) ++static INLINE uint32_t cmdvpu(struct radeon_screen *rscrn, int addr, int count) + { + drm_r300_cmd_header_t cmd; + ++ cmd.u = 0; + cmd.vpu.cmd_type = R300_CMD_VPU; + cmd.vpu.count = count; + cmd.vpu.adrhi = ((unsigned int)addr & 0xFF00) >> 8; +@@ -74,10 +77,12 @@ static INLINE uint32_t cmdvpu(int addr, int count) + return cmd.u; + } + +-static INLINE uint32_t cmdr500fp(int addr, int count, int type, int clamp) ++static INLINE uint32_t cmdr500fp(struct radeon_screen *rscrn, ++ int addr, int count, int type, int clamp) + { + drm_r300_cmd_header_t cmd; + ++ cmd.u = 0; + cmd.r500fp.cmd_type = R300_CMD_R500FP; + cmd.r500fp.count = count; + cmd.r500fp.adrhi_flags = ((unsigned int)addr & 0x100) >> 8; +@@ -88,170 +93,131 @@ static INLINE uint32_t cmdr500fp(int addr, int count, int type, int clamp) + return cmd.u; + } + +-static INLINE uint32_t cmdpacket3(int packet) ++static INLINE uint32_t cmdpacket3(struct radeon_screen *rscrn, int packet) + { + drm_r300_cmd_header_t cmd; + ++ cmd.u = 0; + cmd.packet3.cmd_type = R300_CMD_PACKET3; + cmd.packet3.packet = packet; + + return cmd.u; + } + +-static INLINE uint32_t cmdcpdelay(unsigned short count) ++static INLINE uint32_t cmdcpdelay(struct radeon_screen *rscrn, ++ unsigned short count) + { + drm_r300_cmd_header_t cmd; + ++ cmd.u = 0; ++ + cmd.delay.cmd_type = R300_CMD_CP_DELAY; + cmd.delay.count = count; + + return cmd.u; + } + +-static INLINE uint32_t cmdwait(unsigned char flags) ++static INLINE uint32_t cmdwait(struct radeon_screen *rscrn, ++ unsigned char flags) + { + drm_r300_cmd_header_t cmd; + ++ cmd.u = 0; + cmd.wait.cmd_type = R300_CMD_WAIT; + cmd.wait.flags = flags; + + return cmd.u; + } + +-static INLINE uint32_t cmdpacify(void) ++static INLINE uint32_t cmdpacify(struct radeon_screen *rscrn) + { + drm_r300_cmd_header_t cmd; + ++ cmd.u = 0; + cmd.header.cmd_type = R300_CMD_END3D; + + return cmd.u; + } + + /** +- * Prepare to write a register value to register at address reg. +- * If num_extra > 0 then the following extra values are written +- * to registers with address +4, +8 and so on.. +- */ +-#define reg_start(reg, num_extra) \ +- do { \ +- int _n; \ +- _n=(num_extra); \ +- cmd = (drm_radeon_cmd_header_t*) \ +- r300AllocCmdBuf(rmesa, \ +- (_n+2), \ +- __FUNCTION__); \ +- cmd_reserved=_n+2; \ +- cmd_written=1; \ +- cmd[0].i=cmdpacket0((reg), _n+1); \ +- } while (0); +- +-/** +- * Emit GLuint freestyle ++ * Write the header of a packet3 to the command buffer. ++ * Outputs 2 dwords and expects (num_extra+1) additional dwords afterwards. + */ +-#define e32(dword) \ +- do { \ +- if(cmd_writtenradeonScreen->kernel_mm) { \ ++ OUT_BATCH(cmdpacket3(b_l_rmesa->radeonScreen,\ ++ R300_CMD_PACKET3_RAW)); \ ++ } else b_l_rmesa->cmdbuf.cs->section_cdw++;\ ++ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ + } while(0) + +-#define efloat(f) e32(r300PackFloat32(f)) +- +-#define vsf_start_fragment(dest, length) \ +- do { \ +- int _n; \ +- _n = (length); \ +- cmd = (drm_radeon_cmd_header_t*) \ +- r300AllocCmdBuf(rmesa, \ +- (_n+1), \ +- __FUNCTION__); \ +- cmd_reserved = _n+2; \ +- cmd_written =1; \ +- cmd[0].i = cmdvpu((dest), _n/4); \ +- } while (0); +- +-#define r500fp_start_fragment(dest, length) \ +- do { \ +- int _n; \ +- _n = (length); \ +- cmd = (drm_radeon_cmd_header_t*) \ +- r300AllocCmdBuf(rmesa, \ +- (_n+1), \ +- __FUNCTION__); \ +- cmd_reserved = _n+1; \ +- cmd_written =1; \ +- cmd[0].i = cmdr500fp((dest), _n/6, 0, 0); \ +- } while (0); +- +-#define start_packet3(packet, count) \ +- { \ +- int _n; \ +- GLuint _p; \ +- _n = (count); \ +- _p = (packet); \ +- cmd = (drm_radeon_cmd_header_t*) \ +- r300AllocCmdBuf(rmesa, \ +- (_n+3), \ +- __FUNCTION__); \ +- cmd_reserved = _n+3; \ +- cmd_written = 2; \ +- if(_n > 0x3fff) { \ +- fprintf(stderr,"Too big packet3 %08x: cannot " \ +- "store %d dwords\n", \ +- _p, _n); \ +- _mesa_exit(-1); \ +- } \ +- cmd[0].i = cmdpacket3(R300_CMD_PACKET3_RAW); \ +- cmd[1].i = _p | ((_n & 0x3fff)<<16); \ +- } +- + /** + * Must be sent to switch to 2d commands + */ +-void static INLINE end_3d(r300ContextPtr rmesa) ++void static INLINE end_3d(radeonContextPtr radeon) + { +- drm_radeon_cmd_header_t *cmd = NULL; ++ BATCH_LOCALS(radeon); + +- cmd = +- (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); +- cmd[0].header.cmd_type = R300_CMD_END3D; ++ if (!radeon->radeonScreen->kernel_mm) { ++ BEGIN_BATCH_NO_AUTOSTATE(1); ++ OUT_BATCH(cmdpacify(radeon->radeonScreen)); ++ END_BATCH(); ++ } + } + + void static INLINE cp_delay(r300ContextPtr rmesa, unsigned short count) + { +- drm_radeon_cmd_header_t *cmd = NULL; ++ BATCH_LOCALS(&rmesa->radeon); + +- cmd = +- (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); +- cmd[0].i = cmdcpdelay(count); ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ BEGIN_BATCH_NO_AUTOSTATE(1); ++ OUT_BATCH(cmdcpdelay(rmesa->radeon.radeonScreen, count)); ++ END_BATCH(); ++ } + } + +-void static INLINE cp_wait(r300ContextPtr rmesa, unsigned char flags) ++void static INLINE cp_wait(radeonContextPtr radeon, unsigned char flags) + { +- drm_radeon_cmd_header_t *cmd = NULL; +- +- cmd = +- (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); +- cmd[0].i = cmdwait(flags); ++ BATCH_LOCALS(radeon); ++ uint32_t wait_until; ++ ++ if (!radeon->radeonScreen->kernel_mm) { ++ BEGIN_BATCH_NO_AUTOSTATE(1); ++ OUT_BATCH(cmdwait(radeon->radeonScreen, flags)); ++ END_BATCH(); ++ } else { ++ switch(flags) { ++ case R300_WAIT_2D: ++ wait_until = (1 << 14); ++ break; ++ case R300_WAIT_3D: ++ wait_until = (1 << 15); ++ break; ++ case R300_NEW_WAIT_2D_3D: ++ wait_until = (1 << 14) | (1 << 15); ++ break; ++ case R300_NEW_WAIT_2D_2D_CLEAN: ++ wait_until = (1 << 14) | (1 << 16) | (1 << 18); ++ break; ++ case R300_NEW_WAIT_3D_3D_CLEAN: ++ wait_until = (1 << 15) | (1 << 17) | (1 << 18); ++ break; ++ case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN: ++ wait_until = (1 << 14) | (1 << 16) | (1 << 18); ++ wait_until |= (1 << 15) | (1 << 17) | (1 << 18); ++ break; ++ default: ++ return; ++ } ++ BEGIN_BATCH_NO_AUTOSTATE(2); ++ OUT_BATCH(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); ++ OUT_BATCH(wait_until); ++ END_BATCH(); ++ } + } + + extern int r300EmitArrays(GLcontext * ctx); + +-#ifdef USER_BUFFERS +-void r300UseArrays(GLcontext * ctx); +-#endif +- +-extern void r300ReleaseArrays(GLcontext * ctx); + extern int r300PrimitiveType(r300ContextPtr rmesa, int prim); + extern int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim); + +diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c +index ee85e22..a7f5121 100644 +--- a/src/mesa/drivers/dri/r300/r300_ioctl.c ++++ b/src/mesa/drivers/dri/r300/r300_ioctl.c +@@ -46,8 +46,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/context.h" + #include "swrast/swrast.h" + ++#include "radeon_common.h" ++#include "radeon_lock.h" + #include "r300_context.h" +-#include "radeon_ioctl.h" + #include "r300_ioctl.h" + #include "r300_cmdbuf.h" + #include "r300_state.h" +@@ -55,71 +56,90 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "radeon_reg.h" + #include "r300_emit.h" + #include "r300_fragprog.h" ++#include "r300_context.h" + + #include "vblank.h" + ++#define R200_3D_DRAW_IMMD_2 0xC0003500 ++ + #define CLEARBUFFER_COLOR 0x1 + #define CLEARBUFFER_DEPTH 0x2 + #define CLEARBUFFER_STENCIL 0x4 + +-static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) ++static void r300EmitClearState(GLcontext * ctx); ++ ++static void r300UserClear(GLcontext *ctx, GLuint mask) + { ++ radeon_clear_tris(ctx, mask); ++} ++ ++static void r300ClearBuffer(r300ContextPtr r300, int flags, ++ struct radeon_renderbuffer *rrb, ++ struct radeon_renderbuffer *rrbd) ++{ ++ BATCH_LOCALS(&r300->radeon); + GLcontext *ctx = r300->radeon.glCtx; + __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; +- GLuint cboffset, cbpitch; +- drm_r300_cmd_header_t *cmd2; +- int cmd_reserved = 0; +- int cmd_written = 0; +- drm_radeon_cmd_header_t *cmd = NULL; ++ GLuint cbpitch = 0; + r300ContextPtr rmesa = r300; + + if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s: %s buffer (%i,%i %ix%i)\n", +- __FUNCTION__, buffer ? "back" : "front", +- dPriv->x, dPriv->y, dPriv->w, dPriv->h); +- +- if (buffer) { +- cboffset = r300->radeon.radeonScreen->backOffset; +- cbpitch = r300->radeon.radeonScreen->backPitch; +- } else { +- cboffset = r300->radeon.radeonScreen->frontOffset; +- cbpitch = r300->radeon.radeonScreen->frontPitch; ++ fprintf(stderr, "%s: buffer %p (%i,%i %ix%i)\n", ++ __FUNCTION__, rrb, dPriv->x, dPriv->y, ++ dPriv->w, dPriv->h); ++ ++ if (rrb) { ++ cbpitch = (rrb->pitch / rrb->cpp); ++ if (rrb->cpp == 4) ++ cbpitch |= R300_COLOR_FORMAT_ARGB8888; ++ else ++ cbpitch |= R300_COLOR_FORMAT_RGB565; ++ ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){ ++ cbpitch |= R300_COLOR_TILE_ENABLE; ++ } + } + +- cboffset += r300->radeon.radeonScreen->fbLocation; +- +- cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN); +- end_3d(rmesa); +- +- R300_STATECHANGE(r300, cb); +- reg_start(R300_RB3D_COLOROFFSET0, 0); +- e32(cboffset); +- +- if (r300->radeon.radeonScreen->cpp == 4) +- cbpitch |= R300_COLOR_FORMAT_ARGB8888; +- else +- cbpitch |= R300_COLOR_FORMAT_RGB565; +- +- if (r300->radeon.sarea->tiling_enabled) +- cbpitch |= R300_COLOR_TILE_ENABLE; +- +- reg_start(R300_RB3D_COLORPITCH0, 0); +- e32(cbpitch); +- +- R300_STATECHANGE(r300, cmk); +- reg_start(RB3D_COLOR_CHANNEL_MASK, 0); ++ /* TODO in bufmgr */ ++ cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); ++ end_3d(&rmesa->radeon); + + if (flags & CLEARBUFFER_COLOR) { +- e32((ctx->Color.ColorMask[BCOMP] ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) | +- (ctx->Color.ColorMask[GCOMP] ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) | +- (ctx->Color.ColorMask[RCOMP] ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) | +- (ctx->Color.ColorMask[ACOMP] ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0)); ++ assert(rrb != 0); ++ BEGIN_BATCH_NO_AUTOSTATE(6); ++ OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1); ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ OUT_BATCH_REGVAL(R300_RB3D_COLORPITCH0, cbpitch); ++ END_BATCH(); ++ } ++#if 1 ++ if (flags & (CLEARBUFFER_DEPTH | CLEARBUFFER_STENCIL)) { ++ assert(rrbd != 0); ++ cbpitch = (rrbd->pitch / rrbd->cpp); ++ if (rrbd->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){ ++ cbpitch |= R300_DEPTHMACROTILE_ENABLE; ++ } ++ if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ ++ cbpitch |= R300_DEPTHMICROTILE_TILED; ++ } ++ BEGIN_BATCH_NO_AUTOSTATE(6); ++ OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1); ++ OUT_BATCH_RELOC(0, rrbd->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, cbpitch); ++ END_BATCH(); ++ } ++#endif ++ BEGIN_BATCH_NO_AUTOSTATE(6); ++ OUT_BATCH_REGSEQ(RB3D_COLOR_CHANNEL_MASK, 1); ++ if (flags & CLEARBUFFER_COLOR) { ++ OUT_BATCH((ctx->Color.ColorMask[BCOMP] ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) | ++ (ctx->Color.ColorMask[GCOMP] ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) | ++ (ctx->Color.ColorMask[RCOMP] ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) | ++ (ctx->Color.ColorMask[ACOMP] ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0)); + } else { +- e32(0x0); ++ OUT_BATCH(0); + } + +- R300_STATECHANGE(r300, zs); +- reg_start(R300_ZB_CNTL, 2); + + { + uint32_t t1, t2; +@@ -146,37 +166,55 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) + R300_S_FRONT_ZFAIL_OP_SHIFT); + } + +- e32(t1); +- e32(t2); +- e32(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << R300_STENCILWRITEMASK_SHIFT) | +- (ctx->Stencil.Clear & R300_STENCILREF_MASK)); ++ OUT_BATCH_REGSEQ(R300_ZB_CNTL, 3); ++ OUT_BATCH(t1); ++ OUT_BATCH(t2); ++ OUT_BATCH(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << ++ R300_STENCILWRITEMASK_SHIFT) | ++ (ctx->Stencil.Clear & R300_STENCILREF_MASK)); ++ END_BATCH(); + } + +- cmd2 = (drm_r300_cmd_header_t *) r300AllocCmdBuf(r300, 9, __FUNCTION__); +- cmd2[0].packet3.cmd_type = R300_CMD_PACKET3; +- cmd2[0].packet3.packet = R300_CMD_PACKET3_CLEAR; +- cmd2[1].u = r300PackFloat32(dPriv->w / 2.0); +- cmd2[2].u = r300PackFloat32(dPriv->h / 2.0); +- cmd2[3].u = r300PackFloat32(ctx->Depth.Clear); +- cmd2[4].u = r300PackFloat32(1.0); +- cmd2[5].u = r300PackFloat32(ctx->Color.ClearColor[0]); +- cmd2[6].u = r300PackFloat32(ctx->Color.ClearColor[1]); +- cmd2[7].u = r300PackFloat32(ctx->Color.ClearColor[2]); +- cmd2[8].u = r300PackFloat32(ctx->Color.ClearColor[3]); +- ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ BEGIN_BATCH_NO_AUTOSTATE(9); ++ OUT_BATCH(cmdpacket3(r300->radeon.radeonScreen, R300_CMD_PACKET3_CLEAR)); ++ OUT_BATCH_FLOAT32(dPriv->w / 2.0); ++ OUT_BATCH_FLOAT32(dPriv->h / 2.0); ++ OUT_BATCH_FLOAT32(ctx->Depth.Clear); ++ OUT_BATCH_FLOAT32(1.0); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); ++ END_BATCH(); ++ } else { ++ OUT_BATCH(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); ++ OUT_BATCH(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | ++ (1 << R300_PRIM_NUM_VERTICES_SHIFT)); ++ OUT_BATCH_FLOAT32(dPriv->w / 2.0); ++ OUT_BATCH_FLOAT32(dPriv->h / 2.0); ++ OUT_BATCH_FLOAT32(ctx->Depth.Clear); ++ OUT_BATCH_FLOAT32(1.0); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); ++ } ++ + r300EmitCacheFlush(rmesa); +- cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN); ++ cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); ++ ++ R300_STATECHANGE(r300, cb); ++ R300_STATECHANGE(r300, cmk); ++ R300_STATECHANGE(r300, zs); + } + + static void r300EmitClearState(GLcontext * ctx) + { + r300ContextPtr r300 = R300_CONTEXT(ctx); +- r300ContextPtr rmesa = r300; ++ BATCH_LOCALS(&r300->radeon); + __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; + int i; +- int cmd_reserved = 0; +- int cmd_written = 0; +- drm_radeon_cmd_header_t *cmd = NULL; + int has_tcl = 1; + int is_r500 = 0; + GLuint vap_cntl; +@@ -184,35 +222,37 @@ static void r300EmitClearState(GLcontext * ctx) + if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) + has_tcl = 0; + +- if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) +- is_r500 = 1; +- ++ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ++ is_r500 = 1; + +- /* FIXME: the values written to R300_VAP_INPUT_ROUTE_0_0 and +- * R300_VAP_INPUT_ROUTE_0_1 are in fact known, however, the values are +- * quite complex; see the functions in r300_emit.c. ++ /* State atom dirty tracking is a little subtle here. + * +- * I believe it would be a good idea to extend the functions in +- * r300_emit.c so that they can be used to setup the default values for +- * these registers, as well as the actual values used for rendering. ++ * On the one hand, we need to make sure base state is emitted ++ * here if we start with an empty batch buffer, otherwise clear ++ * works incorrectly with multiple processes. Therefore, the first ++ * BEGIN_BATCH cannot be a BEGIN_BATCH_NO_AUTOSTATE. ++ * ++ * On the other hand, implicit state emission clears the state atom ++ * dirty bits, so we have to call R300_STATECHANGE later than the ++ * first BEGIN_BATCH. ++ * ++ * The final trickiness is that, because we change state, we need ++ * to ensure that any stored swtcl primitives are flushed properly ++ * before we start changing state. See the R300_NEWPRIM in r300Clear ++ * for this. + */ +- R300_STATECHANGE(r300, vir[0]); +- reg_start(R300_VAP_PROG_STREAM_CNTL_0, 0); ++ BEGIN_BATCH(31); ++ OUT_BATCH_REGSEQ(R300_VAP_PROG_STREAM_CNTL_0, 1); + if (!has_tcl) +- e32(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) | ++ OUT_BATCH(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT))); + else +- e32(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) | ++ OUT_BATCH(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT))); + +- /* disable fog */ +- R300_STATECHANGE(r300, fogs); +- reg_start(R300_FG_FOG_BLEND, 0); +- e32(0x0); +- +- R300_STATECHANGE(r300, vir[1]); +- reg_start(R300_VAP_PROG_STREAM_CNTL_EXT_0, 0); +- e32(((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) | ++ OUT_BATCH_REGVAL(R300_FG_FOG_BLEND, 0); ++ OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0, ++ ((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) | + (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) | + (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_SHIFT) | + (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_SHIFT) | +@@ -226,619 +266,402 @@ static void r300EmitClearState(GLcontext * ctx) + << R300_SWIZZLE1_SHIFT))); + + /* R300_VAP_INPUT_CNTL_0, R300_VAP_INPUT_CNTL_1 */ +- R300_STATECHANGE(r300, vic); +- reg_start(R300_VAP_VTX_STATE_CNTL, 1); +- e32((R300_SEL_USER_COLOR_0 << R300_COLOR_0_ASSEMBLY_SHIFT)); +- e32(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0); ++ OUT_BATCH_REGSEQ(R300_VAP_VTX_STATE_CNTL, 2); ++ OUT_BATCH((R300_SEL_USER_COLOR_0 << R300_COLOR_0_ASSEMBLY_SHIFT)); ++ OUT_BATCH(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0); + +- R300_STATECHANGE(r300, vte); + /* comes from fglrx startup of clear */ +- reg_start(R300_SE_VTE_CNTL, 1); +- e32(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA | +- R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA | +- R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA | +- R300_VPORT_Z_OFFSET_ENA); +- e32(0x8); ++ OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL, 2); ++ OUT_BATCH(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA | ++ R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA | ++ R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA | ++ R300_VPORT_Z_OFFSET_ENA); ++ OUT_BATCH(0x8); + +- reg_start(R300_VAP_PSC_SGN_NORM_CNTL, 0); +- e32(0xaaaaaaaa); ++ OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa); + +- R300_STATECHANGE(r300, vof); +- reg_start(R300_VAP_OUTPUT_VTX_FMT_0, 1); +- e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | +- R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT); +- e32(0x0); /* no textures */ ++ OUT_BATCH_REGSEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); ++ OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | ++ R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT); ++ OUT_BATCH(0); /* no textures */ + +- R300_STATECHANGE(r300, txe); +- reg_start(R300_TX_ENABLE, 0); +- e32(0x0); ++ OUT_BATCH_REGVAL(R300_TX_ENABLE, 0); + +- R300_STATECHANGE(r300, vpt); +- reg_start(R300_SE_VPORT_XSCALE, 5); +- efloat(1.0); +- efloat(dPriv->x); +- efloat(1.0); +- efloat(dPriv->y); +- efloat(1.0); +- efloat(0.0); ++ OUT_BATCH_REGSEQ(R300_SE_VPORT_XSCALE, 6); ++ OUT_BATCH_FLOAT32(1.0); ++ OUT_BATCH_FLOAT32(dPriv->x); ++ OUT_BATCH_FLOAT32(1.0); ++ OUT_BATCH_FLOAT32(dPriv->y); ++ OUT_BATCH_FLOAT32(1.0); ++ OUT_BATCH_FLOAT32(0.0); + +- R300_STATECHANGE(r300, at); +- reg_start(R300_FG_ALPHA_FUNC, 0); +- e32(0x0); ++ OUT_BATCH_REGVAL(R300_FG_ALPHA_FUNC, 0); ++ ++ OUT_BATCH_REGSEQ(R300_RB3D_CBLEND, 2); ++ OUT_BATCH(0x0); ++ OUT_BATCH(0x0); ++ END_BATCH(); + ++ R300_STATECHANGE(r300, vir[0]); ++ R300_STATECHANGE(r300, fogs); ++ R300_STATECHANGE(r300, vir[1]); ++ R300_STATECHANGE(r300, vic); ++ R300_STATECHANGE(r300, vte); ++ R300_STATECHANGE(r300, vof); ++ R300_STATECHANGE(r300, txe); ++ R300_STATECHANGE(r300, vpt); ++ R300_STATECHANGE(r300, at); + R300_STATECHANGE(r300, bld); +- reg_start(R300_RB3D_CBLEND, 1); +- e32(0x0); +- e32(0x0); ++ R300_STATECHANGE(r300, ps); + + if (has_tcl) { +- R300_STATECHANGE(r300, vap_clip_cntl); +- reg_start(R300_VAP_CLIP_CNTL, 0); +- e32(R300_PS_UCP_MODE_CLIP_AS_TRIFAN | R300_CLIP_DISABLE); ++ R300_STATECHANGE(r300, vap_clip_cntl); ++ ++ BEGIN_BATCH_NO_AUTOSTATE(2); ++ OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_PS_UCP_MODE_CLIP_AS_TRIFAN | R300_CLIP_DISABLE); ++ END_BATCH(); + } + +- R300_STATECHANGE(r300, ps); +- reg_start(R300_GA_POINT_SIZE, 0); +- e32(((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) | +- ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT)); ++ BEGIN_BATCH_NO_AUTOSTATE(2); ++ OUT_BATCH_REGVAL(R300_GA_POINT_SIZE, ++ ((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) | ++ ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT)); ++ END_BATCH(); + + if (!is_r500) { + R300_STATECHANGE(r300, ri); +- reg_start(R300_RS_IP_0, 7); +- for (i = 0; i < 8; ++i) { +- e32(R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3)); +- } +- + R300_STATECHANGE(r300, rc); +- /* The second constant is needed to get glxgears display anything .. */ +- reg_start(R300_RS_COUNT, 1); +- e32((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); +- e32(0x0); +- + R300_STATECHANGE(r300, rr); +- reg_start(R300_RS_INST_0, 0); +- e32(R300_RS_INST_COL_CN_WRITE); ++ ++ BEGIN_BATCH(14); ++ OUT_BATCH_REGSEQ(R300_RS_IP_0, 8); ++ for (i = 0; i < 8; ++i) ++ OUT_BATCH(R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3)); ++ ++ OUT_BATCH_REGSEQ(R300_RS_COUNT, 2); ++ OUT_BATCH((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); ++ OUT_BATCH(0x0); ++ ++ OUT_BATCH_REGVAL(R300_RS_INST_0, R300_RS_INST_COL_CN_WRITE); ++ END_BATCH(); + } else { + R300_STATECHANGE(r300, ri); +- reg_start(R500_RS_IP_0, 7); ++ R300_STATECHANGE(r300, rc); ++ R300_STATECHANGE(r300, rr); ++ ++ BEGIN_BATCH(14); ++ OUT_BATCH_REGSEQ(R500_RS_IP_0, 8); + for (i = 0; i < 8; ++i) { +- e32((R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | +- (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | +- (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | +- (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)); ++ OUT_BATCH((R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | ++ (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | ++ (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | ++ (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)); + } + +- R300_STATECHANGE(r300, rc); +- /* The second constant is needed to get glxgears display anything .. */ +- reg_start(R300_RS_COUNT, 1); +- e32((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); +- e32(0x0); +- +- R300_STATECHANGE(r300, rr); +- reg_start(R500_RS_INST_0, 0); +- e32(R500_RS_INST_COL_CN_WRITE); ++ OUT_BATCH_REGSEQ(R300_RS_COUNT, 2); ++ OUT_BATCH((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); ++ OUT_BATCH(0x0); + ++ OUT_BATCH_REGVAL(R500_RS_INST_0, R500_RS_INST_COL_CN_WRITE); ++ END_BATCH(); + } + + if (!is_r500) { + R300_STATECHANGE(r300, fp); +- reg_start(R300_US_CONFIG, 2); +- e32(0x0); +- e32(0x0); +- e32(0x0); +- reg_start(R300_US_CODE_ADDR_0, 3); +- e32(0x0); +- e32(0x0); +- e32(0x0); +- e32(R300_RGBA_OUT); +- + R300_STATECHANGE(r300, fpi[0]); + R300_STATECHANGE(r300, fpi[1]); + R300_STATECHANGE(r300, fpi[2]); + R300_STATECHANGE(r300, fpi[3]); + +- reg_start(R300_US_ALU_RGB_INST_0, 0); +- e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO))); +- +- reg_start(R300_US_ALU_RGB_ADDR_0, 0); +- e32(FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0)); +- +- reg_start(R300_US_ALU_ALPHA_INST_0, 0); +- e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO))); +- +- reg_start(R300_US_ALU_ALPHA_ADDR_0, 0); +- e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0)); ++ BEGIN_BATCH(17); ++ OUT_BATCH_REGSEQ(R300_US_CONFIG, 3); ++ OUT_BATCH(0x0); ++ OUT_BATCH(0x0); ++ OUT_BATCH(0x0); ++ OUT_BATCH_REGSEQ(R300_US_CODE_ADDR_0, 4); ++ OUT_BATCH(0x0); ++ OUT_BATCH(0x0); ++ OUT_BATCH(0x0); ++ OUT_BATCH(R300_RGBA_OUT); ++ ++ OUT_BATCH_REGVAL(R300_US_ALU_RGB_INST_0, ++ FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO))); ++ OUT_BATCH_REGVAL(R300_US_ALU_RGB_ADDR_0, ++ FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0)); ++ OUT_BATCH_REGVAL(R300_US_ALU_ALPHA_INST_0, ++ FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO))); ++ OUT_BATCH_REGVAL(R300_US_ALU_ALPHA_ADDR_0, ++ FP_SELA(0, NO, W, FP_TMP(0), 0, 0)); ++ END_BATCH(); + } else { +- R300_STATECHANGE(r300, fp); +- reg_start(R500_US_CONFIG, 1); +- e32(R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); +- e32(0x0); +- reg_start(R500_US_CODE_ADDR, 2); +- e32(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(1)); +- e32(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1)); +- e32(R500_US_CODE_OFFSET_ADDR(0)); ++ struct radeon_state_atom r500fp; ++ uint32_t _cmd[10]; + ++ R300_STATECHANGE(r300, fp); + R300_STATECHANGE(r300, r500fp); +- r500fp_start_fragment(0, 6); +- +- e32(R500_INST_TYPE_OUT | +- R500_INST_TEX_SEM_WAIT | +- R500_INST_LAST | +- R500_INST_RGB_OMASK_R | +- R500_INST_RGB_OMASK_G | +- R500_INST_RGB_OMASK_B | +- R500_INST_ALPHA_OMASK | +- R500_INST_RGB_CLAMP | +- R500_INST_ALPHA_CLAMP); +- +- e32(R500_RGB_ADDR0(0) | +- R500_RGB_ADDR1(0) | +- R500_RGB_ADDR1_CONST | +- R500_RGB_ADDR2(0) | +- R500_RGB_ADDR2_CONST); +- +- e32(R500_ALPHA_ADDR0(0) | +- R500_ALPHA_ADDR1(0) | +- R500_ALPHA_ADDR1_CONST | +- R500_ALPHA_ADDR2(0) | +- R500_ALPHA_ADDR2_CONST); +- +- e32(R500_ALU_RGB_SEL_A_SRC0 | +- R500_ALU_RGB_R_SWIZ_A_R | +- R500_ALU_RGB_G_SWIZ_A_G | +- R500_ALU_RGB_B_SWIZ_A_B | +- R500_ALU_RGB_SEL_B_SRC0 | +- R500_ALU_RGB_R_SWIZ_B_R | +- R500_ALU_RGB_B_SWIZ_B_G | +- R500_ALU_RGB_G_SWIZ_B_B); +- +- e32(R500_ALPHA_OP_CMP | +- R500_ALPHA_SWIZ_A_A | +- R500_ALPHA_SWIZ_B_A); +- +- e32(R500_ALU_RGBA_OP_CMP | +- R500_ALU_RGBA_R_SWIZ_0 | +- R500_ALU_RGBA_G_SWIZ_0 | +- R500_ALU_RGBA_B_SWIZ_0 | +- R500_ALU_RGBA_A_SWIZ_0); ++ ++ BEGIN_BATCH(7); ++ OUT_BATCH_REGSEQ(R500_US_CONFIG, 2); ++ OUT_BATCH(R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); ++ OUT_BATCH(0x0); ++ OUT_BATCH_REGSEQ(R500_US_CODE_ADDR, 3); ++ OUT_BATCH(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(1)); ++ OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1)); ++ OUT_BATCH(R500_US_CODE_OFFSET_ADDR(0)); ++ END_BATCH(); ++ ++ r500fp.check = check_r500fp; ++ r500fp.cmd = _cmd; ++ r500fp.cmd[0] = cmdr500fp(r300->radeon.radeonScreen, 0, 1, 0, 0); ++ r500fp.cmd[1] = R500_INST_TYPE_OUT | ++ R500_INST_TEX_SEM_WAIT | ++ R500_INST_LAST | ++ R500_INST_RGB_OMASK_R | ++ R500_INST_RGB_OMASK_G | ++ R500_INST_RGB_OMASK_B | ++ R500_INST_ALPHA_OMASK | ++ R500_INST_RGB_CLAMP | ++ R500_INST_ALPHA_CLAMP; ++ r500fp.cmd[2] = R500_RGB_ADDR0(0) | ++ R500_RGB_ADDR1(0) | ++ R500_RGB_ADDR1_CONST | ++ R500_RGB_ADDR2(0) | ++ R500_RGB_ADDR2_CONST; ++ r500fp.cmd[3] = R500_ALPHA_ADDR0(0) | ++ R500_ALPHA_ADDR1(0) | ++ R500_ALPHA_ADDR1_CONST | ++ R500_ALPHA_ADDR2(0) | ++ R500_ALPHA_ADDR2_CONST; ++ r500fp.cmd[4] = R500_ALU_RGB_SEL_A_SRC0 | ++ R500_ALU_RGB_R_SWIZ_A_R | ++ R500_ALU_RGB_G_SWIZ_A_G | ++ R500_ALU_RGB_B_SWIZ_A_B | ++ R500_ALU_RGB_SEL_B_SRC0 | ++ R500_ALU_RGB_R_SWIZ_B_R | ++ R500_ALU_RGB_B_SWIZ_B_G | ++ R500_ALU_RGB_G_SWIZ_B_B; ++ r500fp.cmd[5] = R500_ALPHA_OP_CMP | ++ R500_ALPHA_SWIZ_A_A | ++ R500_ALPHA_SWIZ_B_A; ++ r500fp.cmd[6] = R500_ALU_RGBA_OP_CMP | ++ R500_ALU_RGBA_R_SWIZ_0 | ++ R500_ALU_RGBA_G_SWIZ_0 | ++ R500_ALU_RGBA_B_SWIZ_0 | ++ R500_ALU_RGBA_A_SWIZ_0; ++ ++ r500fp.cmd[7] = 0; ++ emit_r500fp(ctx, &r500fp); + } + +- reg_start(R300_VAP_PVS_STATE_FLUSH_REG, 0); +- e32(0x00000000); ++ BEGIN_BATCH(2); ++ OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0); ++ END_BATCH(); ++ + if (has_tcl) { +- vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) | ++ vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) | + (5 << R300_PVS_NUM_CNTLRS_SHIFT) | + (12 << R300_VF_MAX_VTX_NUM_SHIFT)); +- if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) +- vap_cntl |= R500_TCL_STATE_OPTIMIZATION; +- } else +- vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) | ++ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ++ vap_cntl |= R500_TCL_STATE_OPTIMIZATION; ++ } else { ++ vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) | + (5 << R300_PVS_NUM_CNTLRS_SHIFT) | + (5 << R300_VF_MAX_VTX_NUM_SHIFT)); ++ } + + if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515) +- vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT); ++ vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT); + else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) || + (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560) || + (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570)) +- vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT); ++ vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT); + else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410) || + (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420)) +- vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT); ++ vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT); + else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) || + (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580)) +- vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT); ++ vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT); + else +- vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT); ++ vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT); + +- R300_STATECHANGE(rmesa, vap_cntl); +- reg_start(R300_VAP_CNTL, 0); +- e32(vap_cntl); ++ R300_STATECHANGE(r300, vap_cntl); ++ ++ BEGIN_BATCH(2); ++ OUT_BATCH_REGVAL(R300_VAP_CNTL, vap_cntl); ++ END_BATCH(); + + if (has_tcl) { ++ struct radeon_state_atom vpu; ++ uint32_t _cmd[10]; + R300_STATECHANGE(r300, pvs); +- reg_start(R300_VAP_PVS_CODE_CNTL_0, 2); +- +- e32((0 << R300_PVS_FIRST_INST_SHIFT) | +- (0 << R300_PVS_XYZW_VALID_INST_SHIFT) | +- (1 << R300_PVS_LAST_INST_SHIFT)); +- e32((0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | +- (0 << R300_PVS_MAX_CONST_ADDR_SHIFT)); +- e32(1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT); +- + R300_STATECHANGE(r300, vpi); +- vsf_start_fragment(0x0, 8); +- +- e32(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 0, 0xf, PVS_DST_REG_OUT)); +- e32(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); +- e32(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); +- e32(0x0); + +- e32(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, PVS_DST_REG_OUT)); +- e32(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); +- e32(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); +- e32(0x0); ++ BEGIN_BATCH(4); ++ OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0, 3); ++ OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT) | ++ (0 << R300_PVS_XYZW_VALID_INST_SHIFT) | ++ (1 << R300_PVS_LAST_INST_SHIFT)); ++ OUT_BATCH((0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | ++ (0 << R300_PVS_MAX_CONST_ADDR_SHIFT)); ++ OUT_BATCH(1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT); ++ END_BATCH(); ++ ++ vpu.check = check_vpu; ++ vpu.cmd = _cmd; ++ vpu.cmd[0] = cmdvpu(r300->radeon.radeonScreen, 0, 2); ++ ++ vpu.cmd[1] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, ++ 0, 0xf, PVS_DST_REG_OUT); ++ vpu.cmd[2] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, ++ PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, ++ PVS_SRC_REG_INPUT, VSF_FLAG_NONE); ++ vpu.cmd[3] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_REG_INPUT, VSF_FLAG_NONE); ++ vpu.cmd[4] = 0x0; ++ ++ vpu.cmd[5] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, ++ PVS_DST_REG_OUT); ++ vpu.cmd[6] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X, ++ PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, ++ PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, ++ ++ VSF_FLAG_NONE); ++ vpu.cmd[7] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_REG_INPUT, VSF_FLAG_NONE); ++ vpu.cmd[8] = 0x0; ++ ++ r300->vap_flush_needed = GL_TRUE; ++ emit_vpu(ctx, &vpu); + } + } + +-/** +- * Buffer clear +- */ +-static void r300Clear(GLcontext * ctx, GLbitfield mask) +-{ ++static void r300KernelClear(GLcontext *ctx, GLuint flags) ++{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; +- int flags = 0; ++ struct radeon_framebuffer *rfb = dPriv->driverPrivate; ++ struct radeon_renderbuffer *rrb; ++ struct radeon_renderbuffer *rrbd; + int bits = 0; +- int swapped; +- +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "r300Clear\n"); +- +- { +- LOCK_HARDWARE(&r300->radeon); +- UNLOCK_HARDWARE(&r300->radeon); +- if (dPriv->numClipRects == 0) +- return; +- } + +- if (mask & BUFFER_BIT_FRONT_LEFT) { +- flags |= BUFFER_BIT_FRONT_LEFT; +- mask &= ~BUFFER_BIT_FRONT_LEFT; +- } +- +- if (mask & BUFFER_BIT_BACK_LEFT) { +- flags |= BUFFER_BIT_BACK_LEFT; +- mask &= ~BUFFER_BIT_BACK_LEFT; +- } +- +- if (mask & BUFFER_BIT_DEPTH) { ++ /* Make sure it fits there. */ ++ rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); ++ if (flags || bits) ++ r300EmitClearState(ctx); ++ rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); ++ if (rrbd && (flags & BUFFER_BIT_DEPTH)) + bits |= CLEARBUFFER_DEPTH; +- mask &= ~BUFFER_BIT_DEPTH; +- } + +- if ((mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) { ++ if (rrbd && (flags & BUFFER_BIT_STENCIL)) + bits |= CLEARBUFFER_STENCIL; +- mask &= ~BUFFER_BIT_STENCIL; +- } + +- if (mask) { +- if (RADEON_DEBUG & DEBUG_FALLBACKS) +- fprintf(stderr, "%s: swrast clear, mask: %x\n", +- __FUNCTION__, mask); +- _swrast_Clear(ctx, mask); ++ if (flags & BUFFER_BIT_COLOR0) { ++ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0); ++ r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL); ++ bits = 0; + } +- +- swapped = r300->radeon.sarea->pfCurrentPage == 1; +- +- /* Make sure it fits there. */ +- r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__); +- if (flags || bits) +- r300EmitClearState(ctx); +- ++ + if (flags & BUFFER_BIT_FRONT_LEFT) { +- r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped); ++ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT); ++ r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); + bits = 0; + } + + if (flags & BUFFER_BIT_BACK_LEFT) { +- r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1); ++ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT); ++ r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); + bits = 0; + } + + if (bits) +- r300ClearBuffer(r300, bits, 0); ++ r300ClearBuffer(r300, bits, NULL, rrbd); + ++ COMMIT_BATCH(); + } + +-void r300Flush(GLcontext * ctx) ++/** ++ * Buffer clear ++ */ ++static void r300Clear(GLcontext * ctx, GLbitfield mask) + { +- r300ContextPtr rmesa = R300_CONTEXT(ctx); ++ r300ContextPtr r300 = R300_CONTEXT(ctx); ++ __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; ++ const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); ++ GLbitfield swrast_mask = 0, tri_mask = 0; ++ int i; ++ struct gl_framebuffer *fb = ctx->DrawBuffer; + + if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); +- +- if (rmesa->cmdbuf.count_used > rmesa->cmdbuf.count_reemit) +- r300FlushCmdBuf(rmesa, __FUNCTION__); +-} +- +-#ifdef USER_BUFFERS +-#include "r300_mem.h" +- +-void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size) +-{ +- struct r300_dma_buffer *dmabuf; +- size = MAX2(size, RADEON_BUFFER_SIZE * 16); +- +- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- if (rmesa->dma.flush) { +- rmesa->dma.flush(rmesa); +- } ++ fprintf(stderr, "r300Clear\n"); + +- if (rmesa->dma.current.buf) { +-#ifdef USER_BUFFERS +- r300_mem_use(rmesa, rmesa->dma.current.buf->id); +-#endif +- r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__); ++ if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) { ++ LOCK_HARDWARE(&r300->radeon); ++ UNLOCK_HARDWARE(&r300->radeon); ++ if (dPriv->numClipRects == 0) ++ return; + } +- if (rmesa->dma.nr_released_bufs > 4) +- r300FlushCmdBuf(rmesa, __FUNCTION__); + +- dmabuf = CALLOC_STRUCT(r300_dma_buffer); +- dmabuf->buf = (void *)1; /* hack */ +- dmabuf->refcount = 1; +- +- dmabuf->id = r300_mem_alloc(rmesa, 4, size); +- if (dmabuf->id == 0) { +- LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */ +- +- r300FlushCmdBufLocked(rmesa, __FUNCTION__); +- radeonWaitForIdleLocked(&rmesa->radeon); ++ /* Flush swtcl vertices if necessary, because we will change hardware ++ * state during clear. See also the state-related comment in ++ * r300EmitClearState. ++ */ ++ R300_NEWPRIM(r300); + +- dmabuf->id = r300_mem_alloc(rmesa, 4, size); ++ if (colorMask == ~0) ++ tri_mask |= (mask & BUFFER_BITS_COLOR); + +- UNLOCK_HARDWARE(&rmesa->radeon); + +- if (dmabuf->id == 0) { +- fprintf(stderr, +- "Error: Could not get dma buffer... exiting\n"); +- _mesa_exit(-1); +- } ++ /* HW stencil */ ++ if (mask & BUFFER_BIT_STENCIL) { ++ tri_mask |= BUFFER_BIT_STENCIL; + } + +- rmesa->dma.current.buf = dmabuf; +- rmesa->dma.current.address = r300_mem_ptr(rmesa, dmabuf->id); +- rmesa->dma.current.end = size; +- rmesa->dma.current.start = 0; +- rmesa->dma.current.ptr = 0; +-} +- +-void r300ReleaseDmaRegion(r300ContextPtr rmesa, +- struct r300_dma_region *region, const char *caller) +-{ +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); +- +- if (!region->buf) +- return; +- +- if (rmesa->dma.flush) +- rmesa->dma.flush(rmesa); +- +- if (--region->buf->refcount == 0) { +- r300_mem_free(rmesa, region->buf->id); +- FREE(region->buf); +- rmesa->dma.nr_released_bufs++; ++ /* HW depth */ ++ if (mask & BUFFER_BIT_DEPTH) { ++ tri_mask |= BUFFER_BIT_DEPTH; + } + +- region->buf = 0; +- region->start = 0; +-} +- +-/* Allocates a region from rmesa->dma.current. If there isn't enough +- * space in current, grab a new buffer (and discard what was left of current) +- */ +-void r300AllocDmaRegion(r300ContextPtr rmesa, +- struct r300_dma_region *region, +- int bytes, int alignment) +-{ +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); +- +- if (rmesa->dma.flush) +- rmesa->dma.flush(rmesa); +- +- if (region->buf) +- r300ReleaseDmaRegion(rmesa, region, __FUNCTION__); +- +- alignment--; +- rmesa->dma.current.start = rmesa->dma.current.ptr = +- (rmesa->dma.current.ptr + alignment) & ~alignment; +- +- if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end) +- r300RefillCurrentDmaRegion(rmesa, (bytes + 0x7) & ~0x7); +- +- region->start = rmesa->dma.current.start; +- region->ptr = rmesa->dma.current.start; +- region->end = rmesa->dma.current.start + bytes; +- region->address = rmesa->dma.current.address; +- region->buf = rmesa->dma.current.buf; +- region->buf->refcount++; +- +- rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ +- rmesa->dma.current.start = +- rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7; +- +- assert(rmesa->dma.current.ptr <= rmesa->dma.current.end); +-} ++ /* If we're doing a tri pass for depth/stencil, include a likely color ++ * buffer with it. ++ */ + +-#else +-static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa) +-{ +- struct r300_dma_buffer *dmabuf; +- int fd = rmesa->radeon.dri.fd; +- int index = 0; +- int size = 0; +- drmDMAReq dma; +- int ret; +- +- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- if (rmesa->dma.flush) { +- rmesa->dma.flush(rmesa); ++ for (i = 0; i < BUFFER_COUNT; i++) { ++ GLuint bufBit = 1 << i; ++ if ((tri_mask) & bufBit) { ++ if (!fb->Attachment[i].Renderbuffer->ClassID) { ++ tri_mask &= ~bufBit; ++ swrast_mask |= bufBit; ++ } ++ } + } + +- if (rmesa->dma.current.buf) +- r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__); +- +- if (rmesa->dma.nr_released_bufs > 4) +- r300FlushCmdBuf(rmesa, __FUNCTION__); +- +- dma.context = rmesa->radeon.dri.hwContext; +- dma.send_count = 0; +- dma.send_list = NULL; +- dma.send_sizes = NULL; +- dma.flags = 0; +- dma.request_count = 1; +- dma.request_size = RADEON_BUFFER_SIZE; +- dma.request_list = &index; +- dma.request_sizes = &size; +- dma.granted_count = 0; +- +- LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */ +- +- ret = drmDMA(fd, &dma); +- +- if (ret != 0) { +- /* Try to release some buffers and wait until we can't get any more */ +- if (rmesa->dma.nr_released_bufs) { +- r300FlushCmdBufLocked(rmesa, __FUNCTION__); +- } ++ /* SW fallback clearing */ ++ swrast_mask = mask & ~tri_mask; + +- if (RADEON_DEBUG & DEBUG_DMA) +- fprintf(stderr, "Waiting for buffers\n"); +- +- radeonWaitForIdleLocked(&rmesa->radeon); +- ret = drmDMA(fd, &dma); +- +- if (ret != 0) { +- UNLOCK_HARDWARE(&rmesa->radeon); +- fprintf(stderr, +- "Error: Could not get dma buffer... exiting\n"); +- _mesa_exit(-1); +- } ++ if (tri_mask) { ++ if (r300->radeon.radeonScreen->kernel_mm) ++ r300UserClear(ctx, tri_mask); ++ else ++ r300KernelClear(ctx, tri_mask); + } +- +- UNLOCK_HARDWARE(&rmesa->radeon); +- +- if (RADEON_DEBUG & DEBUG_DMA) +- fprintf(stderr, "Allocated buffer %d\n", index); +- +- dmabuf = CALLOC_STRUCT(r300_dma_buffer); +- dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index]; +- dmabuf->refcount = 1; +- +- rmesa->dma.current.buf = dmabuf; +- rmesa->dma.current.address = dmabuf->buf->address; +- rmesa->dma.current.end = dmabuf->buf->total; +- rmesa->dma.current.start = 0; +- rmesa->dma.current.ptr = 0; +-} +- +-void r300ReleaseDmaRegion(r300ContextPtr rmesa, +- struct r300_dma_region *region, const char *caller) +-{ +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); +- +- if (!region->buf) +- return; +- +- if (rmesa->dma.flush) +- rmesa->dma.flush(rmesa); +- +- if (--region->buf->refcount == 0) { +- drm_radeon_cmd_header_t *cmd; +- +- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) +- fprintf(stderr, "%s -- DISCARD BUF %d\n", +- __FUNCTION__, region->buf->buf->idx); +- cmd = +- (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, +- sizeof +- (*cmd) / 4, +- __FUNCTION__); +- cmd->dma.cmd_type = R300_CMD_DMA_DISCARD; +- cmd->dma.buf_idx = region->buf->buf->idx; +- +- FREE(region->buf); +- rmesa->dma.nr_released_bufs++; ++ if (swrast_mask) { ++ if (RADEON_DEBUG & DEBUG_FALLBACKS) ++ fprintf(stderr, "%s: swrast clear, mask: %x\n", ++ __FUNCTION__, swrast_mask); ++ _swrast_Clear(ctx, swrast_mask); + } +- +- region->buf = 0; +- region->start = 0; +-} +- +-/* Allocates a region from rmesa->dma.current. If there isn't enough +- * space in current, grab a new buffer (and discard what was left of current) +- */ +-void r300AllocDmaRegion(r300ContextPtr rmesa, +- struct r300_dma_region *region, +- int bytes, int alignment) +-{ +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); +- +- if (rmesa->dma.flush) +- rmesa->dma.flush(rmesa); +- +- if (region->buf) +- r300ReleaseDmaRegion(rmesa, region, __FUNCTION__); +- +- alignment--; +- rmesa->dma.current.start = rmesa->dma.current.ptr = +- (rmesa->dma.current.ptr + alignment) & ~alignment; +- +- if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end) +- r300RefillCurrentDmaRegion(rmesa); +- +- region->start = rmesa->dma.current.start; +- region->ptr = rmesa->dma.current.start; +- region->end = rmesa->dma.current.start + bytes; +- region->address = rmesa->dma.current.address; +- region->buf = rmesa->dma.current.buf; +- region->buf->refcount++; +- +- rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ +- rmesa->dma.current.start = +- rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7; +- +- assert(rmesa->dma.current.ptr <= rmesa->dma.current.end); + } + +-#endif +- +-GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer, +- GLint size) +-{ +- int offset = +- (char *)pointer - +- (char *)rmesa->radeon.radeonScreen->gartTextures.map; +- int valid = (size >= 0 && offset >= 0 +- && offset + size < +- rmesa->radeon.radeonScreen->gartTextures.size); +- +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer, +- valid); +- +- return valid; +-} +- +-GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer) +-{ +- int offset = +- (char *)pointer - +- (char *)rmesa->radeon.radeonScreen->gartTextures.map; +- +- //fprintf(stderr, "offset=%08x\n", offset); +- +- if (offset < 0 +- || offset > rmesa->radeon.radeonScreen->gartTextures.size) +- return ~0; +- else +- return rmesa->radeon.radeonScreen->gart_texture_offset + offset; +-} + + void r300InitIoctlFuncs(struct dd_function_table *functions) + { + functions->Clear = r300Clear; + functions->Finish = radeonFinish; +- functions->Flush = r300Flush; ++ functions->Flush = radeonFlush; + } +diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.h b/src/mesa/drivers/dri/r300/r300_ioctl.h +index e1143fb..3abfa71 100644 +--- a/src/mesa/drivers/dri/r300/r300_ioctl.h ++++ b/src/mesa/drivers/dri/r300/r300_ioctl.h +@@ -39,22 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r300_context.h" + #include "radeon_drm.h" + +-extern GLboolean r300IsGartMemory(r300ContextPtr rmesa, +- const GLvoid * pointer, GLint size); +- +-extern GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, +- const GLvoid * pointer); +- +-extern void r300Flush(GLcontext * ctx); +- +-extern void r300ReleaseDmaRegion(r300ContextPtr rmesa, +- struct r300_dma_region *region, +- const char *caller); +-extern void r300AllocDmaRegion(r300ContextPtr rmesa, +- struct r300_dma_region *region, int bytes, +- int alignment); +- + extern void r300InitIoctlFuncs(struct dd_function_table *functions); + +-extern void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size); + #endif /* __R300_IOCTL_H__ */ +diff --git a/src/mesa/drivers/dri/r300/r300_mem.c b/src/mesa/drivers/dri/r300/r300_mem.c +deleted file mode 100644 +index f8f9d4f..0000000 +--- a/src/mesa/drivers/dri/r300/r300_mem.c ++++ /dev/null +@@ -1,385 +0,0 @@ +-/* +- * Copyright (C) 2005 Aapo Tahkola. +- * +- * All Rights Reserved. +- * +- * Permission is hereby granted, free of charge, to any person obtaining +- * a copy of this software and associated documentation files (the +- * "Software"), to deal in the Software without restriction, including +- * without limitation the rights to use, copy, modify, merge, publish, +- * distribute, sublicense, and/or sell copies of the Software, and to +- * permit persons to whom the Software is furnished to do so, subject to +- * the following conditions: +- * +- * The above copyright notice and this permission notice (including the +- * next paragraph) shall be included in all copies or substantial +- * portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- * +- */ +- +-/** +- * \file +- * +- * \author Aapo Tahkola +- */ +- +-#include +- +-#include "r300_context.h" +-#include "r300_cmdbuf.h" +-#include "r300_ioctl.h" +-#include "r300_mem.h" +-#include "radeon_ioctl.h" +- +-#ifdef USER_BUFFERS +- +-static void resize_u_list(r300ContextPtr rmesa) +-{ +- void *temp; +- int nsize; +- +- temp = rmesa->rmm->u_list; +- nsize = rmesa->rmm->u_size * 2; +- +- rmesa->rmm->u_list = _mesa_malloc(nsize * sizeof(*rmesa->rmm->u_list)); +- _mesa_memset(rmesa->rmm->u_list, 0, +- nsize * sizeof(*rmesa->rmm->u_list)); +- +- if (temp) { +- r300FlushCmdBuf(rmesa, __FUNCTION__); +- +- _mesa_memcpy(rmesa->rmm->u_list, temp, +- rmesa->rmm->u_size * sizeof(*rmesa->rmm->u_list)); +- _mesa_free(temp); +- } +- +- rmesa->rmm->u_size = nsize; +-} +- +-void r300_mem_init(r300ContextPtr rmesa) +-{ +- rmesa->rmm = malloc(sizeof(struct r300_memory_manager)); +- memset(rmesa->rmm, 0, sizeof(struct r300_memory_manager)); +- +- rmesa->rmm->u_size = 128; +- resize_u_list(rmesa); +-} +- +-void r300_mem_destroy(r300ContextPtr rmesa) +-{ +- _mesa_free(rmesa->rmm->u_list); +- rmesa->rmm->u_list = NULL; +- +- _mesa_free(rmesa->rmm); +- rmesa->rmm = NULL; +-} +- +-void *r300_mem_ptr(r300ContextPtr rmesa, int id) +-{ +- assert(id <= rmesa->rmm->u_last); +- return rmesa->rmm->u_list[id].ptr; +-} +- +-int r300_mem_find(r300ContextPtr rmesa, void *ptr) +-{ +- int i; +- +- for (i = 1; i < rmesa->rmm->u_size + 1; i++) +- if (rmesa->rmm->u_list[i].ptr && +- ptr >= rmesa->rmm->u_list[i].ptr && +- ptr < +- rmesa->rmm->u_list[i].ptr + rmesa->rmm->u_list[i].size) +- break; +- +- if (i < rmesa->rmm->u_size + 1) +- return i; +- +- fprintf(stderr, "%p failed\n", ptr); +- return 0; +-} +- +-//#define MM_DEBUG +-int r300_mem_alloc(r300ContextPtr rmesa, int alignment, int size) +-{ +- drm_radeon_mem_alloc_t alloc; +- int offset = 0, ret; +- int i, free = -1; +- int done_age; +- drm_radeon_mem_free_t memfree; +- int tries = 0; +- static int bytes_wasted = 0, allocated = 0; +- +- if (size < 4096) +- bytes_wasted += 4096 - size; +- +- allocated += size; +- +-#if 0 +- static int t = 0; +- if (t != time(NULL)) { +- t = time(NULL); +- fprintf(stderr, "slots used %d, wasted %d kb, allocated %d\n", +- rmesa->rmm->u_last, bytes_wasted / 1024, +- allocated / 1024); +- } +-#endif +- +- memfree.region = RADEON_MEM_REGION_GART; +- +- again: +- +- done_age = radeonGetAge((radeonContextPtr) rmesa); +- +- if (rmesa->rmm->u_last + 1 >= rmesa->rmm->u_size) +- resize_u_list(rmesa); +- +- for (i = rmesa->rmm->u_last + 1; i > 0; i--) { +- if (rmesa->rmm->u_list[i].ptr == NULL) { +- free = i; +- continue; +- } +- +- if (rmesa->rmm->u_list[i].h_pending == 0 && +- rmesa->rmm->u_list[i].pending +- && rmesa->rmm->u_list[i].age <= done_age) { +- memfree.region_offset = +- (char *)rmesa->rmm->u_list[i].ptr - +- (char *)rmesa->radeon.radeonScreen->gartTextures. +- map; +- +- ret = +- drmCommandWrite(rmesa->radeon.radeonScreen-> +- driScreen->fd, DRM_RADEON_FREE, +- &memfree, sizeof(memfree)); +- +- if (ret) { +- fprintf(stderr, "Failed to free at %p\n", +- rmesa->rmm->u_list[i].ptr); +- fprintf(stderr, "ret = %s\n", strerror(-ret)); +- exit(1); +- } else { +-#ifdef MM_DEBUG +- fprintf(stderr, "really freed %d at age %x\n", +- i, +- radeonGetAge((radeonContextPtr) rmesa)); +-#endif +- if (i == rmesa->rmm->u_last) +- rmesa->rmm->u_last--; +- +- if (rmesa->rmm->u_list[i].size < 4096) +- bytes_wasted -= +- 4096 - rmesa->rmm->u_list[i].size; +- +- allocated -= rmesa->rmm->u_list[i].size; +- rmesa->rmm->u_list[i].pending = 0; +- rmesa->rmm->u_list[i].ptr = NULL; +- free = i; +- } +- } +- } +- rmesa->rmm->u_head = i; +- +- if (free == -1) { +- WARN_ONCE("Ran out of slots!\n"); +- //usleep(100); +- r300FlushCmdBuf(rmesa, __FUNCTION__); +- tries++; +- if (tries > 100) { +- WARN_ONCE("Ran out of slots!\n"); +- exit(1); +- } +- goto again; +- } +- +- alloc.region = RADEON_MEM_REGION_GART; +- alloc.alignment = alignment; +- alloc.size = size; +- alloc.region_offset = &offset; +- +- ret = +- drmCommandWriteRead(rmesa->radeon.dri.fd, DRM_RADEON_ALLOC, &alloc, +- sizeof(alloc)); +- if (ret) { +-#if 0 +- WARN_ONCE("Ran out of mem!\n"); +- r300FlushCmdBuf(rmesa, __FUNCTION__); +- //usleep(100); +- tries2++; +- tries = 0; +- if (tries2 > 100) { +- WARN_ONCE("Ran out of GART memory!\n"); +- exit(1); +- } +- goto again; +-#else +- WARN_ONCE +- ("Ran out of GART memory (for %d)!\nPlease consider adjusting GARTSize option.\n", +- size); +- return 0; +-#endif +- } +- +- i = free; +- +- if (i > rmesa->rmm->u_last) +- rmesa->rmm->u_last = i; +- +- rmesa->rmm->u_list[i].ptr = +- ((GLubyte *) rmesa->radeon.radeonScreen->gartTextures.map) + offset; +- rmesa->rmm->u_list[i].size = size; +- rmesa->rmm->u_list[i].age = 0; +- //fprintf(stderr, "alloc %p at id %d\n", rmesa->rmm->u_list[i].ptr, i); +- +-#ifdef MM_DEBUG +- fprintf(stderr, "allocated %d at age %x\n", i, +- radeonGetAge((radeonContextPtr) rmesa)); +-#endif +- +- return i; +-} +- +-void r300_mem_use(r300ContextPtr rmesa, int id) +-{ +- uint64_t ull; +-#ifdef MM_DEBUG +- fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, +- radeonGetAge((radeonContextPtr) rmesa)); +-#endif +- drm_r300_cmd_header_t *cmd; +- +- assert(id <= rmesa->rmm->u_last); +- +- if (id == 0) +- return; +- +- cmd = +- (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa, +- 2 + sizeof(ull) / 4, +- __FUNCTION__); +- cmd[0].scratch.cmd_type = R300_CMD_SCRATCH; +- cmd[0].scratch.reg = R300_MEM_SCRATCH; +- cmd[0].scratch.n_bufs = 1; +- cmd[0].scratch.flags = 0; +- cmd++; +- +- ull = (uint64_t) (intptr_t) & rmesa->rmm->u_list[id].age; +- _mesa_memcpy(cmd, &ull, sizeof(ull)); +- cmd += sizeof(ull) / 4; +- +- cmd[0].u = /*id */ 0; +- +- LOCK_HARDWARE(&rmesa->radeon); /* Protect from DRM. */ +- rmesa->rmm->u_list[id].h_pending++; +- UNLOCK_HARDWARE(&rmesa->radeon); +-} +- +-unsigned long r300_mem_offset(r300ContextPtr rmesa, int id) +-{ +- unsigned long offset; +- +- assert(id <= rmesa->rmm->u_last); +- +- offset = (char *)rmesa->rmm->u_list[id].ptr - +- (char *)rmesa->radeon.radeonScreen->gartTextures.map; +- offset += rmesa->radeon.radeonScreen->gart_texture_offset; +- +- return offset; +-} +- +-void *r300_mem_map(r300ContextPtr rmesa, int id, int access) +-{ +-#ifdef MM_DEBUG +- fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, +- radeonGetAge((radeonContextPtr) rmesa)); +-#endif +- void *ptr; +- int tries = 0; +- +- assert(id <= rmesa->rmm->u_last); +- +- if (access == R300_MEM_R) { +- +- if (rmesa->rmm->u_list[id].mapped == 1) +- WARN_ONCE("buffer %d already mapped\n", id); +- +- rmesa->rmm->u_list[id].mapped = 1; +- ptr = r300_mem_ptr(rmesa, id); +- +- return ptr; +- } +- +- if (rmesa->rmm->u_list[id].h_pending) +- r300FlushCmdBuf(rmesa, __FUNCTION__); +- +- if (rmesa->rmm->u_list[id].h_pending) { +- return NULL; +- } +- +- while (rmesa->rmm->u_list[id].age > +- radeonGetAge((radeonContextPtr) rmesa) && tries++ < 1000) +- usleep(10); +- +- if (tries >= 1000) { +- fprintf(stderr, "Idling failed (%x vs %x)\n", +- rmesa->rmm->u_list[id].age, +- radeonGetAge((radeonContextPtr) rmesa)); +- return NULL; +- } +- +- if (rmesa->rmm->u_list[id].mapped == 1) +- WARN_ONCE("buffer %d already mapped\n", id); +- +- rmesa->rmm->u_list[id].mapped = 1; +- ptr = r300_mem_ptr(rmesa, id); +- +- return ptr; +-} +- +-void r300_mem_unmap(r300ContextPtr rmesa, int id) +-{ +-#ifdef MM_DEBUG +- fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, +- radeonGetAge((radeonContextPtr) rmesa)); +-#endif +- +- assert(id <= rmesa->rmm->u_last); +- +- if (rmesa->rmm->u_list[id].mapped == 0) +- WARN_ONCE("buffer %d not mapped\n", id); +- +- rmesa->rmm->u_list[id].mapped = 0; +-} +- +-void r300_mem_free(r300ContextPtr rmesa, int id) +-{ +-#ifdef MM_DEBUG +- fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, +- radeonGetAge((radeonContextPtr) rmesa)); +-#endif +- +- assert(id <= rmesa->rmm->u_last); +- +- if (id == 0) +- return; +- +- if (rmesa->rmm->u_list[id].ptr == NULL) { +- WARN_ONCE("Not allocated!\n"); +- return; +- } +- +- if (rmesa->rmm->u_list[id].pending) { +- WARN_ONCE("%p already pended!\n", rmesa->rmm->u_list[id].ptr); +- return; +- } +- +- rmesa->rmm->u_list[id].pending = 1; +-} +-#endif +diff --git a/src/mesa/drivers/dri/r300/r300_mem.h b/src/mesa/drivers/dri/r300/r300_mem.h +deleted file mode 100644 +index 625a7f6..0000000 +--- a/src/mesa/drivers/dri/r300/r300_mem.h ++++ /dev/null +@@ -1,37 +0,0 @@ +-#ifndef __R300_MEM_H__ +-#define __R300_MEM_H__ +- +-//#define R300_MEM_PDL 0 +-#define R300_MEM_UL 1 +- +-#define R300_MEM_R 1 +-#define R300_MEM_W 2 +-#define R300_MEM_RW (R300_MEM_R | R300_MEM_W) +- +-#define R300_MEM_SCRATCH 2 +- +-struct r300_memory_manager { +- struct { +- void *ptr; +- uint32_t size; +- uint32_t age; +- uint32_t h_pending; +- int pending; +- int mapped; +- } *u_list; +- int u_head, u_size, u_last; +- +-}; +- +-extern void r300_mem_init(r300ContextPtr rmesa); +-extern void r300_mem_destroy(r300ContextPtr rmesa); +-extern void *r300_mem_ptr(r300ContextPtr rmesa, int id); +-extern int r300_mem_find(r300ContextPtr rmesa, void *ptr); +-extern int r300_mem_alloc(r300ContextPtr rmesa, int alignment, int size); +-extern void r300_mem_use(r300ContextPtr rmesa, int id); +-extern unsigned long r300_mem_offset(r300ContextPtr rmesa, int id); +-extern void *r300_mem_map(r300ContextPtr rmesa, int id, int access); +-extern void r300_mem_unmap(r300ContextPtr rmesa, int id); +-extern void r300_mem_free(r300ContextPtr rmesa, int id); +- +-#endif +diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h +index 8f1a663..ed552d0 100644 +--- a/src/mesa/drivers/dri/r300/r300_reg.h ++++ b/src/mesa/drivers/dri/r300/r300_reg.h +@@ -1531,6 +1531,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. + # define R500_SEL_FILTER4_TC3 (3 << 18) + + #define R300_TX_OFFSET_0 0x4540 ++#define R300_TX_OFFSET_1 0x4544 ++#define R300_TX_OFFSET_2 0x4548 ++#define R300_TX_OFFSET_3 0x454C ++#define R300_TX_OFFSET_4 0x4550 ++#define R300_TX_OFFSET_5 0x4554 ++#define R300_TX_OFFSET_6 0x4558 ++#define R300_TX_OFFSET_7 0x455C + /* BEGIN: Guess from R200 */ + # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) + # define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) +diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c +index 16ce4a1..924305d 100644 +--- a/src/mesa/drivers/dri/r300/r300_render.c ++++ b/src/mesa/drivers/dri/r300/r300_render.c +@@ -66,8 +66,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "tnl/t_vp_build.h" + #include "radeon_reg.h" + #include "radeon_macros.h" +-#include "radeon_ioctl.h" +-#include "radeon_state.h" + #include "r300_context.h" + #include "r300_ioctl.h" + #include "r300_state.h" +@@ -175,85 +173,164 @@ int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim) + static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts) + { + r300ContextPtr rmesa = R300_CONTEXT(ctx); +- struct r300_dma_region *rvb = &rmesa->state.elt_dma; + void *out; + +- if (r300IsGartMemory(rmesa, elts, n_elts * 4)) { +- rvb->address = rmesa->radeon.radeonScreen->gartTextures.map; +- rvb->start = ((char *)elts) - rvb->address; +- rvb->aos_offset = +- rmesa->radeon.radeonScreen->gart_texture_offset + +- rvb->start; +- return; +- } else if (r300IsGartMemory(rmesa, elts, 1)) { +- WARN_ONCE("Pointer not within GART memory!\n"); +- _mesa_exit(-1); +- } +- +- r300AllocDmaRegion(rmesa, rvb, n_elts * 4, 4); +- rvb->aos_offset = GET_START(rvb); +- +- out = rvb->address + rvb->start; ++ radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo, ++ &rmesa->radeon.tcl.elt_dma_offset, n_elts * 4, 4); ++ radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1); ++ out = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset; + memcpy(out, elts, n_elts * 4); ++ radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo); + } + +-static void r300FireEB(r300ContextPtr rmesa, unsigned long addr, +- int vertex_count, int type) ++static void r300FireEB(r300ContextPtr rmesa, int vertex_count, int type) + { +- int cmd_reserved = 0; +- int cmd_written = 0; +- drm_radeon_cmd_header_t *cmd = NULL; +- +- start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0), 0); +- e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count << 16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); +- +- start_packet3(CP_PACKET3(R300_PACKET3_INDX_BUFFER, 2), 2); +- e32(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) | +- (R300_VAP_PORT_IDX0 >> 2)); +- e32(addr); +- e32(vertex_count); ++ BATCH_LOCALS(&rmesa->radeon); ++ ++ if (vertex_count > 0) { ++ BEGIN_BATCH(10); ++ OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0); ++ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | ++ ((vertex_count + 0) << 16) | ++ type | ++ R300_VAP_VF_CNTL__INDEX_SIZE_32bit); ++ ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2); ++ OUT_BATCH(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) | ++ (R300_VAP_PORT_IDX0 >> 2)); ++ OUT_BATCH_RELOC(rmesa->radeon.tcl.elt_dma_offset, ++ rmesa->radeon.tcl.elt_dma_bo, ++ rmesa->radeon.tcl.elt_dma_offset, ++ RADEON_GEM_DOMAIN_GTT, 0, 0); ++ OUT_BATCH(vertex_count); ++ } else { ++ OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2); ++ OUT_BATCH(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) | ++ (R300_VAP_PORT_IDX0 >> 2)); ++ OUT_BATCH(rmesa->radeon.tcl.elt_dma_offset); ++ OUT_BATCH(vertex_count); ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.elt_dma_bo, ++ RADEON_GEM_DOMAIN_GTT, 0, 0); ++ } ++ END_BATCH(); ++ } + } + + static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) + { ++ BATCH_LOCALS(&rmesa->radeon); ++ uint32_t voffset; + int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2; + int i; +- int cmd_reserved = 0; +- int cmd_written = 0; +- drm_radeon_cmd_header_t *cmd = NULL; +- ++ + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr, + offset); + +- start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1), sz - 1); +- e32(nr); +- +- for (i = 0; i + 1 < nr; i += 2) { +- e32((rmesa->state.aos[i].aos_size << 0) | +- (rmesa->state.aos[i].aos_stride << 8) | +- (rmesa->state.aos[i + 1].aos_size << 16) | +- (rmesa->state.aos[i + 1].aos_stride << 24)); ++ ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ BEGIN_BATCH(sz+2+(nr * 2)); ++ OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1); ++ OUT_BATCH(nr); ++ ++ for (i = 0; i + 1 < nr; i += 2) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) | ++ (rmesa->radeon.tcl.aos[i].stride << 8) | ++ (rmesa->radeon.tcl.aos[i + 1].components << 16) | ++ (rmesa->radeon.tcl.aos[i + 1].stride << 24)); ++ ++ voffset = rmesa->radeon.tcl.aos[i + 0].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->radeon.tcl.aos[i].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ voffset = rmesa->radeon.tcl.aos[i + 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->radeon.tcl.aos[i+1].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++ ++ if (nr & 1) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | ++ (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); ++ voffset = rmesa->radeon.tcl.aos[nr - 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->radeon.tcl.aos[nr - 1].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++ END_BATCH(); ++ } else { + +- e32(rmesa->state.aos[i].aos_offset + offset * 4 * rmesa->state.aos[i].aos_stride); +- e32(rmesa->state.aos[i + 1].aos_offset + offset * 4 * rmesa->state.aos[i + 1].aos_stride); ++ BEGIN_BATCH(sz+2+(nr * 2)); ++ OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1); ++ OUT_BATCH(nr); ++ ++ for (i = 0; i + 1 < nr; i += 2) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) | ++ (rmesa->radeon.tcl.aos[i].stride << 8) | ++ (rmesa->radeon.tcl.aos[i + 1].components << 16) | ++ (rmesa->radeon.tcl.aos[i + 1].stride << 24)); ++ ++ voffset = rmesa->radeon.tcl.aos[i + 0].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; ++ OUT_BATCH(voffset); ++ voffset = rmesa->radeon.tcl.aos[i + 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; ++ OUT_BATCH(voffset); ++ } ++ ++ if (nr & 1) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | ++ (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); ++ voffset = rmesa->radeon.tcl.aos[nr - 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; ++ OUT_BATCH(voffset); ++ } ++ for (i = 0; i + 1 < nr; i += 2) { ++ voffset = rmesa->radeon.tcl.aos[i + 0].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.aos[i+0].bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ voffset = rmesa->radeon.tcl.aos[i + 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.aos[i+1].bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++ if (nr & 1) { ++ voffset = rmesa->radeon.tcl.aos[nr - 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.aos[nr-1].bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++ END_BATCH(); + } + +- if (nr & 1) { +- e32((rmesa->state.aos[nr - 1].aos_size << 0) | +- (rmesa->state.aos[nr - 1].aos_stride << 8)); +- e32(rmesa->state.aos[nr - 1].aos_offset + offset * 4 * rmesa->state.aos[nr - 1].aos_stride); +- } + } + + static void r300FireAOS(r300ContextPtr rmesa, int vertex_count, int type) + { +- int cmd_reserved = 0; +- int cmd_written = 0; +- drm_radeon_cmd_header_t *cmd = NULL; ++ BATCH_LOCALS(&rmesa->radeon); + +- start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0); +- e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type); ++ BEGIN_BATCH(3); ++ OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0); ++ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type); ++ END_BATCH(); + } + + static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, +@@ -269,6 +346,12 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, + if (type < 0 || num_verts <= 0) + return; + ++ /* Make space for at least 64 dwords. ++ * This is supposed to ensure that we can get all rendering ++ * commands into a single command buffer. ++ */ ++ rcommonEnsureCmdBufSpace(&rmesa->radeon, 64, __FUNCTION__); ++ + if (vb->Elts) { + if (num_verts > 65535) { + /* not implemented yet */ +@@ -287,12 +370,13 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, + * arrays. *sigh* + */ + r300EmitElts(ctx, vb->Elts, num_verts); +- r300EmitAOS(rmesa, rmesa->state.aos_count, start); +- r300FireEB(rmesa, rmesa->state.elt_dma.aos_offset, num_verts, type); ++ r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start); ++ r300FireEB(rmesa, num_verts, type); + } else { +- r300EmitAOS(rmesa, rmesa->state.aos_count, start); ++ r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start); + r300FireAOS(rmesa, num_verts, type); + } ++ COMMIT_BATCH(); + } + + static GLboolean r300RunRender(GLcontext * ctx, +@@ -303,7 +387,6 @@ static GLboolean r300RunRender(GLcontext * ctx, + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *vb = &tnl->vb; + +- + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s\n", __FUNCTION__); + +@@ -314,7 +397,7 @@ static GLboolean r300RunRender(GLcontext * ctx, + r300UpdateShaderStates(rmesa); + + r300EmitCacheFlush(rmesa); +- r300EmitState(rmesa); ++ radeonEmitState(&rmesa->radeon); + + for (i = 0; i < vb->PrimitiveCount; i++) { + GLuint prim = _tnl_translate_prim(&vb->Primitive[i]); +@@ -325,11 +408,7 @@ static GLboolean r300RunRender(GLcontext * ctx, + + r300EmitCacheFlush(rmesa); + +-#ifdef USER_BUFFERS +- r300UseArrays(ctx); +-#endif +- +- r300ReleaseArrays(ctx); ++ radeonReleaseArrays(ctx, ~0); + + return GL_FALSE; + } +@@ -348,7 +427,8 @@ static int r300Fallback(GLcontext * ctx) + { + r300ContextPtr r300 = R300_CONTEXT(ctx); + const unsigned back = ctx->Stencil._BackFace; +- ++ ++ FALLBACK_IF(r300->radeon.Fallback); + /* Do we need to use new-style shaders? + * Also is there a better way to do this? */ + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { +@@ -410,6 +490,9 @@ static GLboolean r300RunNonTCLRender(GLcontext * ctx, + if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) + return GL_TRUE; + ++ if (!r300ValidateBuffers(ctx)) ++ return GL_TRUE; ++ + return r300RunRender(ctx, stage); + } + +@@ -432,6 +515,9 @@ static GLboolean r300RunTCLRender(GLcontext * ctx, + return GL_TRUE; + } + ++ if (!r300ValidateBuffers(ctx)) ++ return GL_TRUE; ++ + r300UpdateShaders(rmesa); + + vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); +diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c +index 8095538..6796d36 100644 +--- a/src/mesa/drivers/dri/r300/r300_state.c ++++ b/src/mesa/drivers/dri/r300/r300_state.c +@@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/macros.h" + #include "main/context.h" + #include "main/dd.h" ++#include "main/framebuffer.h" + #include "main/simple_list.h" + #include "main/api_arrayelt.h" + #include "main/texformat.h" +@@ -53,8 +54,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "vbo/vbo.h" + #include "tnl/tnl.h" + +-#include "radeon_ioctl.h" +-#include "radeon_state.h" + #include "r300_context.h" + #include "r300_ioctl.h" + #include "r300_state.h" +@@ -589,8 +588,14 @@ static void r300SetDepthState(GLcontext * ctx) + static void r300SetStencilState(GLcontext * ctx, GLboolean state) + { + r300ContextPtr r300 = R300_CONTEXT(ctx); ++ GLboolean hw_stencil = GL_FALSE; ++ if (ctx->DrawBuffer) { ++ struct radeon_renderbuffer *rrbStencil ++ = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); ++ hw_stencil = (rrbStencil && rrbStencil->bo); ++ } + +- if (r300->state.stencil.hw_stencil) { ++ if (hw_stencil) { + R300_STATECHANGE(r300, zs); + if (state) { + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= +@@ -935,15 +940,25 @@ static void r300UpdateWindow(GLcontext * ctx) + GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0; + GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0; + const GLfloat *v = ctx->Viewport._WindowMap.m; ++ const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; ++ const GLboolean render_to_fbo = (ctx->DrawBuffer->Name != 0); ++ GLfloat y_scale, y_bias; ++ ++ if (render_to_fbo) { ++ y_scale = 1.0; ++ y_bias = 0; ++ } else { ++ y_scale = -1.0; ++ y_bias = yoffset; ++ } + + GLfloat sx = v[MAT_SX]; + GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; +- GLfloat sy = -v[MAT_SY]; +- GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y; +- GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale; +- GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale; ++ GLfloat sy = v[MAT_SY] * y_scale; ++ GLfloat ty = (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y; ++ GLfloat sz = v[MAT_SZ] * depthScale; ++ GLfloat tz = v[MAT_TZ] * depthScale; + +- R300_FIREVERTICES(rmesa); + R300_STATECHANGE(rmesa, vpt); + + rmesa->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(sx); +@@ -962,6 +977,8 @@ static void r300Viewport(GLcontext * ctx, GLint x, GLint y, + * values, or keep the originals hanging around. + */ + r300UpdateWindow(ctx); ++ ++ radeon_viewport(ctx, x, y, width, height); + } + + static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) +@@ -994,64 +1011,6 @@ void r300UpdateViewportOffset(GLcontext * ctx) + radeonUpdateScissor(ctx); + } + +-/** +- * Tell the card where to render (offset, pitch). +- * Effected by glDrawBuffer, etc +- */ +-void r300UpdateDrawBuffer(GLcontext * ctx) +-{ +- r300ContextPtr rmesa = R300_CONTEXT(ctx); +- r300ContextPtr r300 = rmesa; +- struct gl_framebuffer *fb = ctx->DrawBuffer; +- driRenderbuffer *drb; +- +- if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { +- /* draw to front */ +- drb = +- (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT]. +- Renderbuffer; +- } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { +- /* draw to back */ +- drb = +- (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT]. +- Renderbuffer; +- } else { +- /* drawing to multiple buffers, or none */ +- return; +- } +- +- assert(drb); +- assert(drb->flippedPitch); +- +- R300_STATECHANGE(rmesa, cb); +- +- r300->hw.cb.cmd[R300_CB_OFFSET] = drb->flippedOffset + //r300->radeon.state.color.drawOffset + +- r300->radeon.radeonScreen->fbLocation; +- r300->hw.cb.cmd[R300_CB_PITCH] = drb->flippedPitch; //r300->radeon.state.color.drawPitch; +- +- if (r300->radeon.radeonScreen->cpp == 4) +- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888; +- else +- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565; +- +- if (r300->radeon.sarea->tiling_enabled) +- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE; +-#if 0 +- R200_STATECHANGE(rmesa, ctx); +- +- /* Note: we used the (possibly) page-flipped values */ +- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] +- = ((drb->flippedOffset + rmesa->r200Screen->fbLocation) +- & R200_COLOROFFSET_MASK); +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch; +- +- if (rmesa->sarea->tiling_enabled) { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= +- R200_COLOR_TILE_ENABLE; +- } +-#endif +-} +- + static void + r300FetchStateParameter(GLcontext * ctx, + const gl_state_index state[STATE_LENGTH], +@@ -1269,7 +1228,8 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) + } + + r300->hw.fpt.cmd[R300_FPT_CMD_0] = +- cmdpacket0(R300_US_TEX_INST_0, code->tex.length); ++ cmdpacket0(r300->radeon.radeonScreen, ++ R300_US_TEX_INST_0, code->tex.length); + } + + static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) +@@ -1320,7 +1280,7 @@ static GLuint translate_lod_bias(GLfloat bias) + static void r300SetupTextures(GLcontext * ctx) + { + int i, mtu; +- struct r300_tex_obj *t; ++ struct radeon_tex_obj *t; + r300ContextPtr r300 = R300_CONTEXT(ctx); + int hw_tmu = 0; + int last_hw_tmu = -1; /* -1 translates into no setup costs for fields */ +@@ -1354,21 +1314,16 @@ static void r300SetupTextures(GLcontext * ctx) + /* We cannot let disabled tmu offsets pass DRM */ + for (i = 0; i < mtu; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { +- +-#if 0 /* Enables old behaviour */ +- hw_tmu = i; +-#endif + tmu_mappings[i] = hw_tmu; + +- t = r300->state.texture.unit[i].texobj; +- /* XXX questionable fix for bug 9170: */ ++ t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); + if (!t) + continue; + +- if ((t->format & 0xffffff00) == 0xffffff00) { ++ if ((t->pp_txformat & 0xffffff00) == 0xffffff00) { + WARN_ONCE + ("unknown texture format (entry %x) encountered. Help me !\n", +- t->format & 0xff); ++ t->pp_txformat & 0xff); + } + + if (RADEON_DEBUG & DEBUG_STATE) +@@ -1379,29 +1334,28 @@ static void r300SetupTextures(GLcontext * ctx) + + r300->hw.tex.filter.cmd[R300_TEX_VALUE_0 + + hw_tmu] = +- gen_fixed_filter(t->filter) | (hw_tmu << 28); ++ gen_fixed_filter(t->pp_txfilter) | (hw_tmu << 28); + /* Note: There is a LOD bias per texture unit and a LOD bias + * per texture object. We add them here to get the correct behaviour. + * (The per-texture object LOD bias was introduced in OpenGL 1.4 + * and is not present in the EXT_texture_object extension). + */ + r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = +- t->filter_1 | +- translate_lod_bias(ctx->Texture.Unit[i].LodBias + t->base.tObj->LodBias); ++ t->pp_txfilter_1 | ++ translate_lod_bias(ctx->Texture.Unit[i].LodBias + t->base.LodBias); + r300->hw.tex.size.cmd[R300_TEX_VALUE_0 + hw_tmu] = +- t->size; ++ t->pp_txsize; + r300->hw.tex.format.cmd[R300_TEX_VALUE_0 + +- hw_tmu] = t->format; ++ hw_tmu] = t->pp_txformat; + r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0 + hw_tmu] = +- t->pitch_reg; +- r300->hw.tex.offset.cmd[R300_TEX_VALUE_0 + +- hw_tmu] = t->offset; ++ t->pp_txpitch; ++ r300->hw.textures[hw_tmu] = t; + +- if (t->offset & R300_TXO_MACRO_TILE) { ++ if (t->tile_bits & R300_TXO_MACRO_TILE) { + WARN_ONCE("macro tiling enabled!\n"); + } + +- if (t->offset & R300_TXO_MICRO_TILE) { ++ if (t->tile_bits & R300_TXO_MICRO_TILE) { + WARN_ONCE("micro tiling enabled!\n"); + } + +@@ -1418,21 +1372,21 @@ static void r300SetupTextures(GLcontext * ctx) + } + + r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER0_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, last_hw_tmu + 1); + r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER1_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER1_0, last_hw_tmu + 1); + r300->hw.tex.size.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_SIZE_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_SIZE_0, last_hw_tmu + 1); + r300->hw.tex.format.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FORMAT_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT_0, last_hw_tmu + 1); + r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FORMAT2_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT2_0, last_hw_tmu + 1); + r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_OFFSET_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_OFFSET_0, last_hw_tmu + 1); + r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_CHROMA_KEY_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_CHROMA_KEY_0, last_hw_tmu + 1); + r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_BORDER_COLOR_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1); + + if (!fp) /* should only happenen once, just after context is created */ + return; +@@ -1444,7 +1398,7 @@ static void r300SetupTextures(GLcontext * ctx) + r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1; + r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0; + r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER0_0, 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 1); + } + r300SetupFragmentShaderTextures(ctx, tmu_mappings); + } else +@@ -1609,7 +1563,7 @@ static void r300SetupRSUnit(GLcontext * ctx) + r300->hw.rc.cmd[1] |= (rs_tex_count << R300_IT_COUNT_SHIFT) | (col_ip << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; + r300->hw.rc.cmd[2] |= high_rr - 1; + +- r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, high_rr); ++ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_INST_0, high_rr); + + if (InputsRead) + WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead); +@@ -1787,7 +1741,7 @@ static void r500SetupRSUnit(GLcontext * ctx) + r300->hw.rc.cmd[1] |= (rs_tex_count << R300_IT_COUNT_SHIFT) | (col_ip << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; + r300->hw.rc.cmd[2] |= 0xC0 | (high_rr - 1); + +- r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R500_RS_INST_0, high_rr); ++ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_INST_0, high_rr); + + if (InputsRead) + WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead); +@@ -1984,6 +1938,7 @@ static void r300SetupRealVertexProgram(r300ContextPtr rmesa) + (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT); + } + ++ + static void r300SetupVertexProgram(r300ContextPtr rmesa) + { + GLcontext *ctx = rmesa->radeon.glCtx; +@@ -2013,6 +1968,7 @@ static void r300SetupVertexProgram(r300ContextPtr rmesa) + */ + static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) + { ++ r300ContextPtr rmesa = R300_CONTEXT(ctx); + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(cap), +@@ -2058,8 +2014,12 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) + case GL_POLYGON_OFFSET_FILL: + r300SetPolygonOffsetState(ctx, state); + break; ++ case GL_SCISSOR_TEST: ++ radeon_firevertices(&rmesa->radeon); ++ rmesa->radeon.state.scissor.enabled = state; ++ radeonUpdateScissor( ctx ); ++ break; + default: +- radeonEnable(ctx, cap, state); + break; + } + } +@@ -2078,7 +2038,7 @@ static void r300ResetHwState(r300ContextPtr r300) + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s\n", __FUNCTION__); + +- r300UpdateWindow(ctx); ++ radeon_firevertices(&r300->radeon); + + r300ColorMask(ctx, + ctx->Color.ColorMask[RCOMP], +@@ -2100,8 +2060,6 @@ static void r300ResetHwState(r300ContextPtr r300) + + r300UpdateCulling(ctx); + +- r300UpdateTextureState(ctx); +- + r300SetBlendState(ctx); + r300SetLogicOpState(ctx); + +@@ -2240,20 +2198,6 @@ static void r300ResetHwState(r300ContextPtr r300) + + r300BlendColor(ctx, ctx->Color.BlendColor); + +- /* Again, r300ClearBuffer uses this */ +- r300->hw.cb.cmd[R300_CB_OFFSET] = +- r300->radeon.state.color.drawOffset + +- r300->radeon.radeonScreen->fbLocation; +- r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.state.color.drawPitch; +- +- if (r300->radeon.radeonScreen->cpp == 4) +- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888; +- else +- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565; +- +- if (r300->radeon.sarea->tiling_enabled) +- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE; +- + r300->hw.rb3d_dither_ctl.cmd[1] = 0; + r300->hw.rb3d_dither_ctl.cmd[2] = 0; + r300->hw.rb3d_dither_ctl.cmd[3] = 0; +@@ -2269,34 +2213,8 @@ static void r300ResetHwState(r300ContextPtr r300) + r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000; + r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff; + +- r300->hw.zb.cmd[R300_ZB_OFFSET] = +- r300->radeon.radeonScreen->depthOffset + +- r300->radeon.radeonScreen->fbLocation; +- r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch; +- +- if (r300->radeon.sarea->tiling_enabled) { +- /* XXX: Turn off when clearing buffers ? */ +- r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTHMACROTILE_ENABLE; +- +- if (ctx->Visual.depthBits == 24) +- r300->hw.zb.cmd[R300_ZB_PITCH] |= +- R300_DEPTHMICROTILE_TILED; +- } +- + r300->hw.zb_depthclearvalue.cmd[1] = 0; + +- switch (ctx->Visual.depthBits) { +- case 16: +- r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_16BIT_INT_Z; +- break; +- case 24: +- r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; +- break; +- default: +- fprintf(stderr, "Error: Unsupported depth %d... exiting\n", ctx->Visual.depthBits); +- _mesa_exit(-1); +- } +- + r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE; + r300->hw.zstencil_format.cmd[3] = 0x00000003; + r300->hw.zstencil_format.cmd[4] = 0x00000000; +@@ -2317,7 +2235,7 @@ static void r300ResetHwState(r300ContextPtr r300) + r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0; + } + +- r300->hw.all_dirty = GL_TRUE; ++ r300->radeon.hw.all_dirty = GL_TRUE; + } + + void r300UpdateShaders(r300ContextPtr rmesa) +@@ -2328,8 +2246,8 @@ void r300UpdateShaders(r300ContextPtr rmesa) + + ctx = rmesa->radeon.glCtx; + +- if (rmesa->NewGLState && hw_tcl_on) { +- rmesa->NewGLState = 0; ++ if (rmesa->radeon.NewGLState && hw_tcl_on) { ++ rmesa->radeon.NewGLState = 0; + + for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { + rmesa->temp_attrib[i] = +@@ -2408,10 +2326,10 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) + R300_STATECHANGE(rmesa, fpi[1]); + R300_STATECHANGE(rmesa, fpi[2]); + R300_STATECHANGE(rmesa, fpi[3]); +- rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, code->alu.length); +- rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, code->alu.length); +- rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, code->alu.length); +- rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, code->alu.length); ++ rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_RGB_INST_0, code->alu.length); ++ rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_RGB_ADDR_0, code->alu.length); ++ rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_ALPHA_INST_0, code->alu.length); ++ rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_ALPHA_ADDR_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) { + rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst0; + rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst1; +@@ -2442,7 +2360,7 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) + } + + R300_STATECHANGE(rmesa, fpp); +- rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, code->const_nr * 4); ++ rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, code->const_nr * 4); + for (i = 0; i < code->const_nr; i++) { + const GLfloat *constant = get_fragmentprogram_constant(ctx, + &fp->mesa_program.Base, code->constant[i]); +@@ -2534,7 +2452,6 @@ void r300UpdateShaderStates(r300ContextPtr rmesa) + GLcontext *ctx; + ctx = rmesa->radeon.glCtx; + +- r300UpdateTextureState(ctx); + r300SetEarlyZState(ctx); + + /* w_fmt value is set to get best performance +@@ -2587,12 +2504,16 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) + _ae_invalidate_state(ctx, new_state); + + if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { +- r300UpdateDrawBuffer(ctx); ++ _mesa_update_framebuffer(ctx); ++ /* this updates the DrawBuffer's Width/Height if it's a FBO */ ++ _mesa_update_draw_buffer_bounds(ctx); ++ ++ R300_STATECHANGE(r300, cb); + } + + r300UpdateStateParameters(ctx, new_state); + +- r300->NewGLState |= new_state; ++ r300->radeon.NewGLState |= new_state; + } + + /** +@@ -2602,30 +2523,6 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) + */ + void r300InitState(r300ContextPtr r300) + { +- GLcontext *ctx = r300->radeon.glCtx; +- GLuint depth_fmt; +- +- radeonInitState(&r300->radeon); +- +- switch (ctx->Visual.depthBits) { +- case 16: +- r300->state.depth.scale = 1.0 / (GLfloat) 0xffff; +- depth_fmt = R300_DEPTHFORMAT_16BIT_INT_Z; +- break; +- case 24: +- r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff; +- depth_fmt = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; +- break; +- default: +- fprintf(stderr, "Error: Unsupported depth %d... exiting\n", +- ctx->Visual.depthBits); +- _mesa_exit(-1); +- } +- +- /* Only have hw stencil when depth buffer is 24 bits deep */ +- r300->state.stencil.hw_stencil = (ctx->Visual.stencilBits > 0 && +- ctx->Visual.depthBits == 24); +- + memset(&(r300->state.texture), 0, sizeof(r300->state.texture)); + + r300ResetHwState(r300); +@@ -2661,7 +2558,6 @@ void r300UpdateClipPlanes( GLcontext *ctx ) + */ + void r300InitStateFuncs(struct dd_function_table *functions) + { +- radeonInitStateFuncs(functions); + + functions->UpdateState = r300InvalidateState; + functions->AlphaFunc = r300AlphaFunc; +@@ -2697,4 +2593,8 @@ void r300InitStateFuncs(struct dd_function_table *functions) + functions->RenderMode = r300RenderMode; + + functions->ClipPlane = r300ClipPlane; ++ functions->Scissor = radeonScissor; ++ ++ functions->DrawBuffer = radeonDrawBuffer; ++ functions->ReadBuffer = radeonReadBuffer; + } +diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h +index 0589ab7..247a20e 100644 +--- a/src/mesa/drivers/dri/r300/r300_state.h ++++ b/src/mesa/drivers/dri/r300/r300_state.h +@@ -39,32 +39,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #define R300_NEWPRIM( rmesa ) \ + do { \ +- if ( rmesa->dma.flush ) \ +- rmesa->dma.flush( rmesa ); \ ++ if ( rmesa->radeon.dma.flush ) \ ++ rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); \ + } while (0) + + #define R300_STATECHANGE(r300, atom) \ + do { \ + R300_NEWPRIM(r300); \ + r300->hw.atom.dirty = GL_TRUE; \ +- r300->hw.is_dirty = GL_TRUE; \ ++ r300->radeon.hw.is_dirty = GL_TRUE; \ + } while(0) + +-#define R300_PRINT_STATE(r300, atom) \ +- r300PrintStateAtom(r300, &r300->hw.atom) +- +-/* Fire the buffered vertices no matter what. +- TODO: This has not been implemented yet +- */ +-#define R300_FIREVERTICES( r300 ) \ +-do { \ +- \ +- if ( (r300)->cmdbuf.count_used || (r300)->dma.flush ) { \ +- r300Flush( (r300)->radeon.glCtx ); \ +- } \ +- \ +-} while (0) +- + // r300_state.c + extern int future_hw_tcl_on; + void _tnl_UpdateFixedFunctionProgram (GLcontext * ctx); +diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c +index d463ab3..f57516a 100644 +--- a/src/mesa/drivers/dri/r300/r300_swtcl.c ++++ b/src/mesa/drivers/dri/r300/r300_swtcl.c +@@ -56,26 +56,23 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r300_state.h" + #include "r300_ioctl.h" + #include "r300_emit.h" +-#include "r300_mem.h" ++#include "r300_tex.h" + +-static void flush_last_swtcl_prim( r300ContextPtr rmesa ); +- +- +-void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset); ++void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset); + void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr); + #define EMIT_ATTR( ATTR, STYLE ) \ + do { \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR); \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = (STYLE); \ +- rmesa->swtcl.vertex_attr_count++; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \ ++ rmesa->radeon.swtcl.vertex_attr_count++; \ + } while (0) + + #define EMIT_PAD( N ) \ + do { \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = 0; \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = EMIT_PAD; \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].offset = (N); \ +- rmesa->swtcl.vertex_attr_count++; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = 0; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = EMIT_PAD; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].offset = (N); \ ++ rmesa->radeon.swtcl.vertex_attr_count++; \ + } while (0) + + static void r300SetVertexFormat( GLcontext *ctx ) +@@ -114,7 +111,7 @@ static void r300SetVertexFormat( GLcontext *ctx ) + } + + assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL ); +- rmesa->swtcl.vertex_attr_count = 0; ++ rmesa->radeon.swtcl.vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. +@@ -266,14 +263,27 @@ static void r300SetVertexFormat( GLcontext *ctx ) + } + + R300_NEWPRIM(rmesa); +- R300_STATECHANGE(rmesa, vir[0]); +- ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ R300_STATECHANGE(rmesa, vir[0]); ++ rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF; ++ rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF; ++ rmesa->hw.vir[0].cmd[0] |= ++ (r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], ++ VB->AttribPtr, inputs, tab, nr) & 0x3FFF) << 16; ++ R300_STATECHANGE(rmesa, vir[1]); ++ rmesa->hw.vir[1].cmd[0] |= ++ (r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, ++ nr) & 0x3FFF) << 16; ++ } else { ++ R300_STATECHANGE(rmesa, vir[0]); ++ ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = + r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], + VB->AttribPtr, inputs, tab, nr); +- R300_STATECHANGE(rmesa, vir[1]); +- ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = ++ R300_STATECHANGE(rmesa, vir[1]); ++ ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = + r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, + nr); ++ } + + R300_STATECHANGE(rmesa, vic); + rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead); +@@ -283,89 +293,20 @@ static void r300SetVertexFormat( GLcontext *ctx ) + rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten); + rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = vap_fmt_1; + +- rmesa->swtcl.vertex_size = ++ rmesa->radeon.swtcl.vertex_size = + _tnl_install_attrs( ctx, +- rmesa->swtcl.vertex_attrs, +- rmesa->swtcl.vertex_attr_count, ++ rmesa->radeon.swtcl.vertex_attrs, ++ rmesa->radeon.swtcl.vertex_attr_count, + NULL, 0 ); + +- rmesa->swtcl.vertex_size /= 4; ++ rmesa->radeon.swtcl.vertex_size /= 4; + + RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset ); + + + R300_STATECHANGE(rmesa, vte); + rmesa->hw.vte.cmd[1] = vte; +- rmesa->hw.vte.cmd[2] = rmesa->swtcl.vertex_size; +-} +- +- +-/* Flush vertices in the current dma region. +- */ +-static void flush_last_swtcl_prim( r300ContextPtr rmesa ) +-{ +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- rmesa->dma.flush = NULL; +- +- if (rmesa->dma.current.buf) { +- struct r300_dma_region *current = &rmesa->dma.current; +- GLuint current_offset = GET_START(current); +- +- assert (current->start + +- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == +- current->ptr); +- +- if (rmesa->dma.current.start != rmesa->dma.current.ptr) { +- +- r300EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size + (12*sizeof(int)), __FUNCTION__); +- +- r300EmitState(rmesa); +- +- r300EmitVertexAOS( rmesa, +- rmesa->swtcl.vertex_size, +- current_offset); +- +- r300EmitVbufPrim( rmesa, +- rmesa->swtcl.hw_primitive, +- rmesa->swtcl.numverts); +- +- r300EmitCacheFlush(rmesa); +- } +- +- rmesa->swtcl.numverts = 0; +- current->start = current->ptr; +- } +-} +- +-/* Alloc space in the current dma region. +- */ +-static void * +-r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize ) +-{ +- GLuint bytes = vsize * nverts; +- +- if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) +- r300RefillCurrentDmaRegion( rmesa, bytes); +- +- if (!rmesa->dma.flush) { +- rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; +- rmesa->dma.flush = flush_last_swtcl_prim; +- } +- +- ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); +- ASSERT( rmesa->dma.flush == flush_last_swtcl_prim ); +- ASSERT( rmesa->dma.current.start + +- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == +- rmesa->dma.current.ptr ); +- +- { +- GLubyte *head = (GLubyte *) (rmesa->dma.current.address + rmesa->dma.current.ptr); +- rmesa->dma.current.ptr += bytes; +- rmesa->swtcl.numverts += nverts; +- return head; +- } ++ rmesa->hw.vte.cmd[2] = rmesa->radeon.swtcl.vertex_size; + } + + static GLuint reduced_prim[] = { +@@ -405,11 +346,11 @@ static void r300RenderPrimitive( GLcontext *ctx, GLenum prim ); + #undef LOCAL_VARS + #undef ALLOC_VERTS + #define CTX_ARG r300ContextPtr rmesa +-#define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size +-#define ALLOC_VERTS( n, size ) r300AllocDmaLowVerts( rmesa, n, size * 4 ) ++#define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size ++#define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 ) + #define LOCAL_VARS \ + r300ContextPtr rmesa = R300_CONTEXT(ctx); \ +- const char *r300verts = (char *)rmesa->swtcl.verts; ++ const char *r300verts = (char *)rmesa->radeon.swtcl.verts; + #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int))) + #define VERTEX r300Vertex + #define DO_DEBUG_VERTS (1 && (RADEON_DEBUG & DEBUG_VERTS)) +@@ -468,7 +409,7 @@ static struct { + #define VERT_Y(_v) _v->v.y + #define VERT_Z(_v) _v->v.z + #define AREA_IS_CCW( a ) (a < 0) +-#define GET_VERTEX(e) (rmesa->swtcl.verts + (e*rmesa->swtcl.vertex_size*sizeof(int))) ++#define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int))) + + /* Only used to pull back colors into vertices (ie, we know color is + * floating point). +@@ -514,7 +455,7 @@ do { \ + ***********************************************************************/ + + #define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] ) +-#define RENDER_PRIMITIVE rmesa->swtcl.render_primitive ++#define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive + #undef TAG + #define TAG(x) x + #include "tnl_dd/t_dd_unfilled.h" +@@ -571,8 +512,8 @@ static void init_rast_tab( void ) + #undef LOCAL_VARS + #define LOCAL_VARS \ + r300ContextPtr rmesa = R300_CONTEXT(ctx); \ +- const GLuint vertsize = rmesa->swtcl.vertex_size; \ +- const char *r300verts = (char *)rmesa->swtcl.verts; \ ++ const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \ ++ const char *r300verts = (char *)rmesa->radeon.swtcl.verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) elt; (void) stipple; +@@ -604,7 +545,7 @@ static void r300ChooseRenderState( GLcontext *ctx ) + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R300_TWOSIDE_BIT; + if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT; + +- if (index != rmesa->swtcl.RenderIndex) { ++ if (index != rmesa->radeon.swtcl.RenderIndex) { + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; +@@ -621,7 +562,7 @@ static void r300ChooseRenderState( GLcontext *ctx ) + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + } + +- rmesa->swtcl.RenderIndex = index; ++ rmesa->radeon.swtcl.RenderIndex = index; + } + } + +@@ -634,14 +575,17 @@ static void r300RenderStart(GLcontext *ctx) + r300ChooseRenderState(ctx); + r300SetVertexFormat(ctx); + ++ r300ValidateBuffers(ctx); ++ + r300UpdateShaders(rmesa); + r300UpdateShaderStates(rmesa); + + r300EmitCacheFlush(rmesa); + +- if (rmesa->dma.flush != 0 && +- rmesa->dma.flush != flush_last_swtcl_prim) +- rmesa->dma.flush( rmesa ); ++ /* investigate if we can put back flush optimisation if needed */ ++ if (rmesa->radeon.dma.flush != NULL) { ++ rmesa->radeon.dma.flush(ctx); ++ } + + } + +@@ -653,9 +597,9 @@ static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim ) + { + r300ContextPtr rmesa = R300_CONTEXT(ctx); + +- if (rmesa->swtcl.hw_primitive != hwprim) { ++ if (rmesa->radeon.swtcl.hw_primitive != hwprim) { + R300_NEWPRIM( rmesa ); +- rmesa->swtcl.hw_primitive = hwprim; ++ rmesa->radeon.swtcl.hw_primitive = hwprim; + } + } + +@@ -663,7 +607,7 @@ static void r300RenderPrimitive(GLcontext *ctx, GLenum prim) + { + + r300ContextPtr rmesa = R300_CONTEXT(ctx); +- rmesa->swtcl.render_primitive = prim; ++ rmesa->radeon.swtcl.render_primitive = prim; + + if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; +@@ -702,10 +646,10 @@ void r300InitSwtcl(GLcontext *ctx) + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, + 48 * sizeof(GLfloat) ); + +- rmesa->swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf; +- rmesa->swtcl.RenderIndex = ~0; +- rmesa->swtcl.render_primitive = GL_TRIANGLES; +- rmesa->swtcl.hw_primitive = 0; ++ rmesa->radeon.swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf; ++ rmesa->radeon.swtcl.RenderIndex = ~0; ++ rmesa->radeon.swtcl.render_primitive = GL_TRIANGLES; ++ rmesa->radeon.swtcl.hw_primitive = 0; + + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); +@@ -724,33 +668,52 @@ void r300DestroySwtcl(GLcontext *ctx) + { + } + +-void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset) ++void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset) + { +- int cmd_reserved = 0; +- int cmd_written = 0; ++ BATCH_LOCALS(&rmesa->radeon); + +- drm_radeon_cmd_header_t *cmd = NULL; + if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s: vertex_size %d, offset 0x%x \n", +- __FUNCTION__, vertex_size, offset); +- +- start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2), 2); +- e32(1); +- e32(vertex_size | (vertex_size << 8)); +- e32(offset); ++ fprintf(stderr, "%s: vertex_size %d, offset 0x%x \n", ++ __FUNCTION__, vertex_size, offset); ++ ++ BEGIN_BATCH(7); ++ OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2); ++ OUT_BATCH(1); ++ OUT_BATCH(vertex_size | (vertex_size << 8)); ++ OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0); ++ END_BATCH(); + } + + void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr) + { +- +- int cmd_reserved = 0; +- int cmd_written = 0; ++ BATCH_LOCALS(&rmesa->radeon); + int type, num_verts; +- drm_radeon_cmd_header_t *cmd = NULL; + + type = r300PrimitiveType(rmesa, primitive); + num_verts = r300NumVerts(rmesa, vertex_nr, primitive); + +- start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0); +- e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type); ++ BEGIN_BATCH(3); ++ OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0); ++ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type); ++ END_BATCH(); ++} ++ ++void r300_swtcl_flush(GLcontext *ctx, uint32_t current_offset) ++{ ++ r300ContextPtr rmesa = R300_CONTEXT(ctx); ++ ++ rcommonEnsureCmdBufSpace(&rmesa->radeon, ++ rmesa->radeon.hw.max_state_size + (12*sizeof(int)), ++ __FUNCTION__); ++ radeonEmitState(&rmesa->radeon); ++ r300EmitVertexAOS(rmesa, ++ rmesa->radeon.swtcl.vertex_size, ++ rmesa->radeon.dma.current, ++ current_offset); ++ ++ r300EmitVbufPrim(rmesa, ++ rmesa->radeon.swtcl.hw_primitive, ++ rmesa->radeon.swtcl.numverts); ++ r300EmitCacheFlush(rmesa); ++ COMMIT_BATCH(); + } +diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.h b/src/mesa/drivers/dri/r300/r300_swtcl.h +index 55df53c..23b4ce3 100644 +--- a/src/mesa/drivers/dri/r300/r300_swtcl.h ++++ b/src/mesa/drivers/dri/r300/r300_swtcl.h +@@ -42,4 +42,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + extern void r300InitSwtcl( GLcontext *ctx ); + extern void r300DestroySwtcl( GLcontext *ctx ); + ++extern void r300_swtcl_flush(GLcontext *ctx, uint32_t current_offset); + #endif +diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c +index 8ab382c..0cbb2bc 100644 +--- a/src/mesa/drivers/dri/r300/r300_tex.c ++++ b/src/mesa/drivers/dri/r300/r300_tex.c +@@ -38,6 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/context.h" + #include "main/enums.h" + #include "main/image.h" ++#include "main/mipmap.h" + #include "main/simple_list.h" + #include "main/texformat.h" + #include "main/texstore.h" +@@ -49,6 +50,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r300_context.h" + #include "r300_state.h" + #include "r300_ioctl.h" ++#include "radeon_mipmap_tree.h" + #include "r300_tex.h" + + #include "xmlpool.h" +@@ -77,20 +79,20 @@ static unsigned int translate_wrap_mode(GLenum wrapmode) + * + * \param t Texture object whose wrap modes are to be set + */ +-static void r300UpdateTexWrap(r300TexObjPtr t) ++static void r300UpdateTexWrap(radeonTexObjPtr t) + { +- struct gl_texture_object *tObj = t->base.tObj; ++ struct gl_texture_object *tObj = &t->base; + +- t->filter &= ++ t->pp_txfilter &= + ~(R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | R300_TX_WRAP_R_MASK); + +- t->filter |= translate_wrap_mode(tObj->WrapS) << R300_TX_WRAP_S_SHIFT; ++ t->pp_txfilter |= translate_wrap_mode(tObj->WrapS) << R300_TX_WRAP_S_SHIFT; + + if (tObj->Target != GL_TEXTURE_1D) { +- t->filter |= translate_wrap_mode(tObj->WrapT) << R300_TX_WRAP_T_SHIFT; ++ t->pp_txfilter |= translate_wrap_mode(tObj->WrapT) << R300_TX_WRAP_T_SHIFT; + + if (tObj->Target == GL_TEXTURE_3D) +- t->filter |= translate_wrap_mode(tObj->WrapR) << R300_TX_WRAP_R_SHIFT; ++ t->pp_txfilter |= translate_wrap_mode(tObj->WrapR) << R300_TX_WRAP_R_SHIFT; + } + } + +@@ -117,10 +119,13 @@ static GLuint aniso_filter(GLfloat anisotropy) + * \param magf Texture magnification mode + * \param anisotropy Maximum anisotropy level + */ +-static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy) ++static void r300SetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy) + { +- t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MIN_FILTER_MIP_MASK | R300_TX_MAG_FILTER_MASK | R300_TX_MAX_ANISO_MASK); +- t->filter_1 &= ~R300_EDGE_ANISO_EDGE_ONLY; ++ /* Force revalidation to account for switches from/to mipmapping. */ ++ t->validated = GL_FALSE; ++ ++ t->pp_txfilter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MIN_FILTER_MIP_MASK | R300_TX_MAG_FILTER_MASK | R300_TX_MAX_ANISO_MASK); ++ t->pp_txfilter_1 &= ~R300_EDGE_ANISO_EDGE_ONLY; + + /* Note that EXT_texture_filter_anisotropic is extremely vague about + * how anisotropic filtering interacts with the "normal" filter modes. +@@ -128,7 +133,7 @@ static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat + * filter settings completely. This includes driconf's settings. + */ + if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) { +- t->filter |= R300_TX_MAG_FILTER_ANISO ++ t->pp_txfilter |= R300_TX_MAG_FILTER_ANISO + | R300_TX_MIN_FILTER_ANISO + | R300_TX_MIN_FILTER_MIP_LINEAR + | aniso_filter(anisotropy); +@@ -139,22 +144,22 @@ static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat + + switch (minf) { + case GL_NEAREST: +- t->filter |= R300_TX_MIN_FILTER_NEAREST; ++ t->pp_txfilter |= R300_TX_MIN_FILTER_NEAREST; + break; + case GL_LINEAR: +- t->filter |= R300_TX_MIN_FILTER_LINEAR; ++ t->pp_txfilter |= R300_TX_MIN_FILTER_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: +- t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_NEAREST; ++ t->pp_txfilter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: +- t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_LINEAR; ++ t->pp_txfilter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_LINEAR; + break; + case GL_LINEAR_MIPMAP_NEAREST: +- t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_NEAREST; ++ t->pp_txfilter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_NEAREST; + break; + case GL_LINEAR_MIPMAP_LINEAR: +- t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_LINEAR; ++ t->pp_txfilter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_LINEAR; + break; + } + +@@ -163,743 +168,20 @@ static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat + */ + switch (magf) { + case GL_NEAREST: +- t->filter |= R300_TX_MAG_FILTER_NEAREST; ++ t->pp_txfilter |= R300_TX_MAG_FILTER_NEAREST; + break; + case GL_LINEAR: +- t->filter |= R300_TX_MAG_FILTER_LINEAR; ++ t->pp_txfilter |= R300_TX_MAG_FILTER_LINEAR; + break; + } + } + +-static void r300SetTexBorderColor(r300TexObjPtr t, GLubyte c[4]) ++static void r300SetTexBorderColor(radeonTexObjPtr t, GLubyte c[4]) + { + t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]); + } + + /** +- * Allocate space for and load the mesa images into the texture memory block. +- * This will happen before drawing with a new texture, or drawing with a +- * texture after it was swapped out or teximaged again. +- */ +- +-static r300TexObjPtr r300AllocTexObj(struct gl_texture_object *texObj) +-{ +- r300TexObjPtr t; +- +- t = CALLOC_STRUCT(r300_tex_obj); +- texObj->DriverData = t; +- if (t != NULL) { +- if (RADEON_DEBUG & DEBUG_TEXTURE) { +- fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__, +- (void *)texObj, (void *)t); +- } +- +- /* Initialize non-image-dependent parts of the state: +- */ +- t->base.tObj = texObj; +- t->border_fallback = GL_FALSE; +- +- make_empty_list(&t->base); +- +- r300UpdateTexWrap(t); +- r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy); +- r300SetTexBorderColor(t, texObj->_BorderChan); +- } +- +- return t; +-} +- +-/* try to find a format which will only need a memcopy */ +-static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat, +- GLenum srcType) +-{ +- const GLuint ui = 1; +- const GLubyte littleEndian = *((const GLubyte *)&ui); +- +- if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || +- (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || +- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || +- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { +- return &_mesa_texformat_rgba8888; +- } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || +- (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || +- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || +- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { +- return &_mesa_texformat_rgba8888_rev; +- } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || +- srcType == GL_UNSIGNED_INT_8_8_8_8)) { +- return &_mesa_texformat_argb8888_rev; +- } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || +- srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { +- return &_mesa_texformat_argb8888; +- } else +- return _dri_texformat_argb8888; +-} +- +-static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, +- GLint +- internalFormat, +- GLenum format, +- GLenum type) +-{ +- r300ContextPtr rmesa = R300_CONTEXT(ctx); +- const GLboolean do32bpt = +- (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); +- const GLboolean force16bpt = +- (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); +- (void)format; +- +-#if 0 +- fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", +- _mesa_lookup_enum_by_nr(internalFormat), internalFormat, +- _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); +- fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); +-#endif +- +- switch (internalFormat) { +- case 4: +- case GL_RGBA: +- case GL_COMPRESSED_RGBA: +- switch (type) { +- case GL_UNSIGNED_INT_10_10_10_2: +- case GL_UNSIGNED_INT_2_10_10_10_REV: +- return do32bpt ? _dri_texformat_argb8888 : +- _dri_texformat_argb1555; +- case GL_UNSIGNED_SHORT_4_4_4_4: +- case GL_UNSIGNED_SHORT_4_4_4_4_REV: +- return _dri_texformat_argb4444; +- case GL_UNSIGNED_SHORT_5_5_5_1: +- case GL_UNSIGNED_SHORT_1_5_5_5_REV: +- return _dri_texformat_argb1555; +- default: +- return do32bpt ? r300Choose8888TexFormat(format, type) : +- _dri_texformat_argb4444; +- } +- +- case 3: +- case GL_RGB: +- case GL_COMPRESSED_RGB: +- switch (type) { +- case GL_UNSIGNED_SHORT_4_4_4_4: +- case GL_UNSIGNED_SHORT_4_4_4_4_REV: +- return _dri_texformat_argb4444; +- case GL_UNSIGNED_SHORT_5_5_5_1: +- case GL_UNSIGNED_SHORT_1_5_5_5_REV: +- return _dri_texformat_argb1555; +- case GL_UNSIGNED_SHORT_5_6_5: +- case GL_UNSIGNED_SHORT_5_6_5_REV: +- return _dri_texformat_rgb565; +- default: +- return do32bpt ? _dri_texformat_argb8888 : +- _dri_texformat_rgb565; +- } +- +- case GL_RGBA8: +- case GL_RGB10_A2: +- case GL_RGBA12: +- case GL_RGBA16: +- return !force16bpt ? +- r300Choose8888TexFormat(format, +- type) : _dri_texformat_argb4444; +- +- case GL_RGBA4: +- case GL_RGBA2: +- return _dri_texformat_argb4444; +- +- case GL_RGB5_A1: +- return _dri_texformat_argb1555; +- +- case GL_RGB8: +- case GL_RGB10: +- case GL_RGB12: +- case GL_RGB16: +- return !force16bpt ? _dri_texformat_argb8888 : +- _dri_texformat_rgb565; +- +- case GL_RGB5: +- case GL_RGB4: +- case GL_R3_G3_B2: +- return _dri_texformat_rgb565; +- +- case GL_ALPHA: +- case GL_ALPHA4: +- case GL_ALPHA8: +- case GL_ALPHA12: +- case GL_ALPHA16: +- case GL_COMPRESSED_ALPHA: +- return _dri_texformat_a8; +- +- case 1: +- case GL_LUMINANCE: +- case GL_LUMINANCE4: +- case GL_LUMINANCE8: +- case GL_LUMINANCE12: +- case GL_LUMINANCE16: +- case GL_COMPRESSED_LUMINANCE: +- return _dri_texformat_l8; +- +- case 2: +- case GL_LUMINANCE_ALPHA: +- case GL_LUMINANCE4_ALPHA4: +- case GL_LUMINANCE6_ALPHA2: +- case GL_LUMINANCE8_ALPHA8: +- case GL_LUMINANCE12_ALPHA4: +- case GL_LUMINANCE12_ALPHA12: +- case GL_LUMINANCE16_ALPHA16: +- case GL_COMPRESSED_LUMINANCE_ALPHA: +- return _dri_texformat_al88; +- +- case GL_INTENSITY: +- case GL_INTENSITY4: +- case GL_INTENSITY8: +- case GL_INTENSITY12: +- case GL_INTENSITY16: +- case GL_COMPRESSED_INTENSITY: +- return _dri_texformat_i8; +- +- case GL_YCBCR_MESA: +- if (type == GL_UNSIGNED_SHORT_8_8_APPLE || +- type == GL_UNSIGNED_BYTE) +- return &_mesa_texformat_ycbcr; +- else +- return &_mesa_texformat_ycbcr_rev; +- +- case GL_RGB_S3TC: +- case GL_RGB4_S3TC: +- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: +- return &_mesa_texformat_rgb_dxt1; +- +- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: +- return &_mesa_texformat_rgba_dxt1; +- +- case GL_RGBA_S3TC: +- case GL_RGBA4_S3TC: +- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: +- return &_mesa_texformat_rgba_dxt3; +- +- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: +- return &_mesa_texformat_rgba_dxt5; +- +- case GL_ALPHA16F_ARB: +- return &_mesa_texformat_alpha_float16; +- case GL_ALPHA32F_ARB: +- return &_mesa_texformat_alpha_float32; +- case GL_LUMINANCE16F_ARB: +- return &_mesa_texformat_luminance_float16; +- case GL_LUMINANCE32F_ARB: +- return &_mesa_texformat_luminance_float32; +- case GL_LUMINANCE_ALPHA16F_ARB: +- return &_mesa_texformat_luminance_alpha_float16; +- case GL_LUMINANCE_ALPHA32F_ARB: +- return &_mesa_texformat_luminance_alpha_float32; +- case GL_INTENSITY16F_ARB: +- return &_mesa_texformat_intensity_float16; +- case GL_INTENSITY32F_ARB: +- return &_mesa_texformat_intensity_float32; +- case GL_RGB16F_ARB: +- return &_mesa_texformat_rgba_float16; +- case GL_RGB32F_ARB: +- return &_mesa_texformat_rgba_float32; +- case GL_RGBA16F_ARB: +- return &_mesa_texformat_rgba_float16; +- case GL_RGBA32F_ARB: +- return &_mesa_texformat_rgba_float32; +- +- case GL_DEPTH_COMPONENT: +- case GL_DEPTH_COMPONENT16: +- case GL_DEPTH_COMPONENT24: +- case GL_DEPTH_COMPONENT32: +-#if 0 +- switch (type) { +- case GL_UNSIGNED_BYTE: +- case GL_UNSIGNED_SHORT: +- return &_mesa_texformat_z16; +- case GL_UNSIGNED_INT: +- return &_mesa_texformat_z32; +- case GL_UNSIGNED_INT_24_8_EXT: +- default: +- return &_mesa_texformat_z24_s8; +- } +-#else +- return &_mesa_texformat_z16; +-#endif +- +- default: +- _mesa_problem(ctx, +- "unexpected internalFormat 0x%x in r300ChooseTextureFormat", +- (int)internalFormat); +- return NULL; +- } +- +- return NULL; /* never get here */ +-} +- +-static GLboolean +-r300ValidateClientStorage(GLcontext * ctx, GLenum target, +- GLint internalFormat, +- GLint srcWidth, GLint srcHeight, +- GLenum format, GLenum type, const void *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +-{ +- r300ContextPtr rmesa = R300_CONTEXT(ctx); +- +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "intformat %s format %s type %s\n", +- _mesa_lookup_enum_by_nr(internalFormat), +- _mesa_lookup_enum_by_nr(format), +- _mesa_lookup_enum_by_nr(type)); +- +- if (!ctx->Unpack.ClientStorage) +- return 0; +- +- if (ctx->_ImageTransferState || +- texImage->IsCompressed || texObj->GenerateMipmap) +- return 0; +- +- /* This list is incomplete, may be different on ppc??? +- */ +- switch (internalFormat) { +- case GL_RGBA: +- if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV) { +- texImage->TexFormat = _dri_texformat_argb8888; +- } else +- return 0; +- break; +- +- case GL_RGB: +- if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { +- texImage->TexFormat = _dri_texformat_rgb565; +- } else +- return 0; +- break; +- +- case GL_YCBCR_MESA: +- if (format == GL_YCBCR_MESA && +- type == GL_UNSIGNED_SHORT_8_8_REV_APPLE) { +- texImage->TexFormat = &_mesa_texformat_ycbcr_rev; +- } else if (format == GL_YCBCR_MESA && +- (type == GL_UNSIGNED_SHORT_8_8_APPLE || +- type == GL_UNSIGNED_BYTE)) { +- texImage->TexFormat = &_mesa_texformat_ycbcr; +- } else +- return 0; +- break; +- +- default: +- return 0; +- } +- +- /* Could deal with these packing issues, but currently don't: +- */ +- if (packing->SkipPixels || +- packing->SkipRows || packing->SwapBytes || packing->LsbFirst) { +- return 0; +- } +- +- GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth, +- format, type); +- +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: srcRowStride %d/%x\n", +- __FUNCTION__, srcRowStride, srcRowStride); +- +- /* Could check this later in upload, pitch restrictions could be +- * relaxed, but would need to store the image pitch somewhere, +- * as packing details might change before image is uploaded: +- */ +- if (!r300IsGartMemory(rmesa, pixels, srcHeight * srcRowStride) +- || (srcRowStride & 63)) +- return 0; +- +- /* Have validated that _mesa_transfer_teximage would be a straight +- * memcpy at this point. NOTE: future calls to TexSubImage will +- * overwrite the client data. This is explicitly mentioned in the +- * extension spec. +- */ +- texImage->Data = (void *)pixels; +- texImage->IsClientData = GL_TRUE; +- texImage->RowStride = srcRowStride / texImage->TexFormat->TexelBytes; +- +- return 1; +-} +- +-static void r300TexImage1D(GLcontext * ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint border, +- GLenum format, GLenum type, const GLvoid * pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +-{ +- driTextureObject *t = (driTextureObject *) texObj->DriverData; +- +- if (t) { +- driSwapOutTextureObject(t); +- } else { +- t = (driTextureObject *) r300AllocTexObj(texObj); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); +- return; +- } +- } +- +- /* Note, this will call ChooseTextureFormat */ +- _mesa_store_teximage1d(ctx, target, level, internalFormat, +- width, border, format, type, pixels, +- &ctx->Unpack, texObj, texImage); +- +- t->dirty_images[0] |= (1 << level); +-} +- +-static void r300TexSubImage1D(GLcontext * ctx, GLenum target, GLint level, +- GLint xoffset, +- GLsizei width, +- GLenum format, GLenum type, +- const GLvoid * pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +-{ +- driTextureObject *t = (driTextureObject *) texObj->DriverData; +- +- assert(t); /* this _should_ be true */ +- if (t) { +- driSwapOutTextureObject(t); +- } else { +- t = (driTextureObject *) r300AllocTexObj(texObj); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); +- return; +- } +- } +- +- _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, +- format, type, pixels, packing, texObj, +- texImage); +- +- t->dirty_images[0] |= (1 << level); +-} +- +-static void r300TexImage2D(GLcontext * ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint height, GLint border, +- GLenum format, GLenum type, const GLvoid * pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +-{ +- driTextureObject *t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = +- (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- if (t != NULL) { +- driSwapOutTextureObject(t); +- } else { +- t = (driTextureObject *) r300AllocTexObj(texObj); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); +- return; +- } +- } +- +- texImage->IsClientData = GL_FALSE; +- +- if (r300ValidateClientStorage(ctx, target, +- internalFormat, +- width, height, +- format, type, pixels, +- packing, texObj, texImage)) { +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using client storage\n", +- __FUNCTION__); +- } else { +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using normal storage\n", +- __FUNCTION__); +- +- /* Normal path: copy (to cached memory) and eventually upload +- * via another copy to GART memory and then a blit... Could +- * eliminate one copy by going straight to (permanent) GART. +- * +- * Note, this will call r300ChooseTextureFormat. +- */ +- _mesa_store_teximage2d(ctx, target, level, internalFormat, +- width, height, border, format, type, +- pixels, &ctx->Unpack, texObj, texImage); +- +- t->dirty_images[face] |= (1 << level); +- } +-} +- +-static void r300TexSubImage2D(GLcontext * ctx, GLenum target, GLint level, +- GLint xoffset, GLint yoffset, +- GLsizei width, GLsizei height, +- GLenum format, GLenum type, +- const GLvoid * pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +-{ +- driTextureObject *t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = +- (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- assert(t); /* this _should_ be true */ +- if (t) { +- driSwapOutTextureObject(t); +- } else { +- t = (driTextureObject *) r300AllocTexObj(texObj); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); +- return; +- } +- } +- +- _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, +- height, format, type, pixels, packing, texObj, +- texImage); +- +- t->dirty_images[face] |= (1 << level); +-} +- +-static void r300CompressedTexImage2D(GLcontext * ctx, GLenum target, +- GLint level, GLint internalFormat, +- GLint width, GLint height, GLint border, +- GLsizei imageSize, const GLvoid * data, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +-{ +- driTextureObject *t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = +- (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- if (t != NULL) { +- driSwapOutTextureObject(t); +- } else { +- t = (driTextureObject *) r300AllocTexObj(texObj); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, +- "glCompressedTexImage2D"); +- return; +- } +- } +- +- texImage->IsClientData = GL_FALSE; +- +- /* can't call this, different parameters. Would never evaluate to true anyway currently */ +-#if 0 +- if (r300ValidateClientStorage(ctx, target, +- internalFormat, +- width, height, +- format, type, pixels, +- packing, texObj, texImage)) { +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using client storage\n", +- __FUNCTION__); +- } else +-#endif +- { +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using normal storage\n", +- __FUNCTION__); +- +- /* Normal path: copy (to cached memory) and eventually upload +- * via another copy to GART memory and then a blit... Could +- * eliminate one copy by going straight to (permanent) GART. +- * +- * Note, this will call r300ChooseTextureFormat. +- */ +- _mesa_store_compressed_teximage2d(ctx, target, level, +- internalFormat, width, height, +- border, imageSize, data, +- texObj, texImage); +- +- t->dirty_images[face] |= (1 << level); +- } +-} +- +-static void r300CompressedTexSubImage2D(GLcontext * ctx, GLenum target, +- GLint level, GLint xoffset, +- GLint yoffset, GLsizei width, +- GLsizei height, GLenum format, +- GLsizei imageSize, const GLvoid * data, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +-{ +- driTextureObject *t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = +- (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- assert(t); /* this _should_ be true */ +- if (t) { +- driSwapOutTextureObject(t); +- } else { +- t = (driTextureObject *) r300AllocTexObj(texObj); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, +- "glCompressedTexSubImage3D"); +- return; +- } +- } +- +- _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, +- yoffset, width, height, format, +- imageSize, data, texObj, texImage); +- +- t->dirty_images[face] |= (1 << level); +-} +- +-static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint height, GLint depth, +- GLint border, +- GLenum format, GLenum type, const GLvoid * pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +-{ +- driTextureObject *t = (driTextureObject *) texObj->DriverData; +- +- if (t) { +- driSwapOutTextureObject(t); +- } else { +- t = (driTextureObject *) r300AllocTexObj(texObj); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); +- return; +- } +- } +- +- texImage->IsClientData = GL_FALSE; +- +-#if 0 +- if (r300ValidateClientStorage(ctx, target, +- internalFormat, +- width, height, +- format, type, pixels, +- packing, texObj, texImage)) { +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using client storage\n", +- __FUNCTION__); +- } else +-#endif +- { +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: Using normal storage\n", +- __FUNCTION__); +- +- /* Normal path: copy (to cached memory) and eventually upload +- * via another copy to GART memory and then a blit... Could +- * eliminate one copy by going straight to (permanent) GART. +- * +- * Note, this will call r300ChooseTextureFormat. +- */ +- _mesa_store_teximage3d(ctx, target, level, internalFormat, +- width, height, depth, border, +- format, type, pixels, +- &ctx->Unpack, texObj, texImage); +- +- t->dirty_images[0] |= (1 << level); +- } +-} +- +-static void +-r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level, +- GLint xoffset, GLint yoffset, GLint zoffset, +- GLsizei width, GLsizei height, GLsizei depth, +- GLenum format, GLenum type, +- const GLvoid * pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage) +-{ +- driTextureObject *t = (driTextureObject *) texObj->DriverData; +- +-/* fprintf(stderr, "%s\n", __FUNCTION__); */ +- +- assert(t); /* this _should_ be true */ +- if (t) { +- driSwapOutTextureObject(t); +- } else { +- t = (driTextureObject *) r300AllocTexObj(texObj); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D"); +- return; +- } +- texObj->DriverData = t; +- } +- +- _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset, +- width, height, depth, +- format, type, pixels, packing, texObj, +- texImage); +- +- t->dirty_images[0] |= (1 << level); +-} +- +-/** + * Changes variables and flags for a state update, which will happen at the + * next UpdateTextureState + */ +@@ -908,7 +190,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat * params) + { +- r300TexObjPtr t = (r300TexObjPtr) texObj->DriverData; ++ radeonTexObj* t = radeon_tex_obj(texObj); + + if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { + fprintf(stderr, "%s( %s )\n", __FUNCTION__, +@@ -941,7 +223,11 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, + * we just have to rely on loading the right subset of mipmap levels + * to simulate a clamped LOD. + */ +- driSwapOutTextureObject((driTextureObject *) t); ++ if (t->mt) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = 0; ++ t->validated = GL_FALSE; ++ } + break; + + case GL_DEPTH_TEXTURE_MODE: +@@ -964,27 +250,10 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, + } + } + +-static void r300BindTexture(GLcontext * ctx, GLenum target, +- struct gl_texture_object *texObj) +-{ +- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { +- fprintf(stderr, "%s( %p ) unit=%d\n", __FUNCTION__, +- (void *)texObj, ctx->Texture.CurrentUnit); +- } +- +- if ((target == GL_TEXTURE_1D) +- || (target == GL_TEXTURE_2D) +- || (target == GL_TEXTURE_3D) +- || (target == GL_TEXTURE_CUBE_MAP) +- || (target == GL_TEXTURE_RECTANGLE_NV)) { +- assert(texObj->DriverData != NULL); +- } +-} +- + static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) + { + r300ContextPtr rmesa = R300_CONTEXT(ctx); +- driTextureObject *t = (driTextureObject *) texObj->DriverData; ++ radeonTexObj* t = radeon_tex_obj(texObj); + + if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { + fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, +@@ -992,14 +261,24 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) + _mesa_lookup_enum_by_nr(texObj->Target)); + } + +- if (t != NULL) { +- if (rmesa) { +- R300_FIREVERTICES(rmesa); +- } ++ if (rmesa) { ++ int i; ++ radeon_firevertices(&rmesa->radeon); ++ ++ for(i = 0; i < R300_MAX_TEXTURE_UNITS; ++i) ++ if (rmesa->hw.textures[i] == t) ++ rmesa->hw.textures[i] = 0; ++ } + +- driDestroyTextureObject(t); ++ if (t->bo) { ++ radeon_bo_unref(t->bo); ++ t->bo = NULL; ++ } ++ ++ if (t->mt) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = 0; + } +- /* Free mipmap images and the texture object itself */ + _mesa_delete_texture_object(ctx, texObj); + } + +@@ -1008,8 +287,6 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) + * Called via ctx->Driver.NewTextureObject. + * Note: this function will be called during context creation to + * allocate the default texture objects. +- * Note: we could use containment here to 'derive' the driver-specific +- * texture object from the core mesa gl_texture_object. Not done at this time. + * Fixup MaxAnisotropy according to user preference. + */ + static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, +@@ -1017,14 +294,23 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, + GLenum target) + { + r300ContextPtr rmesa = R300_CONTEXT(ctx); +- struct gl_texture_object *obj; +- obj = _mesa_new_texture_object(ctx, name, target); +- if (!obj) +- return NULL; +- obj->MaxAnisotropy = rmesa->initialMaxAnisotropy; ++ radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj); ++ + +- r300AllocTexObj(obj); +- return obj; ++ if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { ++ fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, ++ t, _mesa_lookup_enum_by_nr(target)); ++ } ++ ++ _mesa_initialize_texture_object(&t->base, name, target); ++ t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy; ++ ++ /* Initialize hardware state */ ++ r300UpdateTexWrap(t); ++ r300SetTexFilter(t, t->base.MinFilter, t->base.MagFilter, t->base.MaxAnisotropy); ++ r300SetTexBorderColor(t, t->base._BorderChan); ++ ++ return &t->base; + } + + void r300InitTextureFuncs(struct dd_function_table *functions) +@@ -1032,22 +318,30 @@ void r300InitTextureFuncs(struct dd_function_table *functions) + /* Note: we only plug in the functions we implement in the driver + * since _mesa_init_driver_functions() was already called. + */ +- functions->ChooseTextureFormat = r300ChooseTextureFormat; +- functions->TexImage1D = r300TexImage1D; +- functions->TexImage2D = r300TexImage2D; +- functions->TexImage3D = r300TexImage3D; +- functions->TexSubImage1D = r300TexSubImage1D; +- functions->TexSubImage2D = r300TexSubImage2D; +- functions->TexSubImage3D = r300TexSubImage3D; ++ functions->NewTextureImage = radeonNewTextureImage; ++ functions->FreeTexImageData = radeonFreeTexImageData; ++ functions->MapTexture = radeonMapTexture; ++ functions->UnmapTexture = radeonUnmapTexture; ++ ++ functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; ++ functions->TexImage1D = radeonTexImage1D; ++ functions->TexImage2D = radeonTexImage2D; ++ functions->TexImage3D = radeonTexImage3D; ++ functions->TexSubImage1D = radeonTexSubImage1D; ++ functions->TexSubImage2D = radeonTexSubImage2D; ++ functions->TexSubImage3D = radeonTexSubImage3D; ++ functions->GetTexImage = radeonGetTexImage; ++ functions->GetCompressedTexImage = radeonGetCompressedTexImage; + functions->NewTextureObject = r300NewTextureObject; +- functions->BindTexture = r300BindTexture; + functions->DeleteTexture = r300DeleteTexture; + functions->IsTextureResident = driIsTextureResident; + + functions->TexParameter = r300TexParameter; + +- functions->CompressedTexImage2D = r300CompressedTexImage2D; +- functions->CompressedTexSubImage2D = r300CompressedTexSubImage2D; ++ functions->CompressedTexImage2D = radeonCompressedTexImage2D; ++ functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; ++ ++ functions->GenerateMipmap = radeonGenerateMipmap; + + driInitTextureFormats(); + } +diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h +index b86d45b..8a653ea 100644 +--- a/src/mesa/drivers/dri/r300/r300_tex.h ++++ b/src/mesa/drivers/dri/r300/r300_tex.h +@@ -37,16 +37,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + extern void r300SetDepthTexMode(struct gl_texture_object *tObj); + ++extern void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, ++ __DRIdrawable *dPriv); ++ ++extern void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, ++ GLint format, __DRIdrawable *dPriv); ++ + extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, + GLuint pitch); + +-extern void r300UpdateTextureState(GLcontext * ctx); +- +-extern int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, +- GLuint face); +- +-extern void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t); ++extern GLboolean r300ValidateBuffers(GLcontext * ctx); + + extern void r300InitTextureFuncs(struct dd_function_table *functions); + +diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c +deleted file mode 100644 +index b03eefa..0000000 +--- a/src/mesa/drivers/dri/r300/r300_texmem.c ++++ /dev/null +@@ -1,567 +0,0 @@ +-/************************************************************************** +- +-Copyright (C) Tungsten Graphics 2002. All Rights Reserved. +-The Weather Channel, Inc. funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 +-license. This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation on the rights to use, copy, modify, merge, publish, +-distribute, sub license, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +-NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR THEIR +-SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-SOFTWARE. +- +-**************************************************************************/ +- +-/** +- * \file +- * +- * \author Gareth Hughes +- * +- * \author Kevin E. Martin +- */ +- +-#include +- +-#include "main/glheader.h" +-#include "main/imports.h" +-#include "main/context.h" +-#include "main/colormac.h" +-#include "main/macros.h" +-#include "main/simple_list.h" +-#include "radeon_reg.h" /* gets definition for usleep */ +-#include "r300_context.h" +-#include "r300_state.h" +-#include "r300_cmdbuf.h" +-#include "radeon_ioctl.h" +-#include "r300_tex.h" +-#include "r300_ioctl.h" +-#include /* for usleep() */ +- +-#ifdef USER_BUFFERS +-#include "r300_mem.h" +-#endif +- +-/** +- * Destroy any device-dependent state associated with the texture. This may +- * include NULLing out hardware state that points to the texture. +- */ +-void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t) +-{ +- int i; +- +- if (RADEON_DEBUG & DEBUG_TEXTURE) { +- fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__, +- (void *)t, (void *)t->base.tObj); +- } +- +- for (i = 0; i < rmesa->radeon.glCtx->Const.MaxTextureUnits; i++) { +- if (rmesa->state.texture.unit[i].texobj == t) { +- rmesa->state.texture.unit[i].texobj = NULL; +- } +- } +-} +- +-/* ------------------------------------------------------------ +- * Texture image conversions +- */ +- +-static void r300UploadGARTClientSubImage(r300ContextPtr rmesa, +- r300TexObjPtr t, +- struct gl_texture_image *texImage, +- GLint hwlevel, +- GLint x, GLint y, +- GLint width, GLint height) +-{ +- const struct gl_texture_format *texFormat = texImage->TexFormat; +- GLuint srcPitch, dstPitch; +- int blit_format; +- int srcOffset; +- +- /* +- * XXX it appears that we always upload the full image, not a subimage. +- * I.e. x==0, y==0, width=texWidth, height=texWidth. If this is ever +- * changed, the src pitch will have to change. +- */ +- switch (texFormat->TexelBytes) { +- case 1: +- blit_format = R300_CP_COLOR_FORMAT_CI8; +- srcPitch = t->image[0][0].width * texFormat->TexelBytes; +- dstPitch = t->image[0][0].width * texFormat->TexelBytes; +- break; +- case 2: +- blit_format = R300_CP_COLOR_FORMAT_RGB565; +- srcPitch = t->image[0][0].width * texFormat->TexelBytes; +- dstPitch = t->image[0][0].width * texFormat->TexelBytes; +- break; +- case 4: +- blit_format = R300_CP_COLOR_FORMAT_ARGB8888; +- srcPitch = t->image[0][0].width * texFormat->TexelBytes; +- dstPitch = t->image[0][0].width * texFormat->TexelBytes; +- break; +- case 8: +- case 16: +- blit_format = R300_CP_COLOR_FORMAT_CI8; +- srcPitch = t->image[0][0].width * texFormat->TexelBytes; +- dstPitch = t->image[0][0].width * texFormat->TexelBytes; +- break; +- default: +- return; +- } +- +- t->image[0][hwlevel].data = texImage->Data; +- srcOffset = r300GartOffsetFromVirtual(rmesa, texImage->Data); +- +- assert(srcOffset != ~0); +- +- /* Don't currently need to cope with small pitches? +- */ +- width = texImage->Width; +- height = texImage->Height; +- +- if (texFormat->TexelBytes > 4) { +- width *= texFormat->TexelBytes; +- } +- +- r300EmitWait(rmesa, R300_WAIT_3D); +- +- r300EmitBlit(rmesa, blit_format, +- srcPitch, +- srcOffset, +- dstPitch, +- t->bufAddr, +- x, +- y, +- t->image[0][hwlevel].x + x, +- t->image[0][hwlevel].y + y, width, height); +- +- r300EmitWait(rmesa, R300_WAIT_2D); +-} +- +-static void r300UploadRectSubImage(r300ContextPtr rmesa, +- r300TexObjPtr t, +- struct gl_texture_image *texImage, +- GLint x, GLint y, GLint width, GLint height) +-{ +- const struct gl_texture_format *texFormat = texImage->TexFormat; +- int blit_format, dstPitch, done; +- +- switch (texFormat->TexelBytes) { +- case 1: +- blit_format = R300_CP_COLOR_FORMAT_CI8; +- break; +- case 2: +- blit_format = R300_CP_COLOR_FORMAT_RGB565; +- break; +- case 4: +- blit_format = R300_CP_COLOR_FORMAT_ARGB8888; +- break; +- case 8: +- case 16: +- blit_format = R300_CP_COLOR_FORMAT_CI8; +- break; +- default: +- return; +- } +- +- t->image[0][0].data = texImage->Data; +- +- /* Currently don't need to cope with small pitches. +- */ +- width = texImage->Width; +- height = texImage->Height; +- dstPitch = t->pitch; +- +- if (texFormat->TexelBytes > 4) { +- width *= texFormat->TexelBytes; +- } +- +- if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) { +- /* In this case, could also use GART texturing. This is +- * currently disabled, but has been tested & works. +- */ +- t->offset = r300GartOffsetFromVirtual(rmesa, texImage->Data); +- t->pitch = texImage->RowStride * texFormat->TexelBytes - 32; +- +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, +- "Using GART texturing for rectangular client texture\n"); +- +- /* Release FB memory allocated for this image: +- */ +- /* FIXME This may not be correct as driSwapOutTextureObject sets +- * FIXME dirty_images. It may be fine, though. +- */ +- if (t->base.memBlock) { +- driSwapOutTextureObject((driTextureObject *) t); +- } +- } else if (texImage->IsClientData) { +- /* Data already in GART memory, with usable pitch. +- */ +- GLuint srcPitch; +- srcPitch = texImage->RowStride * texFormat->TexelBytes; +- r300EmitBlit(rmesa, +- blit_format, +- srcPitch, +- r300GartOffsetFromVirtual(rmesa, texImage->Data), +- dstPitch, t->bufAddr, 0, 0, 0, 0, width, height); +- } else { +- /* Data not in GART memory, or bad pitch. +- */ +- for (done = 0; done < height;) { +- struct r300_dma_region region; +- int lines = +- MIN2(height - done, RADEON_BUFFER_SIZE / dstPitch); +- int src_pitch; +- char *tex; +- +- src_pitch = texImage->RowStride * texFormat->TexelBytes; +- +- tex = (char *)texImage->Data + done * src_pitch; +- +- memset(®ion, 0, sizeof(region)); +- r300AllocDmaRegion(rmesa, ®ion, lines * dstPitch, +- 1024); +- +- /* Copy texdata to dma: +- */ +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, +- "%s: src_pitch %d dst_pitch %d\n", +- __FUNCTION__, src_pitch, dstPitch); +- +- if (src_pitch == dstPitch) { +- memcpy(region.address + region.start, tex, +- lines * src_pitch); +- } else { +- char *buf = region.address + region.start; +- int i; +- for (i = 0; i < lines; i++) { +- memcpy(buf, tex, src_pitch); +- buf += dstPitch; +- tex += src_pitch; +- } +- } +- +- r300EmitWait(rmesa, R300_WAIT_3D); +- +- /* Blit to framebuffer +- */ +- r300EmitBlit(rmesa, +- blit_format, +- dstPitch, GET_START(®ion), +- dstPitch | (t->tile_bits >> 16), +- t->bufAddr, 0, 0, 0, done, width, lines); +- +- r300EmitWait(rmesa, R300_WAIT_2D); +-#ifdef USER_BUFFERS +- r300_mem_use(rmesa, region.buf->id); +-#endif +- +- r300ReleaseDmaRegion(rmesa, ®ion, __FUNCTION__); +- done += lines; +- } +- } +-} +- +-/** +- * Upload the texture image associated with texture \a t at the specified +- * level at the address relative to \a start. +- */ +-static void r300UploadSubImage(r300ContextPtr rmesa, r300TexObjPtr t, +- GLint hwlevel, +- GLint x, GLint y, GLint width, GLint height, +- GLuint face) +-{ +- struct gl_texture_image *texImage = NULL; +- GLuint offset; +- GLint imageWidth, imageHeight; +- GLint ret; +- drm_radeon_texture_t tex; +- drm_radeon_tex_image_t tmp; +- const int level = hwlevel + t->base.firstLevel; +- +- if (RADEON_DEBUG & DEBUG_TEXTURE) { +- fprintf(stderr, +- "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n", +- __FUNCTION__, (void *)t, (void *)t->base.tObj, level, +- width, height, face); +- } +- +- ASSERT(face < 6); +- +- /* Ensure we have a valid texture to upload */ +- if ((hwlevel < 0) || (hwlevel >= RADEON_MAX_TEXTURE_LEVELS)) { +- _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__); +- return; +- } +- +- texImage = t->base.tObj->Image[face][level]; +- +- if (!texImage) { +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: texImage %d is NULL!\n", +- __FUNCTION__, level); +- return; +- } +- if (!texImage->Data) { +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: image data is NULL!\n", +- __FUNCTION__); +- return; +- } +- +- if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) { +- assert(level == 0); +- assert(hwlevel == 0); +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: image data is rectangular\n", +- __FUNCTION__); +- r300UploadRectSubImage(rmesa, t, texImage, x, y, width, height); +- return; +- } else if (texImage->IsClientData) { +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, +- "%s: image data is in GART client storage\n", +- __FUNCTION__); +- r300UploadGARTClientSubImage(rmesa, t, texImage, hwlevel, x, y, +- width, height); +- return; +- } else if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "%s: image data is in normal memory\n", +- __FUNCTION__); +- +- imageWidth = texImage->Width; +- imageHeight = texImage->Height; +- +- offset = t->bufAddr; +- +- if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) { +- GLint imageX = 0; +- GLint imageY = 0; +- GLint blitX = t->image[face][hwlevel].x; +- GLint blitY = t->image[face][hwlevel].y; +- GLint blitWidth = t->image[face][hwlevel].width; +- GLint blitHeight = t->image[face][hwlevel].height; +- fprintf(stderr, " upload image: %d,%d at %d,%d\n", +- imageWidth, imageHeight, imageX, imageY); +- fprintf(stderr, " upload blit: %d,%d at %d,%d\n", +- blitWidth, blitHeight, blitX, blitY); +- fprintf(stderr, " blit ofs: 0x%07x level: %d/%d\n", +- (GLuint) offset, hwlevel, level); +- } +- +- t->image[face][hwlevel].data = texImage->Data; +- +- /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct. +- * NOTE: we're always use a 1KB-wide blit and I8 texture format. +- * We used to use 1, 2 and 4-byte texels and used to use the texture +- * width to dictate the blit width - but that won't work for compressed +- * textures. (Brian) +- * NOTE: can't do that with texture tiling. (sroland) +- */ +- tex.offset = offset; +- tex.image = &tmp; +- /* copy (x,y,width,height,data) */ +- memcpy(&tmp, &t->image[face][hwlevel], sizeof(tmp)); +- +- if (texImage->TexFormat->TexelBytes > 4) { +- const int log2TexelBytes = +- (3 + (texImage->TexFormat->TexelBytes >> 4)); +- tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */ +- tex.pitch = +- MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / +- 64, 1); +- tex.height = imageHeight; +- tex.width = imageWidth << log2TexelBytes; +- tex.offset += (tmp.x << log2TexelBytes) & ~1023; +- tmp.x = tmp.x % (1024 >> log2TexelBytes); +- tmp.width = tmp.width << log2TexelBytes; +- } else if (texImage->TexFormat->TexelBytes) { +- /* use multi-byte upload scheme */ +- tex.height = imageHeight; +- tex.width = imageWidth; +- switch (texImage->TexFormat->TexelBytes) { +- case 1: +- tex.format = RADEON_TXFORMAT_I8; +- break; +- case 2: +- tex.format = RADEON_TXFORMAT_AI88; +- break; +- case 4: +- tex.format = RADEON_TXFORMAT_ARGB8888; +- break; +- } +- tex.pitch = +- MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / +- 64, 1); +- tex.offset += tmp.x & ~1023; +- tmp.x = tmp.x % 1024; +- +- if (t->tile_bits & R300_TXO_MICRO_TILE) { +- /* need something like "tiled coordinates" ? */ +- tmp.y = tmp.x / (tex.pitch * 128) * 2; +- tmp.x = +- tmp.x % (tex.pitch * 128) / 2 / +- texImage->TexFormat->TexelBytes; +- tex.pitch |= RADEON_DST_TILE_MICRO >> 22; +- } else { +- tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1); +- } +-#if 1 +- if ((t->tile_bits & R300_TXO_MACRO_TILE) && +- (texImage->Width * texImage->TexFormat->TexelBytes >= 256) +- && ((!(t->tile_bits & R300_TXO_MICRO_TILE) +- && (texImage->Height >= 8)) +- || (texImage->Height >= 16))) { +- /* weird: R200 disables macro tiling if mip width is smaller than 256 bytes, +- OR if height is smaller than 8 automatically, but if micro tiling is active +- the limit is height 16 instead ? */ +- tex.pitch |= RADEON_DST_TILE_MACRO >> 22; +- } +-#endif +- } else { +- /* In case of for instance 8x8 texture (2x2 dxt blocks), +- padding after the first two blocks is needed (only +- with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */ +- /* set tex.height to 1/4 since 1 "macropixel" (dxt-block) +- has 4 real pixels. Needed so the kernel module reads +- the right amount of data. */ +- tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */ +- tex.pitch = (R300_BLIT_WIDTH_BYTES / 64); +- tex.height = (imageHeight + 3) / 4; +- tex.width = (imageWidth + 3) / 4; +- if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) { +- tex.width *= 8; +- } else { +- tex.width *= 16; +- } +- } +- +- LOCK_HARDWARE(&rmesa->radeon); +- do { +- ret = +- drmCommandWriteRead(rmesa->radeon.dri.fd, +- DRM_RADEON_TEXTURE, &tex, +- sizeof(drm_radeon_texture_t)); +- if (ret) { +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, +- "DRM_RADEON_TEXTURE: again!\n"); +- usleep(1); +- } +- } while (ret == -EAGAIN); +- +- UNLOCK_HARDWARE(&rmesa->radeon); +- +- if (ret) { +- fprintf(stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret); +- fprintf(stderr, " offset=0x%08x\n", offset); +- fprintf(stderr, " image width=%d height=%d\n", +- imageWidth, imageHeight); +- fprintf(stderr, " blit width=%d height=%d data=%p\n", +- t->image[face][hwlevel].width, +- t->image[face][hwlevel].height, +- t->image[face][hwlevel].data); +- _mesa_exit(-1); +- } +-} +- +-/** +- * Upload the texture images associated with texture \a t. This might +- * require the allocation of texture memory. +- * +- * \param rmesa Context pointer +- * \param t Texture to be uploaded +- * \param face Cube map face to be uploaded. Zero for non-cube maps. +- */ +- +-int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face) +-{ +- const int numLevels = t->base.lastLevel - t->base.firstLevel + 1; +- +- if (t->image_override) +- return 0; +- +- if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) { +- fprintf(stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, +- (void *)rmesa->radeon.glCtx, (void *)t->base.tObj, +- t->base.totalSize, t->base.firstLevel, +- t->base.lastLevel); +- } +- +- if (t->base.totalSize == 0) +- return 0; +- +- if (RADEON_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "%s: Syncing\n", __FUNCTION__); +- radeonFinish(rmesa->radeon.glCtx); +- } +- +- LOCK_HARDWARE(&rmesa->radeon); +- +- if (t->base.memBlock == NULL) { +- int heap; +- +- heap = driAllocateTexture(rmesa->texture_heaps, rmesa->nr_heaps, +- (driTextureObject *) t); +- if (heap == -1) { +- UNLOCK_HARDWARE(&rmesa->radeon); +- return -1; +- } +- +- /* Set the base offset of the texture image */ +- t->bufAddr = rmesa->radeon.radeonScreen->texOffset[heap] +- + t->base.memBlock->ofs; +- t->offset = t->bufAddr; +- +- if (!(t->base.tObj->Image[0][0]->IsClientData)) { +- /* hope it's safe to add that here... */ +- t->offset |= t->tile_bits; +- } +- } +- +- /* Let the world know we've used this memory recently. +- */ +- driUpdateTextureLRU((driTextureObject *) t); +- UNLOCK_HARDWARE(&rmesa->radeon); +- +- /* Upload any images that are new */ +- if (t->base.dirty_images[face]) { +- int i; +- for (i = 0; i < numLevels; i++) { +- if ((t->base. +- dirty_images[face] & (1 << +- (i + t->base.firstLevel))) != +- 0) { +- r300UploadSubImage(rmesa, t, i, 0, 0, +- t->image[face][i].width, +- t->image[face][i].height, +- face); +- } +- } +- t->base.dirty_images[face] = 0; +- } +- +- if (RADEON_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "%s: Syncing\n", __FUNCTION__); +- radeonFinish(rmesa->radeon.glCtx); +- } +- +- return 0; +-} +diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c +index e2329f0..cf4cad7 100644 +--- a/src/mesa/drivers/dri/r300/r300_texstate.c ++++ b/src/mesa/drivers/dri/r300/r300_texstate.c +@@ -47,7 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r300_context.h" + #include "r300_state.h" + #include "r300_ioctl.h" +-#include "radeon_ioctl.h" ++#include "radeon_mipmap_tree.h" + #include "r300_tex.h" + #include "r300_reg.h" + +@@ -143,13 +143,12 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) + }, + }; + const GLuint *format; +- r300TexObjPtr t; ++ radeonTexObjPtr t; + + if (!tObj) + return; + +- t = (r300TexObjPtr) tObj->DriverData; +- ++ t = radeon_tex_obj(tObj); + + switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) { + case MESA_FORMAT_Z16: +@@ -171,13 +170,13 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) + + switch (tObj->DepthMode) { + case GL_LUMINANCE: +- t->format = format[0]; ++ t->pp_txformat = format[0]; + break; + case GL_INTENSITY: +- t->format = format[1]; ++ t->pp_txformat = format[1]; + break; + case GL_ALPHA: +- t->format = format[2]; ++ t->pp_txformat = format[2]; + break; + default: + /* Error...which should have already been caught by higher +@@ -190,399 +189,134 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) + + + /** +- * Compute sizes and fill in offset and blit information for the given +- * image (determined by \p face and \p level). +- * +- * \param curOffset points to the offset at which the image is to be stored +- * and is updated by this function according to the size of the image. +- */ +-static void compute_tex_image_offset( +- struct gl_texture_object *tObj, +- GLuint face, +- GLint level, +- GLint* curOffset) +-{ +- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData; +- const struct gl_texture_image* texImage; +- GLuint blitWidth = R300_BLIT_WIDTH_BYTES; +- GLuint texelBytes; +- GLuint size; +- +- texImage = tObj->Image[0][level + t->base.firstLevel]; +- if (!texImage) +- return; +- +- texelBytes = texImage->TexFormat->TexelBytes; +- +- /* find image size in bytes */ +- if (texImage->IsCompressed) { +- if ((t->format & R300_TX_FORMAT_DXT1) == +- R300_TX_FORMAT_DXT1) { +- // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format); +- if ((texImage->Width + 3) < 8) /* width one block */ +- size = texImage->CompressedSize * 4; +- else if ((texImage->Width + 3) < 16) +- size = texImage->CompressedSize * 2; +- else +- size = texImage->CompressedSize; +- } else { +- /* DXT3/5, 16 bytes per block */ +- WARN_ONCE +- ("DXT 3/5 suffers from multitexturing problems!\n"); +- // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width); +- if ((texImage->Width + 3) < 8) +- size = texImage->CompressedSize * 2; +- else +- size = texImage->CompressedSize; +- } +- } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { +- size = +- ((texImage->Width * texelBytes + +- 63) & ~63) * texImage->Height; +- blitWidth = 64 / texelBytes; +- } else if (t->tile_bits & R300_TXO_MICRO_TILE) { +- /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, +- though the actual offset may be different (if texture is less than +- 32 bytes width) to the untiled case */ +- int w = (texImage->Width * texelBytes * 2 + 31) & ~31; +- size = +- (w * ((texImage->Height + 1) / 2)) * +- texImage->Depth; +- blitWidth = MAX2(texImage->Width, 64 / texelBytes); +- } else { +- int w = (texImage->Width * texelBytes + 31) & ~31; +- size = w * texImage->Height * texImage->Depth; +- blitWidth = MAX2(texImage->Width, 64 / texelBytes); +- } +- assert(size > 0); +- +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n", +- texImage->Width, texImage->Height, +- texImage->Depth, +- texImage->TexFormat->TexelBytes, +- texImage->InternalFormat); +- +- /* All images are aligned to a 32-byte offset */ +- *curOffset = (*curOffset + 0x1f) & ~0x1f; +- +- if (texelBytes) { +- /* fix x and y coords up later together with offset */ +- t->image[face][level].x = *curOffset; +- t->image[face][level].y = 0; +- t->image[face][level].width = +- MIN2(size / texelBytes, blitWidth); +- t->image[face][level].height = +- (size / texelBytes) / t->image[face][level].width; +- } else { +- t->image[face][level].x = *curOffset % R300_BLIT_WIDTH_BYTES; +- t->image[face][level].y = *curOffset / R300_BLIT_WIDTH_BYTES; +- t->image[face][level].width = +- MIN2(size, R300_BLIT_WIDTH_BYTES); +- t->image[face][level].height = size / t->image[face][level].width; +- } +- +- if (RADEON_DEBUG & DEBUG_TEXTURE) +- fprintf(stderr, +- "level %d, face %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n", +- level, face, texImage->Width, texImage->Height, +- t->image[face][level].x, t->image[face][level].y, +- t->image[face][level].width, t->image[face][level].height, +- size, *curOffset); +- +- *curOffset += size; +-} +- +- +- +-/** +- * This function computes the number of bytes of storage needed for +- * the given texture object (all mipmap levels, all cube faces). +- * The \c image[face][level].x/y/width/height parameters for upload/blitting +- * are computed here. \c filter, \c format, etc. will be set here +- * too. ++ * Compute the cached hardware register values for the given texture object. + * + * \param rmesa Context pointer +- * \param tObj GL texture object whose images are to be posted to +- * hardware state. ++ * \param t the r300 texture object + */ +-static void r300SetTexImages(r300ContextPtr rmesa, +- struct gl_texture_object *tObj) ++static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t) + { +- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData; +- const struct gl_texture_image *baseImage = +- tObj->Image[0][tObj->BaseLevel]; +- GLint curOffset; +- GLint i, texelBytes; +- GLint numLevels; +- GLint log2Width, log2Height, log2Depth; +- +- /* Set the hardware texture format +- */ ++ const struct gl_texture_image *firstImage; ++ int firstlevel = t->mt ? t->mt->firstLevel : 0; ++ ++ firstImage = t->base.Image[0][firstlevel]; ++ + if (!t->image_override +- && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) { +- if (baseImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) { +- r300SetDepthTexMode(tObj); ++ && VALID_FORMAT(firstImage->TexFormat->MesaFormat)) { ++ if (firstImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) { ++ r300SetDepthTexMode(&t->base); + } else { +- t->format = tx_table[baseImage->TexFormat->MesaFormat].format; ++ t->pp_txformat = tx_table[firstImage->TexFormat->MesaFormat].format; + } + +- t->filter |= tx_table[baseImage->TexFormat->MesaFormat].filter; ++ t->pp_txfilter |= tx_table[firstImage->TexFormat->MesaFormat].filter; + } else if (!t->image_override) { + _mesa_problem(NULL, "unexpected texture format in %s", + __FUNCTION__); + return; + } + +- texelBytes = baseImage->TexFormat->TexelBytes; +- +- /* Compute which mipmap levels we really want to send to the hardware. +- */ +- driCalculateTextureFirstLastLevel((driTextureObject *) t); +- log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2; +- log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2; +- log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2; +- +- numLevels = t->base.lastLevel - t->base.firstLevel + 1; ++ if (t->image_override && t->bo) ++ return; + +- assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS); ++ t->pp_txsize = (((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT) ++ | ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT) ++ | ((firstImage->DepthLog2) << R300_TX_DEPTHMASK_SHIFT) ++ | ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT)); + +- /* Calculate mipmap offsets and dimensions for blitting (uploading) +- * The idea is that we lay out the mipmap levels within a block of +- * memory organized as a rectangle of width BLIT_WIDTH_BYTES. +- */ + t->tile_bits = 0; + +- /* figure out if this texture is suitable for tiling. */ +-#if 0 /* Disabled for now */ +- if (texelBytes) { +- if ((tObj->Target != GL_TEXTURE_RECTANGLE_NV) && +- /* texrect might be able to use micro tiling too in theory? */ +- (baseImage->Height > 1)) { +- +- /* allow 32 (bytes) x 1 mip (which will use two times the space +- the non-tiled version would use) max if base texture is large enough */ +- if ((numLevels == 1) || +- (((baseImage->Width * texelBytes / +- baseImage->Height) <= 32) +- && (baseImage->Width * texelBytes > 64)) +- || +- ((baseImage->Width * texelBytes / +- baseImage->Height) <= 16)) { +- t->tile_bits |= R300_TXO_MICRO_TILE; +- } +- } +- +- if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) { +- /* we can set macro tiling even for small textures, they will be untiled anyway */ +- t->tile_bits |= R300_TXO_MACRO_TILE; +- } +- } +-#endif ++ if (t->base.Target == GL_TEXTURE_CUBE_MAP) ++ t->pp_txformat |= R300_TX_FORMAT_CUBIC_MAP; ++ if (t->base.Target == GL_TEXTURE_3D) ++ t->pp_txformat |= R300_TX_FORMAT_3D; + +- curOffset = 0; + +- if (tObj->Target == GL_TEXTURE_CUBE_MAP) { +- ASSERT(log2Width == log2Height); +- t->format |= R300_TX_FORMAT_CUBIC_MAP; +- +- for(i = 0; i < numLevels; i++) { +- GLuint face; +- for(face = 0; face < 6; face++) +- compute_tex_image_offset(tObj, face, i, &curOffset); +- } +- } else { +- if (tObj->Target == GL_TEXTURE_3D) +- t->format |= R300_TX_FORMAT_3D; +- +- for (i = 0; i < numLevels; i++) +- compute_tex_image_offset(tObj, 0, i, &curOffset); +- } +- +- /* Align the total size of texture memory block. +- */ +- t->base.totalSize = +- (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; +- +- t->size = +- (((tObj->Image[0][t->base.firstLevel]->Width - +- 1) << R300_TX_WIDTHMASK_SHIFT) +- | ((tObj->Image[0][t->base.firstLevel]->Height - 1) << +- R300_TX_HEIGHTMASK_SHIFT) +- | ((tObj->Image[0][t->base.firstLevel]->DepthLog2) << +- R300_TX_DEPTHMASK_SHIFT)) +- | ((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT); +- +- t->pitch = 0; +- +- /* Only need to round to nearest 32 for textures, but the blitter +- * requires 64-byte aligned pitches, and we may/may not need the +- * blitter. NPOT only! +- */ +- if (baseImage->IsCompressed) { +- t->pitch |= +- (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63); +- } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { +- unsigned int align = (64 / texelBytes) - 1; +- t->pitch |= ((tObj->Image[0][t->base.firstLevel]->Width * +- texelBytes) + 63) & ~(63); +- t->size |= R300_TX_SIZE_TXPITCH_EN; ++ if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) { ++ unsigned int align = (64 / t->mt->bpp) - 1; ++ t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN; + if (!t->image_override) +- t->pitch_reg = +- (((tObj->Image[0][t->base.firstLevel]->Width) + +- align) & ~align) - 1; +- } else { +- t->pitch |= +- ((tObj->Image[0][t->base.firstLevel]->Width * +- texelBytes) + 63) & ~(63); ++ t->pp_txpitch = ((firstImage->Width + align) & ~align) - 1; + } + + if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { +- if (tObj->Image[0][t->base.firstLevel]->Width > 2048) +- t->pitch_reg |= R500_TXWIDTH_BIT11; +- if (tObj->Image[0][t->base.firstLevel]->Height > 2048) +- t->pitch_reg |= R500_TXHEIGHT_BIT11; ++ if (firstImage->Width > 2048) ++ t->pp_txpitch |= R500_TXWIDTH_BIT11; ++ if (firstImage->Height > 2048) ++ t->pp_txpitch |= R500_TXHEIGHT_BIT11; + } + } + +-/* ================================================================ +- * Texture unit state management ++/** ++ * Ensure the given texture is ready for rendering. ++ * ++ * Mostly this means populating the texture object's mipmap tree. + */ +- +-static GLboolean r300EnableTexture2D(GLcontext * ctx, int unit) ++static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj) + { + r300ContextPtr rmesa = R300_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData; +- +- ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D); +- +- if (t->base.dirty_images[0]) { +- R300_FIREVERTICES(rmesa); ++ radeonTexObj *t = radeon_tex_obj(texObj); + +- r300SetTexImages(rmesa, tObj); +- r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0); +- if (!t->base.memBlock && !t->image_override) +- return GL_FALSE; +- } +- +- return GL_TRUE; +-} +- +-static GLboolean r300EnableTexture3D(GLcontext * ctx, int unit) +-{ +- r300ContextPtr rmesa = R300_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData; +- +- ASSERT(tObj->Target == GL_TEXTURE_3D); +- +- /* r300 does not support mipmaps for 3D textures. */ +- if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) { ++ if (!radeon_validate_texture_miptree(ctx, texObj)) + return GL_FALSE; +- } + +- if (t->base.dirty_images[0]) { +- R300_FIREVERTICES(rmesa); +- r300SetTexImages(rmesa, tObj); +- r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0); +- if (!t->base.memBlock) +- return GL_FALSE; +- } ++ /* Configure the hardware registers (more precisely, the cached version ++ * of the hardware registers). */ ++ setup_hardware_state(rmesa, t); + ++ t->validated = GL_TRUE; + return GL_TRUE; + } + +-static GLboolean r300EnableTextureCube(GLcontext * ctx, int unit) ++/** ++ * Ensure all enabled and complete textures are uploaded along with any buffers being used. ++ */ ++GLboolean r300ValidateBuffers(GLcontext * ctx) + { + r300ContextPtr rmesa = R300_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData; +- GLuint face; +- +- ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP); +- +- if (t->base.dirty_images[0] || t->base.dirty_images[1] || +- t->base.dirty_images[2] || t->base.dirty_images[3] || +- t->base.dirty_images[4] || t->base.dirty_images[5]) { +- /* flush */ +- R300_FIREVERTICES(rmesa); +- /* layout memory space, once for all faces */ +- r300SetTexImages(rmesa, tObj); +- } ++ struct radeon_renderbuffer *rrb; ++ int i; + +- /* upload (per face) */ +- for (face = 0; face < 6; face++) { +- if (t->base.dirty_images[face]) { +- r300UploadTexImages(rmesa, +- (r300TexObjPtr) tObj->DriverData, +- face); +- } +- } ++ radeon_validate_reset_bos(&rmesa->radeon); + +- if (!t->base.memBlock) { +- /* texmem alloc failed, use s/w fallback */ +- return GL_FALSE; ++ rrb = radeon_get_colorbuffer(&rmesa->radeon); ++ /* color buffer */ ++ if (rrb && rrb->bo) { ++ radeon_validate_bo(&rmesa->radeon, rrb->bo, ++ 0, RADEON_GEM_DOMAIN_VRAM); + } + +- return GL_TRUE; +-} +- +-static GLboolean r300EnableTextureRect(GLcontext * ctx, int unit) +-{ +- r300ContextPtr rmesa = R300_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData; +- +- ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV); +- +- if (t->base.dirty_images[0]) { +- R300_FIREVERTICES(rmesa); +- +- r300SetTexImages(rmesa, tObj); +- r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0); +- if (!t->base.memBlock && !t->image_override && +- !rmesa->prefer_gart_client_texturing) +- return GL_FALSE; ++ /* depth buffer */ ++ rrb = radeon_get_depthbuffer(&rmesa->radeon); ++ if (rrb && rrb->bo) { ++ radeon_validate_bo(&rmesa->radeon, rrb->bo, ++ 0, RADEON_GEM_DOMAIN_VRAM); + } ++ ++ for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { ++ radeonTexObj *t; + +- return GL_TRUE; +-} +- +-static GLboolean r300UpdateTexture(GLcontext * ctx, int unit) +-{ +- r300ContextPtr rmesa = R300_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData; ++ if (!ctx->Texture.Unit[i]._ReallyEnabled) ++ continue; + +- /* Fallback if there's a texture border */ +- if (tObj->Image[0][tObj->BaseLevel]->Border > 0) +- return GL_FALSE; +- +- /* Update state if this is a different texture object to last +- * time. +- */ +- if (rmesa->state.texture.unit[unit].texobj != t) { +- if (rmesa->state.texture.unit[unit].texobj != NULL) { +- /* The old texture is no longer bound to this texture unit. +- * Mark it as such. +- */ +- +- rmesa->state.texture.unit[unit].texobj->base.bound &= +- ~(1 << unit); ++ if (!r300_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) { ++ _mesa_warning(ctx, ++ "failed to validate texture for unit %d.\n", ++ i); + } +- +- rmesa->state.texture.unit[unit].texobj = t; +- t->base.bound |= (1 << unit); +- driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */ ++ t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); ++ if (t->image_override && t->bo) ++ radeon_validate_bo(&rmesa->radeon, t->bo, ++ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); ++ ++ else if (t->mt->bo) ++ radeon_validate_bo(&rmesa->radeon, t->mt->bo, ++ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + } ++ if (rmesa->radeon.dma.current) ++ radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); + +- return !t->border_fallback; ++ return radeon_revalidate_bos(ctx); + } + + void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, +@@ -591,78 +325,164 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, + r300ContextPtr rmesa = pDRICtx->driverPrivate; + struct gl_texture_object *tObj = + _mesa_lookup_texture(rmesa->radeon.glCtx, texname); +- r300TexObjPtr t; ++ radeonTexObjPtr t = radeon_tex_obj(tObj); + uint32_t pitch_val; + + if (!tObj) + return; + +- t = (r300TexObjPtr) tObj->DriverData; +- + t->image_override = GL_TRUE; + + if (!offset) + return; + +- t->offset = offset; +- t->pitch_reg &= (1 << 13) -1; ++ t->bo = NULL; ++ t->override_offset = offset; ++ t->pp_txpitch &= (1 << 13) -1; + pitch_val = pitch; + + switch (depth) { + case 32: +- t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); +- t->filter |= tx_table[2].filter; ++ t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); ++ t->pp_txfilter |= tx_table[2].filter; + pitch_val /= 4; + break; + case 24: + default: +- t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); +- t->filter |= tx_table[4].filter; ++ t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); ++ t->pp_txfilter |= tx_table[4].filter; + pitch_val /= 4; + break; + case 16: +- t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); +- t->filter |= tx_table[5].filter; ++ t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); ++ t->pp_txfilter |= tx_table[5].filter; + pitch_val /= 2; + break; + } + pitch_val--; + +- t->pitch_reg |= pitch_val; ++ t->pp_txpitch |= pitch_val; + } + +-static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit) ++void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, __DRIdrawable *dPriv) + { +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- +- if (texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT)) { +- return (r300EnableTextureRect(ctx, unit) && +- r300UpdateTexture(ctx, unit)); +- } else if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) { +- return (r300EnableTexture2D(ctx, unit) && +- r300UpdateTexture(ctx, unit)); +- } else if (texUnit->_ReallyEnabled & (TEXTURE_3D_BIT)) { +- return (r300EnableTexture3D(ctx, unit) && +- r300UpdateTexture(ctx, unit)); +- } else if (texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT)) { +- return (r300EnableTextureCube(ctx, unit) && +- r300UpdateTexture(ctx, unit)); +- } else if (texUnit->_ReallyEnabled) { +- return GL_FALSE; +- } else { +- return GL_TRUE; ++ struct gl_texture_unit *texUnit; ++ struct gl_texture_object *texObj; ++ struct gl_texture_image *texImage; ++ struct radeon_renderbuffer *rb; ++ radeon_texture_image *rImage; ++ radeonContextPtr radeon; ++ r300ContextPtr rmesa; ++ struct radeon_framebuffer *rfb; ++ radeonTexObjPtr t; ++ uint32_t pitch_val; ++ uint32_t internalFormat, type, format; ++ ++ type = GL_BGRA; ++ format = GL_UNSIGNED_BYTE; ++ internalFormat = (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT ? 3 : 4); ++ ++ radeon = pDRICtx->driverPrivate; ++ rmesa = pDRICtx->driverPrivate; ++ ++ rfb = dPriv->driverPrivate; ++ texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit]; ++ texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target); ++ texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0); ++ ++ rImage = get_radeon_texture_image(texImage); ++ t = radeon_tex_obj(texObj); ++ if (t == NULL) { ++ return; ++ } ++ ++ radeon_update_renderbuffers(pDRICtx, dPriv); ++ /* back & depth buffer are useless free them right away */ ++ rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; + } ++ rb = rfb->color_rb[0]; ++ if (rb->bo == NULL) { ++ /* Failed to BO for the buffer */ ++ return; ++ } ++ ++ _mesa_lock_texture(radeon->glCtx, texObj); ++ if (t->bo) { ++ radeon_bo_unref(t->bo); ++ t->bo = NULL; ++ } ++ if (rImage->bo) { ++ radeon_bo_unref(rImage->bo); ++ rImage->bo = NULL; ++ } ++ if (t->mt) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = NULL; ++ } ++ if (rImage->mt) { ++ radeon_miptree_unreference(rImage->mt); ++ rImage->mt = NULL; ++ } ++ fprintf(stderr,"settexbuf %dx%d@%d %d targ %x format %x\n", rb->width, rb->height, rb->cpp, rb->pitch, target, format); ++ _mesa_init_teximage_fields(radeon->glCtx, target, texImage, ++ rb->width, rb->height, 1, 0, rb->cpp); ++ texImage->RowStride = rb->pitch / rb->cpp; ++ texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx, ++ internalFormat, ++ type, format, 0); ++ rImage->bo = rb->bo; ++ radeon_bo_ref(rImage->bo); ++ t->bo = rb->bo; ++ radeon_bo_ref(t->bo); ++ t->tile_bits = 0; ++ t->image_override = GL_TRUE; ++ t->override_offset = 0; ++ t->pp_txpitch &= (1 << 13) -1; ++ pitch_val = rb->pitch; ++ switch (rb->cpp) { ++ case 4: ++ t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); ++ t->pp_txfilter |= tx_table[2].filter; ++ pitch_val /= 4; ++ break; ++ case 3: ++ default: ++ t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); ++ t->pp_txfilter |= tx_table[4].filter; ++ pitch_val /= 4; ++ break; ++ case 2: ++ t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); ++ t->pp_txfilter |= tx_table[5].filter; ++ pitch_val /= 2; ++ break; ++ } ++ pitch_val--; ++ t->pp_txsize = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) | ++ ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT); ++ t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN; ++ t->pp_txpitch |= pitch_val; ++ ++ if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { ++ if (rb->width > 2048) ++ t->pp_txpitch |= R500_TXWIDTH_BIT11; ++ if (rb->height > 2048) ++ t->pp_txpitch |= R500_TXHEIGHT_BIT11; ++ } ++ t->validated = GL_TRUE; ++ _mesa_unlock_texture(radeon->glCtx, texObj); ++ return; + } + +-void r300UpdateTextureState(GLcontext * ctx) ++void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) + { +- int i; +- +- for (i = 0; i < 8; i++) { +- if (!r300UpdateTextureUnit(ctx, i)) { +- _mesa_warning(ctx, +- "failed to update texture state for unit %d.\n", +- i); +- } +- } ++ r300SetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); + } +diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c +deleted file mode 100644 +index 5267fe9..0000000 +--- a/src/mesa/drivers/dri/r300/radeon_context.c ++++ /dev/null +@@ -1,330 +0,0 @@ +-/* +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/** +- * \file radeon_context.c +- * Common context initialization. +- * +- * \author Keith Whitwell +- */ +- +-#include +- +-#include "main/glheader.h" +-#include "main/imports.h" +-#include "main/context.h" +-#include "main/state.h" +-#include "main/matrix.h" +-#include "main/framebuffer.h" +- +-#include "drivers/common/driverfuncs.h" +-#include "swrast/swrast.h" +- +-#include "radeon_screen.h" +-#include "radeon_ioctl.h" +-#include "radeon_macros.h" +-#include "radeon_reg.h" +- +-#include "radeon_state.h" +-#include "r300_state.h" +- +-#include "utils.h" +-#include "vblank.h" +-#include "xmlpool.h" /* for symbolic values of enum-type options */ +- +-#define DRIVER_DATE "20060815" +- +- +-/* Return various strings for glGetString(). +- */ +-static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) +-{ +- radeonContextPtr radeon = RADEON_CONTEXT(ctx); +- static char buffer[128]; +- +- switch (name) { +- case GL_VENDOR: +- if (IS_R300_CLASS(radeon->radeonScreen)) +- return (GLubyte *) "DRI R300 Project"; +- else +- return (GLubyte *) "Tungsten Graphics, Inc."; +- +- case GL_RENDERER: +- { +- unsigned offset; +- GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : +- radeon->radeonScreen->AGPMode; +- const char* chipname; +- +- if (IS_R300_CLASS(radeon->radeonScreen)) +- chipname = "R300"; +- else +- chipname = "R200"; +- +- offset = driGetRendererString(buffer, chipname, DRIVER_DATE, +- agp_mode); +- +- if (IS_R300_CLASS(radeon->radeonScreen)) { +- sprintf(&buffer[offset], " %sTCL", +- (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) +- ? "" : "NO-"); +- } else { +- sprintf(&buffer[offset], " %sTCL", +- !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) +- ? "" : "NO-"); +- } +- +- return (GLubyte *) buffer; +- } +- +- default: +- return NULL; +- } +-} +- +-/* Initialize the driver's misc functions. +- */ +-static void radeonInitDriverFuncs(struct dd_function_table *functions) +-{ +- functions->GetString = radeonGetString; +-} +- +- +-/** +- * Create and initialize all common fields of the context, +- * including the Mesa context itself. +- */ +-GLboolean radeonInitContext(radeonContextPtr radeon, +- struct dd_function_table* functions, +- const __GLcontextModes * glVisual, +- __DRIcontextPrivate * driContextPriv, +- void *sharedContextPrivate) +-{ +- __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; +- radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); +- GLcontext* ctx; +- GLcontext* shareCtx; +- int fthrottle_mode; +- +- /* Fill in additional standard functions. */ +- radeonInitDriverFuncs(functions); +- +- radeon->radeonScreen = screen; +- /* Allocate and initialize the Mesa context */ +- if (sharedContextPrivate) +- shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx; +- else +- shareCtx = NULL; +- radeon->glCtx = _mesa_create_context(glVisual, shareCtx, +- functions, (void *)radeon); +- if (!radeon->glCtx) +- return GL_FALSE; +- +- ctx = radeon->glCtx; +- driContextPriv->driverPrivate = radeon; +- +- /* DRI fields */ +- radeon->dri.context = driContextPriv; +- radeon->dri.screen = sPriv; +- radeon->dri.drawable = NULL; +- radeon->dri.readable = NULL; +- radeon->dri.hwContext = driContextPriv->hHWContext; +- radeon->dri.hwLock = &sPriv->pSAREA->lock; +- radeon->dri.fd = sPriv->fd; +- radeon->dri.drmMinor = sPriv->drm_version.minor; +- +- radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + +- screen->sarea_priv_offset); +- +- /* Setup IRQs */ +- fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); +- radeon->iw.irq_seq = -1; +- radeon->irqsEmitted = 0; +- radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && +- radeon->radeonScreen->irq); +- +- radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); +- +- if (!radeon->do_irqs) +- fprintf(stderr, +- "IRQ's not enabled, falling back to %s: %d %d\n", +- radeon->do_usleeps ? "usleeps" : "busy waits", +- fthrottle_mode, radeon->radeonScreen->irq); +- +- (*sPriv->systemTime->getUST) (&radeon->swap_ust); +- +- return GL_TRUE; +-} +- +- +-/** +- * Cleanup common context fields. +- * Called by r200DestroyContext/r300DestroyContext +- */ +-void radeonCleanupContext(radeonContextPtr radeon) +-{ +- /* _mesa_destroy_context() might result in calls to functions that +- * depend on the DriverCtx, so don't set it to NULL before. +- * +- * radeon->glCtx->DriverCtx = NULL; +- */ +- +- /* free the Mesa context */ +- _mesa_destroy_context(radeon->glCtx); +- +- if (radeon->state.scissor.pClipRects) { +- FREE(radeon->state.scissor.pClipRects); +- radeon->state.scissor.pClipRects = 0; +- } +-} +- +- +-/** +- * Swap front and back buffer. +- */ +-void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) +-{ +- if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { +- radeonContextPtr radeon; +- GLcontext *ctx; +- +- radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; +- ctx = radeon->glCtx; +- +- if (ctx->Visual.doubleBufferMode) { +- _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ +- if (radeon->doPageFlip) { +- radeonPageFlip(dPriv); +- } else { +- radeonCopyBuffer(dPriv, NULL); +- } +- } +- } else { +- /* XXX this shouldn't be an error but we can't handle it for now */ +- _mesa_problem(NULL, "%s: drawable has no context!", +- __FUNCTION__); +- } +-} +- +-void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, +- int x, int y, int w, int h ) +-{ +- if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { +- radeonContextPtr radeon; +- GLcontext *ctx; +- +- radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; +- ctx = radeon->glCtx; +- +- if (ctx->Visual.doubleBufferMode) { +- drm_clip_rect_t rect; +- rect.x1 = x + dPriv->x; +- rect.y1 = (dPriv->h - y - h) + dPriv->y; +- rect.x2 = rect.x1 + w; +- rect.y2 = rect.y1 + h; +- _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ +- radeonCopyBuffer(dPriv, &rect); +- } +- } else { +- /* XXX this shouldn't be an error but we can't handle it for now */ +- _mesa_problem(NULL, "%s: drawable has no context!", +- __FUNCTION__); +- } +-} +- +-/* Force the context `c' to be the current context and associate with it +- * buffer `b'. +- */ +-GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, +- __DRIdrawablePrivate * driDrawPriv, +- __DRIdrawablePrivate * driReadPriv) +-{ +- if (driContextPriv) { +- radeonContextPtr radeon = +- (radeonContextPtr) driContextPriv->driverPrivate; +- +- if (RADEON_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s ctx %p\n", __FUNCTION__, +- radeon->glCtx); +- +- if (radeon->dri.drawable != driDrawPriv) { +- if (driDrawPriv->swap_interval == (unsigned)-1) { +- driDrawPriv->vblFlags = +- (radeon->radeonScreen->irq != 0) +- ? driGetDefaultVBlankFlags(&radeon-> +- optionCache) +- : VBLANK_FLAG_NO_IRQ; +- +- driDrawableInitVBlank(driDrawPriv); +- } +- } +- +- radeon->dri.readable = driReadPriv; +- +- if (radeon->dri.drawable != driDrawPriv || +- radeon->lastStamp != driDrawPriv->lastStamp) { +- radeon->dri.drawable = driDrawPriv; +- +- radeonSetCliprects(radeon); +- r300UpdateViewportOffset(radeon->glCtx); +- } +- +- _mesa_make_current(radeon->glCtx, +- (GLframebuffer *) driDrawPriv-> +- driverPrivate, +- (GLframebuffer *) driReadPriv-> +- driverPrivate); +- +- _mesa_update_state(radeon->glCtx); +- +- radeonUpdatePageFlipping(radeon); +- } else { +- if (RADEON_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s ctx is null\n", __FUNCTION__); +- _mesa_make_current(0, 0, 0); +- } +- +- if (RADEON_DEBUG & DEBUG_DRI) +- fprintf(stderr, "End %s\n", __FUNCTION__); +- return GL_TRUE; +-} +- +-/* Force the context `c' to be unbound from its buffer. +- */ +-GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) +-{ +- radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; +- +- if (RADEON_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s ctx %p\n", __FUNCTION__, +- radeon->glCtx); +- +- return GL_TRUE; +-} +- +diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h +index 47cbc22..250570f 100644 +--- a/src/mesa/drivers/dri/r300/radeon_context.h ++++ b/src/mesa/drivers/dri/r300/radeon_context.h +@@ -49,20 +49,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "drm.h" + #include "dri_util.h" + +-struct radeon_context; +-typedef struct radeon_context radeonContextRec; +-typedef struct radeon_context *radeonContextPtr; +- +-/* Rasterizing fallbacks */ +-/* See correponding strings in r200_swtcl.c */ +-#define RADEON_FALLBACK_TEXTURE 0x0001 +-#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 +-#define RADEON_FALLBACK_STENCIL 0x0004 +-#define RADEON_FALLBACK_RENDER_MODE 0x0008 +-#define RADEON_FALLBACK_BLEND_EQ 0x0010 +-#define RADEON_FALLBACK_BLEND_FUNC 0x0020 +-#define RADEON_FALLBACK_DISABLE 0x0040 +-#define RADEON_FALLBACK_BORDER_MODE 0x0080 ++#include "radeon_screen.h" + + #if R200_MERGED + extern void radeonFallback(GLcontext * ctx, GLuint bit, GLboolean mode); +@@ -79,155 +66,11 @@ extern void radeonFallback(GLcontext * ctx, GLuint bit, GLboolean mode); + /* TCL fallbacks */ + extern void radeonTclFallback(GLcontext * ctx, GLuint bit, GLboolean mode); + +-#define RADEON_TCL_FALLBACK_RASTER 0x0001 /* rasterization */ +-#define RADEON_TCL_FALLBACK_UNFILLED 0x0002 /* unfilled tris */ +-#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x0004 /* twoside tris */ +-#define RADEON_TCL_FALLBACK_MATERIAL 0x0008 /* material in vb */ +-#define RADEON_TCL_FALLBACK_TEXGEN_0 0x0010 /* texgen, unit 0 */ +-#define RADEON_TCL_FALLBACK_TEXGEN_1 0x0020 /* texgen, unit 1 */ +-#define RADEON_TCL_FALLBACK_TEXGEN_2 0x0040 /* texgen, unit 2 */ +-#define RADEON_TCL_FALLBACK_TEXGEN_3 0x0080 /* texgen, unit 3 */ +-#define RADEON_TCL_FALLBACK_TEXGEN_4 0x0100 /* texgen, unit 4 */ +-#define RADEON_TCL_FALLBACK_TEXGEN_5 0x0200 /* texgen, unit 5 */ +-#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x0400 /* user disable */ +-#define RADEON_TCL_FALLBACK_BITMAP 0x0800 /* draw bitmap with points */ +-#define RADEON_TCL_FALLBACK_VERTEX_PROGRAM 0x1000 /* vertex program active */ +- + #if R200_MERGED + #define TCL_FALLBACK( ctx, bit, mode ) radeonTclFallback( ctx, bit, mode ) + #else + #define TCL_FALLBACK( ctx, bit, mode ) ; + #endif + +-struct radeon_dri_mirror { +- __DRIcontextPrivate *context; /* DRI context */ +- __DRIscreenPrivate *screen; /* DRI screen */ +- /** +- * DRI drawable bound to this context for drawing. +- */ +- __DRIdrawablePrivate *drawable; +- +- /** +- * DRI drawable bound to this context for reading. +- */ +- __DRIdrawablePrivate *readable; +- +- drm_context_t hwContext; +- drm_hw_lock_t *hwLock; +- int fd; +- int drmMinor; +-}; +- +-/** +- * Derived state for internal purposes. +- */ +-struct radeon_scissor_state { +- drm_clip_rect_t rect; +- GLboolean enabled; +- +- GLuint numClipRects; /* Cliprects active */ +- GLuint numAllocedClipRects; /* Cliprects available */ +- drm_clip_rect_t *pClipRects; +-}; +- +-struct radeon_colorbuffer_state { +- GLuint clear; +- GLint drawOffset, drawPitch; +-}; +- +-struct radeon_state { +- struct radeon_colorbuffer_state color; +- struct radeon_scissor_state scissor; +-}; +- +-/** +- * Common per-context variables shared by R200 and R300. +- * R200- and R300-specific code "derive" their own context from this +- * structure. +- */ +-struct radeon_context { +- GLcontext *glCtx; /* Mesa context */ +- radeonScreenPtr radeonScreen; /* Screen private DRI data */ +- +- /* Fallback state */ +- GLuint Fallback; +- GLuint TclFallback; +- +- /* Page flipping */ +- GLuint doPageFlip; +- +- /* Drawable, cliprect and scissor information */ +- GLuint numClipRects; /* Cliprects for the draw buffer */ +- drm_clip_rect_t *pClipRects; +- unsigned int lastStamp; +- GLboolean lost_context; +- drm_radeon_sarea_t *sarea; /* Private SAREA data */ +- +- /* Mirrors of some DRI state */ +- struct radeon_dri_mirror dri; +- +- /* Busy waiting */ +- GLuint do_usleeps; +- GLuint do_irqs; +- GLuint irqsEmitted; +- drm_radeon_irq_wait_t iw; +- +- /* buffer swap */ +- int64_t swap_ust; +- int64_t swap_missed_ust; +- +- GLuint swap_count; +- GLuint swap_missed_count; +- +- /* Derived state */ +- struct radeon_state state; +- +- /* Configuration cache +- */ +- driOptionCache optionCache; +-}; +- +-#define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx)) +- +-extern void radeonSwapBuffers(__DRIdrawablePrivate * dPriv); +-extern void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, +- int x, int y, int w, int h); +-extern GLboolean radeonInitContext(radeonContextPtr radeon, +- struct dd_function_table *functions, +- const __GLcontextModes * glVisual, +- __DRIcontextPrivate * driContextPriv, +- void *sharedContextPrivate); +-extern void radeonCleanupContext(radeonContextPtr radeon); +-extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, +- __DRIdrawablePrivate * driDrawPriv, +- __DRIdrawablePrivate * driReadPriv); +-extern GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); +- +-/* ================================================================ +- * Debugging: +- */ +-#define DO_DEBUG 1 +- +-#if DO_DEBUG +-extern int RADEON_DEBUG; +-#else +-#define RADEON_DEBUG 0 +-#endif +- +-#define DEBUG_TEXTURE 0x0001 +-#define DEBUG_STATE 0x0002 +-#define DEBUG_IOCTL 0x0004 +-#define DEBUG_PRIMS 0x0008 +-#define DEBUG_VERTS 0x0010 +-#define DEBUG_FALLBACKS 0x0020 +-#define DEBUG_VFMT 0x0040 +-#define DEBUG_CODEGEN 0x0080 +-#define DEBUG_VERBOSE 0x0100 +-#define DEBUG_DRI 0x0200 +-#define DEBUG_DMA 0x0400 +-#define DEBUG_SANITY 0x0800 +-#define DEBUG_SYNC 0x1000 +-#define DEBUG_PIXEL 0x2000 +-#define DEBUG_MEMORY 0x4000 + + #endif /* __RADEON_CONTEXT_H__ */ +diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c +deleted file mode 100644 +index f042a7b..0000000 +--- a/src/mesa/drivers/dri/r300/radeon_ioctl.c ++++ /dev/null +@@ -1,396 +0,0 @@ +-/* +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Keith Whitwell +- */ +- +-#include +-#include +- +-#include "main/glheader.h" +-#include "main/imports.h" +-#include "main/macros.h" +-#include "main/context.h" +-#include "swrast/swrast.h" +-#include "r300_context.h" +-#include "radeon_ioctl.h" +-#include "r300_ioctl.h" +-#include "r300_state.h" +-#include "radeon_reg.h" +- +-#include "drirenderbuffer.h" +-#include "vblank.h" +- +-static void radeonWaitForIdle(radeonContextPtr radeon); +- +-/* ================================================================ +- * SwapBuffers with client-side throttling +- */ +- +-static uint32_t radeonGetLastFrame(radeonContextPtr radeon) +-{ +- drm_radeon_getparam_t gp; +- int ret; +- uint32_t frame = 0; +- +- gp.param = RADEON_PARAM_LAST_FRAME; +- gp.value = (int *)&frame; +- ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, +- &gp, sizeof(gp)); +- if (ret) { +- fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, +- ret); +- exit(1); +- } +- +- return frame; +-} +- +-uint32_t radeonGetAge(radeonContextPtr radeon) +-{ +- drm_radeon_getparam_t gp; +- int ret; +- uint32_t age = 0; +- +- gp.param = RADEON_PARAM_LAST_CLEAR; +- gp.value = (int *)&age; +- ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, +- &gp, sizeof(gp)); +- if (ret) { +- fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, +- ret); +- exit(1); +- } +- +- return age; +-} +- +-static void radeonEmitIrqLocked(radeonContextPtr radeon) +-{ +- drm_radeon_irq_emit_t ie; +- int ret; +- +- ie.irq_seq = &radeon->iw.irq_seq; +- ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_IRQ_EMIT, +- &ie, sizeof(ie)); +- if (ret) { +- fprintf(stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, +- ret); +- exit(1); +- } +-} +- +-static void radeonWaitIrq(radeonContextPtr radeon) +-{ +- int ret; +- +- do { +- ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT, +- &radeon->iw, sizeof(radeon->iw)); +- } while (ret && (errno == EINTR || errno == EBUSY)); +- +- if (ret) { +- fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, +- ret); +- exit(1); +- } +-} +- +-static void radeonWaitForFrameCompletion(radeonContextPtr radeon) +-{ +- drm_radeon_sarea_t *sarea = radeon->sarea; +- +- if (radeon->do_irqs) { +- if (radeonGetLastFrame(radeon) < sarea->last_frame) { +- if (!radeon->irqsEmitted) { +- while (radeonGetLastFrame(radeon) < +- sarea->last_frame) ; +- } else { +- UNLOCK_HARDWARE(radeon); +- radeonWaitIrq(radeon); +- LOCK_HARDWARE(radeon); +- } +- radeon->irqsEmitted = 10; +- } +- +- if (radeon->irqsEmitted) { +- radeonEmitIrqLocked(radeon); +- radeon->irqsEmitted--; +- } +- } else { +- while (radeonGetLastFrame(radeon) < sarea->last_frame) { +- UNLOCK_HARDWARE(radeon); +- if (radeon->do_usleeps) +- DO_USLEEP(1); +- LOCK_HARDWARE(radeon); +- } +- } +-} +- +-/* Copy the back color buffer to the front color buffer. +- */ +-void radeonCopyBuffer(__DRIdrawablePrivate * dPriv, +- const drm_clip_rect_t * rect) +-{ +- radeonContextPtr radeon; +- GLint nbox, i, ret; +- GLboolean missed_target; +- int64_t ust; +- __DRIscreenPrivate *psp = dPriv->driScreenPriv; +- +- assert(dPriv); +- assert(dPriv->driContextPriv); +- assert(dPriv->driContextPriv->driverPrivate); +- +- radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; +- +- if (RADEON_DEBUG & DEBUG_IOCTL) { +- fprintf(stderr, "\n%s( %p )\n\n", __FUNCTION__, +- (void *)radeon->glCtx); +- } +- +- r300Flush(radeon->glCtx); +- +- LOCK_HARDWARE(radeon); +- +- /* Throttle the frame rate -- only allow one pending swap buffers +- * request at a time. +- */ +- radeonWaitForFrameCompletion(radeon); +- if (!rect) +- { +- UNLOCK_HARDWARE(radeon); +- driWaitForVBlank(dPriv, &missed_target); +- LOCK_HARDWARE(radeon); +- } +- +- nbox = dPriv->numClipRects; /* must be in locked region */ +- +- for (i = 0; i < nbox;) { +- GLint nr = MIN2(i + RADEON_NR_SAREA_CLIPRECTS, nbox); +- drm_clip_rect_t *box = dPriv->pClipRects; +- drm_clip_rect_t *b = radeon->sarea->boxes; +- GLint n = 0; +- +- for ( ; i < nr ; i++ ) { +- +- *b = box[i]; +- +- if (rect) +- { +- if (rect->x1 > b->x1) +- b->x1 = rect->x1; +- if (rect->y1 > b->y1) +- b->y1 = rect->y1; +- if (rect->x2 < b->x2) +- b->x2 = rect->x2; +- if (rect->y2 < b->y2) +- b->y2 = rect->y2; +- +- if (b->x1 >= b->x2 || b->y1 >= b->y2) +- continue; +- } +- +- b++; +- n++; +- } +- radeon->sarea->nbox = n; +- +- if (!n) +- continue; +- +- ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_SWAP); +- +- if (ret) { +- fprintf(stderr, "DRM_RADEON_SWAP: return = %d\n", +- ret); +- UNLOCK_HARDWARE(radeon); +- exit(1); +- } +- } +- +- UNLOCK_HARDWARE(radeon); +- if (!rect) +- { +- ((r300ContextPtr)radeon)->hw.all_dirty = GL_TRUE; +- +- radeon->swap_count++; +- (*psp->systemTime->getUST) (&ust); +- if (missed_target) { +- radeon->swap_missed_count++; +- radeon->swap_missed_ust = ust - radeon->swap_ust; +- } +- +- radeon->swap_ust = ust; +- +- sched_yield(); +- } +-} +- +-void radeonPageFlip(__DRIdrawablePrivate * dPriv) +-{ +- radeonContextPtr radeon; +- GLint ret; +- GLboolean missed_target; +- __DRIscreenPrivate *psp = dPriv->driScreenPriv; +- +- assert(dPriv); +- assert(dPriv->driContextPriv); +- assert(dPriv->driContextPriv->driverPrivate); +- +- radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; +- +- if (RADEON_DEBUG & DEBUG_IOCTL) { +- fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, +- radeon->sarea->pfCurrentPage); +- } +- +- r300Flush(radeon->glCtx); +- LOCK_HARDWARE(radeon); +- +- if (!dPriv->numClipRects) { +- UNLOCK_HARDWARE(radeon); +- usleep(10000); /* throttle invisible client 10ms */ +- return; +- } +- +- /* Need to do this for the perf box placement: +- */ +- { +- drm_clip_rect_t *box = dPriv->pClipRects; +- drm_clip_rect_t *b = radeon->sarea->boxes; +- b[0] = box[0]; +- radeon->sarea->nbox = 1; +- } +- +- /* Throttle the frame rate -- only allow a few pending swap buffers +- * request at a time. +- */ +- radeonWaitForFrameCompletion(radeon); +- UNLOCK_HARDWARE(radeon); +- driWaitForVBlank(dPriv, &missed_target); +- if (missed_target) { +- radeon->swap_missed_count++; +- (void)(*psp->systemTime->getUST) (&radeon->swap_missed_ust); +- } +- LOCK_HARDWARE(radeon); +- +- ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_FLIP); +- +- UNLOCK_HARDWARE(radeon); +- +- if (ret) { +- fprintf(stderr, "DRM_RADEON_FLIP: return = %d\n", ret); +- exit(1); +- } +- +- radeon->swap_count++; +- (void)(*psp->systemTime->getUST) (&radeon->swap_ust); +- +- driFlipRenderbuffers(radeon->glCtx->WinSysDrawBuffer, +- radeon->sarea->pfCurrentPage); +- +- if (radeon->sarea->pfCurrentPage == 1) { +- radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset; +- radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch; +- } else { +- radeon->state.color.drawOffset = radeon->radeonScreen->backOffset; +- radeon->state.color.drawPitch = radeon->radeonScreen->backPitch; +- } +- +- if (IS_R300_CLASS(radeon->radeonScreen)) { +- r300ContextPtr r300 = (r300ContextPtr)radeon; +- R300_STATECHANGE(r300, cb); +- r300->hw.cb.cmd[R300_CB_OFFSET] = r300->radeon.state.color.drawOffset + +- r300->radeon.radeonScreen->fbLocation; +- r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.state.color.drawPitch; +- +- if (r300->radeon.radeonScreen->cpp == 4) +- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888; +- else +- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565; +- +- if (r300->radeon.sarea->tiling_enabled) +- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE; +- } +-} +- +-void radeonWaitForIdleLocked(radeonContextPtr radeon) +-{ +- int ret; +- int i = 0; +- +- do { +- ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE); +- if (ret) +- DO_USLEEP(1); +- } while (ret && ++i < 100); +- +- if (ret < 0) { +- UNLOCK_HARDWARE(radeon); +- fprintf(stderr, "Error: R300 timed out... exiting\n"); +- exit(-1); +- } +-} +- +-static void radeonWaitForIdle(radeonContextPtr radeon) +-{ +- LOCK_HARDWARE(radeon); +- radeonWaitForIdleLocked(radeon); +- UNLOCK_HARDWARE(radeon); +-} +- +-void radeonFlush(GLcontext * ctx) +-{ +- radeonContextPtr radeon = RADEON_CONTEXT(ctx); +- +- if (IS_R300_CLASS(radeon->radeonScreen)) +- r300Flush(ctx); +-} +- +- +-/* Make sure all commands have been sent to the hardware and have +- * completed processing. +- */ +-void radeonFinish(GLcontext * ctx) +-{ +- radeonContextPtr radeon = RADEON_CONTEXT(ctx); +- +- radeonFlush(ctx); +- +- if (radeon->do_irqs) { +- LOCK_HARDWARE(radeon); +- radeonEmitIrqLocked(radeon); +- UNLOCK_HARDWARE(radeon); +- radeonWaitIrq(radeon); +- } else +- radeonWaitForIdle(radeon); +-} +diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.h b/src/mesa/drivers/dri/r300/radeon_ioctl.h +deleted file mode 100644 +index 3add775..0000000 +--- a/src/mesa/drivers/dri/r300/radeon_ioctl.h ++++ /dev/null +@@ -1,57 +0,0 @@ +-/* +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Keith Whitwell +- */ +- +-#ifndef __RADEON_IOCTL_H__ +-#define __RADEON_IOCTL_H__ +- +-#include "main/simple_list.h" +-#include "radeon_dri.h" +-#include "radeon_lock.h" +- +-#include "xf86drm.h" +-#include "drm.h" +-#if 0 +-#include "r200context.h" +-#endif +-#include "radeon_drm.h" +- +-extern void radeonCopyBuffer(__DRIdrawablePrivate * drawable, +- const drm_clip_rect_t * rect); +-extern void radeonPageFlip(__DRIdrawablePrivate * drawable); +-extern void radeonFlush(GLcontext * ctx); +-extern void radeonFinish(GLcontext * ctx); +-extern void radeonWaitForIdleLocked(radeonContextPtr radeon); +-extern uint32_t radeonGetAge(radeonContextPtr radeon); +- +-#endif /* __RADEON_IOCTL_H__ */ +diff --git a/src/mesa/drivers/dri/r300/radeon_lock.c b/src/mesa/drivers/dri/r300/radeon_lock.c +deleted file mode 100644 +index 4f47afd..0000000 +--- a/src/mesa/drivers/dri/r300/radeon_lock.c ++++ /dev/null +@@ -1,137 +0,0 @@ +-/************************************************************************** +- +-Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and +- VA Linux Systems Inc., Fremont, California. +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-All Rights Reserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Gareth Hughes +- * Keith Whitwell +- * Kevin E. Martin +- */ +- +-#include "radeon_lock.h" +-#include "radeon_ioctl.h" +-#include "radeon_state.h" +-#include "r300_context.h" +-#include "r300_state.h" +- +-#include "main/framebuffer.h" +- +-#include "drirenderbuffer.h" +- +-#if DEBUG_LOCKING +-char *prevLockFile = NULL; +-int prevLockLine = 0; +-#endif +- +-/* Turn on/off page flipping according to the flags in the sarea: +- */ +-void radeonUpdatePageFlipping(radeonContextPtr rmesa) +-{ +- int use_back; +- +- rmesa->doPageFlip = rmesa->sarea->pfState; +- if (rmesa->glCtx->WinSysDrawBuffer) { +- driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, +- rmesa->sarea->pfCurrentPage); +- r300UpdateDrawBuffer(rmesa->glCtx); +- } +- +- use_back = rmesa->glCtx->DrawBuffer ? +- (rmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] == +- BUFFER_BACK_LEFT) : 1; +- use_back ^= (rmesa->sarea->pfCurrentPage == 1); +- +- if (use_back) { +- rmesa->state.color.drawOffset = +- rmesa->radeonScreen->backOffset; +- rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; +- } else { +- rmesa->state.color.drawOffset = +- rmesa->radeonScreen->frontOffset; +- rmesa->state.color.drawPitch = +- rmesa->radeonScreen->frontPitch; +- } +-} +- +-/* Update the hardware state. This is called if another context has +- * grabbed the hardware lock, which includes the X server. This +- * function also updates the driver's window state after the X server +- * moves, resizes or restacks a window -- the change will be reflected +- * in the drawable position and clip rects. Since the X server grabs +- * the hardware lock when it changes the window state, this routine will +- * automatically be called after such a change. +- */ +-void radeonGetLock(radeonContextPtr rmesa, GLuint flags) +-{ +- __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; +- __DRIdrawablePrivate *const readable = rmesa->dri.readable; +- __DRIscreenPrivate *sPriv = rmesa->dri.screen; +- drm_radeon_sarea_t *sarea = rmesa->sarea; +- r300ContextPtr r300 = (r300ContextPtr) rmesa; +- +- assert(drawable != NULL); +- +- drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); +- +- /* The window might have moved, so we might need to get new clip +- * rects. +- * +- * NOTE: This releases and regrabs the hw lock to allow the X server +- * to respond to the DRI protocol request for new drawable info. +- * Since the hardware state depends on having the latest drawable +- * clip rects, all state checking must be done _after_ this call. +- */ +- DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); +- if (drawable != readable) { +- DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); +- } +- +- if (rmesa->lastStamp != drawable->lastStamp) { +- radeonUpdatePageFlipping(rmesa); +- radeonSetCliprects(rmesa); +- r300UpdateViewportOffset(rmesa->glCtx); +- driUpdateFramebufferSize(rmesa->glCtx, drawable); +- } +- +- if (sarea->ctx_owner != rmesa->dri.hwContext) { +- int i; +- +- sarea->ctx_owner = rmesa->dri.hwContext; +- for (i = 0; i < r300->nr_heaps; i++) { +- DRI_AGE_TEXTURES(r300->texture_heaps[i]); +- } +- } +- +- rmesa->lost_context = GL_TRUE; +-} +diff --git a/src/mesa/drivers/dri/r300/radeon_lock.h b/src/mesa/drivers/dri/r300/radeon_lock.h +deleted file mode 100644 +index a344837..0000000 +--- a/src/mesa/drivers/dri/r300/radeon_lock.h ++++ /dev/null +@@ -1,115 +0,0 @@ +-/************************************************************************** +- +-Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and +- VA Linux Systems Inc., Fremont, California. +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-All Rights Reserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Gareth Hughes +- * Keith Whitwell +- * Kevin E. Martin +- */ +- +-#ifndef __RADEON_LOCK_H__ +-#define __RADEON_LOCK_H__ +- +-#include "radeon_context.h" +- +-extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); +-extern void radeonUpdatePageFlipping(radeonContextPtr rmesa); +- +-/* Turn DEBUG_LOCKING on to find locking conflicts. +- */ +-#define DEBUG_LOCKING 0 +- +-#if DEBUG_LOCKING +-extern char *prevLockFile; +-extern int prevLockLine; +- +-#define DEBUG_LOCK() \ +- do { \ +- prevLockFile = (__FILE__); \ +- prevLockLine = (__LINE__); \ +- } while (0) +- +-#define DEBUG_RESET() \ +- do { \ +- prevLockFile = 0; \ +- prevLockLine = 0; \ +- } while (0) +- +-#define DEBUG_CHECK_LOCK() \ +- do { \ +- if (prevLockFile) { \ +- fprintf(stderr, \ +- "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ +- prevLockFile, prevLockLine, __FILE__, __LINE__); \ +- exit(1); \ +- } \ +- } while (0) +- +-#else +- +-#define DEBUG_LOCK() +-#define DEBUG_RESET() +-#define DEBUG_CHECK_LOCK() +- +-#endif +- +-/* +- * !!! We may want to separate locks from locks with validation. This +- * could be used to improve performance for those things commands that +- * do not do any drawing !!! +- */ +- +-/* Lock the hardware and validate our state. +- */ +-#define LOCK_HARDWARE( rmesa ) \ +- do { \ +- char __ret = 0; \ +- DEBUG_CHECK_LOCK(); \ +- DRM_CAS((rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ +- (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret); \ +- if (__ret) \ +- radeonGetLock((rmesa), 0); \ +- DEBUG_LOCK(); \ +- } while (0) +- +-#define UNLOCK_HARDWARE( rmesa ) \ +- do { \ +- DRM_UNLOCK((rmesa)->dri.fd, \ +- (rmesa)->dri.hwLock, \ +- (rmesa)->dri.hwContext); \ +- DEBUG_RESET(); \ +- } while (0) +- +-#endif /* __RADEON_LOCK_H__ */ +diff --git a/src/mesa/drivers/dri/r300/radeon_program_pair.c b/src/mesa/drivers/dri/r300/radeon_program_pair.c +index f398404..49aa90d 100644 +--- a/src/mesa/drivers/dri/r300/radeon_program_pair.c ++++ b/src/mesa/drivers/dri/r300/radeon_program_pair.c +@@ -35,7 +35,7 @@ + + #include "radeon_program_pair.h" + +-#include "radeon_context.h" ++#include "radeon_common.h" + + #include "shader/prog_print.h" + +diff --git a/src/mesa/drivers/dri/r300/radeon_span.c b/src/mesa/drivers/dri/r300/radeon_span.c +deleted file mode 100644 +index 16f9fb9..0000000 +--- a/src/mesa/drivers/dri/r300/radeon_span.c ++++ /dev/null +@@ -1,349 +0,0 @@ +-/************************************************************************** +- +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +-Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and +- VA Linux Systems Inc., Fremont, California. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-All Rights Reserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Kevin E. Martin +- * Gareth Hughes +- * Keith Whitwell +- * +- */ +- +-#include "main/glheader.h" +-#include "swrast/swrast.h" +- +-#include "r300_state.h" +-#include "radeon_ioctl.h" +-#include "r300_ioctl.h" +-#include "radeon_span.h" +- +-#include "drirenderbuffer.h" +- +-#define DBG 0 +- +-/* +- * Note that all information needed to access pixels in a renderbuffer +- * should be obtained through the gl_renderbuffer parameter, not per-context +- * information. +- */ +-#define LOCAL_VARS \ +- driRenderbuffer *drb = (driRenderbuffer *) rb; \ +- const __DRIdrawablePrivate *dPriv = drb->dPriv; \ +- const GLuint bottom = dPriv->h - 1; \ +- GLubyte *buf = (GLubyte *) drb->flippedData \ +- + (dPriv->y * drb->flippedPitch + dPriv->x) * drb->cpp; \ +- GLuint p; \ +- (void) p; +- +-#define LOCAL_DEPTH_VARS \ +- driRenderbuffer *drb = (driRenderbuffer *) rb; \ +- const __DRIdrawablePrivate *dPriv = drb->dPriv; \ +- const GLuint bottom = dPriv->h - 1; \ +- GLuint xo = dPriv->x; \ +- GLuint yo = dPriv->y; \ +- GLubyte *buf = (GLubyte *) drb->Base.Data; +- +-#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS +- +-#define Y_FLIP(Y) (bottom - (Y)) +- +-#define HW_LOCK() +- +-#define HW_UNLOCK() +- +-/* ================================================================ +- * Color buffer +- */ +- +-/* 16 bit, RGB565 color spanline and pixel functions +- */ +-#define SPANTMP_PIXEL_FMT GL_RGB +-#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 +- +-#define TAG(x) radeon##x##_RGB565 +-#define TAG2(x,y) radeon##x##_RGB565##y +-#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 2) +-#include "spantmp2.h" +- +-/* 32 bit, ARGB8888 color spanline and pixel functions +- */ +-#define SPANTMP_PIXEL_FMT GL_BGRA +-#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV +- +-#define TAG(x) radeon##x##_ARGB8888 +-#define TAG2(x,y) radeon##x##_ARGB8888##y +-#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 4) +-#include "spantmp2.h" +- +-/* ================================================================ +- * Depth buffer +- */ +- +-/* The Radeon family has depth tiling on all the time, so we have to convert +- * the x,y coordinates into the memory bus address (mba) in the same +- * manner as the engine. In each case, the linear block address (ba) +- * is calculated, and then wired with x and y to produce the final +- * memory address. +- * The chip will do address translation on its own if the surface registers +- * are set up correctly. It is not quite enough to get it working with hyperz +- * too... +- */ +- +-static GLuint radeon_mba_z32(const driRenderbuffer * drb, GLint x, GLint y) +-{ +- GLuint pitch = drb->pitch; +- if (drb->depthHasSurface) { +- return 4 * (x + y * pitch); +- } else { +- GLuint ba, address = 0; /* a[0..1] = 0 */ +- +-#ifdef COMPILE_R300 +- ba = (y / 8) * (pitch / 8) + (x / 8); +-#else +- ba = (y / 16) * (pitch / 16) + (x / 16); +-#endif +- +- address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */ +- address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ +- address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */ +- address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ +- +- address |= (y & 0x8) << 7; /* a[10] = y[3] */ +- address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */ +- address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ +- +- return address; +- } +-} +- +-static INLINE GLuint +-radeon_mba_z16(const driRenderbuffer * drb, GLint x, GLint y) +-{ +- GLuint pitch = drb->pitch; +- if (drb->depthHasSurface) { +- return 2 * (x + y * pitch); +- } else { +- GLuint ba, address = 0; /* a[0] = 0 */ +- +- ba = (y / 16) * (pitch / 32) + (x / 32); +- +- address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ +- address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ +- address |= (x & 0x8) << 4; /* a[7] = x[3] */ +- address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ +- address |= (y & 0x8) << 7; /* a[10] = y[3] */ +- address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ +- address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ +- +- return address; +- } +-} +- +-/* 16-bit depth buffer functions +- */ +-#define VALUE_TYPE GLushort +- +-#define WRITE_DEPTH( _x, _y, d ) \ +- *(GLushort *)(buf + radeon_mba_z16( drb, _x + xo, _y + yo )) = d; +- +-#define READ_DEPTH( d, _x, _y ) \ +- d = *(GLushort *)(buf + radeon_mba_z16( drb, _x + xo, _y + yo )); +- +-#define TAG(x) radeon##x##_z16 +-#include "depthtmp.h" +- +-/* 24 bit depth, 8 bit stencil depthbuffer functions +- * +- * Careful: It looks like the R300 uses ZZZS byte order while the R200 +- * uses SZZZ for 24 bit depth, 8 bit stencil mode. +- */ +-#define VALUE_TYPE GLuint +- +-#ifdef COMPILE_R300 +-#define WRITE_DEPTH( _x, _y, d ) \ +-do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ +- tmp &= 0x000000ff; \ +- tmp |= ((d << 8) & 0xffffff00); \ +- *(GLuint *)(buf + offset) = tmp; \ +-} while (0) +-#else +-#define WRITE_DEPTH( _x, _y, d ) \ +-do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ +- tmp &= 0xff000000; \ +- tmp |= ((d) & 0x00ffffff); \ +- *(GLuint *)(buf + offset) = tmp; \ +-} while (0) +-#endif +- +-#ifdef COMPILE_R300 +-#define READ_DEPTH( d, _x, _y ) \ +- do { \ +- d = (*(GLuint *)(buf + radeon_mba_z32( drb, _x + xo, \ +- _y + yo )) & 0xffffff00) >> 8; \ +- }while(0) +-#else +-#define READ_DEPTH( d, _x, _y ) \ +- d = *(GLuint *)(buf + radeon_mba_z32( drb, _x + xo, \ +- _y + yo )) & 0x00ffffff; +-#endif +- +-#define TAG(x) radeon##x##_z24_s8 +-#include "depthtmp.h" +- +-/* ================================================================ +- * Stencil buffer +- */ +- +-/* 24 bit depth, 8 bit stencil depthbuffer functions +- */ +-#ifdef COMPILE_R300 +-#define WRITE_STENCIL( _x, _y, d ) \ +-do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ +- tmp &= 0xffffff00; \ +- tmp |= (d) & 0xff; \ +- *(GLuint *)(buf + offset) = tmp; \ +-} while (0) +-#else +-#define WRITE_STENCIL( _x, _y, d ) \ +-do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ +- tmp &= 0x00ffffff; \ +- tmp |= (((d) & 0xff) << 24); \ +- *(GLuint *)(buf + offset) = tmp; \ +-} while (0) +-#endif +- +-#ifdef COMPILE_R300 +-#define READ_STENCIL( d, _x, _y ) \ +-do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ +- d = tmp & 0x000000ff; \ +-} while (0) +-#else +-#define READ_STENCIL( d, _x, _y ) \ +-do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ +- d = (tmp & 0xff000000) >> 24; \ +-} while (0) +-#endif +- +-#define TAG(x) radeon##x##_z24_s8 +-#include "stenciltmp.h" +- +-/* Move locking out to get reasonable span performance (10x better +- * than doing this in HW_LOCK above). WaitForIdle() is the main +- * culprit. +- */ +- +-static void radeonSpanRenderStart(GLcontext * ctx) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +-#ifdef COMPILE_R300 +- r300ContextPtr r300 = (r300ContextPtr) rmesa; +- R300_FIREVERTICES(r300); +-#else +- RADEON_FIREVERTICES(rmesa); +-#endif +- LOCK_HARDWARE(rmesa); +- radeonWaitForIdleLocked(rmesa); +- +- /* Read the first pixel in the frame buffer. This should +- * be a noop, right? In fact without this conform fails as reading +- * from the framebuffer sometimes produces old results -- the +- * on-card read cache gets mixed up and doesn't notice that the +- * framebuffer has been updated. +- * +- * Note that we should probably be reading some otherwise unused +- * region of VRAM, otherwise we might get incorrect results when +- * reading pixels from the top left of the screen. +- * +- * I found this problem on an R420 with glean's texCube test. +- * Note that the R200 span code also *writes* the first pixel in the +- * framebuffer, but I've found this to be unnecessary. +- * -- Nicolai Hähnle, June 2008 +- */ +- { +- int p; +- driRenderbuffer *drb = +- (driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0]; +- volatile int *buf = +- (volatile int *)(rmesa->dri.screen->pFB + drb->offset); +- p = *buf; +- } +-} +- +-static void radeonSpanRenderFinish(GLcontext * ctx) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- _swrast_flush(ctx); +- UNLOCK_HARDWARE(rmesa); +-} +- +-void radeonInitSpanFuncs(GLcontext * ctx) +-{ +- struct swrast_device_driver *swdd = +- _swrast_GetDeviceDriverReference(ctx); +- swdd->SpanRenderStart = radeonSpanRenderStart; +- swdd->SpanRenderFinish = radeonSpanRenderFinish; +-} +- +-/** +- * Plug in the Get/Put routines for the given driRenderbuffer. +- */ +-void radeonSetSpanFunctions(driRenderbuffer * drb, const GLvisual * vis) +-{ +- if (drb->Base.InternalFormat == GL_RGBA) { +- if (vis->redBits == 5 && vis->greenBits == 6 +- && vis->blueBits == 5) { +- radeonInitPointers_RGB565(&drb->Base); +- } else { +- radeonInitPointers_ARGB8888(&drb->Base); +- } +- } else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) { +- radeonInitDepthPointers_z16(&drb->Base); +- } else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) { +- radeonInitDepthPointers_z24_s8(&drb->Base); +- } else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) { +- radeonInitStencilPointers_z24_s8(&drb->Base); +- } +-} +diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c +deleted file mode 100644 +index c401da6..0000000 +--- a/src/mesa/drivers/dri/r300/radeon_state.c ++++ /dev/null +@@ -1,244 +0,0 @@ +-/************************************************************************** +- +-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +- +-The Weather Channel (TM) funded Tungsten Graphics to develop the +-initial release of the Radeon 8500 driver under the XFree86 license. +-This notice must be preserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Keith Whitwell +- */ +- +-#include "main/glheader.h" +-#include "main/imports.h" +-#include "main/api_arrayelt.h" +-#include "main/enums.h" +-#include "main/framebuffer.h" +-#include "main/colormac.h" +-#include "main/light.h" +- +-#include "swrast/swrast.h" +-#include "vbo/vbo.h" +-#include "tnl/tnl.h" +-#include "tnl/t_pipeline.h" +-#include "swrast_setup/swrast_setup.h" +- +-#include "radeon_ioctl.h" +-#include "radeon_state.h" +-#include "r300_ioctl.h" +- +- +-/* ============================================================= +- * Scissoring +- */ +- +-static GLboolean intersect_rect(drm_clip_rect_t * out, +- drm_clip_rect_t * a, drm_clip_rect_t * b) +-{ +- *out = *a; +- if (b->x1 > out->x1) +- out->x1 = b->x1; +- if (b->y1 > out->y1) +- out->y1 = b->y1; +- if (b->x2 < out->x2) +- out->x2 = b->x2; +- if (b->y2 < out->y2) +- out->y2 = b->y2; +- if (out->x1 >= out->x2) +- return GL_FALSE; +- if (out->y1 >= out->y2) +- return GL_FALSE; +- return GL_TRUE; +-} +- +-void radeonRecalcScissorRects(radeonContextPtr radeon) +-{ +- drm_clip_rect_t *out; +- int i; +- +- /* Grow cliprect store? +- */ +- if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { +- while (radeon->state.scissor.numAllocedClipRects < +- radeon->numClipRects) { +- radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ +- radeon->state.scissor.numAllocedClipRects *= 2; +- } +- +- if (radeon->state.scissor.pClipRects) +- FREE(radeon->state.scissor.pClipRects); +- +- radeon->state.scissor.pClipRects = +- MALLOC(radeon->state.scissor.numAllocedClipRects * +- sizeof(drm_clip_rect_t)); +- +- if (radeon->state.scissor.pClipRects == NULL) { +- radeon->state.scissor.numAllocedClipRects = 0; +- return; +- } +- } +- +- out = radeon->state.scissor.pClipRects; +- radeon->state.scissor.numClipRects = 0; +- +- for (i = 0; i < radeon->numClipRects; i++) { +- if (intersect_rect(out, +- &radeon->pClipRects[i], +- &radeon->state.scissor.rect)) { +- radeon->state.scissor.numClipRects++; +- out++; +- } +- } +-} +- +-void radeonUpdateScissor(GLcontext* ctx) +-{ +- radeonContextPtr radeon = RADEON_CONTEXT(ctx); +- +- if (radeon->dri.drawable) { +- __DRIdrawablePrivate *dPriv = radeon->dri.drawable; +- int x1 = dPriv->x + ctx->Scissor.X; +- int y1 = dPriv->y + dPriv->h - (ctx->Scissor.Y + ctx->Scissor.Height); +- +- radeon->state.scissor.rect.x1 = x1; +- radeon->state.scissor.rect.y1 = y1; +- radeon->state.scissor.rect.x2 = x1 + ctx->Scissor.Width; +- radeon->state.scissor.rect.y2 = y1 + ctx->Scissor.Height; +- +- radeonRecalcScissorRects(radeon); +- } +-} +- +-static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) +-{ +- if (ctx->Scissor.Enabled) { +- /* We don't pipeline cliprect changes */ +- r300Flush(ctx); +- radeonUpdateScissor(ctx); +- } +-} +- +- +-/** +- * Update cliprects and scissors. +- */ +-void radeonSetCliprects(radeonContextPtr radeon) +-{ +- __DRIdrawablePrivate *const drawable = radeon->dri.drawable; +- __DRIdrawablePrivate *const readable = radeon->dri.readable; +- GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; +- GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; +- +- if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { +- /* Can't ignore 2d windows if we are page flipping. */ +- if (drawable->numBackClipRects == 0 || radeon->doPageFlip || +- radeon->sarea->pfCurrentPage == 1) { +- radeon->numClipRects = drawable->numClipRects; +- radeon->pClipRects = drawable->pClipRects; +- } else { +- radeon->numClipRects = drawable->numBackClipRects; +- radeon->pClipRects = drawable->pBackClipRects; +- } +- } else { +- /* front buffer (or none, or multiple buffers */ +- radeon->numClipRects = drawable->numClipRects; +- radeon->pClipRects = drawable->pClipRects; +- } +- +- if ((draw_fb->Width != drawable->w) || +- (draw_fb->Height != drawable->h)) { +- _mesa_resize_framebuffer(radeon->glCtx, draw_fb, +- drawable->w, drawable->h); +- draw_fb->Initialized = GL_TRUE; +- } +- +- if (drawable != readable) { +- if ((read_fb->Width != readable->w) || +- (read_fb->Height != readable->h)) { +- _mesa_resize_framebuffer(radeon->glCtx, read_fb, +- readable->w, readable->h); +- read_fb->Initialized = GL_TRUE; +- } +- } +- +- if (radeon->state.scissor.enabled) +- radeonRecalcScissorRects(radeon); +- +- radeon->lastStamp = drawable->lastStamp; +-} +- +- +-/** +- * Handle common enable bits. +- * Called as a fallback by r200Enable/r300Enable. +- */ +-void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state) +-{ +- radeonContextPtr radeon = RADEON_CONTEXT(ctx); +- +- switch(cap) { +- case GL_SCISSOR_TEST: +- /* We don't pipeline cliprect & scissor changes */ +- r300Flush(ctx); +- +- radeon->state.scissor.enabled = state; +- radeonUpdateScissor(ctx); +- break; +- +- default: +- return; +- } +-} +- +- +-/** +- * Initialize default state. +- * This function is called once at context init time from +- * r200InitState/r300InitState +- */ +-void radeonInitState(radeonContextPtr radeon) +-{ +- radeon->Fallback = 0; +- +- if (radeon->glCtx->Visual.doubleBufferMode && radeon->sarea->pfCurrentPage == 0) { +- radeon->state.color.drawOffset = radeon->radeonScreen->backOffset; +- radeon->state.color.drawPitch = radeon->radeonScreen->backPitch; +- } else { +- radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset; +- radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch; +- } +-} +- +- +-/** +- * Initialize common state functions. +- * Called by r200InitStateFuncs/r300InitStateFuncs +- */ +-void radeonInitStateFuncs(struct dd_function_table *functions) +-{ +- functions->Scissor = radeonScissor; +-} +diff --git a/src/mesa/drivers/dri/r300/radeon_state.h b/src/mesa/drivers/dri/r300/radeon_state.h +deleted file mode 100644 +index 821cb40..0000000 +--- a/src/mesa/drivers/dri/r300/radeon_state.h ++++ /dev/null +@@ -1,43 +0,0 @@ +-/* +-Copyright (C) 2004 Nicolai Haehnle. All Rights Reserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation the rights to use, copy, modify, merge, publish, +-distribute, sublicense, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Nicolai Haehnle +- */ +- +-#ifndef __RADEON_STATE_H__ +-#define __RADEON_STATE_H__ +- +-extern void radeonRecalcScissorRects(radeonContextPtr radeon); +-extern void radeonSetCliprects(radeonContextPtr radeon); +-extern void radeonUpdateScissor(GLcontext* ctx); +- +-extern void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state); +- +-extern void radeonInitState(radeonContextPtr radeon); +-extern void radeonInitStateFuncs(struct dd_function_table* functions); +- +-#endif +diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile +index f223b2d..ba409ba 100644 +--- a/src/mesa/drivers/dri/radeon/Makefile ++++ b/src/mesa/drivers/dri/radeon/Makefile +@@ -4,25 +4,37 @@ + TOP = ../../../../.. + include $(TOP)/configs/current + ++CFLAGS += $(RADEON_CFLAGS) ++ + LIBNAME = radeon_dri.so + + MINIGLX_SOURCES = server/radeon_dri.c + ++RADEON_COMMON_SOURCES = \ ++ radeon_texture.c \ ++ radeon_common_context.c \ ++ radeon_common.c \ ++ radeon_dma.c \ ++ radeon_lock.c \ ++ radeon_bo_legacy.c \ ++ radeon_cs_legacy.c \ ++ radeon_mipmap_tree.c \ ++ radeon_span.c \ ++ radeon_fbo.c ++ + DRIVER_SOURCES = \ + radeon_context.c \ + radeon_ioctl.c \ +- radeon_lock.c \ + radeon_screen.c \ + radeon_state.c \ + radeon_state_init.c \ + radeon_tex.c \ +- radeon_texmem.c \ + radeon_texstate.c \ + radeon_tcl.c \ + radeon_swtcl.c \ +- radeon_span.c \ + radeon_maos.c \ +- radeon_sanity.c ++ radeon_sanity.c \ ++ $(RADEON_COMMON_SOURCES) + + C_SOURCES = \ + $(COMMON_SOURCES) \ +@@ -30,6 +42,8 @@ C_SOURCES = \ + + DRIVER_DEFINES = -DRADEON_COMMON=0 + ++DRI_LIB_DEPS += $(RADEON_LDFLAGS) ++ + X86_SOURCES = + + include ../Makefile.template +diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h +new file mode 100644 +index 0000000..1ed13f1 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h +@@ -0,0 +1,182 @@ ++/* ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS ++ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Jérôme Glisse ++ */ ++#ifndef RADEON_BO_H ++#define RADEON_BO_H ++ ++#include ++#include ++//#include "radeon_track.h" ++ ++/* bo object */ ++#define RADEON_BO_FLAGS_MACRO_TILE 1 ++#define RADEON_BO_FLAGS_MICRO_TILE 2 ++ ++struct radeon_bo_manager; ++ ++struct radeon_bo { ++ uint32_t alignment; ++ uint32_t handle; ++ uint32_t size; ++ uint32_t domains; ++ uint32_t flags; ++ unsigned cref; ++#ifdef RADEON_BO_TRACK ++ struct radeon_track *track; ++#endif ++ void *ptr; ++ struct radeon_bo_manager *bom; ++ uint32_t space_accounted; ++}; ++ ++/* bo functions */ ++struct radeon_bo_funcs { ++ struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom, ++ uint32_t handle, ++ uint32_t size, ++ uint32_t alignment, ++ uint32_t domains, ++ uint32_t flags); ++ void (*bo_ref)(struct radeon_bo *bo); ++ struct radeon_bo *(*bo_unref)(struct radeon_bo *bo); ++ int (*bo_map)(struct radeon_bo *bo, int write); ++ int (*bo_unmap)(struct radeon_bo *bo); ++ int (*bo_wait)(struct radeon_bo *bo); ++}; ++ ++struct radeon_bo_manager { ++ struct radeon_bo_funcs *funcs; ++ int fd; ++ ++#ifdef RADEON_BO_TRACK ++ struct radeon_tracker tracker; ++#endif ++}; ++ ++static inline void _radeon_bo_debug(struct radeon_bo *bo, ++ const char *op, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ fprintf(stderr, "%s %p 0x%08X 0x%08X 0x%08X [%s %s %d]\n", ++ op, bo, bo->handle, bo->size, bo->cref, file, func, line); ++} ++ ++static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom, ++ uint32_t handle, ++ uint32_t size, ++ uint32_t alignment, ++ uint32_t domains, ++ uint32_t flags, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ struct radeon_bo *bo; ++ ++ bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags); ++#ifdef RADEON_BO_TRACK ++ if (bo) { ++ bo->track = radeon_tracker_add_track(&bom->tracker, bo->handle); ++ radeon_track_add_event(bo->track, file, func, "open", line); ++ } ++#endif ++ return bo; ++} ++ ++static inline void _radeon_bo_ref(struct radeon_bo *bo, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ bo->cref++; ++#ifdef RADEON_BO_TRACK ++ radeon_track_add_event(bo->track, file, func, "ref", line); ++#endif ++ bo->bom->funcs->bo_ref(bo); ++} ++ ++static inline struct radeon_bo *_radeon_bo_unref(struct radeon_bo *bo, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ bo->cref--; ++#ifdef RADEON_BO_TRACK ++ radeon_track_add_event(bo->track, file, func, "unref", line); ++ if (bo->cref <= 0) { ++ radeon_tracker_remove_track(&bo->bom->tracker, bo->track); ++ bo->track = NULL; ++ } ++#endif ++ return bo->bom->funcs->bo_unref(bo); ++} ++ ++static inline int _radeon_bo_map(struct radeon_bo *bo, ++ int write, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ return bo->bom->funcs->bo_map(bo, write); ++} ++ ++static inline int _radeon_bo_unmap(struct radeon_bo *bo, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ return bo->bom->funcs->bo_unmap(bo); ++} ++ ++static inline int _radeon_bo_wait(struct radeon_bo *bo, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ return bo->bom->funcs->bo_wait(bo); ++} ++ ++#define radeon_bo_open(bom, h, s, a, d, f)\ ++ _radeon_bo_open(bom, h, s, a, d, f, __FILE__, __FUNCTION__, __LINE__) ++#define radeon_bo_ref(bo)\ ++ _radeon_bo_ref(bo, __FILE__, __FUNCTION__, __LINE__) ++#define radeon_bo_unref(bo)\ ++ _radeon_bo_unref(bo, __FILE__, __FUNCTION__, __LINE__) ++#define radeon_bo_map(bo, w)\ ++ _radeon_bo_map(bo, w, __FILE__, __FUNCTION__, __LINE__) ++#define radeon_bo_unmap(bo)\ ++ _radeon_bo_unmap(bo, __FILE__, __FUNCTION__, __LINE__) ++#define radeon_bo_debug(bo, opcode)\ ++ _radeon_bo_debug(bo, opcode, __FILE__, __FUNCTION__, __LINE__) ++#define radeon_bo_wait(bo) \ ++ _radeon_bo_wait(bo, __FILE__, __func__, __LINE__) ++ ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +new file mode 100644 +index 0000000..03a6299 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +@@ -0,0 +1,825 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Dave Airlie ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Dave Airlie ++ * Jérôme Glisse ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "xf86drm.h" ++#include "texmem.h" ++#include "main/simple_list.h" ++ ++#include "drm.h" ++#include "radeon_drm.h" ++#include "radeon_common.h" ++#include "radeon_bocs_wrapper.h" ++ ++/* no seriously texmem.c is this screwed up */ ++struct bo_legacy_texture_object { ++ driTextureObject base; ++ struct bo_legacy *parent; ++}; ++ ++struct bo_legacy { ++ struct radeon_bo base; ++ int map_count; ++ uint32_t pending; ++ int is_pending; ++ int static_bo; ++ uint32_t offset; ++ struct bo_legacy_texture_object *tobj; ++ int validated; ++ int dirty; ++ void *ptr; ++ struct bo_legacy *next, *prev; ++ struct bo_legacy *pnext, *pprev; ++}; ++ ++struct bo_manager_legacy { ++ struct radeon_bo_manager base; ++ unsigned nhandle; ++ unsigned nfree_handles; ++ unsigned cfree_handles; ++ uint32_t current_age; ++ struct bo_legacy bos; ++ struct bo_legacy pending_bos; ++ uint32_t fb_location; ++ uint32_t texture_offset; ++ unsigned dma_alloc_size; ++ uint32_t dma_buf_count; ++ unsigned cpendings; ++ driTextureObject texture_swapped; ++ driTexHeap *texture_heap; ++ struct radeon_screen *screen; ++ unsigned *free_handles; ++}; ++ ++static void bo_legacy_tobj_destroy(void *data, driTextureObject *t) ++{ ++ struct bo_legacy_texture_object *tobj = (struct bo_legacy_texture_object *)t; ++ ++ if (tobj->parent) { ++ tobj->parent->tobj = NULL; ++ tobj->parent->validated = 0; ++ } ++} ++ ++static void inline clean_handles(struct bo_manager_legacy *bom) ++{ ++ while (bom->cfree_handles > 0 && ++ !bom->free_handles[bom->cfree_handles - 1]) ++ bom->cfree_handles--; ++ ++} ++static int legacy_new_handle(struct bo_manager_legacy *bom, uint32_t *handle) ++{ ++ uint32_t tmp; ++ ++ *handle = 0; ++ if (bom->nhandle == 0xFFFFFFFF) { ++ return -EINVAL; ++ } ++ if (bom->cfree_handles > 0) { ++ tmp = bom->free_handles[--bom->cfree_handles]; ++ clean_handles(bom); ++ } else { ++ bom->cfree_handles = 0; ++ tmp = bom->nhandle++; ++ } ++ assert(tmp); ++ *handle = tmp; ++ return 0; ++} ++ ++static int legacy_free_handle(struct bo_manager_legacy *bom, uint32_t handle) ++{ ++ uint32_t *handles; ++ ++ if (!handle) { ++ return 0; ++ } ++ if (handle == (bom->nhandle - 1)) { ++ int i; ++ ++ bom->nhandle--; ++ for (i = bom->cfree_handles - 1; i >= 0; i--) { ++ if (bom->free_handles[i] == (bom->nhandle - 1)) { ++ bom->nhandle--; ++ bom->free_handles[i] = 0; ++ } ++ } ++ clean_handles(bom); ++ return 0; ++ } ++ if (bom->cfree_handles < bom->nfree_handles) { ++ bom->free_handles[bom->cfree_handles++] = handle; ++ return 0; ++ } ++ bom->nfree_handles += 0x100; ++ handles = (uint32_t*)realloc(bom->free_handles, bom->nfree_handles * 4); ++ if (handles == NULL) { ++ bom->nfree_handles -= 0x100; ++ return -ENOMEM; ++ } ++ bom->free_handles = handles; ++ bom->free_handles[bom->cfree_handles++] = handle; ++ return 0; ++} ++ ++static void legacy_get_current_age(struct bo_manager_legacy *boml) ++{ ++ drm_radeon_getparam_t gp; ++ int r; ++ ++ if (IS_R300_CLASS(boml->screen)) { ++ gp.param = RADEON_PARAM_LAST_CLEAR; ++ gp.value = (int *)&boml->current_age; ++ r = drmCommandWriteRead(boml->base.fd, DRM_RADEON_GETPARAM, ++ &gp, sizeof(gp)); ++ if (r) { ++ fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, r); ++ exit(1); ++ } ++ } else ++ boml->current_age = boml->screen->scratch[3]; ++} ++ ++static int legacy_is_pending(struct radeon_bo *bo) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (bo_legacy->is_pending <= 0) { ++ bo_legacy->is_pending = 0; ++ return 0; ++ } ++ if (boml->current_age >= bo_legacy->pending) { ++ if (boml->pending_bos.pprev == bo_legacy) { ++ boml->pending_bos.pprev = bo_legacy->pprev; ++ } ++ bo_legacy->pprev->pnext = bo_legacy->pnext; ++ if (bo_legacy->pnext) { ++ bo_legacy->pnext->pprev = bo_legacy->pprev; ++ } ++ assert(bo_legacy->is_pending <= bo->cref); ++ while (bo_legacy->is_pending--) { ++ bo = radeon_bo_unref(bo); ++ if (!bo) ++ break; ++ } ++ if (bo) ++ bo_legacy->is_pending = 0; ++ boml->cpendings--; ++ return 0; ++ } ++ return 1; ++} ++ ++static int legacy_wait_pending(struct radeon_bo *bo) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (!bo_legacy->is_pending) { ++ return 0; ++ } ++ /* FIXME: lockup and userspace busy looping that's all the folks */ ++ legacy_get_current_age(boml); ++ while (legacy_is_pending(bo)) { ++ usleep(10); ++ legacy_get_current_age(boml); ++ } ++ return 0; ++} ++ ++static void legacy_track_pending(struct bo_manager_legacy *boml, int debug) ++{ ++ struct bo_legacy *bo_legacy; ++ struct bo_legacy *next; ++ ++ legacy_get_current_age(boml); ++ bo_legacy = boml->pending_bos.pnext; ++ while (bo_legacy) { ++ if (debug) ++ fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size, ++ boml->current_age, bo_legacy->pending); ++ next = bo_legacy->pnext; ++ if (legacy_is_pending(&(bo_legacy->base))) { ++ } ++ bo_legacy = next; ++ } ++} ++ ++static int legacy_wait_any_pending(struct bo_manager_legacy *boml) ++{ ++ struct bo_legacy *bo_legacy; ++ ++ legacy_get_current_age(boml); ++ bo_legacy = boml->pending_bos.pnext; ++ if (!bo_legacy) ++ return -1; ++ legacy_wait_pending(&bo_legacy->base); ++ return 0; ++} ++ ++static void legacy_kick_all_buffers(struct bo_manager_legacy *boml) ++{ ++ struct bo_legacy *legacy; ++ ++ legacy = boml->bos.next; ++ while (legacy != &boml->bos) { ++ if (legacy->tobj) { ++ if (legacy->validated) { ++ driDestroyTextureObject(&legacy->tobj->base); ++ legacy->tobj = 0; ++ legacy->validated = 0; ++ } ++ } ++ legacy = legacy->next; ++ } ++} ++ ++static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml, ++ uint32_t size, ++ uint32_t alignment, ++ uint32_t domains, ++ uint32_t flags) ++{ ++ struct bo_legacy *bo_legacy; ++ static int pgsize; ++ ++ if (pgsize == 0) ++ pgsize = getpagesize() - 1; ++ ++ size = (size + pgsize) & ~pgsize; ++ ++ bo_legacy = (struct bo_legacy*)calloc(1, sizeof(struct bo_legacy)); ++ if (bo_legacy == NULL) { ++ return NULL; ++ } ++ bo_legacy->base.bom = (struct radeon_bo_manager*)boml; ++ bo_legacy->base.handle = 0; ++ bo_legacy->base.size = size; ++ bo_legacy->base.alignment = alignment; ++ bo_legacy->base.domains = domains; ++ bo_legacy->base.flags = flags; ++ bo_legacy->base.ptr = NULL; ++ bo_legacy->map_count = 0; ++ bo_legacy->next = NULL; ++ bo_legacy->prev = NULL; ++ bo_legacy->pnext = NULL; ++ bo_legacy->pprev = NULL; ++ bo_legacy->next = boml->bos.next; ++ bo_legacy->prev = &boml->bos; ++ boml->bos.next = bo_legacy; ++ if (bo_legacy->next) { ++ bo_legacy->next->prev = bo_legacy; ++ } ++ return bo_legacy; ++} ++ ++static int bo_dma_alloc(struct radeon_bo *bo) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ drm_radeon_mem_alloc_t alloc; ++ unsigned size; ++ int base_offset; ++ int r; ++ ++ /* align size on 4Kb */ ++ size = (((4 * 1024) - 1) + bo->size) & ~((4 * 1024) - 1); ++ alloc.region = RADEON_MEM_REGION_GART; ++ alloc.alignment = bo_legacy->base.alignment; ++ alloc.size = size; ++ alloc.region_offset = &base_offset; ++ r = drmCommandWriteRead(bo->bom->fd, ++ DRM_RADEON_ALLOC, ++ &alloc, ++ sizeof(alloc)); ++ if (r) { ++ /* ptr is set to NULL if dma allocation failed */ ++ bo_legacy->ptr = NULL; ++ return r; ++ } ++ bo_legacy->ptr = boml->screen->gartTextures.map + base_offset; ++ bo_legacy->offset = boml->screen->gart_texture_offset + base_offset; ++ bo->size = size; ++ boml->dma_alloc_size += size; ++ boml->dma_buf_count++; ++ return 0; ++} ++ ++static int bo_dma_free(struct radeon_bo *bo) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ drm_radeon_mem_free_t memfree; ++ int r; ++ ++ if (bo_legacy->ptr == NULL) { ++ /* ptr is set to NULL if dma allocation failed */ ++ return 0; ++ } ++ legacy_get_current_age(boml); ++ memfree.region = RADEON_MEM_REGION_GART; ++ memfree.region_offset = bo_legacy->offset; ++ memfree.region_offset -= boml->screen->gart_texture_offset; ++ r = drmCommandWrite(boml->base.fd, ++ DRM_RADEON_FREE, ++ &memfree, ++ sizeof(memfree)); ++ if (r) { ++ fprintf(stderr, "Failed to free bo[%p] at %08x\n", ++ &bo_legacy->base, memfree.region_offset); ++ fprintf(stderr, "ret = %s\n", strerror(-r)); ++ return r; ++ } ++ boml->dma_alloc_size -= bo_legacy->base.size; ++ boml->dma_buf_count--; ++ return 0; ++} ++ ++static void bo_free(struct bo_legacy *bo_legacy) ++{ ++ struct bo_manager_legacy *boml; ++ ++ if (bo_legacy == NULL) { ++ return; ++ } ++ boml = (struct bo_manager_legacy *)bo_legacy->base.bom; ++ bo_legacy->prev->next = bo_legacy->next; ++ if (bo_legacy->next) { ++ bo_legacy->next->prev = bo_legacy->prev; ++ } ++ if (!bo_legacy->static_bo) { ++ legacy_free_handle(boml, bo_legacy->base.handle); ++ if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) { ++ /* dma buffers */ ++ bo_dma_free(&bo_legacy->base); ++ } else { ++ driDestroyTextureObject(&bo_legacy->tobj->base); ++ bo_legacy->tobj = NULL; ++ /* free backing store */ ++ free(bo_legacy->ptr); ++ } ++ } ++ memset(bo_legacy, 0 , sizeof(struct bo_legacy)); ++ free(bo_legacy); ++} ++ ++static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, ++ uint32_t handle, ++ uint32_t size, ++ uint32_t alignment, ++ uint32_t domains, ++ uint32_t flags) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom; ++ struct bo_legacy *bo_legacy; ++ int r; ++ ++ if (handle) { ++ bo_legacy = boml->bos.next; ++ while (bo_legacy) { ++ if (bo_legacy->base.handle == handle) { ++ radeon_bo_ref(&(bo_legacy->base)); ++ return (struct radeon_bo*)bo_legacy; ++ } ++ bo_legacy = bo_legacy->next; ++ } ++ return NULL; ++ } ++ ++ bo_legacy = bo_allocate(boml, size, alignment, domains, flags); ++ bo_legacy->static_bo = 0; ++ r = legacy_new_handle(boml, &bo_legacy->base.handle); ++ if (r) { ++ bo_free(bo_legacy); ++ return NULL; ++ } ++ if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) { ++ retry: ++ legacy_track_pending(boml, 0); ++ /* dma buffers */ ++ ++ r = bo_dma_alloc(&(bo_legacy->base)); ++ if (r) { ++ if (legacy_wait_any_pending(boml) == -1) { ++ bo_free(bo_legacy); ++ return NULL; ++ } ++ goto retry; ++ return NULL; ++ } ++ } else { ++ bo_legacy->ptr = malloc(bo_legacy->base.size); ++ if (bo_legacy->ptr == NULL) { ++ bo_free(bo_legacy); ++ return NULL; ++ } ++ } ++ radeon_bo_ref(&(bo_legacy->base)); ++ return (struct radeon_bo*)bo_legacy; ++} ++ ++static void bo_ref(struct radeon_bo *bo) ++{ ++} ++ ++static struct radeon_bo *bo_unref(struct radeon_bo *bo) ++{ ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (bo->cref <= 0) { ++ bo_legacy->prev->next = bo_legacy->next; ++ if (bo_legacy->next) { ++ bo_legacy->next->prev = bo_legacy->prev; ++ } ++ if (!bo_legacy->is_pending) { ++ bo_free(bo_legacy); ++ } ++ return NULL; ++ } ++ return bo; ++} ++ ++static int bo_map(struct radeon_bo *bo, int write) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ legacy_wait_pending(bo); ++ bo_legacy->validated = 0; ++ bo_legacy->dirty = 1; ++ bo_legacy->map_count++; ++ bo->ptr = bo_legacy->ptr; ++ /* Read the first pixel in the frame buffer. This should ++ * be a noop, right? In fact without this conform fails as reading ++ * from the framebuffer sometimes produces old results -- the ++ * on-card read cache gets mixed up and doesn't notice that the ++ * framebuffer has been updated. ++ * ++ * Note that we should probably be reading some otherwise unused ++ * region of VRAM, otherwise we might get incorrect results when ++ * reading pixels from the top left of the screen. ++ * ++ * I found this problem on an R420 with glean's texCube test. ++ * Note that the R200 span code also *writes* the first pixel in the ++ * framebuffer, but I've found this to be unnecessary. ++ * -- Nicolai Hähnle, June 2008 ++ */ ++ if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) { ++ int p; ++ volatile int *buf = (int*)boml->screen->driScreen->pFB; ++ p = *buf; ++ } ++ return 0; ++} ++ ++static int bo_unmap(struct radeon_bo *bo) ++{ ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (--bo_legacy->map_count > 0) { ++ return 0; ++ } ++ bo->ptr = NULL; ++ return 0; ++} ++ ++static struct radeon_bo_funcs bo_legacy_funcs = { ++ bo_open, ++ bo_ref, ++ bo_unref, ++ bo_map, ++ bo_unmap ++}; ++ ++static int bo_vram_validate(struct radeon_bo *bo, ++ uint32_t *soffset, ++ uint32_t *eoffset) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ int r; ++ int retry_count = 0, pending_retry = 0; ++ ++ if (!bo_legacy->tobj) { ++ bo_legacy->tobj = CALLOC(sizeof(struct bo_legacy_texture_object)); ++ bo_legacy->tobj->parent = bo_legacy; ++ make_empty_list(&bo_legacy->tobj->base); ++ bo_legacy->tobj->base.totalSize = bo->size; ++ retry: ++ r = driAllocateTexture(&boml->texture_heap, 1, ++ &bo_legacy->tobj->base); ++ if (r) { ++ pending_retry = 0; ++ while(boml->cpendings && pending_retry++ < 10000) { ++ legacy_track_pending(boml, 0); ++ retry_count++; ++ if (retry_count > 2) { ++ free(bo_legacy->tobj); ++ bo_legacy->tobj = NULL; ++ fprintf(stderr, "Ouch! vram_validate failed %d\n", r); ++ return -1; ++ } ++ goto retry; ++ } ++ } ++ bo_legacy->offset = boml->texture_offset + ++ bo_legacy->tobj->base.memBlock->ofs; ++ bo_legacy->dirty = 1; ++ } ++ ++ assert(bo_legacy->tobj->base.memBlock); ++ ++ if (bo_legacy->tobj) ++ driUpdateTextureLRU(&bo_legacy->tobj->base); ++ ++ if (bo_legacy->dirty || bo_legacy->tobj->base.dirty_images[0]) { ++ /* Copy to VRAM using a blit. ++ * All memory is 4K aligned. We're using 1024 pixels wide blits. ++ */ ++ drm_radeon_texture_t tex; ++ drm_radeon_tex_image_t tmp; ++ int ret; ++ ++ tex.offset = bo_legacy->offset; ++ tex.image = &tmp; ++ assert(!(tex.offset & 1023)); ++ ++ tmp.x = 0; ++ tmp.y = 0; ++ if (bo->size < 4096) { ++ tmp.width = (bo->size + 3) / 4; ++ tmp.height = 1; ++ } else { ++ tmp.width = 1024; ++ tmp.height = (bo->size + 4095) / 4096; ++ } ++ tmp.data = bo_legacy->ptr; ++ tex.format = RADEON_TXFORMAT_ARGB8888; ++ tex.width = tmp.width; ++ tex.height = tmp.height; ++ tex.pitch = MAX2(tmp.width / 16, 1); ++ do { ++ ret = drmCommandWriteRead(bo->bom->fd, ++ DRM_RADEON_TEXTURE, ++ &tex, ++ sizeof(drm_radeon_texture_t)); ++ if (ret) { ++ if (RADEON_DEBUG & DEBUG_IOCTL) ++ fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n"); ++ usleep(1); ++ } ++ } while (ret == -EAGAIN); ++ bo_legacy->dirty = 0; ++ bo_legacy->tobj->base.dirty_images[0] = 0; ++ } ++ return 0; ++} ++ ++/* ++ * radeon_bo_legacy_validate - ++ * returns: ++ * 0 - all good ++ * -EINVAL - mapped buffer can't be validated ++ * -EAGAIN - restart validation we've kicked all the buffers out ++ */ ++int radeon_bo_legacy_validate(struct radeon_bo *bo, ++ uint32_t *soffset, ++ uint32_t *eoffset) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ int r; ++ int retries = 0; ++ ++ if (bo_legacy->map_count) { ++ fprintf(stderr, "bo(%p, %d) is mapped (%d) can't valide it.\n", ++ bo, bo->size, bo_legacy->map_count); ++ return -EINVAL; ++ } ++ if (bo_legacy->static_bo || bo_legacy->validated) { ++ *soffset = bo_legacy->offset; ++ *eoffset = bo_legacy->offset + bo->size; ++ return 0; ++ } ++ if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) { ++ ++ r = bo_vram_validate(bo, soffset, eoffset); ++ if (r) { ++ legacy_track_pending(boml, 0); ++ legacy_kick_all_buffers(boml); ++ retries++; ++ if (retries == 2) { ++ fprintf(stderr,"legacy bo: failed to get relocations into aperture\n"); ++ assert(0); ++ exit(-1); ++ } ++ return -EAGAIN; ++ } ++ } ++ *soffset = bo_legacy->offset; ++ *eoffset = bo_legacy->offset + bo->size; ++ bo_legacy->validated = 1; ++ return 0; ++} ++ ++void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ bo_legacy->pending = pending; ++ bo_legacy->is_pending++; ++ /* add to pending list */ ++ radeon_bo_ref(bo); ++ if (bo_legacy->is_pending > 1) { ++ return; ++ } ++ bo_legacy->pprev = boml->pending_bos.pprev; ++ bo_legacy->pnext = NULL; ++ bo_legacy->pprev->pnext = bo_legacy; ++ boml->pending_bos.pprev = bo_legacy; ++ boml->cpendings++; ++} ++ ++void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom; ++ struct bo_legacy *bo_legacy; ++ ++ if (bom == NULL) { ++ return; ++ } ++ bo_legacy = boml->bos.next; ++ while (bo_legacy) { ++ struct bo_legacy *next; ++ ++ next = bo_legacy->next; ++ bo_free(bo_legacy); ++ bo_legacy = next; ++ } ++ driDestroyTextureHeap(boml->texture_heap); ++ free(boml->free_handles); ++ free(boml); ++} ++ ++static struct bo_legacy *radeon_legacy_bo_alloc_static(struct bo_manager_legacy *bom, ++ int size, uint32_t offset) ++{ ++ struct bo_legacy *bo; ++ ++ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ if (bo == NULL) ++ return NULL; ++ bo->static_bo = 1; ++ bo->offset = offset + bom->fb_location; ++ bo->base.handle = bo->offset; ++ bo->ptr = bom->screen->driScreen->pFB + offset; ++ if (bo->base.handle > bom->nhandle) { ++ bom->nhandle = bo->base.handle + 1; ++ } ++ radeon_bo_ref(&(bo->base)); ++ return bo; ++} ++ ++struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn) ++{ ++ struct bo_manager_legacy *bom; ++ struct bo_legacy *bo; ++ unsigned size; ++ ++ bom = (struct bo_manager_legacy*) ++ calloc(1, sizeof(struct bo_manager_legacy)); ++ if (bom == NULL) { ++ return NULL; ++ } ++ ++ make_empty_list(&bom->texture_swapped); ++ ++ bom->texture_heap = driCreateTextureHeap(0, ++ bom, ++ scrn->texSize[0], ++ 12, ++ RADEON_NR_TEX_REGIONS, ++ (drmTextureRegionPtr)scrn->sarea->tex_list[0], ++ &scrn->sarea->tex_age[0], ++ &bom->texture_swapped, ++ sizeof(struct bo_legacy_texture_object), ++ &bo_legacy_tobj_destroy); ++ bom->texture_offset = scrn->texOffset[0]; ++ ++ bom->base.funcs = &bo_legacy_funcs; ++ bom->base.fd = scrn->driScreen->fd; ++ bom->bos.next = NULL; ++ bom->bos.prev = NULL; ++ bom->pending_bos.pprev = &bom->pending_bos; ++ bom->pending_bos.pnext = NULL; ++ bom->screen = scrn; ++ bom->fb_location = scrn->fbLocation; ++ bom->nhandle = 1; ++ bom->cfree_handles = 0; ++ bom->nfree_handles = 0x400; ++ bom->free_handles = (uint32_t*)malloc(bom->nfree_handles * 4); ++ if (bom->free_handles == NULL) { ++ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); ++ return NULL; ++ } ++ ++ /* biggest framebuffer size */ ++ size = 4096*4096*4; ++ ++ /* allocate front */ ++ bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->frontOffset); ++ if (!bo) { ++ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); ++ return NULL; ++ } ++ if (scrn->sarea->tiling_enabled) { ++ bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE; ++ } ++ ++ /* allocate back */ ++ bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->backOffset); ++ if (!bo) { ++ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); ++ return NULL; ++ } ++ if (scrn->sarea->tiling_enabled) { ++ bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE; ++ } ++ ++ /* allocate depth */ ++ bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->depthOffset); ++ if (!bo) { ++ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); ++ return NULL; ++ } ++ bo->base.flags = 0; ++ if (scrn->sarea->tiling_enabled) { ++ bo->base.flags |= RADEON_BO_FLAGS_MACRO_TILE; ++ bo->base.flags |= RADEON_BO_FLAGS_MICRO_TILE; ++ } ++ return (struct radeon_bo_manager*)bom; ++} ++ ++void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom; ++ DRI_AGE_TEXTURES(boml->texture_heap); ++} ++ ++unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo) ++{ ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (bo_legacy->static_bo || (bo->domains & RADEON_GEM_DOMAIN_GTT)) { ++ return 0; ++ } ++ return bo->size; ++} ++ ++int radeon_legacy_bo_is_static(struct radeon_bo *bo) ++{ ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ return bo_legacy->static_bo; ++} ++ +diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h +new file mode 100644 +index 0000000..9187cd7 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#ifndef RADEON_BO_LEGACY_H ++#define RADEON_BO_LEGACY_H ++ ++#include "radeon_screen.h" ++ ++void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending); ++int radeon_bo_legacy_validate(struct radeon_bo *bo, ++ uint32_t *soffset, ++ uint32_t *eoffset); ++struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn); ++void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom); ++void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom); ++unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo); ++ ++int radeon_legacy_bo_is_static(struct radeon_bo *bo); ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h +new file mode 100644 +index 0000000..9921d35 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h +@@ -0,0 +1,70 @@ ++#ifndef RADEON_CS_WRAPPER_H ++#define RADEON_CS_WRAPPER_H ++ ++#ifndef RADEON_PARAM_DEVICE_ID ++#define RADEON_PARAM_DEVICE_ID 16 ++#endif ++ ++#ifdef HAVE_LIBDRM_RADEON ++ ++#include "radeon_bo.h" ++#include "radeon_bo_gem.h" ++#include "radeon_cs.h" ++#include "radeon_cs_gem.h" ++ ++#else ++#include ++ ++#define RADEON_GEM_DOMAIN_CPU 0x1 // Cached CPU domain ++#define RADEON_GEM_DOMAIN_GTT 0x2 // GTT or cache flushed ++#define RADEON_GEM_DOMAIN_VRAM 0x4 // VRAM domain ++ ++/* to be used to build locally in mesa with no libdrm bits */ ++#include "../radeon/radeon_bo_drm.h" ++#include "../radeon/radeon_cs_drm.h" ++ ++#ifndef DRM_RADEON_GEM_INFO ++#define DRM_RADEON_GEM_INFO 0x1c ++ ++struct drm_radeon_gem_info { ++ uint64_t gart_start; ++ uint64_t gart_size; ++ uint64_t vram_start; ++ uint64_t vram_size; ++ uint64_t vram_visible; ++}; ++#endif ++ ++ ++static inline uint32_t radeon_gem_name_bo(struct radeon_bo *dummy) ++{ ++ return 0; ++} ++ ++static inline void *radeon_bo_manager_gem_ctor(int fd) ++{ ++ return NULL; ++} ++ ++static inline void radeon_bo_manager_gem_dtor(void *dummy) ++{ ++} ++ ++static inline void *radeon_cs_manager_gem_ctor(int fd) ++{ ++ return NULL; ++} ++ ++static inline void radeon_cs_manager_gem_dtor(void *dummy) ++{ ++} ++ ++static inline void radeon_tracker_print(void *ptr, int io) ++{ ++} ++#endif ++ ++#include "radeon_bo_legacy.h" ++#include "radeon_cs_legacy.h" ++ ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h +new file mode 100644 +index 0000000..4b5116c +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h +@@ -0,0 +1,143 @@ ++#ifndef COMMON_CMDBUF_H ++#define COMMON_CMDBUF_H ++ ++#include "radeon_bocs_wrapper.h" ++ ++void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller); ++int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller); ++int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller); ++void rcommonInitCmdBuf(radeonContextPtr rmesa); ++void rcommonDestroyCmdBuf(radeonContextPtr rmesa); ++ ++void rcommonBeginBatch(radeonContextPtr rmesa, ++ int n, ++ int dostate, ++ const char *file, ++ const char *function, ++ int line); ++ ++#define RADEON_CP_PACKET3_NOP 0xC0001000 ++#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 ++#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 ++#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 ++#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 ++#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 ++#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 ++#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 ++#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 ++#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 ++#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 ++#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 ++#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 ++#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 ++#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 ++#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 ++#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 ++#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 ++#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 ++#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 ++#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 ++ ++#define CP_PACKET2 (2 << 30) ++#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) ++#define CP_PACKET0_ONE(reg, n) (RADEON_CP_PACKET0 | RADEON_CP_PACKET0_ONE_REG_WR | ((n)<<16) | ((reg)>>2)) ++#define CP_PACKET3( pkt, n ) \ ++ (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) ++ ++/** ++ * Every function writing to the command buffer needs to declare this ++ * to get the necessary local variables. ++ */ ++#define BATCH_LOCALS(rmesa) \ ++ const radeonContextPtr b_l_rmesa = rmesa ++ ++/** ++ * Prepare writing n dwords to the command buffer, ++ * including producing any necessary state emits on buffer wraparound. ++ */ ++#define BEGIN_BATCH(n) rcommonBeginBatch(b_l_rmesa, n, 1, __FILE__, __FUNCTION__, __LINE__) ++ ++/** ++ * Same as BEGIN_BATCH, but do not cause automatic state emits. ++ */ ++#define BEGIN_BATCH_NO_AUTOSTATE(n) rcommonBeginBatch(b_l_rmesa, n, 0, __FILE__, __FUNCTION__, __LINE__) ++ ++/** ++ * Write one dword to the command buffer. ++ */ ++#define OUT_BATCH(data) \ ++ do { \ ++ radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, data);\ ++ } while(0) ++ ++/** ++ * Write a relocated dword to the command buffer. ++ */ ++#define OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) \ ++ do { \ ++ if (0 && offset) { \ ++ fprintf(stderr, "(%s:%s:%d) offset : %d\n", \ ++ __FILE__, __FUNCTION__, __LINE__, offset); \ ++ } \ ++ radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, offset); \ ++ radeon_cs_write_reloc(b_l_rmesa->cmdbuf.cs, \ ++ bo, rd, wd, flags); \ ++ if (!b_l_rmesa->radeonScreen->kernel_mm) \ ++ b_l_rmesa->cmdbuf.cs->section_cdw += 2; \ ++ } while(0) ++ ++ ++/** ++ * Write n dwords from ptr to the command buffer. ++ */ ++#define OUT_BATCH_TABLE(ptr,n) \ ++ do { \ ++ int _i; \ ++ for (_i=0; _i < n; _i++) {\ ++ radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, ptr[_i]);\ ++ }\ ++ } while(0) ++ ++/** ++ * Finish writing dwords to the command buffer. ++ * The number of (direct or indirect) OUT_BATCH calls between the previous ++ * BEGIN_BATCH and END_BATCH must match the number specified at BEGIN_BATCH time. ++ */ ++#define END_BATCH() \ ++ do { \ ++ radeon_cs_end(b_l_rmesa->cmdbuf.cs, __FILE__, __FUNCTION__, __LINE__);\ ++ } while(0) ++ ++/** ++ * After the last END_BATCH() of rendering, this indicates that flushing ++ * the command buffer now is okay. ++ */ ++#define COMMIT_BATCH() \ ++ do { \ ++ } while(0) ++ ++ ++/** Single register write to command buffer; requires 2 dwords. */ ++#define OUT_BATCH_REGVAL(reg, val) \ ++ OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), 1)); \ ++ OUT_BATCH((val)) ++ ++/** Continuous register range write to command buffer; requires 1 dword, ++ * expects count dwords afterwards for register contents. */ ++#define OUT_BATCH_REGSEQ(reg, count) \ ++ OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), (count))); ++ ++/** Write a 32 bit float to the ring; requires 1 dword. */ ++#define OUT_BATCH_FLOAT32(f) \ ++ OUT_BATCH(radeonPackFloat32((f))); ++ ++ ++/* Fire the buffered vertices no matter what. ++ */ ++static INLINE void radeon_firevertices(radeonContextPtr radeon) ++{ ++ if (radeon->cmdbuf.cs->cdw || radeon->dma.flush ) ++ radeonFlush(radeon->glCtx); ++} ++ ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c +new file mode 100644 +index 0000000..756c09f +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_common.c +@@ -0,0 +1,1407 @@ ++/************************************************************************** ++ ++Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. ++ ++The Weather Channel (TM) funded Tungsten Graphics to develop the ++initial release of the Radeon 8500 driver under the XFree86 license. ++This notice must be preserved. ++ ++Permission is hereby granted, free of charge, to any person obtaining ++a copy of this software and associated documentation files (the ++"Software"), to deal in the Software without restriction, including ++without limitation the rights to use, copy, modify, merge, publish, ++distribute, sublicense, and/or sell copies of the Software, and to ++permit persons to whom the Software is furnished to do so, subject to ++the following conditions: ++ ++The above copyright notice and this permission notice (including the ++next paragraph) shall be included in all copies or substantial ++portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ ++**************************************************************************/ ++ ++/* ++ * Authors: ++ * Keith Whitwell ++ */ ++ ++/* ++ - Scissor implementation ++ - buffer swap/copy ioctls ++ - finish/flush ++ - state emission ++ - cmdbuffer management ++*/ ++ ++#include ++#include "main/glheader.h" ++#include "main/imports.h" ++#include "main/context.h" ++#include "main/api_arrayelt.h" ++#include "main/enums.h" ++#include "main/colormac.h" ++#include "main/light.h" ++#include "main/framebuffer.h" ++#include "main/simple_list.h" ++#include "main/renderbuffer.h" ++#include "swrast/swrast.h" ++#include "vbo/vbo.h" ++#include "tnl/tnl.h" ++#include "tnl/t_pipeline.h" ++#include "swrast_setup/swrast_setup.h" ++ ++#include "main/blend.h" ++#include "main/bufferobj.h" ++#include "main/buffers.h" ++#include "main/depth.h" ++#include "main/shaders.h" ++#include "main/texstate.h" ++#include "main/varray.h" ++#include "glapi/dispatch.h" ++#include "swrast/swrast.h" ++#include "main/stencil.h" ++#include "main/matrix.h" ++#include "main/attrib.h" ++#include "main/enable.h" ++#include "main/viewport.h" ++ ++#include "dri_util.h" ++#include "vblank.h" ++ ++#include "radeon_common.h" ++#include "radeon_bocs_wrapper.h" ++#include "radeon_lock.h" ++#include "radeon_drm.h" ++#include "radeon_mipmap_tree.h" ++ ++#define DEBUG_CMDBUF 0 ++ ++/* ============================================================= ++ * Scissoring ++ */ ++ ++static GLboolean intersect_rect(drm_clip_rect_t * out, ++ drm_clip_rect_t * a, drm_clip_rect_t * b) ++{ ++ *out = *a; ++ if (b->x1 > out->x1) ++ out->x1 = b->x1; ++ if (b->y1 > out->y1) ++ out->y1 = b->y1; ++ if (b->x2 < out->x2) ++ out->x2 = b->x2; ++ if (b->y2 < out->y2) ++ out->y2 = b->y2; ++ if (out->x1 >= out->x2) ++ return GL_FALSE; ++ if (out->y1 >= out->y2) ++ return GL_FALSE; ++ return GL_TRUE; ++} ++ ++void radeonRecalcScissorRects(radeonContextPtr radeon) ++{ ++ drm_clip_rect_t *out; ++ int i; ++ ++ /* Grow cliprect store? ++ */ ++ if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { ++ while (radeon->state.scissor.numAllocedClipRects < ++ radeon->numClipRects) { ++ radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ ++ radeon->state.scissor.numAllocedClipRects *= 2; ++ } ++ ++ if (radeon->state.scissor.pClipRects) ++ FREE(radeon->state.scissor.pClipRects); ++ ++ radeon->state.scissor.pClipRects = ++ MALLOC(radeon->state.scissor.numAllocedClipRects * ++ sizeof(drm_clip_rect_t)); ++ ++ if (radeon->state.scissor.pClipRects == NULL) { ++ radeon->state.scissor.numAllocedClipRects = 0; ++ return; ++ } ++ } ++ ++ out = radeon->state.scissor.pClipRects; ++ radeon->state.scissor.numClipRects = 0; ++ ++ for (i = 0; i < radeon->numClipRects; i++) { ++ if (intersect_rect(out, ++ &radeon->pClipRects[i], ++ &radeon->state.scissor.rect)) { ++ radeon->state.scissor.numClipRects++; ++ out++; ++ } ++ } ++} ++ ++void radeon_get_cliprects(radeonContextPtr radeon, ++ struct drm_clip_rect **cliprects, ++ unsigned int *num_cliprects, ++ int *x_off, int *y_off) ++{ ++ __DRIdrawablePrivate *dPriv = radeon->dri.drawable; ++ struct radeon_framebuffer *rfb = dPriv->driverPrivate; ++ ++ if (radeon->constant_cliprect) { ++ radeon->fboRect.x1 = 0; ++ radeon->fboRect.y1 = 0; ++ radeon->fboRect.x2 = radeon->glCtx->DrawBuffer->Width; ++ radeon->fboRect.y2 = radeon->glCtx->DrawBuffer->Height; ++ ++ *cliprects = &radeon->fboRect; ++ *num_cliprects = 1; ++ *x_off = 0; ++ *y_off = 0; ++ } else if (radeon->front_cliprects || ++ rfb->pf_active || dPriv->numBackClipRects == 0) { ++ *cliprects = dPriv->pClipRects; ++ *num_cliprects = dPriv->numClipRects; ++ *x_off = dPriv->x; ++ *y_off = dPriv->y; ++ } else { ++ *num_cliprects = dPriv->numBackClipRects; ++ *cliprects = dPriv->pBackClipRects; ++ *x_off = dPriv->backX; ++ *y_off = dPriv->backY; ++ } ++} ++ ++/** ++ * Update cliprects and scissors. ++ */ ++void radeonSetCliprects(radeonContextPtr radeon) ++{ ++ __DRIdrawablePrivate *const drawable = radeon->dri.drawable; ++ __DRIdrawablePrivate *const readable = radeon->dri.readable; ++ struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate; ++ struct radeon_framebuffer *const read_rfb = readable->driverPrivate; ++ int x_off, y_off; ++ ++ radeon_get_cliprects(radeon, &radeon->pClipRects, ++ &radeon->numClipRects, &x_off, &y_off); ++ ++ if ((draw_rfb->base.Width != drawable->w) || ++ (draw_rfb->base.Height != drawable->h)) { ++ _mesa_resize_framebuffer(radeon->glCtx, &draw_rfb->base, ++ drawable->w, drawable->h); ++ draw_rfb->base.Initialized = GL_TRUE; ++ } ++ ++ if (drawable != readable) { ++ if ((read_rfb->base.Width != readable->w) || ++ (read_rfb->base.Height != readable->h)) { ++ _mesa_resize_framebuffer(radeon->glCtx, &read_rfb->base, ++ readable->w, readable->h); ++ read_rfb->base.Initialized = GL_TRUE; ++ } ++ } ++ ++ if (radeon->state.scissor.enabled) ++ radeonRecalcScissorRects(radeon); ++ ++} ++ ++ ++ ++void radeonUpdateScissor( GLcontext *ctx ) ++{ ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ ++ if ( rmesa->dri.drawable ) { ++ __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; ++ ++ int x = ctx->Scissor.X; ++ int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; ++ int w = ctx->Scissor.X + ctx->Scissor.Width - 1; ++ int h = dPriv->h - ctx->Scissor.Y - 1; ++ ++ rmesa->state.scissor.rect.x1 = x + dPriv->x; ++ rmesa->state.scissor.rect.y1 = y + dPriv->y; ++ rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; ++ rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; ++ ++ radeonRecalcScissorRects( rmesa ); ++ } ++} ++ ++/* ============================================================= ++ * Scissoring ++ */ ++ ++void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) ++{ ++ radeonContextPtr radeon = RADEON_CONTEXT(ctx); ++ if (ctx->Scissor.Enabled) { ++ /* We don't pipeline cliprect changes */ ++ radeon_firevertices(radeon); ++ radeonUpdateScissor(ctx); ++ } ++} ++ ++ ++/* ================================================================ ++ * SwapBuffers with client-side throttling ++ */ ++ ++static uint32_t radeonGetLastFrame(radeonContextPtr radeon) ++{ ++ drm_radeon_getparam_t gp; ++ int ret; ++ uint32_t frame = 0; ++ ++ gp.param = RADEON_PARAM_LAST_FRAME; ++ gp.value = (int *)&frame; ++ ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, ++ &gp, sizeof(gp)); ++ if (ret) { ++ fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ++ ret); ++ exit(1); ++ } ++ ++ return frame; ++} ++ ++uint32_t radeonGetAge(radeonContextPtr radeon) ++{ ++ drm_radeon_getparam_t gp; ++ int ret; ++ uint32_t age; ++ ++ gp.param = RADEON_PARAM_LAST_CLEAR; ++ gp.value = (int *)&age; ++ ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, ++ &gp, sizeof(gp)); ++ if (ret) { ++ fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ++ ret); ++ exit(1); ++ } ++ ++ return age; ++} ++ ++static void radeonEmitIrqLocked(radeonContextPtr radeon) ++{ ++ drm_radeon_irq_emit_t ie; ++ int ret; ++ ++ ie.irq_seq = &radeon->iw.irq_seq; ++ ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_IRQ_EMIT, ++ &ie, sizeof(ie)); ++ if (ret) { ++ fprintf(stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ++ ret); ++ exit(1); ++ } ++} ++ ++static void radeonWaitIrq(radeonContextPtr radeon) ++{ ++ int ret; ++ ++ do { ++ ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT, ++ &radeon->iw, sizeof(radeon->iw)); ++ } while (ret && (errno == EINTR || errno == EBUSY)); ++ ++ if (ret) { ++ fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ++ ret); ++ exit(1); ++ } ++} ++ ++static void radeonWaitForFrameCompletion(radeonContextPtr radeon) ++{ ++ drm_radeon_sarea_t *sarea = radeon->sarea; ++ ++ if (radeon->do_irqs) { ++ if (radeonGetLastFrame(radeon) < sarea->last_frame) { ++ if (!radeon->irqsEmitted) { ++ while (radeonGetLastFrame(radeon) < ++ sarea->last_frame) ; ++ } else { ++ UNLOCK_HARDWARE(radeon); ++ radeonWaitIrq(radeon); ++ LOCK_HARDWARE(radeon); ++ } ++ radeon->irqsEmitted = 10; ++ } ++ ++ if (radeon->irqsEmitted) { ++ radeonEmitIrqLocked(radeon); ++ radeon->irqsEmitted--; ++ } ++ } else { ++ while (radeonGetLastFrame(radeon) < sarea->last_frame) { ++ UNLOCK_HARDWARE(radeon); ++ if (radeon->do_usleeps) ++ DO_USLEEP(1); ++ LOCK_HARDWARE(radeon); ++ } ++ } ++} ++ ++/* wait for idle */ ++void radeonWaitForIdleLocked(radeonContextPtr radeon) ++{ ++ int ret; ++ int i = 0; ++ ++ do { ++ ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE); ++ if (ret) ++ DO_USLEEP(1); ++ } while (ret && ++i < 100); ++ ++ if (ret < 0) { ++ UNLOCK_HARDWARE(radeon); ++ fprintf(stderr, "Error: R300 timed out... exiting\n"); ++ exit(-1); ++ } ++} ++ ++static void radeonWaitForIdle(radeonContextPtr radeon) ++{ ++ if (!radeon->radeonScreen->driScreen->dri2.enabled) { ++ LOCK_HARDWARE(radeon); ++ radeonWaitForIdleLocked(radeon); ++ UNLOCK_HARDWARE(radeon); ++ } ++} ++ ++static void radeon_flip_renderbuffers(struct radeon_framebuffer *rfb) ++{ ++ int current_page = rfb->pf_current_page; ++ int next_page = (current_page + 1) % rfb->pf_num_pages; ++ struct gl_renderbuffer *tmp_rb; ++ ++ /* Exchange renderbuffers if necessary but make sure their ++ * reference counts are preserved. ++ */ ++ if (rfb->color_rb[current_page] && ++ rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer != ++ &rfb->color_rb[current_page]->base) { ++ tmp_rb = NULL; ++ _mesa_reference_renderbuffer(&tmp_rb, ++ rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); ++ tmp_rb = &rfb->color_rb[current_page]->base; ++ _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer, tmp_rb); ++ _mesa_reference_renderbuffer(&tmp_rb, NULL); ++ } ++ ++ if (rfb->color_rb[next_page] && ++ rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer != ++ &rfb->color_rb[next_page]->base) { ++ tmp_rb = NULL; ++ _mesa_reference_renderbuffer(&tmp_rb, ++ rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); ++ tmp_rb = &rfb->color_rb[next_page]->base; ++ _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer, tmp_rb); ++ _mesa_reference_renderbuffer(&tmp_rb, NULL); ++ } ++} ++ ++/* Copy the back color buffer to the front color buffer. ++ */ ++void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, ++ const drm_clip_rect_t *rect) ++{ ++ radeonContextPtr rmesa; ++ struct radeon_framebuffer *rfb; ++ GLint nbox, i, ret; ++ ++ assert(dPriv); ++ assert(dPriv->driContextPriv); ++ assert(dPriv->driContextPriv->driverPrivate); ++ ++ rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; ++ ++ LOCK_HARDWARE(rmesa); ++ ++ rfb = dPriv->driverPrivate; ++ ++ if ( RADEON_DEBUG & DEBUG_IOCTL ) { ++ fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); ++ } ++ ++ nbox = dPriv->numClipRects; /* must be in locked region */ ++ ++ for ( i = 0 ; i < nbox ; ) { ++ GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); ++ drm_clip_rect_t *box = dPriv->pClipRects; ++ drm_clip_rect_t *b = rmesa->sarea->boxes; ++ GLint n = 0; ++ ++ for ( ; i < nr ; i++ ) { ++ ++ *b = box[i]; ++ ++ if (rect) ++ { ++ if (rect->x1 > b->x1) ++ b->x1 = rect->x1; ++ if (rect->y1 > b->y1) ++ b->y1 = rect->y1; ++ if (rect->x2 < b->x2) ++ b->x2 = rect->x2; ++ if (rect->y2 < b->y2) ++ b->y2 = rect->y2; ++ ++ if (b->x1 >= b->x2 || b->y1 >= b->y2) ++ continue; ++ } ++ ++ b++; ++ n++; ++ } ++ rmesa->sarea->nbox = n; ++ ++ if (!n) ++ continue; ++ ++ ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP ); ++ ++ if ( ret ) { ++ fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret ); ++ UNLOCK_HARDWARE( rmesa ); ++ exit( 1 ); ++ } ++ } ++ ++ UNLOCK_HARDWARE( rmesa ); ++} ++ ++static int radeonScheduleSwap(__DRIdrawablePrivate *dPriv, GLboolean *missed_target) ++{ ++ radeonContextPtr rmesa; ++ ++ rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; ++ radeon_firevertices(rmesa); ++ ++ LOCK_HARDWARE( rmesa ); ++ ++ if (!dPriv->numClipRects) { ++ UNLOCK_HARDWARE(rmesa); ++ usleep(10000); /* throttle invisible client 10ms */ ++ return 0; ++ } ++ ++ radeonWaitForFrameCompletion(rmesa); ++ ++ UNLOCK_HARDWARE(rmesa); ++ driWaitForVBlank(dPriv, missed_target); ++ ++ return 0; ++} ++ ++static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv ) ++{ ++ radeonContextPtr radeon; ++ GLint ret; ++ __DRIscreenPrivate *psp; ++ struct radeon_renderbuffer *rrb; ++ struct radeon_framebuffer *rfb; ++ ++ assert(dPriv); ++ assert(dPriv->driContextPriv); ++ assert(dPriv->driContextPriv->driverPrivate); ++ ++ radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; ++ rfb = dPriv->driverPrivate; ++ rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; ++ ++ psp = dPriv->driScreenPriv; ++ ++ LOCK_HARDWARE(radeon); ++ ++ if ( RADEON_DEBUG & DEBUG_IOCTL ) { ++ fprintf(stderr, "%s: pfCurrentPage: %d %d\n", __FUNCTION__, ++ radeon->sarea->pfCurrentPage, radeon->sarea->pfState); ++ } ++ drm_clip_rect_t *box = dPriv->pClipRects; ++ drm_clip_rect_t *b = radeon->sarea->boxes; ++ b[0] = box[0]; ++ radeon->sarea->nbox = 1; ++ ++ ret = drmCommandNone( radeon->dri.fd, DRM_RADEON_FLIP ); ++ ++ UNLOCK_HARDWARE(radeon); ++ ++ if ( ret ) { ++ fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); ++ return GL_FALSE; ++ } ++ ++ if (!rfb->pf_active) ++ return GL_FALSE; ++ ++ rfb->pf_current_page = radeon->sarea->pfCurrentPage; ++ radeon_flip_renderbuffers(rfb); ++ radeon_draw_buffer(radeon->glCtx, &rfb->base); ++ ++ return GL_TRUE; ++} ++ ++ ++/** ++ * Swap front and back buffer. ++ */ ++void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) ++{ ++ int64_t ust; ++ __DRIscreenPrivate *psp; ++ ++ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { ++ radeonContextPtr radeon; ++ GLcontext *ctx; ++ ++ radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; ++ ctx = radeon->glCtx; ++ ++ if (ctx->Visual.doubleBufferMode) { ++ GLboolean missed_target; ++ struct radeon_framebuffer *rfb = dPriv->driverPrivate; ++ _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ ++ ++ radeonScheduleSwap(dPriv, &missed_target); ++ ++ if (rfb->pf_active) { ++ radeonPageFlip(dPriv); ++ } else { ++ radeonCopyBuffer(dPriv, NULL); ++ } ++ ++ psp = dPriv->driScreenPriv; ++ ++ rfb->swap_count++; ++ (*psp->systemTime->getUST)( & ust ); ++ if ( missed_target ) { ++ rfb->swap_missed_count++; ++ rfb->swap_missed_ust = ust - rfb->swap_ust; ++ } ++ ++ rfb->swap_ust = ust; ++ radeon->hw.all_dirty = GL_TRUE; ++ } ++ } else { ++ /* XXX this shouldn't be an error but we can't handle it for now */ ++ _mesa_problem(NULL, "%s: drawable has no context!", ++ __FUNCTION__); ++ } ++} ++ ++void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, ++ int x, int y, int w, int h ) ++{ ++ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { ++ radeonContextPtr radeon; ++ GLcontext *ctx; ++ ++ radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; ++ ctx = radeon->glCtx; ++ ++ if (ctx->Visual.doubleBufferMode) { ++ drm_clip_rect_t rect; ++ rect.x1 = x + dPriv->x; ++ rect.y1 = (dPriv->h - y - h) + dPriv->y; ++ rect.x2 = rect.x1 + w; ++ rect.y2 = rect.y1 + h; ++ _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ ++ radeonCopyBuffer(dPriv, &rect); ++ } ++ } else { ++ /* XXX this shouldn't be an error but we can't handle it for now */ ++ _mesa_problem(NULL, "%s: drawable has no context!", ++ __FUNCTION__); ++ } ++} ++ ++void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) ++{ ++ radeonContextPtr radeon = RADEON_CONTEXT(ctx); ++ struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL, ++ *rrbColor = NULL; ++ uint32_t offset = 0; ++ ++ ++ if (!fb) { ++ /* this can happen during the initial context initialization */ ++ return; ++ } ++ ++ /* radeons only handle 1 color draw so far */ ++ if (fb->_NumColorDrawBuffers != 1) { ++ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); ++ return; ++ } ++ ++ /* Do this here, note core Mesa, since this function is called from ++ * many places within the driver. ++ */ ++ if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { ++ /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ ++ _mesa_update_framebuffer(ctx); ++ /* this updates the DrawBuffer's Width/Height if it's a FBO */ ++ _mesa_update_draw_buffer_bounds(ctx); ++ } ++ ++ if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { ++ /* this may occur when we're called by glBindFrameBuffer() during ++ * the process of someone setting up renderbuffers, etc. ++ */ ++ /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/ ++ return; ++ } ++ ++ if (fb->Name) ++ ;/* do something depthy/stencily TODO */ ++ ++ ++ /* none */ ++ if (fb->Name == 0) { ++ if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { ++ rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); ++ radeon->front_cliprects = GL_TRUE; ++ } else { ++ rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); ++ radeon->front_cliprects = GL_FALSE; ++ } ++ } else { ++ /* user FBO in theory */ ++ struct radeon_renderbuffer *rrb; ++ rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]); ++ if (rrb) { ++ offset = rrb->draw_offset; ++ rrbColor = rrb; ++ } ++ radeon->constant_cliprect = GL_TRUE; ++ } ++ ++ if (rrbColor == NULL) ++ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); ++ else ++ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE); ++ ++ ++ if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { ++ rrbDepth = radeon_renderbuffer(fb->_DepthBuffer->Wrapped); ++ if (rrbDepth && rrbDepth->bo) { ++ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); ++ } else { ++ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_TRUE); ++ } ++ } else { ++ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); ++ rrbDepth = NULL; ++ } ++ ++ if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { ++ rrbStencil = radeon_renderbuffer(fb->_DepthBuffer->Wrapped); ++ if (rrbStencil && rrbStencil->bo) { ++ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); ++ /* need to re-compute stencil hw state */ ++ if (!rrbDepth) ++ rrbDepth = rrbStencil; ++ } else { ++ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_TRUE); ++ } ++ } else { ++ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); ++ if (ctx->Driver.Enable != NULL) ++ ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); ++ else ++ ctx->NewState |= _NEW_STENCIL; ++ } ++ ++ /* Update culling direction which changes depending on the ++ * orientation of the buffer: ++ */ ++ if (ctx->Driver.FrontFace) ++ ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); ++ else ++ ctx->NewState |= _NEW_POLYGON; ++ ++ /* ++ * Update depth test state ++ */ ++ if (ctx->Driver.Enable) { ++ ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ++ (ctx->Depth.Test && fb->Visual.depthBits > 0)); ++ ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ++ (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0)); ++ } else { ++ ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL); ++ } ++ ++ radeon->state.depth.rrb = rrbDepth; ++ radeon->state.color.rrb = rrbColor; ++ radeon->state.color.draw_offset = offset; ++ ++#if 0 ++ /* update viewport since it depends on window size */ ++ if (ctx->Driver.Viewport) { ++ ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, ++ ctx->Viewport.Width, ctx->Viewport.Height); ++ } else { ++ ++ } ++#endif ++ ctx->NewState |= _NEW_VIEWPORT; ++ ++ /* Set state we know depends on drawable parameters: ++ */ ++ if (ctx->Driver.Scissor) ++ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, ++ ctx->Scissor.Width, ctx->Scissor.Height); ++ radeon->NewGLState |= _NEW_SCISSOR; ++ ++ if (ctx->Driver.DepthRange) ++ ctx->Driver.DepthRange(ctx, ++ ctx->Viewport.Near, ++ ctx->Viewport.Far); ++ ++ /* Update culling direction which changes depending on the ++ * orientation of the buffer: ++ */ ++ if (ctx->Driver.FrontFace) ++ ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); ++ else ++ ctx->NewState |= _NEW_POLYGON; ++} ++ ++/** ++ * Called via glDrawBuffer. ++ */ ++void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) ++{ ++ if (RADEON_DEBUG & DEBUG_DRI) ++ fprintf(stderr, "%s %s\n", __FUNCTION__, ++ _mesa_lookup_enum_by_nr( mode )); ++ ++ radeon_draw_buffer(ctx, ctx->DrawBuffer); ++} ++ ++void radeonReadBuffer( GLcontext *ctx, GLenum mode ) ++{ ++ /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ ++ if (ctx->ReadBuffer == ctx->DrawBuffer) { ++ /* This will update FBO completeness status. ++ * A framebuffer will be incomplete if the GL_READ_BUFFER setting ++ * refers to a missing renderbuffer. Calling glReadBuffer can set ++ * that straight and can make the drawing buffer complete. ++ */ ++ radeon_draw_buffer(ctx, ctx->DrawBuffer); ++ } ++} ++ ++ ++/* Turn on/off page flipping according to the flags in the sarea: ++ */ ++void radeonUpdatePageFlipping(radeonContextPtr radeon) ++{ ++ struct radeon_framebuffer *rfb = radeon->dri.drawable->driverPrivate; ++ ++ rfb->pf_active = radeon->sarea->pfState; ++ rfb->pf_current_page = radeon->sarea->pfCurrentPage; ++ rfb->pf_num_pages = 2; ++ radeon_flip_renderbuffers(rfb); ++ radeon_draw_buffer(radeon->glCtx, radeon->glCtx->DrawBuffer); ++} ++ ++void radeon_window_moved(radeonContextPtr radeon) ++{ ++ if (!radeon->radeonScreen->driScreen->dri2.enabled) { ++ radeonUpdatePageFlipping(radeon); ++ } ++ radeonSetCliprects(radeon); ++} ++ ++void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height) ++{ ++ radeonContextPtr radeon = RADEON_CONTEXT(ctx); ++ __DRIcontext *driContext = radeon->dri.context; ++ void (*old_viewport)(GLcontext *ctx, GLint x, GLint y, ++ GLsizei w, GLsizei h); ++ ++ if (!driContext->driScreenPriv->dri2.enabled) ++ return; ++ ++ radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); ++ if (driContext->driDrawablePriv != driContext->driReadablePriv) ++ radeon_update_renderbuffers(driContext, driContext->driReadablePriv); ++ ++ old_viewport = ctx->Driver.Viewport; ++ ctx->Driver.Viewport = NULL; ++ radeon->dri.drawable = driContext->driDrawablePriv; ++ radeon_window_moved(radeon); ++ radeon_draw_buffer(ctx, radeon->glCtx->DrawBuffer); ++ ctx->Driver.Viewport = old_viewport; ++ ++ ++} ++static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state ) ++{ ++ int i; ++ int dwords = (*state->check)(radeon->glCtx, state); ++ ++ fprintf(stderr, "emit %s %d/%d\n", state->name, state->cmd_size, dwords); ++ ++ if (RADEON_DEBUG & DEBUG_VERBOSE) ++ for (i = 0 ; i < dwords; i++) ++ fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); ++ ++} ++ ++static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty) ++{ ++ BATCH_LOCALS(radeon); ++ struct radeon_state_atom *atom; ++ int dwords; ++ ++ if (radeon->vtbl.pre_emit_atoms) ++ radeon->vtbl.pre_emit_atoms(radeon); ++ ++ /* Emit actual atoms */ ++ foreach(atom, &radeon->hw.atomlist) { ++ if ((atom->dirty || radeon->hw.all_dirty) == dirty) { ++ dwords = (*atom->check) (radeon->glCtx, atom); ++ if (dwords) { ++ if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { ++ radeon_print_state_atom(radeon, atom); ++ } ++ if (atom->emit) { ++ (*atom->emit)(radeon->glCtx, atom); ++ } else { ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_BATCH_TABLE(atom->cmd, dwords); ++ END_BATCH(); ++ } ++ atom->dirty = GL_FALSE; ++ } else { ++ if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { ++ fprintf(stderr, " skip state %s\n", ++ atom->name); ++ } ++ } ++ } ++ } ++ ++ COMMIT_BATCH(); ++} ++ ++GLboolean radeon_revalidate_bos(GLcontext *ctx) ++{ ++ radeonContextPtr radeon = RADEON_CONTEXT(ctx); ++ int flushed = 0; ++ int ret; ++again: ++ ret = radeon_cs_space_check(radeon->cmdbuf.cs, radeon->state.bos, radeon->state.validated_bo_count); ++ if (ret == RADEON_CS_SPACE_OP_TO_BIG) ++ return GL_FALSE; ++ if (ret == RADEON_CS_SPACE_FLUSH) { ++ radeonFlush(ctx); ++ if (flushed) ++ return GL_FALSE; ++ flushed = 1; ++ goto again; ++ } ++ return GL_TRUE; ++} ++ ++void radeon_validate_reset_bos(radeonContextPtr radeon) ++{ ++ int i; ++ ++ for (i = 0; i < radeon->state.validated_bo_count; i++) { ++ radeon->state.bos[i].bo = NULL; ++ radeon->state.bos[i].read_domains = 0; ++ radeon->state.bos[i].write_domain = 0; ++ radeon->state.bos[i].new_accounted = 0; ++ } ++ radeon->state.validated_bo_count = 0; ++} ++ ++void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) ++{ ++ radeon->state.bos[radeon->state.validated_bo_count].bo = bo; ++ radeon->state.bos[radeon->state.validated_bo_count].read_domains = read_domains; ++ radeon->state.bos[radeon->state.validated_bo_count].write_domain = write_domain; ++ radeon->state.bos[radeon->state.validated_bo_count].new_accounted = 0; ++ radeon->state.validated_bo_count++; ++ ++ assert(radeon->state.validated_bo_count < RADEON_MAX_BOS); ++} ++ ++void radeonEmitState(radeonContextPtr radeon) ++{ ++ if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) ++ fprintf(stderr, "%s\n", __FUNCTION__); ++ ++ if (radeon->vtbl.pre_emit_state) ++ radeon->vtbl.pre_emit_state(radeon); ++ ++ /* this code used to return here but now it emits zbs */ ++ if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty) ++ return; ++ ++ /* To avoid going across the entire set of states multiple times, just check ++ * for enough space for the case of emitting all state, and inline the ++ * radeonAllocCmdBuf code here without all the checks. ++ */ ++ rcommonEnsureCmdBufSpace(radeon, radeon->hw.max_state_size, __FUNCTION__); ++ ++ if (!radeon->cmdbuf.cs->cdw) { ++ if (RADEON_DEBUG & DEBUG_STATE) ++ fprintf(stderr, "Begin reemit state\n"); ++ ++ radeonEmitAtoms(radeon, GL_FALSE); ++ } ++ ++ if (RADEON_DEBUG & DEBUG_STATE) ++ fprintf(stderr, "Begin dirty state\n"); ++ ++ radeonEmitAtoms(radeon, GL_TRUE); ++ radeon->hw.is_dirty = GL_FALSE; ++ radeon->hw.all_dirty = GL_FALSE; ++ ++} ++ ++ ++void radeonFlush(GLcontext *ctx) ++{ ++ radeonContextPtr radeon = RADEON_CONTEXT(ctx); ++ if (RADEON_DEBUG & DEBUG_IOCTL) ++ fprintf(stderr, "%s %d\n", __FUNCTION__, radeon->cmdbuf.cs->cdw); ++ ++ /* okay if we have no cmds in the buffer && ++ we have no DMA flush && ++ we have no DMA buffer allocated. ++ then no point flushing anything at all. ++ */ ++ if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && !radeon->dma.current) ++ return; ++ ++ if (radeon->dma.flush) ++ radeon->dma.flush( ctx ); ++ ++ radeonEmitState(radeon); ++ ++ if (radeon->cmdbuf.cs->cdw) ++ rcommonFlushCmdBuf(radeon, __FUNCTION__); ++} ++ ++/* Make sure all commands have been sent to the hardware and have ++ * completed processing. ++ */ ++void radeonFinish(GLcontext * ctx) ++{ ++ radeonContextPtr radeon = RADEON_CONTEXT(ctx); ++ struct gl_framebuffer *fb = ctx->DrawBuffer; ++ int i; ++ ++ radeonFlush(ctx); ++ ++ if (radeon->radeonScreen->kernel_mm) { ++ for (i = 0; i < fb->_NumColorDrawBuffers; i++) { ++ struct radeon_renderbuffer *rrb; ++ rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[i]); ++ if (rrb && rrb->bo) ++ radeon_bo_wait(rrb->bo); ++ } ++ { ++ struct radeon_renderbuffer *rrb; ++ rrb = radeon_get_depthbuffer(radeon); ++ if (rrb && rrb->bo) ++ radeon_bo_wait(rrb->bo); ++ } ++ } else if (radeon->do_irqs) { ++ LOCK_HARDWARE(radeon); ++ radeonEmitIrqLocked(radeon); ++ UNLOCK_HARDWARE(radeon); ++ radeonWaitIrq(radeon); ++ } else { ++ radeonWaitForIdle(radeon); ++ } ++} ++ ++/* cmdbuffer */ ++/** ++ * Send the current command buffer via ioctl to the hardware. ++ */ ++int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) ++{ ++ int ret = 0; ++ ++ if (rmesa->cmdbuf.flushing) { ++ fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); ++ exit(-1); ++ } ++ rmesa->cmdbuf.flushing = 1; ++ ++ if (RADEON_DEBUG & DEBUG_IOCTL) { ++ fprintf(stderr, "%s from %s - %i cliprects\n", ++ __FUNCTION__, caller, rmesa->numClipRects); ++ } ++ ++ if (rmesa->cmdbuf.cs->cdw) { ++ ret = radeon_cs_emit(rmesa->cmdbuf.cs); ++ rmesa->hw.all_dirty = GL_TRUE; ++ } ++ radeon_cs_erase(rmesa->cmdbuf.cs); ++ rmesa->cmdbuf.flushing = 0; ++ ++ if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE) { ++ fprintf(stderr,"failed to revalidate buffers\n"); ++ } ++ ++ return ret; ++} ++ ++int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) ++{ ++ int ret; ++ ++ radeonReleaseDmaRegion(rmesa); ++ ++ LOCK_HARDWARE(rmesa); ++ ret = rcommonFlushCmdBufLocked(rmesa, caller); ++ UNLOCK_HARDWARE(rmesa); ++ ++ if (ret) { ++ fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); ++ _mesa_exit(ret); ++ } ++ ++ return ret; ++} ++ ++/** ++ * Make sure that enough space is available in the command buffer ++ * by flushing if necessary. ++ * ++ * \param dwords The number of dwords we need to be free on the command buffer ++ */ ++void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller) ++{ ++ if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size || ++ radeon_cs_need_flush(rmesa->cmdbuf.cs)) { ++ rcommonFlushCmdBuf(rmesa, caller); ++ } ++} ++ ++void rcommonInitCmdBuf(radeonContextPtr rmesa) ++{ ++ GLuint size; ++ /* Initialize command buffer */ ++ size = 256 * driQueryOptioni(&rmesa->optionCache, ++ "command_buffer_size"); ++ if (size < 2 * rmesa->hw.max_state_size) { ++ size = 2 * rmesa->hw.max_state_size + 65535; ++ } ++ if (size > 64 * 256) ++ size = 64 * 256; ++ ++ if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { ++ fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", ++ sizeof(drm_r300_cmd_header_t)); ++ fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", ++ sizeof(drm_radeon_cmd_buffer_t)); ++ fprintf(stderr, ++ "Allocating %d bytes command buffer (max state is %d bytes)\n", ++ size * 4, rmesa->hw.max_state_size * 4); ++ } ++ ++ if (rmesa->radeonScreen->kernel_mm) { ++ int fd = rmesa->radeonScreen->driScreen->fd; ++ rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); ++ } else { ++ rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa); ++ } ++ if (rmesa->cmdbuf.csm == NULL) { ++ /* FIXME: fatal error */ ++ return; ++ } ++ rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size); ++ assert(rmesa->cmdbuf.cs != NULL); ++ rmesa->cmdbuf.size = size; ++ ++ if (!rmesa->radeonScreen->kernel_mm) { ++ radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]); ++ radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size); ++ } else { ++ struct drm_radeon_gem_info mminfo; ++ ++ if (!drmCommandWriteRead(rmesa->dri.fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) ++ { ++ radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, mminfo.vram_visible); ++ radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, mminfo.gart_size); ++ } ++ } ++ ++} ++/** ++ * Destroy the command buffer ++ */ ++void rcommonDestroyCmdBuf(radeonContextPtr rmesa) ++{ ++ radeon_cs_destroy(rmesa->cmdbuf.cs); ++ if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) { ++ radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm); ++ } else { ++ radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm); ++ } ++} ++ ++void rcommonBeginBatch(radeonContextPtr rmesa, int n, ++ int dostate, ++ const char *file, ++ const char *function, ++ int line) ++{ ++ rcommonEnsureCmdBufSpace(rmesa, n, function); ++ if (!rmesa->cmdbuf.cs->cdw && dostate) { ++ if (RADEON_DEBUG & DEBUG_IOCTL) ++ fprintf(stderr, "Reemit state after flush (from %s)\n", function); ++ radeonEmitState(rmesa); ++ } ++ radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line); ++ ++ if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_IOCTL) ++ fprintf(stderr, "BEGIN_BATCH(%d) at %d, from %s:%i\n", ++ n, rmesa->cmdbuf.cs->cdw, function, line); ++ ++} ++ ++ ++ ++static void ++radeon_meta_set_passthrough_transform(radeonContextPtr radeon) ++{ ++ GLcontext *ctx = radeon->glCtx; ++ ++ radeon->meta.saved_vp_x = ctx->Viewport.X; ++ radeon->meta.saved_vp_y = ctx->Viewport.Y; ++ radeon->meta.saved_vp_width = ctx->Viewport.Width; ++ radeon->meta.saved_vp_height = ctx->Viewport.Height; ++ radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode; ++ ++ _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); ++ ++ _mesa_MatrixMode(GL_PROJECTION); ++ _mesa_PushMatrix(); ++ _mesa_LoadIdentity(); ++ _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); ++ ++ _mesa_MatrixMode(GL_MODELVIEW); ++ _mesa_PushMatrix(); ++ _mesa_LoadIdentity(); ++} ++ ++static void ++radeon_meta_restore_transform(radeonContextPtr radeon) ++{ ++ _mesa_MatrixMode(GL_PROJECTION); ++ _mesa_PopMatrix(); ++ _mesa_MatrixMode(GL_MODELVIEW); ++ _mesa_PopMatrix(); ++ ++ _mesa_MatrixMode(radeon->meta.saved_matrix_mode); ++ ++ _mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y, ++ radeon->meta.saved_vp_width, radeon->meta.saved_vp_height); ++} ++ ++ ++/** ++ * Perform glClear where mask contains only color, depth, and/or stencil. ++ * ++ * The implementation is based on calling into Mesa to set GL state and ++ * performing normal triangle rendering. The intent of this path is to ++ * have as generic a path as possible, so that any driver could make use of ++ * it. ++ */ ++ ++ ++void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) ++{ ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ GLfloat vertices[4][3]; ++ GLfloat color[4][4]; ++ GLfloat dst_z; ++ struct gl_framebuffer *fb = ctx->DrawBuffer; ++ int i; ++ GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; ++ GLboolean saved_shader_program = 0; ++ unsigned int saved_active_texture; ++ ++ assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | ++ BUFFER_BIT_STENCIL)) == 0); ++ ++ _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | ++ GL_CURRENT_BIT | ++ GL_DEPTH_BUFFER_BIT | ++ GL_ENABLE_BIT | ++ GL_STENCIL_BUFFER_BIT | ++ GL_TRANSFORM_BIT | ++ GL_CURRENT_BIT); ++ _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); ++ saved_active_texture = ctx->Texture.CurrentUnit; ++ ++ /* Disable existing GL state we don't want to apply to a clear. */ ++ _mesa_Disable(GL_ALPHA_TEST); ++ _mesa_Disable(GL_BLEND); ++ _mesa_Disable(GL_CULL_FACE); ++ _mesa_Disable(GL_FOG); ++ _mesa_Disable(GL_POLYGON_SMOOTH); ++ _mesa_Disable(GL_POLYGON_STIPPLE); ++ _mesa_Disable(GL_POLYGON_OFFSET_FILL); ++ _mesa_Disable(GL_LIGHTING); ++ _mesa_Disable(GL_CLIP_PLANE0); ++ _mesa_Disable(GL_CLIP_PLANE1); ++ _mesa_Disable(GL_CLIP_PLANE2); ++ _mesa_Disable(GL_CLIP_PLANE3); ++ _mesa_Disable(GL_CLIP_PLANE4); ++ _mesa_Disable(GL_CLIP_PLANE5); ++ if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { ++ saved_fp_enable = GL_TRUE; ++ _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); ++ } ++ if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { ++ saved_vp_enable = GL_TRUE; ++ _mesa_Disable(GL_VERTEX_PROGRAM_ARB); ++ } ++ if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { ++ saved_shader_program = ctx->Shader.CurrentProgram->Name; ++ _mesa_UseProgramObjectARB(0); ++ } ++ ++ if (ctx->Texture._EnabledUnits != 0) { ++ int i; ++ ++ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { ++ _mesa_ActiveTextureARB(GL_TEXTURE0 + i); ++ _mesa_Disable(GL_TEXTURE_1D); ++ _mesa_Disable(GL_TEXTURE_2D); ++ _mesa_Disable(GL_TEXTURE_3D); ++ if (ctx->Extensions.ARB_texture_cube_map) ++ _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); ++ if (ctx->Extensions.NV_texture_rectangle) ++ _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); ++ if (ctx->Extensions.MESA_texture_array) { ++ _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); ++ _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); ++ } ++ } ++ } ++ ++ radeon_meta_set_passthrough_transform(rmesa); ++ ++ for (i = 0; i < 4; i++) { ++ color[i][0] = ctx->Color.ClearColor[0]; ++ color[i][1] = ctx->Color.ClearColor[1]; ++ color[i][2] = ctx->Color.ClearColor[2]; ++ color[i][3] = ctx->Color.ClearColor[3]; ++ } ++ ++ /* convert clear Z from [0,1] to NDC coord in [-1,1] */ ++ ++ dst_z = -1.0 + 2.0 * ctx->Depth.Clear; ++ /* Prepare the vertices, which are the same regardless of which buffer we're ++ * drawing to. ++ */ ++ vertices[0][0] = fb->_Xmin; ++ vertices[0][1] = fb->_Ymin; ++ vertices[0][2] = dst_z; ++ vertices[1][0] = fb->_Xmax; ++ vertices[1][1] = fb->_Ymin; ++ vertices[1][2] = dst_z; ++ vertices[2][0] = fb->_Xmax; ++ vertices[2][1] = fb->_Ymax; ++ vertices[2][2] = dst_z; ++ vertices[3][0] = fb->_Xmin; ++ vertices[3][1] = fb->_Ymax; ++ vertices[3][2] = dst_z; ++ ++ _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); ++ _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); ++ _mesa_Enable(GL_COLOR_ARRAY); ++ _mesa_Enable(GL_VERTEX_ARRAY); ++ ++ while (mask != 0) { ++ GLuint this_mask = 0; ++ GLuint color_bit; ++ ++ color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); ++ if (color_bit != 0) ++ this_mask |= (1 << (color_bit - 1)); ++ ++ /* Clear depth/stencil in the same pass as color. */ ++ this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); ++ ++ /* Select the current color buffer and use the color write mask if ++ * we have one, otherwise don't write any color channels. ++ */ ++ if (this_mask & BUFFER_BIT_FRONT_LEFT) ++ _mesa_DrawBuffer(GL_FRONT_LEFT); ++ else if (this_mask & BUFFER_BIT_BACK_LEFT) ++ _mesa_DrawBuffer(GL_BACK_LEFT); ++ else if (color_bit != 0) ++ _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + ++ (color_bit - BUFFER_COLOR0 - 1)); ++ else ++ _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); ++ ++ /* Control writing of the depth clear value to depth. */ ++ if (this_mask & BUFFER_BIT_DEPTH) { ++ _mesa_DepthFunc(GL_ALWAYS); ++ _mesa_DepthMask(GL_TRUE); ++ _mesa_Enable(GL_DEPTH_TEST); ++ } else { ++ _mesa_Disable(GL_DEPTH_TEST); ++ _mesa_DepthMask(GL_FALSE); ++ } ++ ++ /* Control writing of the stencil clear value to stencil. */ ++ if (this_mask & BUFFER_BIT_STENCIL) { ++ _mesa_Enable(GL_STENCIL_TEST); ++ _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); ++ _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear, ++ ctx->Stencil.WriteMask[0]); ++ } else { ++ _mesa_Disable(GL_STENCIL_TEST); ++ } ++ ++ CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); ++ ++ mask &= ~this_mask; ++ } ++ ++ radeon_meta_restore_transform(rmesa); ++ ++ _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); ++ if (saved_fp_enable) ++ _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); ++ if (saved_vp_enable) ++ _mesa_Enable(GL_VERTEX_PROGRAM_ARB); ++ ++ if (saved_shader_program) ++ _mesa_UseProgramObjectARB(saved_shader_program); ++ ++ _mesa_PopClientAttrib(); ++ _mesa_PopAttrib(); ++} +diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h +new file mode 100644 +index 0000000..c2fbb09 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_common.h +@@ -0,0 +1,100 @@ ++#ifndef COMMON_MISC_H ++#define COMMON_MISC_H ++ ++#include "radeon_common_context.h" ++#include "radeon_dma.h" ++#include "radeon_texture.h" ++ ++ ++#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \ ++ BUFFER_BIT_FRONT_LEFT | \ ++ BUFFER_BIT_COLOR0 | \ ++ BUFFER_BIT_COLOR1 | \ ++ BUFFER_BIT_COLOR2 | \ ++ BUFFER_BIT_COLOR3 | \ ++ BUFFER_BIT_COLOR4 | \ ++ BUFFER_BIT_COLOR5 | \ ++ BUFFER_BIT_COLOR6 | \ ++ BUFFER_BIT_COLOR7) ++ ++void radeonRecalcScissorRects(radeonContextPtr radeon); ++void radeonSetCliprects(radeonContextPtr radeon); ++void radeonUpdateScissor( GLcontext *ctx ); ++void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h); ++ ++void radeonWaitForIdleLocked(radeonContextPtr radeon); ++extern uint32_t radeonGetAge(radeonContextPtr radeon); ++void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, ++ const drm_clip_rect_t *rect); ++void radeonSwapBuffers(__DRIdrawablePrivate * dPriv); ++void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, ++ int x, int y, int w, int h ); ++ ++void radeonUpdatePageFlipping(radeonContextPtr rmesa); ++ ++void radeonFlush(GLcontext *ctx); ++void radeonFinish(GLcontext * ctx); ++void radeonEmitState(radeonContextPtr radeon); ++ ++void radeon_clear_tris(GLcontext *ctx, GLbitfield mask); ++ ++void radeon_window_moved(radeonContextPtr radeon); ++void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb); ++void radeonDrawBuffer( GLcontext *ctx, GLenum mode ); ++void radeonReadBuffer( GLcontext *ctx, GLenum mode ); ++void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height); ++void radeon_get_cliprects(radeonContextPtr radeon, ++ struct drm_clip_rect **cliprects, ++ unsigned int *num_cliprects, ++ int *x_off, int *y_off); ++GLboolean radeon_revalidate_bos(GLcontext *ctx); ++void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain); ++void radeon_validate_reset_bos(radeonContextPtr radeon); ++ ++void radeon_fbo_init(struct radeon_context *radeon); ++void ++radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, ++ struct radeon_bo *bo); ++struct radeon_renderbuffer * ++radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv); ++static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb) ++{ ++ struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb; ++ if (rrb && rrb->base.ClassID == RADEON_RB_CLASS) ++ return rrb; ++ else ++ return NULL; ++} ++ ++static inline struct radeon_renderbuffer *radeon_get_renderbuffer(struct gl_framebuffer *fb, int att_index) ++{ ++ if (att_index >= 0) ++ return radeon_renderbuffer(fb->Attachment[att_index].Renderbuffer); ++ else ++ return NULL; ++} ++ ++static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa) ++{ ++ struct radeon_renderbuffer *rrb; ++ rrb = rmesa->state.depth.rrb; ++ if (!rrb) ++ return NULL; ++ ++ return rrb; ++} ++ ++static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa) ++{ ++ struct radeon_renderbuffer *rrb; ++ ++ rrb = rmesa->state.color.rrb; ++ if (!rrb) ++ return NULL; ++ return rrb; ++} ++ ++#include "radeon_cmdbuf.h" ++ ++ ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c +new file mode 100644 +index 0000000..ba74c97 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c +@@ -0,0 +1,623 @@ ++/************************************************************************** ++ ++Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and ++ VA Linux Systems Inc., Fremont, California. ++Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. ++ ++The Weather Channel (TM) funded Tungsten Graphics to develop the ++initial release of the Radeon 8500 driver under the XFree86 license. ++This notice must be preserved. ++ ++All Rights Reserved. ++ ++Permission is hereby granted, free of charge, to any person obtaining ++a copy of this software and associated documentation files (the ++"Software"), to deal in the Software without restriction, including ++without limitation the rights to use, copy, modify, merge, publish, ++distribute, sublicense, and/or sell copies of the Software, and to ++permit persons to whom the Software is furnished to do so, subject to ++the following conditions: ++ ++The above copyright notice and this permission notice (including the ++next paragraph) shall be included in all copies or substantial ++portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ ++**************************************************************************/ ++ ++#include "radeon_common.h" ++#include "xmlpool.h" /* for symbolic values of enum-type options */ ++#include "utils.h" ++#include "vblank.h" ++#include "drirenderbuffer.h" ++#include "main/context.h" ++#include "main/framebuffer.h" ++#include "main/state.h" ++#include "main/simple_list.h" ++#include "swrast/swrast.h" ++#include "swrast_setup/swrast_setup.h" ++#include "tnl/tnl.h" ++ ++#define DRIVER_DATE "20090101" ++ ++#ifndef RADEON_DEBUG ++int RADEON_DEBUG = (0); ++#endif ++ ++/* Return various strings for glGetString(). ++ */ ++static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) ++{ ++ radeonContextPtr radeon = RADEON_CONTEXT(ctx); ++ static char buffer[128]; ++ ++ switch (name) { ++ case GL_VENDOR: ++ if (IS_R300_CLASS(radeon->radeonScreen)) ++ return (GLubyte *) "DRI R300 Project"; ++ else ++ return (GLubyte *) "Tungsten Graphics, Inc."; ++ ++ case GL_RENDERER: ++ { ++ unsigned offset; ++ GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : ++ radeon->radeonScreen->AGPMode; ++ const char* chipname; ++ ++ if (IS_R300_CLASS(radeon->radeonScreen)) ++ chipname = "R300"; ++ else if (IS_R200_CLASS(radeon->radeonScreen)) ++ chipname = "R200"; ++ else ++ chipname = "R100"; ++ ++ offset = driGetRendererString(buffer, chipname, DRIVER_DATE, ++ agp_mode); ++ ++ if (IS_R300_CLASS(radeon->radeonScreen)) { ++ sprintf(&buffer[offset], " %sTCL", ++ (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) ++ ? "" : "NO-"); ++ } else { ++ sprintf(&buffer[offset], " %sTCL", ++ !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) ++ ? "" : "NO-"); ++ } ++ ++ if (radeon->radeonScreen->driScreen->dri2.enabled) ++ strcat(buffer, " DRI2"); ++ ++ return (GLubyte *) buffer; ++ } ++ ++ default: ++ return NULL; ++ } ++} ++ ++/* Initialize the driver's misc functions. ++ */ ++static void radeonInitDriverFuncs(struct dd_function_table *functions) ++{ ++ functions->GetString = radeonGetString; ++} ++ ++/** ++ * Create and initialize all common fields of the context, ++ * including the Mesa context itself. ++ */ ++GLboolean radeonInitContext(radeonContextPtr radeon, ++ struct dd_function_table* functions, ++ const __GLcontextModes * glVisual, ++ __DRIcontextPrivate * driContextPriv, ++ void *sharedContextPrivate) ++{ ++ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; ++ radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); ++ GLcontext* ctx; ++ GLcontext* shareCtx; ++ int fthrottle_mode; ++ ++ /* Fill in additional standard functions. */ ++ radeonInitDriverFuncs(functions); ++ ++ radeon->radeonScreen = screen; ++ /* Allocate and initialize the Mesa context */ ++ if (sharedContextPrivate) ++ shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx; ++ else ++ shareCtx = NULL; ++ radeon->glCtx = _mesa_create_context(glVisual, shareCtx, ++ functions, (void *)radeon); ++ if (!radeon->glCtx) ++ return GL_FALSE; ++ ++ ctx = radeon->glCtx; ++ driContextPriv->driverPrivate = radeon; ++ ++ /* DRI fields */ ++ radeon->dri.context = driContextPriv; ++ radeon->dri.screen = sPriv; ++ radeon->dri.drawable = NULL; ++ radeon->dri.readable = NULL; ++ radeon->dri.hwContext = driContextPriv->hHWContext; ++ radeon->dri.hwLock = &sPriv->pSAREA->lock; ++ radeon->dri.fd = sPriv->fd; ++ radeon->dri.drmMinor = sPriv->drm_version.minor; ++ ++ radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + ++ screen->sarea_priv_offset); ++ ++ /* Setup IRQs */ ++ fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); ++ radeon->iw.irq_seq = -1; ++ radeon->irqsEmitted = 0; ++ radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && ++ radeon->radeonScreen->irq); ++ ++ radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); ++ ++ if (!radeon->do_irqs) ++ fprintf(stderr, ++ "IRQ's not enabled, falling back to %s: %d %d\n", ++ radeon->do_usleeps ? "usleeps" : "busy waits", ++ fthrottle_mode, radeon->radeonScreen->irq); ++ ++ radeon->texture_depth = driQueryOptioni (&radeon->optionCache, ++ "texture_depth"); ++ if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) ++ radeon->texture_depth = ( glVisual->rgbBits > 16 ) ? ++ DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; ++ ++ return GL_TRUE; ++} ++ ++ ++ ++/** ++ * Destroy the command buffer and state atoms. ++ */ ++static void radeon_destroy_atom_list(radeonContextPtr radeon) ++{ ++ struct radeon_state_atom *atom; ++ ++ foreach(atom, &radeon->hw.atomlist) { ++ FREE(atom->cmd); ++ if (atom->lastcmd) ++ FREE(atom->lastcmd); ++ } ++ ++} ++ ++/** ++ * Cleanup common context fields. ++ * Called by r200DestroyContext/r300DestroyContext ++ */ ++void radeonDestroyContext(__DRIcontextPrivate *driContextPriv ) ++{ ++#ifdef RADEON_BO_TRACK ++ FILE *track; ++#endif ++ GET_CURRENT_CONTEXT(ctx); ++ radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; ++ radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL; ++ ++ if (radeon == current) { ++ radeon_firevertices(radeon); ++ _mesa_make_current(NULL, NULL, NULL); ++ } ++ ++ assert(radeon); ++ if (radeon) { ++ ++ if (radeon->dma.current) { ++ rcommonFlushCmdBuf( radeon, __FUNCTION__ ); ++ } ++ ++ radeonReleaseArrays(radeon->glCtx, ~0); ++ ++ if (radeon->vtbl.free_context) ++ radeon->vtbl.free_context(radeon->glCtx); ++ _swsetup_DestroyContext( radeon->glCtx ); ++ _tnl_DestroyContext( radeon->glCtx ); ++ _vbo_DestroyContext( radeon->glCtx ); ++ _swrast_DestroyContext( radeon->glCtx ); ++ ++ radeonDestroyBuffer(radeon->dri.drawable); ++ radeonDestroyBuffer(radeon->dri.readable); ++ ++ /* free atom list */ ++ /* free the Mesa context */ ++ _mesa_destroy_context(radeon->glCtx); ++ ++ /* _mesa_destroy_context() might result in calls to functions that ++ * depend on the DriverCtx, so don't set it to NULL before. ++ * ++ * radeon->glCtx->DriverCtx = NULL; ++ */ ++ /* free the option cache */ ++ driDestroyOptionCache(&radeon->optionCache); ++ ++ rcommonDestroyCmdBuf(radeon); ++ ++ radeon_destroy_atom_list(radeon); ++ ++ if (radeon->state.scissor.pClipRects) { ++ FREE(radeon->state.scissor.pClipRects); ++ radeon->state.scissor.pClipRects = 0; ++ } ++ } ++#ifdef RADEON_BO_TRACK ++ track = fopen("/tmp/tracklog", "w"); ++ if (track) { ++ radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track); ++ fclose(track); ++ } ++#endif ++ FREE(radeon); ++} ++ ++/* Force the context `c' to be unbound from its buffer. ++ */ ++GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) ++{ ++ radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; ++ ++ if (RADEON_DEBUG & DEBUG_DRI) ++ fprintf(stderr, "%s ctx %p\n", __FUNCTION__, ++ radeon->glCtx); ++ ++ return GL_TRUE; ++} ++ ++ ++static void ++radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, ++ struct radeon_framebuffer *draw) ++{ ++ /* if radeon->fake */ ++ struct radeon_renderbuffer *rb; ++ ++ if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->frontOffset, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; ++ } ++ if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->backOffset, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; ++ } ++ if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->depthOffset, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; ++ } ++ if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->depthOffset, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; ++ } ++} ++ ++static void ++radeon_make_renderbuffer_current(radeonContextPtr radeon, ++ struct radeon_framebuffer *draw) ++{ ++ int size = 4096*4096*4; ++ /* if radeon->fake */ ++ struct radeon_renderbuffer *rb; ++ ++ if (radeon->radeonScreen->kernel_mm) { ++ radeon_make_kernel_renderbuffer_current(radeon, draw); ++ return; ++ } ++ ++ ++ if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->frontOffset + ++ radeon->radeonScreen->fbLocation, ++ size, ++ 4096, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; ++ } ++ if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->backOffset + ++ radeon->radeonScreen->fbLocation, ++ size, ++ 4096, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; ++ } ++ if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->depthOffset + ++ radeon->radeonScreen->fbLocation, ++ size, ++ 4096, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; ++ } ++ if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->depthOffset + ++ radeon->radeonScreen->fbLocation, ++ size, ++ 4096, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; ++ } ++} ++ ++ ++void ++radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) ++{ ++ unsigned int attachments[10]; ++ __DRIbuffer *buffers; ++ __DRIscreen *screen; ++ struct radeon_renderbuffer *rb; ++ int i, count; ++ struct radeon_framebuffer *draw; ++ radeonContextPtr radeon; ++ char *regname; ++ struct radeon_bo *depth_bo = NULL, *bo; ++ ++ if (RADEON_DEBUG & DEBUG_DRI) ++ fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); ++ ++ draw = drawable->driverPrivate; ++ screen = context->driScreenPriv; ++ radeon = (radeonContextPtr) context->driverPrivate; ++ i = 0; ++ if (draw->color_rb[0]) ++ attachments[i++] = __DRI_BUFFER_FRONT_LEFT; ++ if (draw->color_rb[1]) ++ attachments[i++] = __DRI_BUFFER_BACK_LEFT; ++ if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH)) ++ attachments[i++] = __DRI_BUFFER_DEPTH; ++ if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL)) ++ attachments[i++] = __DRI_BUFFER_STENCIL; ++ ++ buffers = (*screen->dri2.loader->getBuffers)(drawable, ++ &drawable->w, ++ &drawable->h, ++ attachments, i, ++ &count, ++ drawable->loaderPrivate); ++ if (buffers == NULL) ++ return; ++ ++ /* set one cliprect to cover the whole drawable */ ++ drawable->x = 0; ++ drawable->y = 0; ++ drawable->backX = 0; ++ drawable->backY = 0; ++ drawable->numClipRects = 1; ++ drawable->pClipRects[0].x1 = 0; ++ drawable->pClipRects[0].y1 = 0; ++ drawable->pClipRects[0].x2 = drawable->w; ++ drawable->pClipRects[0].y2 = drawable->h; ++ drawable->numBackClipRects = 1; ++ drawable->pBackClipRects[0].x1 = 0; ++ drawable->pBackClipRects[0].y1 = 0; ++ drawable->pBackClipRects[0].x2 = drawable->w; ++ drawable->pBackClipRects[0].y2 = drawable->h; ++ for (i = 0; i < count; i++) { ++ switch (buffers[i].attachment) { ++ case __DRI_BUFFER_FRONT_LEFT: ++ rb = draw->color_rb[0]; ++ regname = "dri2 front buffer"; ++ break; ++ case __DRI_BUFFER_BACK_LEFT: ++ rb = draw->color_rb[1]; ++ regname = "dri2 back buffer"; ++ break; ++ case __DRI_BUFFER_DEPTH: ++ rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); ++ regname = "dri2 depth buffer"; ++ break; ++ case __DRI_BUFFER_STENCIL: ++ rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); ++ regname = "dri2 stencil buffer"; ++ break; ++ case __DRI_BUFFER_ACCUM: ++ default: ++ fprintf(stderr, ++ "unhandled buffer attach event, attacment type %d\n", ++ buffers[i].attachment); ++ return; ++ } ++ ++ if (rb == NULL) ++ continue; ++ ++ if (rb->bo) { ++ uint32_t name = radeon_gem_name_bo(rb->bo); ++ if (name == buffers[i].name) ++ continue; ++ } ++ ++ if (RADEON_DEBUG & DEBUG_DRI) ++ fprintf(stderr, ++ "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n", ++ regname, buffers[i].name, buffers[i].attachment, ++ buffers[i].cpp, buffers[i].pitch); ++ ++ rb->cpp = buffers[i].cpp; ++ rb->pitch = buffers[i].pitch; ++ rb->width = drawable->w; ++ rb->height = drawable->h; ++ rb->has_surface = 0; ++ ++ if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) { ++ if (RADEON_DEBUG & DEBUG_DRI) ++ fprintf(stderr, "(reusing depth buffer as stencil)\n"); ++ bo = depth_bo; ++ radeon_bo_ref(bo); ++ } else { ++ bo = radeon_bo_open(radeon->radeonScreen->bom, ++ buffers[i].name, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ buffers[i].flags); ++ if (bo == NULL) { ++ ++ fprintf(stderr, "failed to attach %s %d\n", ++ regname, buffers[i].name); ++ ++ } ++ } ++ ++ if (buffers[i].attachment == __DRI_BUFFER_DEPTH) { ++ if (draw->base.Visual.depthBits == 16) ++ rb->cpp = 2; ++ depth_bo = bo; ++ } ++ ++ radeon_renderbuffer_set_bo(rb, bo); ++ radeon_bo_unref(bo); ++ ++ } ++ ++ driUpdateFramebufferSize(radeon->glCtx, drawable); ++} ++ ++/* Force the context `c' to be the current context and associate with it ++ * buffer `b'. ++ */ ++GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, ++ __DRIdrawablePrivate * driDrawPriv, ++ __DRIdrawablePrivate * driReadPriv) ++{ ++ radeonContextPtr radeon; ++ struct radeon_framebuffer *drfb; ++ struct gl_framebuffer *readfb; ++ ++ if (!driContextPriv) { ++ if (RADEON_DEBUG & DEBUG_DRI) ++ fprintf(stderr, "%s ctx is null\n", __FUNCTION__); ++ _mesa_make_current(NULL, NULL, NULL); ++ return GL_TRUE; ++ } ++ ++ radeon = (radeonContextPtr) driContextPriv->driverPrivate; ++ drfb = driDrawPriv->driverPrivate; ++ readfb = driReadPriv->driverPrivate; ++ ++ if (driContextPriv->driScreenPriv->dri2.enabled) { ++ radeon_update_renderbuffers(driContextPriv, driDrawPriv); ++ if (driDrawPriv != driReadPriv) ++ radeon_update_renderbuffers(driContextPriv, driReadPriv); ++ radeon->state.color.rrb = ++ radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT); ++ radeon->state.depth.rrb = ++ radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH); ++ } else { ++ radeon_make_renderbuffer_current(radeon, drfb); ++ } ++ ++ ++ if (RADEON_DEBUG & DEBUG_DRI) ++ fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb); ++ ++ if (radeon->dri.readable != driReadPriv) ++ radeon->dri.readable = driReadPriv; ++ ++ driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); ++ if (driReadPriv != driDrawPriv) ++ driUpdateFramebufferSize(radeon->glCtx, driReadPriv); ++ ++ _mesa_make_current(radeon->glCtx, &drfb->base, readfb); ++ ++ _mesa_update_state(radeon->glCtx); ++ ++ if (radeon->glCtx->DrawBuffer == &drfb->base) { ++ ++ if (radeon->dri.drawable != driDrawPriv) { ++ if (driDrawPriv->swap_interval == (unsigned)-1) { ++ int i; ++ driDrawPriv->vblFlags = ++ (radeon->radeonScreen->irq != 0) ++ ? driGetDefaultVBlankFlags(&radeon-> ++ optionCache) ++ : VBLANK_FLAG_NO_IRQ; ++ ++ driDrawableInitVBlank(driDrawPriv); ++ drfb->vbl_waited = driDrawPriv->vblSeq; ++ ++ for (i = 0; i < 2; i++) { ++ if (drfb->color_rb[i]) ++ drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq; ++ } ++ ++ } ++ radeon->dri.drawable = driDrawPriv; ++ ++ radeon_window_moved(radeon); ++ } ++ radeon_draw_buffer(radeon->glCtx, &drfb->base); ++ } ++ ++ ++ if (RADEON_DEBUG & DEBUG_DRI) ++ fprintf(stderr, "End %s\n", __FUNCTION__); ++ return GL_TRUE; ++} ++ +diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h +new file mode 100644 +index 0000000..d32e5af +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h +@@ -0,0 +1,563 @@ ++ ++#ifndef COMMON_CONTEXT_H ++#define COMMON_CONTEXT_H ++ ++#include "main/mm.h" ++#include "math/m_vector.h" ++#include "texmem.h" ++#include "tnl/t_context.h" ++#include "main/colormac.h" ++ ++#include "radeon_screen.h" ++#include "radeon_drm.h" ++#include "dri_util.h" ++#include "tnl/t_vertex.h" ++ ++struct radeon_context; ++ ++#include "radeon_bocs_wrapper.h" ++ ++/* This union is used to avoid warnings/miscompilation ++ with float to uint32_t casts due to strict-aliasing */ ++typedef union { GLfloat f; uint32_t ui32; } float_ui32_type; ++ ++struct radeon_context; ++typedef struct radeon_context radeonContextRec; ++typedef struct radeon_context *radeonContextPtr; ++ ++ ++#define TEX_0 0x1 ++#define TEX_1 0x2 ++#define TEX_2 0x4 ++#define TEX_3 0x8 ++#define TEX_4 0x10 ++#define TEX_5 0x20 ++ ++/* Rasterizing fallbacks */ ++/* See correponding strings in r200_swtcl.c */ ++#define RADEON_FALLBACK_TEXTURE 0x0001 ++#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 ++#define RADEON_FALLBACK_STENCIL 0x0004 ++#define RADEON_FALLBACK_RENDER_MODE 0x0008 ++#define RADEON_FALLBACK_BLEND_EQ 0x0010 ++#define RADEON_FALLBACK_BLEND_FUNC 0x0020 ++#define RADEON_FALLBACK_DISABLE 0x0040 ++#define RADEON_FALLBACK_BORDER_MODE 0x0080 ++#define RADEON_FALLBACK_DEPTH_BUFFER 0x0100 ++#define RADEON_FALLBACK_STENCIL_BUFFER 0x0200 ++ ++#define R200_FALLBACK_TEXTURE 0x01 ++#define R200_FALLBACK_DRAW_BUFFER 0x02 ++#define R200_FALLBACK_STENCIL 0x04 ++#define R200_FALLBACK_RENDER_MODE 0x08 ++#define R200_FALLBACK_DISABLE 0x10 ++#define R200_FALLBACK_BORDER_MODE 0x20 ++ ++#define RADEON_TCL_FALLBACK_RASTER 0x1 /* rasterization */ ++#define RADEON_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */ ++#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */ ++#define RADEON_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */ ++#define RADEON_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */ ++#define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */ ++#define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */ ++#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */ ++#define RADEON_TCL_FALLBACK_FOGCOORDSPEC 0x100 /* fogcoord, sep. spec light */ ++ ++/* The blit width for texture uploads ++ */ ++#define BLIT_WIDTH_BYTES 1024 ++ ++/* Use the templated vertex format: ++ */ ++#define COLOR_IS_RGBA ++#define TAG(x) radeon##x ++#include "tnl_dd/t_dd_vertex.h" ++#undef TAG ++ ++#define RADEON_RB_CLASS 0xdeadbeef ++ ++struct radeon_renderbuffer ++{ ++ struct gl_renderbuffer base; ++ struct radeon_bo *bo; ++ unsigned int cpp; ++ /* unsigned int offset; */ ++ unsigned int pitch; ++ unsigned int width; ++ unsigned int height; ++ ++ uint32_t draw_offset; /* FBO */ ++ /* boo Xorg 6.8.2 compat */ ++ int has_surface; ++ ++ GLuint pf_pending; /**< sequence number of pending flip */ ++ GLuint vbl_pending; /**< vblank sequence number of pending flip */ ++ __DRIdrawablePrivate *dPriv; ++}; ++ ++struct radeon_framebuffer ++{ ++ struct gl_framebuffer base; ++ ++ struct radeon_renderbuffer *color_rb[2]; ++ ++ GLuint vbl_waited; ++ ++ /* buffer swap */ ++ int64_t swap_ust; ++ int64_t swap_missed_ust; ++ ++ GLuint swap_count; ++ GLuint swap_missed_count; ++ ++ /* Drawable page flipping state */ ++ GLboolean pf_active; ++ GLint pf_current_page; ++ GLint pf_num_pages; ++ ++}; ++ ++ ++struct radeon_colorbuffer_state { ++ GLuint clear; ++ int roundEnable; ++ struct radeon_renderbuffer *rrb; ++ uint32_t draw_offset; /* offset into color renderbuffer - FBOs */ ++}; ++ ++struct radeon_depthbuffer_state { ++ GLuint clear; ++ struct radeon_renderbuffer *rrb; ++}; ++ ++struct radeon_scissor_state { ++ drm_clip_rect_t rect; ++ GLboolean enabled; ++ ++ GLuint numClipRects; /* Cliprects active */ ++ GLuint numAllocedClipRects; /* Cliprects available */ ++ drm_clip_rect_t *pClipRects; ++}; ++ ++struct radeon_stencilbuffer_state { ++ GLuint clear; /* rb3d_stencilrefmask value */ ++}; ++ ++struct radeon_stipple_state { ++ GLuint mask[32]; ++}; ++ ++struct radeon_state_atom { ++ struct radeon_state_atom *next, *prev; ++ const char *name; /* for debug */ ++ int cmd_size; /* size in bytes */ ++ GLuint idx; ++ GLuint is_tcl; ++ GLuint *cmd; /* one or more cmd's */ ++ GLuint *lastcmd; /* one or more cmd's */ ++ GLboolean dirty; /* dirty-mark in emit_state_list */ ++ int (*check) (GLcontext *, struct radeon_state_atom *atom); /* is this state active? */ ++ void (*emit) (GLcontext *, struct radeon_state_atom *atom); ++}; ++ ++struct radeon_hw_state { ++ /* Head of the linked list of state atoms. */ ++ struct radeon_state_atom atomlist; ++ int max_state_size; /* Number of bytes necessary for a full state emit. */ ++ GLboolean is_dirty, all_dirty; ++}; ++ ++ ++/* Texture related */ ++typedef struct _radeon_texture_image radeon_texture_image; ++ ++struct _radeon_texture_image { ++ struct gl_texture_image base; ++ ++ /** ++ * If mt != 0, the image is stored in hardware format in the ++ * given mipmap tree. In this case, base.Data may point into the ++ * mapping of the buffer object that contains the mipmap tree. ++ * ++ * If mt == 0, the image is stored in normal memory pointed to ++ * by base.Data. ++ */ ++ struct _radeon_mipmap_tree *mt; ++ struct radeon_bo *bo; ++ ++ int mtlevel; /** if mt != 0, this is the image's level in the mipmap tree */ ++ int mtface; /** if mt != 0, this is the image's face in the mipmap tree */ ++}; ++ ++ ++static INLINE radeon_texture_image *get_radeon_texture_image(struct gl_texture_image *image) ++{ ++ return (radeon_texture_image*)image; ++} ++ ++ ++typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; ++ ++#define RADEON_TXO_MICRO_TILE (1 << 3) ++ ++/* Texture object in locally shared texture space. ++ */ ++struct radeon_tex_obj { ++ struct gl_texture_object base; ++ struct _radeon_mipmap_tree *mt; ++ ++ /** ++ * This is true if we've verified that the mipmap tree above is complete ++ * and so on. ++ */ ++ GLboolean validated; ++ ++ GLuint override_offset; ++ GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ ++ GLuint tile_bits; /* hw texture tile bits used on this texture */ ++ struct radeon_bo *bo; ++ ++ GLuint pp_txfilter; /* hardware register values */ ++ GLuint pp_txformat; ++ GLuint pp_txformat_x; ++ GLuint pp_txsize; /* npot only */ ++ GLuint pp_txpitch; /* npot only */ ++ GLuint pp_border_color; ++ GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ ++ ++ GLuint pp_txfilter_1; /* r300 */ ++ ++ GLboolean border_fallback; ++ ++ ++}; ++ ++static INLINE radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj) ++{ ++ return (radeonTexObj*)texObj; ++} ++ ++/* Need refcounting on dma buffers: ++ */ ++struct radeon_dma_buffer { ++ int refcount; /* the number of retained regions in buf */ ++ drmBufPtr buf; ++}; ++ ++struct radeon_aos { ++ struct radeon_bo *bo; /** Buffer object where vertex data is stored */ ++ int offset; /** Offset into buffer object, in bytes */ ++ int components; /** Number of components per vertex */ ++ int stride; /** Stride in dwords (may be 0 for repeating) */ ++ int count; /** Number of vertices */ ++}; ++ ++struct radeon_dma { ++ /* Active dma region. Allocations for vertices and retained ++ * regions come from here. Also used for emitting random vertices, ++ * these may be flushed by calling flush_current(); ++ */ ++ struct radeon_bo *current; /** Buffer that DMA memory is allocated from */ ++ int current_used; /** Number of bytes allocated and forgotten about */ ++ int current_vertexptr; /** End of active vertex region */ ++ ++ /** ++ * If current_vertexptr != current_used then flush must be non-zero. ++ * flush must be called before non-active vertex allocations can be ++ * performed. ++ */ ++ void (*flush) (GLcontext *); ++ ++ /* Number of "in-flight" DMA buffers, i.e. the number of buffers ++ * for which a DISCARD command is currently queued in the command buffer ++. ++ */ ++ GLuint nr_released_bufs; ++}; ++ ++/* radeon_swtcl.c ++ */ ++struct radeon_swtcl_info { ++ ++ GLuint RenderIndex; ++ GLuint vertex_size; ++ GLubyte *verts; ++ ++ /* Fallback rasterization functions ++ */ ++ GLuint hw_primitive; ++ GLenum render_primitive; ++ GLuint numverts; ++ ++ struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; ++ GLuint vertex_attr_count; ++ ++}; ++ ++#define RADEON_MAX_AOS_ARRAYS 16 ++struct radeon_tcl_info { ++ struct radeon_aos aos[RADEON_MAX_AOS_ARRAYS]; ++ GLuint aos_count; ++ struct radeon_bo *elt_dma_bo; /** Buffer object that contains element indices */ ++ int elt_dma_offset; /** Offset into this buffer object, in bytes */ ++}; ++ ++struct radeon_ioctl { ++ GLuint vertex_offset; ++ struct radeon_bo *bo; ++ GLuint vertex_size; ++}; ++ ++#define RADEON_MAX_PRIMS 64 ++ ++struct radeon_prim { ++ GLuint start; ++ GLuint end; ++ GLuint prim; ++}; ++ ++static INLINE GLuint radeonPackColor(GLuint cpp, ++ GLubyte r, GLubyte g, ++ GLubyte b, GLubyte a) ++{ ++ switch (cpp) { ++ case 2: ++ return PACK_COLOR_565(r, g, b); ++ case 4: ++ return PACK_COLOR_8888(a, r, g, b); ++ default: ++ return 0; ++ } ++} ++ ++#define MAX_CMD_BUF_SZ (16*1024) ++ ++#define MAX_DMA_BUF_SZ (64*1024) ++ ++struct radeon_store { ++ GLuint statenr; ++ GLuint primnr; ++ char cmd_buf[MAX_CMD_BUF_SZ]; ++ int cmd_used; ++ int elts_start; ++}; ++ ++struct radeon_dri_mirror { ++ __DRIcontextPrivate *context; /* DRI context */ ++ __DRIscreenPrivate *screen; /* DRI screen */ ++ ++ /** ++ * DRI drawable bound to this context for drawing. ++ */ ++ __DRIdrawablePrivate *drawable; ++ ++ /** ++ * DRI drawable bound to this context for reading. ++ */ ++ __DRIdrawablePrivate *readable; ++ ++ drm_context_t hwContext; ++ drm_hw_lock_t *hwLock; ++ int fd; ++ int drmMinor; ++}; ++ ++#define DEBUG_TEXTURE 0x001 ++#define DEBUG_STATE 0x002 ++#define DEBUG_IOCTL 0x004 ++#define DEBUG_PRIMS 0x008 ++#define DEBUG_VERTS 0x010 ++#define DEBUG_FALLBACKS 0x020 ++#define DEBUG_VFMT 0x040 ++#define DEBUG_CODEGEN 0x080 ++#define DEBUG_VERBOSE 0x100 ++#define DEBUG_DRI 0x200 ++#define DEBUG_DMA 0x400 ++#define DEBUG_SANITY 0x800 ++#define DEBUG_SYNC 0x1000 ++#define DEBUG_PIXEL 0x2000 ++#define DEBUG_MEMORY 0x4000 ++ ++ ++typedef void (*radeon_tri_func) (radeonContextPtr, ++ radeonVertex *, ++ radeonVertex *, radeonVertex *); ++ ++typedef void (*radeon_line_func) (radeonContextPtr, ++ radeonVertex *, radeonVertex *); ++ ++typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *); ++ ++#define RADEON_MAX_BOS 24 ++struct radeon_state { ++ struct radeon_colorbuffer_state color; ++ struct radeon_depthbuffer_state depth; ++ struct radeon_scissor_state scissor; ++ struct radeon_stencilbuffer_state stencil; ++ ++ struct radeon_cs_space_check bos[RADEON_MAX_BOS]; ++ int validated_bo_count; ++}; ++ ++/** ++ * This structure holds the command buffer while it is being constructed. ++ * ++ * The first batch of commands in the buffer is always the state that needs ++ * to be re-emitted when the context is lost. This batch can be skipped ++ * otherwise. ++ */ ++struct radeon_cmdbuf { ++ struct radeon_cs_manager *csm; ++ struct radeon_cs *cs; ++ int size; /** # of dwords total */ ++ unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */ ++}; ++ ++struct radeon_context { ++ GLcontext *glCtx; ++ radeonScreenPtr radeonScreen; /* Screen private DRI data */ ++ ++ /* Texture object bookkeeping ++ */ ++ int texture_depth; ++ float initialMaxAnisotropy; ++ ++ struct radeon_dma dma; ++ struct radeon_hw_state hw; ++ /* Rasterization and vertex state: ++ */ ++ GLuint TclFallback; ++ GLuint Fallback; ++ GLuint NewGLState; ++ DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ ++ ++ /* Drawable, cliprect and scissor information */ ++ GLuint numClipRects; /* Cliprects for the draw buffer */ ++ drm_clip_rect_t *pClipRects; ++ unsigned int lastStamp; ++ GLboolean lost_context; ++ drm_radeon_sarea_t *sarea; /* Private SAREA data */ ++ ++ /* Mirrors of some DRI state */ ++ struct radeon_dri_mirror dri; ++ ++ /* Busy waiting */ ++ GLuint do_usleeps; ++ GLuint do_irqs; ++ GLuint irqsEmitted; ++ drm_radeon_irq_wait_t iw; ++ ++ /* Derived state - for r300 only */ ++ struct radeon_state state; ++ ++ struct radeon_swtcl_info swtcl; ++ struct radeon_tcl_info tcl; ++ /* Configuration cache ++ */ ++ driOptionCache optionCache; ++ ++ struct radeon_cmdbuf cmdbuf; ++ ++ drm_clip_rect_t fboRect; ++ GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */ ++ GLboolean front_cliprects; ++ ++ struct { ++ struct gl_fragment_program *bitmap_fp; ++ struct gl_vertex_program *passthrough_vp; ++ ++ struct gl_fragment_program *saved_fp; ++ GLboolean saved_fp_enable; ++ struct gl_vertex_program *saved_vp; ++ GLboolean saved_vp_enable; ++ ++ GLint saved_vp_x, saved_vp_y; ++ GLsizei saved_vp_width, saved_vp_height; ++ GLenum saved_matrix_mode; ++ } meta; ++ ++ struct { ++ void (*get_lock)(radeonContextPtr radeon); ++ void (*update_viewport_offset)(GLcontext *ctx); ++ void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa); ++ void (*swtcl_flush)(GLcontext *ctx, uint32_t offset); ++ void (*pre_emit_atoms)(radeonContextPtr rmesa); ++ void (*pre_emit_state)(radeonContextPtr rmesa); ++ void (*fallback)(GLcontext *ctx, GLuint bit, GLboolean mode); ++ void (*free_context)(GLcontext *ctx); ++ } vtbl; ++}; ++ ++#define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx)) ++ ++/** ++ * This function takes a float and packs it into a uint32_t ++ */ ++static INLINE uint32_t radeonPackFloat32(float fl) ++{ ++ union { ++ float fl; ++ uint32_t u; ++ } u; ++ ++ u.fl = fl; ++ return u.u; ++} ++ ++/* This is probably wrong for some values, I need to test this ++ * some more. Range checking would be a good idea also.. ++ * ++ * But it works for most things. I'll fix it later if someone ++ * else with a better clue doesn't ++ */ ++static INLINE uint32_t radeonPackFloat24(float f) ++{ ++ float mantissa; ++ int exponent; ++ uint32_t float24 = 0; ++ ++ if (f == 0.0) ++ return 0; ++ ++ mantissa = frexpf(f, &exponent); ++ ++ /* Handle -ve */ ++ if (mantissa < 0) { ++ float24 |= (1 << 23); ++ mantissa = mantissa * -1.0; ++ } ++ /* Handle exponent, bias of 63 */ ++ exponent += 62; ++ float24 |= (exponent << 16); ++ /* Kill 7 LSB of mantissa */ ++ float24 |= (radeonPackFloat32(mantissa) & 0x7FFFFF) >> 7; ++ ++ return float24; ++} ++ ++GLboolean radeonInitContext(radeonContextPtr radeon, ++ struct dd_function_table* functions, ++ const __GLcontextModes * glVisual, ++ __DRIcontextPrivate * driContextPriv, ++ void *sharedContextPrivate); ++ ++void radeonCleanupContext(radeonContextPtr radeon); ++GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); ++void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); ++GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, ++ __DRIdrawablePrivate * driDrawPriv, ++ __DRIdrawablePrivate * driReadPriv); ++extern void radeonDestroyContext(__DRIcontextPrivate * driContextPriv); ++ ++/* ================================================================ ++ * Debugging: ++ */ ++#define DO_DEBUG 1 ++ ++#if DO_DEBUG ++extern int RADEON_DEBUG; ++#else ++#define RADEON_DEBUG 0 ++#endif ++ ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_compat.c b/src/mesa/drivers/dri/radeon/radeon_compat.c +deleted file mode 100644 +index 46b490d..0000000 +--- a/src/mesa/drivers/dri/radeon/radeon_compat.c ++++ /dev/null +@@ -1,301 +0,0 @@ +-/************************************************************************** +- +-Copyright 2002 ATI Technologies Inc., Ontario, Canada, and +- Tungsten Graphics Inc., Austin, Texas. +- +-All Rights Reserved. +- +-Permission is hereby granted, free of charge, to any person obtaining a +-copy of this software and associated documentation files (the "Software"), +-to deal in the Software without restriction, including without limitation +-on the rights to use, copy, modify, merge, publish, distribute, sub +-license, and/or sell copies of the Software, and to permit persons to whom +-the Software is furnished to do so, subject to the following conditions: +- +-The above copyright notice and this permission notice (including the next +-paragraph) shall be included in all copies or substantial portions of the +-Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +-ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +-USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Keith Whitwell +- * +- */ +- +-#include "main/glheader.h" +-#include "main/imports.h" +- +-#include "radeon_context.h" +-#include "radeon_state.h" +-#include "radeon_ioctl.h" +- +- +-static struct { +- int start; +- int len; +- const char *name; +-} packet[RADEON_MAX_STATE_PACKETS] = { +- { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, +- { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, +- { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, +- { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, +- { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, +- { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, +- { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, +- { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, +- { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, +- { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, +- { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, +- { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, +- { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, +- { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, +- { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, +- { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, +- { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, +- { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, +- { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, +- { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, +- { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, +-}; +- +- +-static void radeonCompatEmitPacket( radeonContextPtr rmesa, +- struct radeon_state_atom *state ) +-{ +- drm_radeon_sarea_t *sarea = rmesa->sarea; +- drm_radeon_context_regs_t *ctx = &sarea->context_state; +- drm_radeon_texture_regs_t *tex0 = &sarea->tex_state[0]; +- drm_radeon_texture_regs_t *tex1 = &sarea->tex_state[1]; +- int i; +- int *buf = state->cmd; +- +- for ( i = 0 ; i < state->cmd_size ; ) { +- drm_radeon_cmd_header_t *header = (drm_radeon_cmd_header_t *)&buf[i++]; +- +- if (RADEON_DEBUG & DEBUG_STATE) +- fprintf(stderr, "%s %d: %s\n", __FUNCTION__, header->packet.packet_id, +- packet[(int)header->packet.packet_id].name); +- +- switch (header->packet.packet_id) { +- case RADEON_EMIT_PP_MISC: +- ctx->pp_misc = buf[i++]; +- ctx->pp_fog_color = buf[i++]; +- ctx->re_solid_color = buf[i++]; +- ctx->rb3d_blendcntl = buf[i++]; +- ctx->rb3d_depthoffset = buf[i++]; +- ctx->rb3d_depthpitch = buf[i++]; +- ctx->rb3d_zstencilcntl = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_CONTEXT; +- break; +- case RADEON_EMIT_PP_CNTL: +- ctx->pp_cntl = buf[i++]; +- ctx->rb3d_cntl = buf[i++]; +- ctx->rb3d_coloroffset = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_CONTEXT; +- break; +- case RADEON_EMIT_RB3D_COLORPITCH: +- ctx->rb3d_colorpitch = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_CONTEXT; +- break; +- case RADEON_EMIT_RE_LINE_PATTERN: +- ctx->re_line_pattern = buf[i++]; +- ctx->re_line_state = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_LINE; +- break; +- case RADEON_EMIT_SE_LINE_WIDTH: +- ctx->se_line_width = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_LINE; +- break; +- case RADEON_EMIT_PP_LUM_MATRIX: +- ctx->pp_lum_matrix = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_BUMPMAP; +- break; +- case RADEON_EMIT_PP_ROT_MATRIX_0: +- ctx->pp_rot_matrix_0 = buf[i++]; +- ctx->pp_rot_matrix_1 = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_BUMPMAP; +- break; +- case RADEON_EMIT_RB3D_STENCILREFMASK: +- ctx->rb3d_stencilrefmask = buf[i++]; +- ctx->rb3d_ropcntl = buf[i++]; +- ctx->rb3d_planemask = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_MASKS; +- break; +- case RADEON_EMIT_SE_VPORT_XSCALE: +- ctx->se_vport_xscale = buf[i++]; +- ctx->se_vport_xoffset = buf[i++]; +- ctx->se_vport_yscale = buf[i++]; +- ctx->se_vport_yoffset = buf[i++]; +- ctx->se_vport_zscale = buf[i++]; +- ctx->se_vport_zoffset = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_VIEWPORT; +- break; +- case RADEON_EMIT_SE_CNTL: +- ctx->se_cntl = buf[i++]; +- ctx->se_coord_fmt = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_VERTFMT; +- break; +- case RADEON_EMIT_SE_CNTL_STATUS: +- ctx->se_cntl_status = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_SETUP; +- break; +- case RADEON_EMIT_RE_MISC: +- ctx->re_misc = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_MISC; +- break; +- case RADEON_EMIT_PP_TXFILTER_0: +- tex0->pp_txfilter = buf[i++]; +- tex0->pp_txformat = buf[i++]; +- tex0->pp_txoffset = buf[i++]; +- tex0->pp_txcblend = buf[i++]; +- tex0->pp_txablend = buf[i++]; +- tex0->pp_tfactor = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_TEX0; +- break; +- case RADEON_EMIT_PP_BORDER_COLOR_0: +- tex0->pp_border_color = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_TEX0; +- break; +- case RADEON_EMIT_PP_TXFILTER_1: +- tex1->pp_txfilter = buf[i++]; +- tex1->pp_txformat = buf[i++]; +- tex1->pp_txoffset = buf[i++]; +- tex1->pp_txcblend = buf[i++]; +- tex1->pp_txablend = buf[i++]; +- tex1->pp_tfactor = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_TEX1; +- break; +- case RADEON_EMIT_PP_BORDER_COLOR_1: +- tex1->pp_border_color = buf[i++]; +- sarea->dirty |= RADEON_UPLOAD_TEX1; +- break; +- +- case RADEON_EMIT_SE_ZBIAS_FACTOR: +- i++; +- i++; +- break; +- +- case RADEON_EMIT_PP_TXFILTER_2: +- case RADEON_EMIT_PP_BORDER_COLOR_2: +- case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT: +- case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED: +- default: +- /* These states aren't understood by radeon drm 1.1 */ +- fprintf(stderr, "Tried to emit unsupported state\n"); +- return; +- } +- } +-} +- +- +- +-static void radeonCompatEmitStateLocked( radeonContextPtr rmesa ) +-{ +- struct radeon_state_atom *atom; +- +- if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- if (!rmesa->hw.is_dirty && !rmesa->hw.all_dirty) +- return; +- +- foreach(atom, &rmesa->hw.atomlist) { +- if (rmesa->hw.all_dirty) +- atom->dirty = GL_TRUE; +- if (atom->is_tcl) +- atom->dirty = GL_FALSE; +- if (atom->dirty) +- radeonCompatEmitPacket(rmesa, atom); +- } +- +- rmesa->hw.is_dirty = GL_FALSE; +- rmesa->hw.all_dirty = GL_FALSE; +-} +- +- +-static void radeonCompatEmitPrimitiveLocked( radeonContextPtr rmesa, +- GLuint hw_primitive, +- GLuint nverts, +- drm_clip_rect_t *pbox, +- GLuint nbox ) +-{ +- int i; +- +- for ( i = 0 ; i < nbox ; ) { +- int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox ); +- drm_clip_rect_t *b = rmesa->sarea->boxes; +- drm_radeon_vertex_t vtx; +- +- rmesa->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS; +- rmesa->sarea->nbox = nr - i; +- +- for ( ; i < nr ; i++) +- *b++ = pbox[i]; +- +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, +- "RadeonFlushVertexBuffer: prim %x buf %d verts %d " +- "disc %d nbox %d\n", +- hw_primitive, +- rmesa->dma.current.buf->buf->idx, +- nverts, +- nr == nbox, +- rmesa->sarea->nbox ); +- +- vtx.prim = hw_primitive; +- vtx.idx = rmesa->dma.current.buf->buf->idx; +- vtx.count = nverts; +- vtx.discard = (nr == nbox); +- +- drmCommandWrite( rmesa->dri.fd, +- DRM_RADEON_VERTEX, +- &vtx, sizeof(vtx)); +- } +-} +- +- +- +-/* No 'start' for 1.1 vertices ioctl: only one vertex prim/buffer! +- */ +-void radeonCompatEmitPrimitive( radeonContextPtr rmesa, +- GLuint vertex_format, +- GLuint hw_primitive, +- GLuint nrverts ) +-{ +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- LOCK_HARDWARE( rmesa ); +- +- radeonCompatEmitStateLocked( rmesa ); +- rmesa->sarea->vc_format = vertex_format; +- +- if (rmesa->state.scissor.enabled) { +- radeonCompatEmitPrimitiveLocked( rmesa, +- hw_primitive, +- nrverts, +- rmesa->state.scissor.pClipRects, +- rmesa->state.scissor.numClipRects ); +- } +- else { +- radeonCompatEmitPrimitiveLocked( rmesa, +- hw_primitive, +- nrverts, +- rmesa->pClipRects, +- rmesa->numClipRects ); +- } +- +- +- UNLOCK_HARDWARE( rmesa ); +-} +- +diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c +index ea81a32..2600c78 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_context.c ++++ b/src/mesa/drivers/dri/radeon/radeon_context.c +@@ -53,6 +53,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #include "drivers/common/driverfuncs.h" + ++#include "radeon_common.h" + #include "radeon_context.h" + #include "radeon_ioctl.h" + #include "radeon_state.h" +@@ -65,6 +66,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define need_GL_EXT_blend_minmax + #define need_GL_EXT_fog_coord + #define need_GL_EXT_secondary_color ++#define need_GL_EXT_framebuffer_object + #include "extension_helper.h" + + #define DRIVER_DATE "20061018" +@@ -72,40 +74,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "vblank.h" + #include "utils.h" + #include "xmlpool.h" /* for symbolic values of enum-type options */ +-#ifndef RADEON_DEBUG +-int RADEON_DEBUG = (0); +-#endif +- +- +-/* Return various strings for glGetString(). +- */ +-static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- static char buffer[128]; +- unsigned offset; +- GLuint agp_mode = (rmesa->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : +- rmesa->radeonScreen->AGPMode; +- +- switch ( name ) { +- case GL_VENDOR: +- return (GLubyte *)"Tungsten Graphics, Inc."; +- +- case GL_RENDERER: +- offset = driGetRendererString( buffer, "Radeon", DRIVER_DATE, +- agp_mode ); +- +- sprintf( & buffer[ offset ], " %sTCL", +- !(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) +- ? "" : "NO-" ); +- +- return (GLubyte *)buffer; +- +- default: +- return NULL; +- } +-} +- + + /* Extension strings exported by the R100 driver. + */ +@@ -121,6 +89,7 @@ const struct dri_extension card_extensions[] = + { "GL_EXT_blend_logic_op", NULL }, + { "GL_EXT_blend_subtract", GL_EXT_blend_minmax_functions }, + { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, ++ { "GL_EXT_packed_depth_stencil", NULL}, + { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, + { "GL_EXT_stencil_wrap", NULL }, + { "GL_EXT_texture_edge_clamp", NULL }, +@@ -137,6 +106,11 @@ const struct dri_extension card_extensions[] = + { NULL, NULL } + }; + ++const struct dri_extension mm_extensions[] = { ++ { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, ++ { NULL, NULL } ++}; ++ + extern const struct tnl_pipeline_stage _radeon_render_stage; + extern const struct tnl_pipeline_stage _radeon_tcl_stage; + +@@ -160,15 +134,6 @@ static const struct tnl_pipeline_stage *radeon_pipeline[] = { + NULL, + }; + +- +- +-/* Initialize the driver's misc functions. +- */ +-static void radeonInitDriverFuncs( struct dd_function_table *functions ) +-{ +- functions->GetString = radeonGetString; +-} +- + static const struct dri_debug_control debug_control[] = + { + { "fall", DEBUG_FALLBACKS }, +@@ -188,19 +153,69 @@ static const struct dri_debug_control debug_control[] = + { NULL, 0 } + }; + ++static void r100_get_lock(radeonContextPtr radeon) ++{ ++ r100ContextPtr rmesa = (r100ContextPtr)radeon; ++ drm_radeon_sarea_t *sarea = radeon->sarea; ++ ++ RADEON_STATECHANGE(rmesa, ctx); ++ if (rmesa->radeon.sarea->tiling_enabled) { ++ rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= ++ RADEON_COLOR_TILE_ENABLE; ++ } else { ++ rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ++ ~RADEON_COLOR_TILE_ENABLE; ++ } ++ ++ if (sarea->ctx_owner != rmesa->radeon.dri.hwContext) { ++ sarea->ctx_owner = rmesa->radeon.dri.hwContext; ++ ++ if (!radeon->radeonScreen->kernel_mm) ++ radeon_bo_legacy_texture_age(radeon->radeonScreen->bom); ++ } ++} ++ ++static void r100_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa) ++{ ++} ++ ++static void r100_vtbl_pre_emit_state(radeonContextPtr radeon) ++{ ++ r100ContextPtr rmesa = (r100ContextPtr)radeon; ++ ++ /* r100 always needs to emit ZBS to avoid TCL lockups */ ++ rmesa->hw.zbs.dirty = 1; ++ radeon->hw.is_dirty = 1; ++} ++ ++static void r100_vtbl_free_context(GLcontext *ctx) ++{ ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ _mesa_vector4f_free( &rmesa->tcl.ObjClean ); ++} ++ ++static void r100_init_vtbl(radeonContextPtr radeon) ++{ ++ radeon->vtbl.get_lock = r100_get_lock; ++ radeon->vtbl.update_viewport_offset = radeonUpdateViewportOffset; ++ radeon->vtbl.emit_cs_header = r100_vtbl_emit_cs_header; ++ radeon->vtbl.swtcl_flush = r100_swtcl_flush; ++ radeon->vtbl.pre_emit_state = r100_vtbl_pre_emit_state; ++ radeon->vtbl.fallback = radeonFallback; ++} + + /* Create the device specific context. + */ + GLboolean +-radeonCreateContext( const __GLcontextModes *glVisual, ++r100CreateContext( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate) + { + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private); + struct dd_function_table functions; +- radeonContextPtr rmesa; +- GLcontext *ctx, *shareCtx; ++ r100ContextPtr rmesa; ++ GLcontext *ctx; + int i; + int tcl_mode, fthrottle_mode; + +@@ -209,10 +224,12 @@ radeonCreateContext( const __GLcontextModes *glVisual, + assert(screen); + + /* Allocate the Radeon context */ +- rmesa = (radeonContextPtr) CALLOC( sizeof(*rmesa) ); ++ rmesa = (r100ContextPtr) CALLOC( sizeof(*rmesa) ); + if ( !rmesa ) + return GL_FALSE; + ++ r100_init_vtbl(&rmesa->radeon); ++ + /* init exp fog table data */ + radeonInitStaticFogData(); + +@@ -220,12 +237,12 @@ radeonCreateContext( const __GLcontextModes *glVisual, + * Do this here so that initialMaxAnisotropy is set before we create + * the default textures. + */ +- driParseConfigFiles (&rmesa->optionCache, &screen->optionCache, ++ driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache, + screen->driScreen->myNum, "radeon"); +- rmesa->initialMaxAnisotropy = driQueryOptionf(&rmesa->optionCache, ++ rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache, + "def_max_anisotropy"); + +- if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) { ++ if ( driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) { + if ( sPriv->drm_version.minor < 13 ) + fprintf( stderr, "DRM version 1.%d too old to support HyperZ, " + "disabling.\n", sPriv->drm_version.minor ); +@@ -240,65 +257,17 @@ radeonCreateContext( const __GLcontextModes *glVisual, + * (the texture functions are especially important) + */ + _mesa_init_driver_functions( &functions ); +- radeonInitDriverFuncs( &functions ); + radeonInitTextureFuncs( &functions ); + +- /* Allocate the Mesa context */ +- if (sharedContextPrivate) +- shareCtx = ((radeonContextPtr) sharedContextPrivate)->glCtx; +- else +- shareCtx = NULL; +- rmesa->glCtx = _mesa_create_context(glVisual, shareCtx, +- &functions, (void *) rmesa); +- if (!rmesa->glCtx) { +- FREE(rmesa); +- return GL_FALSE; +- } +- driContextPriv->driverPrivate = rmesa; +- +- /* Init radeon context data */ +- rmesa->dri.context = driContextPriv; +- rmesa->dri.screen = sPriv; +- rmesa->dri.drawable = NULL; +- rmesa->dri.readable = NULL; +- rmesa->dri.hwContext = driContextPriv->hHWContext; +- rmesa->dri.hwLock = &sPriv->pSAREA->lock; +- rmesa->dri.fd = sPriv->fd; +- rmesa->dri.drmMinor = sPriv->drm_version.minor; +- +- rmesa->radeonScreen = screen; +- rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA + +- screen->sarea_priv_offset); +- +- +- rmesa->dma.buf0_address = rmesa->radeonScreen->buffers->list[0].address; +- +- (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) ); +- make_empty_list( & rmesa->swapped ); +- +- rmesa->nr_heaps = screen->numTexHeaps; +- for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { +- rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa, +- screen->texSize[i], +- 12, +- RADEON_NR_TEX_REGIONS, +- (drmTextureRegionPtr)rmesa->sarea->tex_list[i], +- & rmesa->sarea->tex_age[i], +- & rmesa->swapped, +- sizeof( radeonTexObj ), +- (destroy_texture_object_t *) radeonDestroyTexObj ); +- +- driSetTextureSwapCounterLocation( rmesa->texture_heaps[i], +- & rmesa->c_textureSwaps ); ++ if (!radeonInitContext(&rmesa->radeon, &functions, ++ glVisual, driContextPriv, ++ sharedContextPrivate)) { ++ FREE(rmesa); ++ return GL_FALSE; + } +- rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache, +- "texture_depth"); +- if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) +- rmesa->texture_depth = ( screen->cpp == 4 ) ? +- DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; + +- rmesa->swtcl.RenderIndex = ~0; +- rmesa->hw.all_dirty = GL_TRUE; ++ rmesa->radeon.swtcl.RenderIndex = ~0; ++ rmesa->radeon.hw.all_dirty = GL_TRUE; + + /* Set the maximum texture size small enough that we can guarentee that + * all texture units can bind a maximal texture and have all of them in +@@ -306,26 +275,13 @@ radeonCreateContext( const __GLcontextModes *glVisual, + * setting allow larger textures. + */ + +- ctx = rmesa->glCtx; +- ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->optionCache, ++ ctx = rmesa->radeon.glCtx; ++ ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache, + "texture_units"); + ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + +- i = driQueryOptioni( &rmesa->optionCache, "allow_large_textures"); +- +- driCalculateMaxTextureLevels( rmesa->texture_heaps, +- rmesa->nr_heaps, +- & ctx->Const, +- 4, +- 11, /* max 2D texture size is 2048x2048 */ +- 8, /* 256^3 */ +- 9, /* \todo: max cube texture size seems to be 512x512(x6) */ +- 11, /* max rect texture size is 2048x2048. */ +- 12, +- GL_FALSE, +- i ); +- ++ i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures"); + + ctx->Const.MaxTextureMaxAnisotropy = 16.0; + +@@ -388,38 +344,39 @@ radeonCreateContext( const __GLcontextModes *glVisual, + } + + driInitExtensions( ctx, card_extensions, GL_TRUE ); +- if (rmesa->radeonScreen->drmSupportsCubeMapsR100) ++ if (rmesa->radeon.radeonScreen->kernel_mm) ++ driInitExtensions(ctx, mm_extensions, GL_FALSE); ++ if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR100) + _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" ); +- if (rmesa->glCtx->Mesa_DXTn) { ++ if (rmesa->radeon.glCtx->Mesa_DXTn) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + _mesa_enable_extension( ctx, "GL_S3_s3tc" ); + } +- else if (driQueryOptionb (&rmesa->optionCache, "force_s3tc_enable")) { ++ else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + } + +- if (rmesa->dri.drmMinor >= 9) ++ if (rmesa->radeon.dri.drmMinor >= 9) + _mesa_enable_extension( ctx, "GL_NV_texture_rectangle"); + + /* XXX these should really go right after _mesa_init_driver_functions() */ ++ radeon_fbo_init(&rmesa->radeon); ++ radeonInitSpanFuncs( ctx ); + radeonInitIoctlFuncs( ctx ); + radeonInitStateFuncs( ctx ); +- radeonInitSpanFuncs( ctx ); + radeonInitState( rmesa ); + radeonInitSwtcl( ctx ); + + _mesa_vector4f_alloc( &rmesa->tcl.ObjClean, 0, + ctx->Const.MaxArrayLockSize, 32 ); + +- fthrottle_mode = driQueryOptioni(&rmesa->optionCache, "fthrottle_mode"); +- rmesa->iw.irq_seq = -1; +- rmesa->irqsEmitted = 0; +- rmesa->do_irqs = (rmesa->radeonScreen->irq != 0 && +- fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS); +- +- rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); ++ fthrottle_mode = driQueryOptioni(&rmesa->radeon.optionCache, "fthrottle_mode"); ++ rmesa->radeon.iw.irq_seq = -1; ++ rmesa->radeon.irqsEmitted = 0; ++ rmesa->radeon.do_irqs = (rmesa->radeon.radeonScreen->irq != 0 && ++ fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS); + +- (*sPriv->systemTime->getUST)( & rmesa->swap_ust ); ++ rmesa->radeon.do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); + + + #if DO_DEBUG +@@ -427,206 +384,21 @@ radeonCreateContext( const __GLcontextModes *glVisual, + debug_control ); + #endif + +- tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode"); +- if (driQueryOptionb(&rmesa->optionCache, "no_rast")) { ++ tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode"); ++ if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) { + fprintf(stderr, "disabling 3D acceleration\n"); + FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1); + } else if (tcl_mode == DRI_CONF_TCL_SW || +- !(rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { +- if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { +- rmesa->radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL; ++ !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { ++ if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { ++ rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL; + fprintf(stderr, "Disabling HW TCL support\n"); + } +- TCL_FALLBACK(rmesa->glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1); ++ TCL_FALLBACK(rmesa->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1); + } + +- if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { ++ if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { + /* _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */ + } + return GL_TRUE; + } +- +- +-/* Destroy the device specific context. +- */ +-/* Destroy the Mesa and driver specific context data. +- */ +-void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) +-{ +- GET_CURRENT_CONTEXT(ctx); +- radeonContextPtr rmesa = (radeonContextPtr) driContextPriv->driverPrivate; +- radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL; +- +- /* check if we're deleting the currently bound context */ +- if (rmesa == current) { +- RADEON_FIREVERTICES( rmesa ); +- _mesa_make_current(NULL, NULL, NULL); +- } +- +- /* Free radeon context resources */ +- assert(rmesa); /* should never be null */ +- if ( rmesa ) { +- GLboolean release_texture_heaps; +- +- +- release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); +- _swsetup_DestroyContext( rmesa->glCtx ); +- _tnl_DestroyContext( rmesa->glCtx ); +- _vbo_DestroyContext( rmesa->glCtx ); +- _swrast_DestroyContext( rmesa->glCtx ); +- +- radeonDestroySwtcl( rmesa->glCtx ); +- radeonReleaseArrays( rmesa->glCtx, ~0 ); +- if (rmesa->dma.current.buf) { +- radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); +- radeonFlushCmdBuf( rmesa, __FUNCTION__ ); +- } +- +- _mesa_vector4f_free( &rmesa->tcl.ObjClean ); +- +- if (rmesa->state.scissor.pClipRects) { +- FREE(rmesa->state.scissor.pClipRects); +- rmesa->state.scissor.pClipRects = NULL; +- } +- +- if ( release_texture_heaps ) { +- /* This share group is about to go away, free our private +- * texture object data. +- */ +- int i; +- +- for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { +- driDestroyTextureHeap( rmesa->texture_heaps[ i ] ); +- rmesa->texture_heaps[ i ] = NULL; +- } +- +- assert( is_empty_list( & rmesa->swapped ) ); +- } +- +- /* free the Mesa context */ +- rmesa->glCtx->DriverCtx = NULL; +- _mesa_destroy_context( rmesa->glCtx ); +- +- /* free the option cache */ +- driDestroyOptionCache (&rmesa->optionCache); +- +- FREE( rmesa ); +- } +-} +- +- +- +- +-void +-radeonSwapBuffers( __DRIdrawablePrivate *dPriv ) +-{ +- +- if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { +- radeonContextPtr rmesa; +- GLcontext *ctx; +- rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; +- ctx = rmesa->glCtx; +- if (ctx->Visual.doubleBufferMode) { +- _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ +- +- if ( rmesa->doPageFlip ) { +- radeonPageFlip( dPriv ); +- } +- else { +- radeonCopyBuffer( dPriv, NULL ); +- } +- } +- } +- else { +- /* XXX this shouldn't be an error but we can't handle it for now */ +- _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__); +- } +-} +- +-void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, +- int x, int y, int w, int h ) +-{ +- if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { +- radeonContextPtr radeon; +- GLcontext *ctx; +- +- radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; +- ctx = radeon->glCtx; +- +- if (ctx->Visual.doubleBufferMode) { +- drm_clip_rect_t rect; +- rect.x1 = x + dPriv->x; +- rect.y1 = (dPriv->h - y - h) + dPriv->y; +- rect.x2 = rect.x1 + w; +- rect.y2 = rect.y1 + h; +- _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ +- radeonCopyBuffer(dPriv, &rect); +- } +- } else { +- /* XXX this shouldn't be an error but we can't handle it for now */ +- _mesa_problem(NULL, "%s: drawable has no context!", +- __FUNCTION__); +- } +-} +- +-/* Make context `c' the current context and bind it to the given +- * drawing and reading surfaces. +- */ +-GLboolean +-radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, +- __DRIdrawablePrivate *driDrawPriv, +- __DRIdrawablePrivate *driReadPriv ) +-{ +- if ( driContextPriv ) { +- radeonContextPtr newCtx = +- (radeonContextPtr) driContextPriv->driverPrivate; +- +- if (RADEON_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *) newCtx->glCtx); +- +- newCtx->dri.readable = driReadPriv; +- +- if ( (newCtx->dri.drawable != driDrawPriv) || +- newCtx->lastStamp != driDrawPriv->lastStamp ) { +- if (driDrawPriv->swap_interval == (unsigned)-1) { +- driDrawPriv->vblFlags = (newCtx->radeonScreen->irq != 0) +- ? driGetDefaultVBlankFlags(&newCtx->optionCache) +- : VBLANK_FLAG_NO_IRQ; +- +- driDrawableInitVBlank( driDrawPriv ); +- } +- +- newCtx->dri.drawable = driDrawPriv; +- +- radeonSetCliprects(newCtx); +- radeonUpdateViewportOffset( newCtx->glCtx ); +- } +- +- _mesa_make_current( newCtx->glCtx, +- (GLframebuffer *) driDrawPriv->driverPrivate, +- (GLframebuffer *) driReadPriv->driverPrivate ); +- +- _mesa_update_state( newCtx->glCtx ); +- } else { +- if (RADEON_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s ctx is null\n", __FUNCTION__); +- _mesa_make_current( NULL, NULL, NULL ); +- } +- +- if (RADEON_DEBUG & DEBUG_DRI) +- fprintf(stderr, "End %s\n", __FUNCTION__); +- return GL_TRUE; +-} +- +-/* Force the context `c' to be unbound from its buffer. +- */ +-GLboolean +-radeonUnbindContext( __DRIcontextPrivate *driContextPriv ) +-{ +- radeonContextPtr rmesa = (radeonContextPtr) driContextPriv->driverPrivate; +- +- if (RADEON_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *) rmesa->glCtx); +- +- return GL_TRUE; +-} +diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h +index 53df766..1795d8b 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_context.h ++++ b/src/mesa/drivers/dri/radeon/radeon_context.h +@@ -48,91 +48,23 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "drm.h" + #include "radeon_drm.h" + #include "texmem.h" +- + #include "main/macros.h" + #include "main/mtypes.h" + #include "main/colormac.h" +- +-struct radeon_context; +-typedef struct radeon_context radeonContextRec; +-typedef struct radeon_context *radeonContextPtr; +- +-/* This union is used to avoid warnings/miscompilation +- with float to uint32_t casts due to strict-aliasing */ +-typedef union { +- GLfloat f; +- uint32_t ui32; +-} float_ui32_type; +- +-#include "radeon_lock.h" + #include "radeon_screen.h" +-#include "main/mm.h" +- +-#include "math/m_vector.h" +- +-#define TEX_0 0x1 +-#define TEX_1 0x2 +-#define TEX_2 0x4 +-#define TEX_ALL 0x7 +- +-/* Rasterizing fallbacks */ +-/* See correponding strings in r200_swtcl.c */ +-#define RADEON_FALLBACK_TEXTURE 0x0001 +-#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 +-#define RADEON_FALLBACK_STENCIL 0x0004 +-#define RADEON_FALLBACK_RENDER_MODE 0x0008 +-#define RADEON_FALLBACK_BLEND_EQ 0x0010 +-#define RADEON_FALLBACK_BLEND_FUNC 0x0020 +-#define RADEON_FALLBACK_DISABLE 0x0040 +-#define RADEON_FALLBACK_BORDER_MODE 0x0080 +- +-/* The blit width for texture uploads +- */ +-#define BLIT_WIDTH_BYTES 1024 + +-/* Use the templated vertex format: +- */ +-#define COLOR_IS_RGBA +-#define TAG(x) radeon##x +-#include "tnl_dd/t_dd_vertex.h" +-#undef TAG +- +-typedef void (*radeon_tri_func) (radeonContextPtr, +- radeonVertex *, +- radeonVertex *, radeonVertex *); +- +-typedef void (*radeon_line_func) (radeonContextPtr, +- radeonVertex *, radeonVertex *); ++#include "radeon_common.h" + +-typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *); +- +-struct radeon_colorbuffer_state { +- GLuint clear; +- int roundEnable; +-}; + +-struct radeon_depthbuffer_state { +- GLuint clear; +- GLfloat scale; +-}; ++struct r100_context; ++typedef struct r100_context r100ContextRec; ++typedef struct r100_context *r100ContextPtr; + +-struct radeon_scissor_state { +- drm_clip_rect_t rect; +- GLboolean enabled; ++#include "radeon_lock.h" + +- GLuint numClipRects; /* Cliprects active */ +- GLuint numAllocedClipRects; /* Cliprects available */ +- drm_clip_rect_t *pClipRects; +-}; + +-struct radeon_stencilbuffer_state { +- GLboolean hwBuffer; +- GLuint clear; /* rb3d_stencilrefmask value */ +-}; + +-struct radeon_stipple_state { +- GLuint mask[32]; +-}; ++#define R100_TEX_ALL 0x7 + + /* used for both tcl_vtx and vc_frmt tex bits (they are identical) */ + #define RADEON_ST_BIT(unit) \ +@@ -141,42 +73,6 @@ struct radeon_stipple_state { + #define RADEON_Q_BIT(unit) \ + (unit == 0 ? RADEON_CP_VC_FRMT_Q0 : (RADEON_CP_VC_FRMT_Q1 >> 2) << (2 * unit)) + +-typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; +- +-/* Texture object in locally shared texture space. +- */ +-struct radeon_tex_obj { +- driTextureObject base; +- +- GLuint bufAddr; /* Offset to start of locally +- shared texture block */ +- +- GLuint dirty_state; /* Flags (1 per texunit) for +- whether or not this texobj +- has dirty hardware state +- (pp_*) that needs to be +- brought into the +- texunit. */ +- +- drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; +- /* Six, for the cube faces */ +- +- GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ +- +- GLuint pp_txfilter; /* hardware register values */ +- GLuint pp_txformat; +- GLuint pp_txoffset; /* Image location in texmem. +- All cube faces follow. */ +- GLuint pp_txsize; /* npot only */ +- GLuint pp_txpitch; /* npot only */ +- GLuint pp_border_color; +- GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ +- +- GLboolean border_fallback; +- +- GLuint tile_bits; /* hw texture tile bits used on this texture */ +-}; +- + struct radeon_texture_env_state { + radeonTexObjPtr texobj; + GLenum format; +@@ -187,17 +83,6 @@ struct radeon_texture_state { + struct radeon_texture_env_state unit[RADEON_MAX_TEXTURE_UNITS]; + }; + +-struct radeon_state_atom { +- struct radeon_state_atom *next, *prev; +- const char *name; /* for debug */ +- int cmd_size; /* size in bytes */ +- GLuint is_tcl; +- int *cmd; /* one or more cmd's */ +- int *lastcmd; /* one or more cmd's */ +- GLboolean dirty; /* dirty-mark in emit_state_list */ +- GLboolean(*check) (GLcontext *); /* is this state active? */ +-}; +- + /* Trying to keep these relatively short as the variables are becoming + * extravagently long. Drop the driver name prefix off the front of + * everything - I think we know which driver we're in by now, and keep the +@@ -410,10 +295,7 @@ struct radeon_state_atom { + #define SHN_SHININESS 1 + #define SHN_STATE_SIZE 2 + +-struct radeon_hw_state { +- /* Head of the linked list of state atoms. */ +- struct radeon_state_atom atomlist; +- ++struct r100_hw_state { + /* Hardware state, stored as cmdbuf commands: + * -- Need to doublebuffer for + * - eliding noop statechange loops? (except line stipple count) +@@ -438,89 +320,19 @@ struct radeon_hw_state { + struct radeon_state_atom glt; + struct radeon_state_atom txr[3]; /* for NPOT */ + +- int max_state_size; /* Number of bytes necessary for a full state emit. */ +- GLboolean is_dirty, all_dirty; + }; + +-struct radeon_state { +- /* Derived state for internal purposes: +- */ +- struct radeon_colorbuffer_state color; +- struct radeon_depthbuffer_state depth; +- struct radeon_scissor_state scissor; +- struct radeon_stencilbuffer_state stencil; ++ ++struct r100_state { + struct radeon_stipple_state stipple; + struct radeon_texture_state texture; + }; + +-/* Need refcounting on dma buffers: +- */ +-struct radeon_dma_buffer { +- int refcount; /* the number of retained regions in buf */ +- drmBufPtr buf; +-}; +- +-#define GET_START(rvb) (rmesa->radeonScreen->gart_buffer_offset + \ +- (rvb)->address - rmesa->dma.buf0_address + \ +- (rvb)->start) +- +-/* A retained region, eg vertices for indexed vertices. +- */ +-struct radeon_dma_region { +- struct radeon_dma_buffer *buf; +- char *address; /* == buf->address */ +- int start, end, ptr; /* offsets from start of buf */ +- int aos_start; +- int aos_stride; +- int aos_size; +-}; +- +-struct radeon_dma { +- /* Active dma region. Allocations for vertices and retained +- * regions come from here. Also used for emitting random vertices, +- * these may be flushed by calling flush_current(); +- */ +- struct radeon_dma_region current; +- +- void (*flush) (radeonContextPtr); +- +- char *buf0_address; /* start of buf[0], for index calcs */ +- GLuint nr_released_bufs; /* flush after so many buffers released */ +-}; +- +-struct radeon_dri_mirror { +- __DRIcontextPrivate *context; /* DRI context */ +- __DRIscreenPrivate *screen; /* DRI screen */ +- +- /** +- * DRI drawable bound to this context for drawing. +- */ +- __DRIdrawablePrivate *drawable; +- +- /** +- * DRI drawable bound to this context for reading. +- */ +- __DRIdrawablePrivate *readable; +- +- drm_context_t hwContext; +- drm_hw_lock_t *hwLock; +- int fd; +- int drmMinor; +-}; +- + #define RADEON_CMD_BUF_SZ (8*1024) +- +-struct radeon_store { +- GLuint statenr; +- GLuint primnr; +- char cmd_buf[RADEON_CMD_BUF_SZ]; +- int cmd_used; +- int elts_start; +-}; +- ++#define R200_ELT_BUF_SZ (8*1024) + /* radeon_tcl.c + */ +-struct radeon_tcl_info { ++struct r100_tcl_info { + GLuint vertex_format; + GLuint hw_primitive; + +@@ -529,30 +341,18 @@ struct radeon_tcl_info { + */ + GLvector4f ObjClean; + +- struct radeon_dma_region *aos_components[8]; +- GLuint nr_aos_components; +- + GLuint *Elts; + +- struct radeon_dma_region indexed_verts; +- struct radeon_dma_region obj; +- struct radeon_dma_region rgba; +- struct radeon_dma_region spec; +- struct radeon_dma_region fog; +- struct radeon_dma_region tex[RADEON_MAX_TEXTURE_UNITS]; +- struct radeon_dma_region norm; ++ int elt_cmd_offset; ++ int elt_cmd_start; ++ int elt_used; + }; + + /* radeon_swtcl.c + */ +-struct radeon_swtcl_info { +- GLuint RenderIndex; +- GLuint vertex_size; ++struct r100_swtcl_info { + GLuint vertex_format; + +- struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; +- GLuint vertex_attr_count; +- + GLubyte *verts; + + /* Fallback rasterization functions +@@ -561,10 +361,6 @@ struct radeon_swtcl_info { + radeon_line_func draw_line; + radeon_tri_func draw_tri; + +- GLuint hw_primitive; +- GLenum render_primitive; +- GLuint numverts; +- + /** + * Offset of the 4UB color data within a hardware (swtcl) vertex. + */ +@@ -576,22 +372,9 @@ struct radeon_swtcl_info { + GLuint specoffset; + + GLboolean needproj; +- +- struct radeon_dma_region indexed_verts; + }; + +-struct radeon_ioctl { +- GLuint vertex_offset; +- GLuint vertex_size; +-}; +- +-#define RADEON_MAX_PRIMS 64 + +-struct radeon_prim { +- GLuint start; +- GLuint end; +- GLuint prim; +-}; + + /* A maximum total of 20 elements per vertex: 3 floats for position, 3 + * floats for normal, 4 floats for color, 4 bytes for secondary color, +@@ -602,59 +385,18 @@ struct radeon_prim { + */ + #define RADEON_MAX_VERTEX_SIZE 20 + +-struct radeon_context { +- GLcontext *glCtx; /* Mesa context */ ++struct r100_context { ++ struct radeon_context radeon; + + /* Driver and hardware state management + */ +- struct radeon_hw_state hw; +- struct radeon_state state; +- +- /* Texture object bookkeeping +- */ +- unsigned nr_heaps; +- driTexHeap *texture_heaps[RADEON_NR_TEX_HEAPS]; +- driTextureObject swapped; +- int texture_depth; +- float initialMaxAnisotropy; +- +- /* Rasterization and vertex state: +- */ +- GLuint TclFallback; +- GLuint Fallback; +- GLuint NewGLState; +- DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ ++ struct r100_hw_state hw; ++ struct r100_state state; + + /* Vertex buffers + */ + struct radeon_ioctl ioctl; +- struct radeon_dma dma; + struct radeon_store store; +- /* A full state emit as of the first state emit in the main store, in case +- * the context is lost. +- */ +- struct radeon_store backup_store; +- +- /* Page flipping +- */ +- GLuint doPageFlip; +- +- /* Busy waiting +- */ +- GLuint do_usleeps; +- GLuint do_irqs; +- GLuint irqsEmitted; +- drm_radeon_irq_wait_t iw; +- +- /* Drawable, cliprect and scissor information +- */ +- GLuint numClipRects; /* Cliprects for the draw buffer */ +- drm_clip_rect_t *pClipRects; +- unsigned int lastStamp; +- GLboolean lost_context; +- GLboolean save_on_next_emit; +- radeonScreenPtr radeonScreen; /* Screen private DRI data */ +- drm_radeon_sarea_t *sarea; /* Private SAREA data */ + + /* TCL stuff + */ +@@ -667,29 +409,13 @@ struct radeon_context { + GLmatrix tmpmat[RADEON_MAX_TEXTURE_UNITS]; + GLuint last_ReallyEnabled; + +- /* VBI +- */ +- int64_t swap_ust; +- int64_t swap_missed_ust; +- +- GLuint swap_count; +- GLuint swap_missed_count; +- + /* radeon_tcl.c + */ +- struct radeon_tcl_info tcl; ++ struct r100_tcl_info tcl; + + /* radeon_swtcl.c + */ +- struct radeon_swtcl_info swtcl; +- +- /* Mirrors of some DRI state +- */ +- struct radeon_dri_mirror dri; +- +- /* Configuration cache +- */ +- driOptionCache optionCache; ++ struct r100_swtcl_info swtcl; + + GLboolean using_hyperz; + GLboolean texmicrotile; +@@ -703,61 +429,19 @@ struct radeon_context { + GLuint c_textureSwaps; + GLuint c_textureBytes; + GLuint c_vertexBuffers; ++ + }; + +-#define RADEON_CONTEXT(ctx) ((radeonContextPtr)(ctx->DriverCtx)) +- +-static INLINE GLuint radeonPackColor(GLuint cpp, +- GLubyte r, GLubyte g, +- GLubyte b, GLubyte a) +-{ +- switch (cpp) { +- case 2: +- return PACK_COLOR_565(r, g, b); +- case 4: +- return PACK_COLOR_8888(a, r, g, b); +- default: +- return 0; +- } +-} ++ ++#define R100_CONTEXT(ctx) ((r100ContextPtr)(ctx->DriverCtx)) ++ + + #define RADEON_OLD_PACKETS 1 + +-extern void radeonDestroyContext(__DRIcontextPrivate * driContextPriv); +-extern GLboolean radeonCreateContext(const __GLcontextModes * glVisual, +- __DRIcontextPrivate * driContextPriv, +- void *sharedContextPrivate); +-extern void radeonSwapBuffers(__DRIdrawablePrivate * dPriv); +-extern void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, +- int x, int y, int w, int h); +-extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, +- __DRIdrawablePrivate * driDrawPriv, +- __DRIdrawablePrivate * driReadPriv); +-extern GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); +- +-/* ================================================================ +- * Debugging: +- */ +-#define DO_DEBUG 1 +- +-#if DO_DEBUG +-extern int RADEON_DEBUG; +-#else +-#define RADEON_DEBUG 0 +-#endif +- +-#define DEBUG_TEXTURE 0x0001 +-#define DEBUG_STATE 0x0002 +-#define DEBUG_IOCTL 0x0004 +-#define DEBUG_PRIMS 0x0008 +-#define DEBUG_VERTS 0x0010 +-#define DEBUG_FALLBACKS 0x0020 +-#define DEBUG_VFMT 0x0040 +-#define DEBUG_CODEGEN 0x0080 +-#define DEBUG_VERBOSE 0x0100 +-#define DEBUG_DRI 0x0200 +-#define DEBUG_DMA 0x0400 +-#define DEBUG_SANITY 0x0800 +-#define DEBUG_SYNC 0x1000 ++extern GLboolean r100CreateContext( const __GLcontextModes *glVisual, ++ __DRIcontextPrivate *driContextPriv, ++ void *sharedContextPrivate); ++ ++ + + #endif /* __RADEON_CONTEXT_H__ */ +diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h +new file mode 100644 +index 0000000..984725a +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h +@@ -0,0 +1,207 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#ifndef RADEON_CS_H ++#define RADEON_CS_H ++ ++#include ++#include ++#include "drm.h" ++#include "radeon_drm.h" ++ ++struct radeon_cs_reloc { ++ struct radeon_bo *bo; ++ uint32_t read_domain; ++ uint32_t write_domain; ++ uint32_t flags; ++}; ++ ++ ++#define RADEON_CS_SPACE_OK 0 ++#define RADEON_CS_SPACE_OP_TO_BIG 1 ++#define RADEON_CS_SPACE_FLUSH 2 ++ ++struct radeon_cs_space_check { ++ struct radeon_bo *bo; ++ uint32_t read_domains; ++ uint32_t write_domain; ++ uint32_t new_accounted; ++}; ++ ++struct radeon_cs_manager; ++ ++struct radeon_cs { ++ struct radeon_cs_manager *csm; ++ void *relocs; ++ uint32_t *packets; ++ unsigned crelocs; ++ unsigned relocs_total_size; ++ unsigned cdw; ++ unsigned ndw; ++ int section; ++ unsigned section_ndw; ++ unsigned section_cdw; ++ const char *section_file; ++ const char *section_func; ++ int section_line; ++ ++}; ++ ++/* cs functions */ ++struct radeon_cs_funcs { ++ struct radeon_cs *(*cs_create)(struct radeon_cs_manager *csm, ++ uint32_t ndw); ++ int (*cs_write_reloc)(struct radeon_cs *cs, ++ struct radeon_bo *bo, ++ uint32_t read_domain, ++ uint32_t write_domain, ++ uint32_t flags); ++ int (*cs_begin)(struct radeon_cs *cs, ++ uint32_t ndw, ++ const char *file, ++ const char *func, ++ int line); ++ int (*cs_end)(struct radeon_cs *cs, ++ const char *file, ++ const char *func, ++ int line); ++ int (*cs_emit)(struct radeon_cs *cs); ++ int (*cs_destroy)(struct radeon_cs *cs); ++ int (*cs_erase)(struct radeon_cs *cs); ++ int (*cs_need_flush)(struct radeon_cs *cs); ++ void (*cs_print)(struct radeon_cs *cs, FILE *file); ++ int (*cs_space_check)(struct radeon_cs *cs, struct radeon_cs_space_check *bos, ++ int num_bo); ++}; ++ ++struct radeon_cs_manager { ++ struct radeon_cs_funcs *funcs; ++ int fd; ++ uint32_t vram_limit, gart_limit; ++ uint32_t vram_write_used, gart_write_used; ++ uint32_t read_used; ++}; ++ ++static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm, ++ uint32_t ndw) ++{ ++ return csm->funcs->cs_create(csm, ndw); ++} ++ ++static inline int radeon_cs_write_reloc(struct radeon_cs *cs, ++ struct radeon_bo *bo, ++ uint32_t read_domain, ++ uint32_t write_domain, ++ uint32_t flags) ++{ ++ return cs->csm->funcs->cs_write_reloc(cs, ++ bo, ++ read_domain, ++ write_domain, ++ flags); ++} ++ ++static inline int radeon_cs_begin(struct radeon_cs *cs, ++ uint32_t ndw, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ return cs->csm->funcs->cs_begin(cs, ndw, file, func, line); ++} ++ ++static inline int radeon_cs_end(struct radeon_cs *cs, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ return cs->csm->funcs->cs_end(cs, file, func, line); ++} ++ ++static inline int radeon_cs_emit(struct radeon_cs *cs) ++{ ++ return cs->csm->funcs->cs_emit(cs); ++} ++ ++static inline int radeon_cs_destroy(struct radeon_cs *cs) ++{ ++ return cs->csm->funcs->cs_destroy(cs); ++} ++ ++static inline int radeon_cs_erase(struct radeon_cs *cs) ++{ ++ return cs->csm->funcs->cs_erase(cs); ++} ++ ++static inline int radeon_cs_need_flush(struct radeon_cs *cs) ++{ ++ return cs->csm->funcs->cs_need_flush(cs); ++} ++ ++static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file) ++{ ++ cs->csm->funcs->cs_print(cs, file); ++} ++ ++static inline int radeon_cs_space_check(struct radeon_cs *cs, ++ struct radeon_cs_space_check *bos, ++ int num_bo) ++{ ++ return cs->csm->funcs->cs_space_check(cs, bos, num_bo); ++} ++ ++static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit) ++{ ++ ++ if (domain == RADEON_GEM_DOMAIN_VRAM) ++ cs->csm->vram_limit = limit; ++ else ++ cs->csm->gart_limit = limit; ++} ++ ++static inline void radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword) ++{ ++ cs->packets[cs->cdw++] = dword; ++ if (cs->section) { ++ cs->section_cdw++; ++ } ++} ++ ++static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword) ++{ ++ ++ memcpy(cs->packets + cs->cdw, &qword, sizeof(qword)); ++ cs->cdw+=2; ++ if (cs->section) { ++ cs->section_cdw+=2; ++ } ++} ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +new file mode 100644 +index 0000000..b47b095 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +@@ -0,0 +1,504 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#include ++ ++#include "radeon_bocs_wrapper.h" ++ ++struct cs_manager_legacy { ++ struct radeon_cs_manager base; ++ struct radeon_context *ctx; ++ /* hack for scratch stuff */ ++ uint32_t pending_age; ++ uint32_t pending_count; ++ ++ ++}; ++ ++struct cs_reloc_legacy { ++ struct radeon_cs_reloc base; ++ uint32_t cindices; ++ uint32_t *indices; ++}; ++ ++ ++static struct radeon_cs *cs_create(struct radeon_cs_manager *csm, ++ uint32_t ndw) ++{ ++ struct radeon_cs *cs; ++ ++ cs = (struct radeon_cs*)calloc(1, sizeof(struct radeon_cs)); ++ if (cs == NULL) { ++ return NULL; ++ } ++ cs->csm = csm; ++ cs->ndw = (ndw + 0x3FF) & (~0x3FF); ++ cs->packets = (uint32_t*)malloc(4*cs->ndw); ++ if (cs->packets == NULL) { ++ free(cs); ++ return NULL; ++ } ++ cs->relocs_total_size = 0; ++ return cs; ++} ++ ++static int cs_write_reloc(struct radeon_cs *cs, ++ struct radeon_bo *bo, ++ uint32_t read_domain, ++ uint32_t write_domain, ++ uint32_t flags) ++{ ++ struct cs_reloc_legacy *relocs; ++ int i; ++ ++ relocs = (struct cs_reloc_legacy *)cs->relocs; ++ /* check domains */ ++ if ((read_domain && write_domain) || (!read_domain && !write_domain)) { ++ /* in one CS a bo can only be in read or write domain but not ++ * in read & write domain at the same sime ++ */ ++ return -EINVAL; ++ } ++ if (read_domain == RADEON_GEM_DOMAIN_CPU) { ++ return -EINVAL; ++ } ++ if (write_domain == RADEON_GEM_DOMAIN_CPU) { ++ return -EINVAL; ++ } ++ /* check if bo is already referenced */ ++ for(i = 0; i < cs->crelocs; i++) { ++ uint32_t *indices; ++ ++ if (relocs[i].base.bo->handle == bo->handle) { ++ /* Check domains must be in read or write. As we check already ++ * checked that in argument one of the read or write domain was ++ * set we only need to check that if previous reloc as the read ++ * domain set then the read_domain should also be set for this ++ * new relocation. ++ */ ++ if (relocs[i].base.read_domain && !read_domain) { ++ return -EINVAL; ++ } ++ if (relocs[i].base.write_domain && !write_domain) { ++ return -EINVAL; ++ } ++ relocs[i].base.read_domain |= read_domain; ++ relocs[i].base.write_domain |= write_domain; ++ /* save indice */ ++ relocs[i].cindices++; ++ indices = (uint32_t*)realloc(relocs[i].indices, ++ relocs[i].cindices * 4); ++ if (indices == NULL) { ++ relocs[i].cindices -= 1; ++ return -ENOMEM; ++ } ++ relocs[i].indices = indices; ++ relocs[i].indices[relocs[i].cindices - 1] = cs->cdw - 1; ++ return 0; ++ } ++ } ++ /* add bo to reloc */ ++ relocs = (struct cs_reloc_legacy*) ++ realloc(cs->relocs, ++ sizeof(struct cs_reloc_legacy) * (cs->crelocs + 1)); ++ if (relocs == NULL) { ++ return -ENOMEM; ++ } ++ cs->relocs = relocs; ++ relocs[cs->crelocs].base.bo = bo; ++ relocs[cs->crelocs].base.read_domain = read_domain; ++ relocs[cs->crelocs].base.write_domain = write_domain; ++ relocs[cs->crelocs].base.flags = flags; ++ relocs[cs->crelocs].indices = (uint32_t*)malloc(4); ++ if (relocs[cs->crelocs].indices == NULL) { ++ return -ENOMEM; ++ } ++ relocs[cs->crelocs].indices[0] = cs->cdw - 1; ++ relocs[cs->crelocs].cindices = 1; ++ cs->relocs_total_size += radeon_bo_legacy_relocs_size(bo); ++ cs->crelocs++; ++ radeon_bo_ref(bo); ++ return 0; ++} ++ ++static int cs_begin(struct radeon_cs *cs, ++ uint32_t ndw, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ if (cs->section) { ++ fprintf(stderr, "CS already in a section(%s,%s,%d)\n", ++ cs->section_file, cs->section_func, cs->section_line); ++ fprintf(stderr, "CS can't start section(%s,%s,%d)\n", ++ file, func, line); ++ return -EPIPE; ++ } ++ cs->section = 1; ++ cs->section_ndw = ndw; ++ cs->section_cdw = 0; ++ cs->section_file = file; ++ cs->section_func = func; ++ cs->section_line = line; ++ ++ ++ if (cs->cdw + ndw > cs->ndw) { ++ uint32_t tmp, *ptr; ++ int num = (ndw > 0x3FF) ? ndw : 0x3FF; ++ ++ tmp = (cs->cdw + 1 + num) & (~num); ++ ptr = (uint32_t*)realloc(cs->packets, 4 * tmp); ++ if (ptr == NULL) { ++ return -ENOMEM; ++ } ++ cs->packets = ptr; ++ cs->ndw = tmp; ++ } ++ ++ return 0; ++} ++ ++static int cs_end(struct radeon_cs *cs, ++ const char *file, ++ const char *func, ++ int line) ++ ++{ ++ if (!cs->section) { ++ fprintf(stderr, "CS no section to end at (%s,%s,%d)\n", ++ file, func, line); ++ return -EPIPE; ++ } ++ cs->section = 0; ++ if (cs->section_ndw != cs->section_cdw) { ++ fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n", ++ cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw); ++ fprintf(stderr, "CS section end at (%s,%s,%d)\n", ++ file, func, line); ++ return -EPIPE; ++ } ++ return 0; ++} ++ ++static int cs_process_relocs(struct radeon_cs *cs) ++{ ++ struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm; ++ struct cs_reloc_legacy *relocs; ++ int i, j, r; ++ ++ csm = (struct cs_manager_legacy*)cs->csm; ++ relocs = (struct cs_reloc_legacy *)cs->relocs; ++ restart: ++ for (i = 0; i < cs->crelocs; i++) { ++ for (j = 0; j < relocs[i].cindices; j++) { ++ uint32_t soffset, eoffset; ++ ++ r = radeon_bo_legacy_validate(relocs[i].base.bo, ++ &soffset, &eoffset); ++ if (r == -EAGAIN) ++ goto restart; ++ if (r) { ++ fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n", ++ relocs[i].base.bo, soffset, eoffset); ++ return r; ++ } ++ cs->packets[relocs[i].indices[j]] += soffset; ++ if (cs->packets[relocs[i].indices[j]] >= eoffset) { ++ /* radeon_bo_debug(relocs[i].base.bo, 12); */ ++ fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n", ++ relocs[i].base.bo, soffset, eoffset); ++ fprintf(stderr, "above end: %p 0x%08X 0x%08X\n", ++ relocs[i].base.bo, ++ cs->packets[relocs[i].indices[j]], ++ eoffset); ++ exit(0); ++ return -EINVAL; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int cs_set_age(struct radeon_cs *cs) ++{ ++ struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm; ++ struct cs_reloc_legacy *relocs; ++ int i; ++ ++ relocs = (struct cs_reloc_legacy *)cs->relocs; ++ for (i = 0; i < cs->crelocs; i++) { ++ radeon_bo_legacy_pending(relocs[i].base.bo, csm->pending_age); ++ radeon_bo_unref(relocs[i].base.bo); ++ } ++ return 0; ++} ++ ++static void dump_cmdbuf(struct radeon_cs *cs) ++{ ++ int i; ++ for (i = 0; i < cs->cdw; i++){ ++ fprintf(stderr,"%x: %08x\n", i, cs->packets[i]); ++ } ++ ++} ++static int cs_emit(struct radeon_cs *cs) ++{ ++ struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm; ++ drm_radeon_cmd_buffer_t cmd; ++ drm_r300_cmd_header_t age; ++ uint64_t ull; ++ int r; ++ ++ csm->ctx->vtbl.emit_cs_header(cs, csm->ctx); ++ ++ /* append buffer age */ ++ if (IS_R300_CLASS(csm->ctx->radeonScreen)) { ++ age.scratch.cmd_type = R300_CMD_SCRATCH; ++ /* Scratch register 2 corresponds to what radeonGetAge polls */ ++ csm->pending_age = 0; ++ csm->pending_count = 1; ++ ull = (uint64_t) (intptr_t) &csm->pending_age; ++ age.scratch.reg = 2; ++ age.scratch.n_bufs = 1; ++ age.scratch.flags = 0; ++ radeon_cs_write_dword(cs, age.u); ++ radeon_cs_write_qword(cs, ull); ++ radeon_cs_write_dword(cs, 0); ++ } ++ ++ r = cs_process_relocs(cs); ++ if (r) { ++ return 0; ++ } ++ ++ cmd.buf = (char *)cs->packets; ++ cmd.bufsz = cs->cdw * 4; ++ if (csm->ctx->state.scissor.enabled) { ++ cmd.nbox = csm->ctx->state.scissor.numClipRects; ++ cmd.boxes = (drm_clip_rect_t *) csm->ctx->state.scissor.pClipRects; ++ } else { ++ cmd.nbox = csm->ctx->numClipRects; ++ cmd.boxes = (drm_clip_rect_t *) csm->ctx->pClipRects; ++ } ++ ++ //dump_cmdbuf(cs); ++ ++ r = drmCommandWrite(cs->csm->fd, DRM_RADEON_CMDBUF, &cmd, sizeof(cmd)); ++ if (r) { ++ return r; ++ } ++ if (!IS_R300_CLASS(csm->ctx->radeonScreen)) { ++ drm_radeon_irq_emit_t emit_cmd; ++ emit_cmd.irq_seq = &csm->pending_age; ++ r = drmCommandWrite(cs->csm->fd, DRM_RADEON_IRQ_EMIT, &emit_cmd, sizeof(emit_cmd)); ++ if (r) { ++ return r; ++ } ++ } ++ cs_set_age(cs); ++ ++ cs->csm->read_used = 0; ++ cs->csm->vram_write_used = 0; ++ cs->csm->gart_write_used = 0; ++ return 0; ++} ++ ++static void inline cs_free_reloc(void *relocs_p, int crelocs) ++{ ++ struct cs_reloc_legacy *relocs = relocs_p; ++ int i; ++ if (!relocs_p) ++ return; ++ for (i = 0; i < crelocs; i++) ++ free(relocs[i].indices); ++} ++ ++static int cs_destroy(struct radeon_cs *cs) ++{ ++ cs_free_reloc(cs->relocs, cs->crelocs); ++ free(cs->relocs); ++ free(cs->packets); ++ free(cs); ++ return 0; ++} ++ ++static int cs_erase(struct radeon_cs *cs) ++{ ++ cs_free_reloc(cs->relocs, cs->crelocs); ++ free(cs->relocs); ++ cs->relocs_total_size = 0; ++ cs->relocs = NULL; ++ cs->crelocs = 0; ++ cs->cdw = 0; ++ cs->section = 0; ++ return 0; ++} ++ ++static int cs_need_flush(struct radeon_cs *cs) ++{ ++ /* this function used to flush when the BO usage got to ++ * a certain size, now the higher levels handle this better */ ++ return 0; ++} ++ ++static void cs_print(struct radeon_cs *cs, FILE *file) ++{ ++} ++ ++static int cs_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo) ++{ ++ struct radeon_cs_manager *csm = cs->csm; ++ int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0; ++ uint32_t read_domains, write_domain; ++ int i; ++ struct radeon_bo *bo; ++ ++ /* check the totals for this operation */ ++ ++ if (num_bo == 0) ++ return 0; ++ ++ /* prepare */ ++ for (i = 0; i < num_bo; i++) { ++ bo = bos[i].bo; ++ ++ bos[i].new_accounted = 0; ++ read_domains = bos[i].read_domains; ++ write_domain = bos[i].write_domain; ++ ++ /* pinned bos don't count */ ++ if (radeon_legacy_bo_is_static(bo)) ++ continue; ++ ++ /* already accounted this bo */ ++ if (write_domain && (write_domain == bo->space_accounted)) ++ continue; ++ ++ if (read_domains && ((read_domains << 16) == bo->space_accounted)) ++ continue; ++ ++ if (bo->space_accounted == 0) { ++ if (write_domain == RADEON_GEM_DOMAIN_VRAM) ++ this_op_vram_write += bo->size; ++ else if (write_domain == RADEON_GEM_DOMAIN_GTT) ++ this_op_gart_write += bo->size; ++ else ++ this_op_read += bo->size; ++ bos[i].new_accounted = (read_domains << 16) | write_domain; ++ } else { ++ uint16_t old_read, old_write; ++ ++ old_read = bo->space_accounted >> 16; ++ old_write = bo->space_accounted & 0xffff; ++ ++ if (write_domain && (old_read & write_domain)) { ++ bos[i].new_accounted = write_domain; ++ /* moving from read to a write domain */ ++ if (write_domain == RADEON_GEM_DOMAIN_VRAM) { ++ this_op_read -= bo->size; ++ this_op_vram_write += bo->size; ++ } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) { ++ this_op_read -= bo->size; ++ this_op_gart_write += bo->size; ++ } ++ } else if (read_domains & old_write) { ++ bos[i].new_accounted = bo->space_accounted & 0xffff; ++ } else { ++ /* rewrite the domains */ ++ if (write_domain != old_write) ++ fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write); ++ if (read_domains != old_read) ++ fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read); ++ return RADEON_CS_SPACE_FLUSH; ++ } ++ } ++ } ++ ++ if (this_op_read < 0) ++ this_op_read = 0; ++ ++ /* check sizes - operation first */ ++ if ((this_op_read + this_op_gart_write > csm->gart_limit) || ++ (this_op_vram_write > csm->vram_limit)) { ++ return RADEON_CS_SPACE_OP_TO_BIG; ++ } ++ ++ if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) || ++ ((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) { ++ return RADEON_CS_SPACE_FLUSH; ++ } ++ ++ csm->gart_write_used += this_op_gart_write; ++ csm->vram_write_used += this_op_vram_write; ++ csm->read_used += this_op_read; ++ /* commit */ ++ for (i = 0; i < num_bo; i++) { ++ bo = bos[i].bo; ++ bo->space_accounted = bos[i].new_accounted; ++ } ++ ++ return RADEON_CS_SPACE_OK; ++} ++ ++static struct radeon_cs_funcs radeon_cs_legacy_funcs = { ++ cs_create, ++ cs_write_reloc, ++ cs_begin, ++ cs_end, ++ cs_emit, ++ cs_destroy, ++ cs_erase, ++ cs_need_flush, ++ cs_print, ++ cs_check_space ++}; ++ ++struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx) ++{ ++ struct cs_manager_legacy *csm; ++ ++ csm = (struct cs_manager_legacy*) ++ calloc(1, sizeof(struct cs_manager_legacy)); ++ if (csm == NULL) { ++ return NULL; ++ } ++ csm->base.funcs = &radeon_cs_legacy_funcs; ++ csm->base.fd = ctx->dri.fd; ++ csm->ctx = ctx; ++ csm->pending_age = 1; ++ return (struct radeon_cs_manager*)csm; ++} ++ ++void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm) ++{ ++ free(csm); ++} ++ +diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +new file mode 100644 +index 0000000..e177b4b +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +@@ -0,0 +1,40 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#ifndef RADEON_CS_LEGACY_H ++#define RADEON_CS_LEGACY_H ++ ++#include "radeon_common.h" ++ ++struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx); ++void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm); ++ ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c +new file mode 100644 +index 0000000..5ffee86 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_dma.c +@@ -0,0 +1,332 @@ ++/************************************************************************** ++ ++Copyright (C) 2004 Nicolai Haehnle. ++Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. ++ ++The Weather Channel (TM) funded Tungsten Graphics to develop the ++initial release of the Radeon 8500 driver under the XFree86 license. ++This notice must be preserved. ++ ++All Rights Reserved. ++ ++Permission is hereby granted, free of charge, to any person obtaining a ++copy of this software and associated documentation files (the "Software"), ++to deal in the Software without restriction, including without limitation ++on the rights to use, copy, modify, merge, publish, distribute, sub ++license, and/or sell copies of the Software, and to permit persons to whom ++the Software is furnished to do so, subject to the following conditions: ++ ++The above copyright notice and this permission notice (including the next ++paragraph) shall be included in all copies or substantial portions of the ++Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, ++DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++USE OR OTHER DEALINGS IN THE SOFTWARE. ++ ++**************************************************************************/ ++ ++#include "radeon_common.h" ++ ++#if defined(USE_X86_ASM) ++#define COPY_DWORDS( dst, src, nr ) \ ++do { \ ++ int __tmp; \ ++ __asm__ __volatile__( "rep ; movsl" \ ++ : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ ++ : "0" (nr), \ ++ "D" ((long)dst), \ ++ "S" ((long)src) ); \ ++} while (0) ++#else ++#define COPY_DWORDS( dst, src, nr ) \ ++do { \ ++ int j; \ ++ for ( j = 0 ; j < nr ; j++ ) \ ++ dst[j] = ((int *)src)[j]; \ ++ dst += nr; \ ++} while (0) ++#endif ++ ++static void radeonEmitVec4(uint32_t *out, GLvoid * data, int stride, int count) ++{ ++ int i; ++ ++ if (RADEON_DEBUG & DEBUG_VERTS) ++ fprintf(stderr, "%s count %d stride %d out %p data %p\n", ++ __FUNCTION__, count, stride, (void *)out, (void *)data); ++ ++ if (stride == 4) ++ COPY_DWORDS(out, data, count); ++ else ++ for (i = 0; i < count; i++) { ++ out[0] = *(int *)data; ++ out++; ++ data += stride; ++ } ++} ++ ++void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count) ++{ ++ int i; ++ ++ if (RADEON_DEBUG & DEBUG_VERTS) ++ fprintf(stderr, "%s count %d stride %d out %p data %p\n", ++ __FUNCTION__, count, stride, (void *)out, (void *)data); ++ ++ if (stride == 8) ++ COPY_DWORDS(out, data, count * 2); ++ else ++ for (i = 0; i < count; i++) { ++ out[0] = *(int *)data; ++ out[1] = *(int *)(data + 4); ++ out += 2; ++ data += stride; ++ } ++} ++ ++void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count) ++{ ++ int i; ++ ++ if (RADEON_DEBUG & DEBUG_VERTS) ++ fprintf(stderr, "%s count %d stride %d out %p data %p\n", ++ __FUNCTION__, count, stride, (void *)out, (void *)data); ++ ++ if (stride == 12) { ++ COPY_DWORDS(out, data, count * 3); ++ } ++ else ++ for (i = 0; i < count; i++) { ++ out[0] = *(int *)data; ++ out[1] = *(int *)(data + 4); ++ out[2] = *(int *)(data + 8); ++ out += 3; ++ data += stride; ++ } ++} ++ ++static void radeonEmitVec16(uint32_t *out, GLvoid * data, int stride, int count) ++{ ++ int i; ++ ++ if (RADEON_DEBUG & DEBUG_VERTS) ++ fprintf(stderr, "%s count %d stride %d out %p data %p\n", ++ __FUNCTION__, count, stride, (void *)out, (void *)data); ++ ++ if (stride == 16) ++ COPY_DWORDS(out, data, count * 4); ++ else ++ for (i = 0; i < count; i++) { ++ out[0] = *(int *)data; ++ out[1] = *(int *)(data + 4); ++ out[2] = *(int *)(data + 8); ++ out[3] = *(int *)(data + 12); ++ out += 4; ++ data += stride; ++ } ++} ++ ++void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, ++ GLvoid * data, int size, int stride, int count) ++{ ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ uint32_t *out; ++ ++ if (stride == 0) { ++ radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); ++ count = 1; ++ aos->stride = 0; ++ } else { ++ radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); ++ aos->stride = size; ++ } ++ ++ aos->components = size; ++ aos->count = count; ++ ++ out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); ++ switch (size) { ++ case 1: radeonEmitVec4(out, data, stride, count); break; ++ case 2: radeonEmitVec8(out, data, stride, count); break; ++ case 3: radeonEmitVec12(out, data, stride, count); break; ++ case 4: radeonEmitVec16(out, data, stride, count); break; ++ default: ++ assert(0); ++ break; ++ } ++} ++ ++void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) ++{ ++ ++ size = MAX2(size, MAX_DMA_BUF_SZ * 16); ++ ++ if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) ++ fprintf(stderr, "%s\n", __FUNCTION__); ++ ++ if (rmesa->dma.flush) { ++ rmesa->dma.flush(rmesa->glCtx); ++ } ++ ++ if (rmesa->dma.nr_released_bufs > 4) { ++ rcommonFlushCmdBuf(rmesa, __FUNCTION__); ++ rmesa->dma.nr_released_bufs = 0; ++ } ++ ++ if (rmesa->dma.current) { ++ radeon_bo_unmap(rmesa->dma.current); ++ radeon_bo_unref(rmesa->dma.current); ++ rmesa->dma.current = 0; ++ } ++ ++again_alloc: ++ rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom, ++ 0, size, 4, RADEON_GEM_DOMAIN_GTT, ++ 0); ++ ++ if (!rmesa->dma.current) { ++ rcommonFlushCmdBuf(rmesa, __FUNCTION__); ++ rmesa->dma.nr_released_bufs = 0; ++ goto again_alloc; ++ } ++ ++ rmesa->dma.current_used = 0; ++ rmesa->dma.current_vertexptr = 0; ++ ++ radeon_validate_bo(rmesa, rmesa->dma.current, RADEON_GEM_DOMAIN_GTT, 0); ++ ++ if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE) ++ fprintf(stderr,"failure to revalidate BOs - badness\n"); ++ ++ radeon_bo_map(rmesa->dma.current, 1); ++} ++ ++/* Allocates a region from rmesa->dma.current. If there isn't enough ++ * space in current, grab a new buffer (and discard what was left of current) ++ */ ++void radeonAllocDmaRegion(radeonContextPtr rmesa, ++ struct radeon_bo **pbo, int *poffset, ++ int bytes, int alignment) ++{ ++ if (RADEON_DEBUG & DEBUG_IOCTL) ++ fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); ++ ++ if (rmesa->dma.flush) ++ rmesa->dma.flush(rmesa->glCtx); ++ ++ assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr); ++ ++ alignment--; ++ rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment; ++ ++ if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size) ++ radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15); ++ ++ *poffset = rmesa->dma.current_used; ++ *pbo = rmesa->dma.current; ++ radeon_bo_ref(*pbo); ++ ++ /* Always align to at least 16 bytes */ ++ rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15; ++ rmesa->dma.current_vertexptr = rmesa->dma.current_used; ++ ++ assert(rmesa->dma.current_used <= rmesa->dma.current->size); ++} ++ ++void radeonReleaseDmaRegion(radeonContextPtr rmesa) ++{ ++ if (RADEON_DEBUG & DEBUG_IOCTL) ++ fprintf(stderr, "%s %p\n", __FUNCTION__, rmesa->dma.current); ++ if (rmesa->dma.current) { ++ rmesa->dma.nr_released_bufs++; ++ radeon_bo_unmap(rmesa->dma.current); ++ radeon_bo_unref(rmesa->dma.current); ++ } ++ rmesa->dma.current = NULL; ++} ++ ++ ++/* Flush vertices in the current dma region. ++ */ ++void rcommon_flush_last_swtcl_prim( GLcontext *ctx ) ++{ ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ struct radeon_dma *dma = &rmesa->dma; ++ ++ ++ if (RADEON_DEBUG & DEBUG_IOCTL) ++ fprintf(stderr, "%s %p\n", __FUNCTION__, dma->current); ++ dma->flush = NULL; ++ ++ if (dma->current) { ++ GLuint current_offset = dma->current_used; ++ ++ assert (dma->current_used + ++ rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == ++ dma->current_vertexptr); ++ ++ if (dma->current_used != dma->current_vertexptr) { ++ dma->current_used = dma->current_vertexptr; ++ ++ rmesa->vtbl.swtcl_flush(ctx, current_offset); ++ } ++ rmesa->swtcl.numverts = 0; ++ } ++} ++/* Alloc space in the current dma region. ++ */ ++void * ++rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) ++{ ++ GLuint bytes = vsize * nverts; ++ void *head; ++restart: ++ if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) { ++ radeonRefillCurrentDmaRegion(rmesa, bytes); ++ } ++ ++ if (!rmesa->dma.flush) { ++ /* make sure we have enough space to use this in cmdbuf */ ++ rcommonEnsureCmdBufSpace(rmesa, ++ rmesa->hw.max_state_size + (12*sizeof(int)), ++ __FUNCTION__); ++ /* if cmdbuf flushed DMA restart */ ++ if (!rmesa->dma.current) ++ goto restart; ++ rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; ++ rmesa->dma.flush = rcommon_flush_last_swtcl_prim; ++ } ++ ++ ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); ++ ASSERT( rmesa->dma.flush == rcommon_flush_last_swtcl_prim ); ++ ASSERT( rmesa->dma.current_used + ++ rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == ++ rmesa->dma.current_vertexptr ); ++ ++ head = (rmesa->dma.current->ptr + rmesa->dma.current_vertexptr); ++ rmesa->dma.current_vertexptr += bytes; ++ rmesa->swtcl.numverts += nverts; ++ return head; ++} ++ ++void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs ) ++{ ++ radeonContextPtr radeon = RADEON_CONTEXT( ctx ); ++ int i; ++ ++ if (radeon->tcl.elt_dma_bo) { ++ radeon_bo_unref(radeon->tcl.elt_dma_bo); ++ radeon->tcl.elt_dma_bo = NULL; ++ } ++ for (i = 0; i < radeon->tcl.aos_count; i++) { ++ if (radeon->tcl.aos[i].bo) { ++ radeon_bo_unref(radeon->tcl.aos[i].bo); ++ radeon->tcl.aos[i].bo = NULL; ++ } ++ } ++} +diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.h b/src/mesa/drivers/dri/radeon/radeon_dma.h +new file mode 100644 +index 0000000..06e388f +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_dma.h +@@ -0,0 +1,52 @@ ++/************************************************************************** ++ ++Copyright (C) 2004 Nicolai Haehnle. ++Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. ++ ++The Weather Channel (TM) funded Tungsten Graphics to develop the ++initial release of the Radeon 8500 driver under the XFree86 license. ++This notice must be preserved. ++ ++All Rights Reserved. ++ ++Permission is hereby granted, free of charge, to any person obtaining a ++copy of this software and associated documentation files (the "Software"), ++to deal in the Software without restriction, including without limitation ++on the rights to use, copy, modify, merge, publish, distribute, sub ++license, and/or sell copies of the Software, and to permit persons to whom ++the Software is furnished to do so, subject to the following conditions: ++ ++The above copyright notice and this permission notice (including the next ++paragraph) shall be included in all copies or substantial portions of the ++Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, ++DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++USE OR OTHER DEALINGS IN THE SOFTWARE. ++ ++**************************************************************************/ ++ ++#ifndef RADEON_DMA_H ++#define RADEON_DMA_H ++ ++void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count); ++void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count); ++ ++void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, ++ GLvoid * data, int size, int stride, int count); ++ ++void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size); ++void radeonAllocDmaRegion(radeonContextPtr rmesa, ++ struct radeon_bo **pbo, int *poffset, ++ int bytes, int alignment); ++void radeonReleaseDmaRegion(radeonContextPtr rmesa); ++ ++void rcommon_flush_last_swtcl_prim(GLcontext *ctx); ++ ++void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize); ++void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs ); ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c +new file mode 100644 +index 0000000..f62ca7f +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c +@@ -0,0 +1,588 @@ ++/************************************************************************** ++ * ++ * Copyright 2008 Red Hat Inc. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ++ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ++ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ++ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ **************************************************************************/ ++ ++ ++#include "main/imports.h" ++#include "main/macros.h" ++#include "main/mtypes.h" ++#include "main/fbobject.h" ++#include "main/framebuffer.h" ++#include "main/renderbuffer.h" ++#include "main/context.h" ++#include "main/texformat.h" ++#include "main/texrender.h" ++ ++#include "radeon_common.h" ++#include "radeon_mipmap_tree.h" ++ ++#define FILE_DEBUG_FLAG DEBUG_TEXTURE ++#define DBG(...) do { \ ++ if (RADEON_DEBUG & FILE_DEBUG_FLAG) \ ++ _mesa_printf(__VA_ARGS__); \ ++} while(0) ++ ++static struct gl_framebuffer * ++radeon_new_framebuffer(GLcontext *ctx, GLuint name) ++{ ++ return _mesa_new_framebuffer(ctx, name); ++} ++ ++static void ++radeon_delete_renderbuffer(struct gl_renderbuffer *rb) ++{ ++ struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); ++ ++ ASSERT(rrb); ++ ++ if (rrb && rrb->bo) { ++ radeon_bo_unref(rrb->bo); ++ } ++ _mesa_free(rrb); ++} ++ ++static void * ++radeon_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, ++ GLint x, GLint y) ++{ ++ return NULL; ++} ++ ++/** ++ * Called via glRenderbufferStorageEXT() to set the format and allocate ++ * storage for a user-created renderbuffer. ++ */ ++static GLboolean ++radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, ++ GLenum internalFormat, ++ GLuint width, GLuint height) ++{ ++ struct radeon_context *radeon = RADEON_CONTEXT(ctx); ++ struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); ++ GLboolean software_buffer = GL_FALSE; ++ int cpp; ++ ++ ASSERT(rb->Name != 0); ++ switch (internalFormat) { ++ case GL_R3_G3_B2: ++ case GL_RGB4: ++ case GL_RGB5: ++ rb->_ActualFormat = GL_RGB5; ++ rb->DataType = GL_UNSIGNED_BYTE; ++ rb->RedBits = 5; ++ rb->GreenBits = 6; ++ rb->BlueBits = 5; ++ cpp = 2; ++ break; ++ case GL_RGB: ++ case GL_RGB8: ++ case GL_RGB10: ++ case GL_RGB12: ++ case GL_RGB16: ++ rb->_ActualFormat = GL_RGB8; ++ rb->DataType = GL_UNSIGNED_BYTE; ++ rb->RedBits = 8; ++ rb->GreenBits = 8; ++ rb->BlueBits = 8; ++ rb->AlphaBits = 0; ++ cpp = 4; ++ break; ++ case GL_RGBA: ++ case GL_RGBA2: ++ case GL_RGBA4: ++ case GL_RGB5_A1: ++ case GL_RGBA8: ++ case GL_RGB10_A2: ++ case GL_RGBA12: ++ case GL_RGBA16: ++ rb->_ActualFormat = GL_RGBA8; ++ rb->DataType = GL_UNSIGNED_BYTE; ++ rb->RedBits = 8; ++ rb->GreenBits = 8; ++ rb->BlueBits = 8; ++ rb->AlphaBits = 8; ++ cpp = 4; ++ break; ++ case GL_STENCIL_INDEX: ++ case GL_STENCIL_INDEX1_EXT: ++ case GL_STENCIL_INDEX4_EXT: ++ case GL_STENCIL_INDEX8_EXT: ++ case GL_STENCIL_INDEX16_EXT: ++ /* alloc a depth+stencil buffer */ ++ rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; ++ rb->DataType = GL_UNSIGNED_INT_24_8_EXT; ++ rb->StencilBits = 8; ++ cpp = 4; ++ break; ++ case GL_DEPTH_COMPONENT16: ++ rb->_ActualFormat = GL_DEPTH_COMPONENT16; ++ rb->DataType = GL_UNSIGNED_SHORT; ++ rb->DepthBits = 16; ++ cpp = 2; ++ break; ++ case GL_DEPTH_COMPONENT: ++ case GL_DEPTH_COMPONENT24: ++ case GL_DEPTH_COMPONENT32: ++ rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; ++ rb->DataType = GL_UNSIGNED_INT_24_8_EXT; ++ rb->DepthBits = 24; ++ cpp = 4; ++ break; ++ case GL_DEPTH_STENCIL_EXT: ++ case GL_DEPTH24_STENCIL8_EXT: ++ rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; ++ rb->DataType = GL_UNSIGNED_INT_24_8_EXT; ++ rb->DepthBits = 24; ++ rb->StencilBits = 8; ++ cpp = 4; ++ break; ++ default: ++ _mesa_problem(ctx, ++ "Unexpected format in intel_alloc_renderbuffer_storage"); ++ return GL_FALSE; ++ } ++ ++ radeonFlush(ctx); ++ ++ if (rrb->bo) ++ radeon_bo_unref(rrb->bo); ++ ++ ++ if (software_buffer) { ++ return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat, ++ width, height); ++ } ++ else { ++ uint32_t size = width * height * cpp; ++ uint32_t pitch = ((cpp * width + 63) & ~63) / cpp; ++ ++ fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width, ++ height, pitch); ++ ++ rrb->pitch = pitch * cpp; ++ rrb->cpp = cpp; ++ rrb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ 0, ++ size, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ rb->Width = width; ++ rb->Height = height; ++ return GL_TRUE; ++ } ++ ++} ++ ++ ++/** ++ * Called for each hardware renderbuffer when a _window_ is resized. ++ * Just update fields. ++ * Not used for user-created renderbuffers! ++ */ ++static GLboolean ++radeon_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb, ++ GLenum internalFormat, GLuint width, GLuint height) ++{ ++ ASSERT(rb->Name == 0); ++ rb->Width = width; ++ rb->Height = height; ++ rb->_ActualFormat = internalFormat; ++ ++ return GL_TRUE; ++} ++ ++ ++static void ++radeon_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb, ++ GLuint width, GLuint height) ++{ ++ struct radeon_framebuffer *radeon_fb = (struct radeon_framebuffer*)fb; ++ int i; ++ ++ _mesa_resize_framebuffer(ctx, fb, width, height); ++ ++ fb->Initialized = GL_TRUE; /* XXX remove someday */ ++ ++ if (fb->Name != 0) { ++ return; ++ } ++ ++ /* Make sure all window system renderbuffers are up to date */ ++ for (i = 0; i < 2; i++) { ++ struct gl_renderbuffer *rb = &radeon_fb->color_rb[i]->base; ++ ++ /* only resize if size is changing */ ++ if (rb && (rb->Width != width || rb->Height != height)) { ++ rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height); ++ } ++ } ++} ++ ++ ++/** Dummy function for gl_renderbuffer::AllocStorage() */ ++static GLboolean ++radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, ++ GLenum internalFormat, GLuint width, GLuint height) ++{ ++ _mesa_problem(ctx, "radeon_op_alloc_storage should never be called."); ++ return GL_FALSE; ++} ++ ++struct radeon_renderbuffer * ++radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv) ++{ ++ struct radeon_renderbuffer *rrb; ++ ++ rrb = CALLOC_STRUCT(radeon_renderbuffer); ++ if (!rrb) ++ return NULL; ++ ++ _mesa_init_renderbuffer(&rrb->base, 0); ++ rrb->base.ClassID = RADEON_RB_CLASS; ++ ++ /* XXX format junk */ ++ switch (format) { ++ case GL_RGB5: ++ rrb->base._ActualFormat = GL_RGB5; ++ rrb->base._BaseFormat = GL_RGBA; ++ rrb->base.RedBits = 5; ++ rrb->base.GreenBits = 6; ++ rrb->base.BlueBits = 5; ++ rrb->base.DataType = GL_UNSIGNED_BYTE; ++ break; ++ case GL_RGB8: ++ rrb->base._ActualFormat = GL_RGB8; ++ rrb->base._BaseFormat = GL_RGB; ++ rrb->base.RedBits = 8; ++ rrb->base.GreenBits = 8; ++ rrb->base.BlueBits = 8; ++ rrb->base.AlphaBits = 8; ++ rrb->base.DataType = GL_UNSIGNED_BYTE; ++ break; ++ case GL_RGBA8: ++ rrb->base._ActualFormat = GL_RGBA8; ++ rrb->base._BaseFormat = GL_RGBA; ++ rrb->base.RedBits = 8; ++ rrb->base.GreenBits = 8; ++ rrb->base.BlueBits = 8; ++ rrb->base.AlphaBits = 8; ++ rrb->base.DataType = GL_UNSIGNED_BYTE; ++ break; ++ case GL_STENCIL_INDEX8_EXT: ++ rrb->base._ActualFormat = GL_STENCIL_INDEX8_EXT; ++ rrb->base._BaseFormat = GL_STENCIL_INDEX; ++ rrb->base.StencilBits = 8; ++ rrb->base.DataType = GL_UNSIGNED_BYTE; ++ break; ++ case GL_DEPTH_COMPONENT16: ++ rrb->base._ActualFormat = GL_DEPTH_COMPONENT16; ++ rrb->base._BaseFormat = GL_DEPTH_COMPONENT; ++ rrb->base.DepthBits = 16; ++ rrb->base.DataType = GL_UNSIGNED_SHORT; ++ break; ++ case GL_DEPTH_COMPONENT24: ++ rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; ++ rrb->base._BaseFormat = GL_DEPTH_COMPONENT; ++ rrb->base.DepthBits = 24; ++ rrb->base.DataType = GL_UNSIGNED_INT; ++ break; ++ case GL_DEPTH24_STENCIL8_EXT: ++ rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; ++ rrb->base._BaseFormat = GL_DEPTH_STENCIL_EXT; ++ rrb->base.DepthBits = 24; ++ rrb->base.StencilBits = 8; ++ rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT; ++ break; ++ default: ++ fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format); ++ _mesa_delete_renderbuffer(&rrb->base); ++ return NULL; ++ } ++ ++ rrb->dPriv = driDrawPriv; ++ rrb->base.InternalFormat = format; ++ ++ rrb->base.Delete = radeon_delete_renderbuffer; ++ rrb->base.AllocStorage = radeon_alloc_window_storage; ++ rrb->base.GetPointer = radeon_get_pointer; ++ ++ rrb->bo = NULL; ++ return rrb; ++} ++ ++static struct gl_renderbuffer * ++radeon_new_renderbuffer(GLcontext * ctx, GLuint name) ++{ ++ struct radeon_renderbuffer *rrb; ++ ++ rrb = CALLOC_STRUCT(radeon_renderbuffer); ++ if (!rrb) ++ return NULL; ++ ++ _mesa_init_renderbuffer(&rrb->base, name); ++ rrb->base.ClassID = RADEON_RB_CLASS; ++ ++ rrb->base.Delete = radeon_delete_renderbuffer; ++ rrb->base.AllocStorage = radeon_alloc_renderbuffer_storage; ++ rrb->base.GetPointer = radeon_get_pointer; ++ ++ return &rrb->base; ++} ++ ++static void ++radeon_bind_framebuffer(GLcontext * ctx, GLenum target, ++ struct gl_framebuffer *fb, struct gl_framebuffer *fbread) ++{ ++ if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { ++ radeon_draw_buffer(ctx, fb); ++ } ++ else { ++ /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ ++ } ++} ++ ++static void ++radeon_framebuffer_renderbuffer(GLcontext * ctx, ++ struct gl_framebuffer *fb, ++ GLenum attachment, struct gl_renderbuffer *rb) ++{ ++ ++ radeonFlush(ctx); ++ ++ _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); ++ radeon_draw_buffer(ctx, fb); ++} ++ ++ ++static GLboolean ++radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb, ++ struct gl_texture_image *texImage) ++{ ++ int retry = 0; ++restart: ++ if (texImage->TexFormat == &_mesa_texformat_argb8888) { ++ rrb->cpp = 4; ++ rrb->base._ActualFormat = GL_RGBA8; ++ rrb->base._BaseFormat = GL_RGBA; ++ rrb->base.DataType = GL_UNSIGNED_BYTE; ++ DBG("Render to RGBA8 texture OK\n"); ++ } ++ else if (texImage->TexFormat == &_mesa_texformat_rgb565) { ++ rrb->cpp = 2; ++ rrb->base._ActualFormat = GL_RGB5; ++ rrb->base._BaseFormat = GL_RGB; ++ rrb->base.DataType = GL_UNSIGNED_SHORT; ++ DBG("Render to RGB5 texture OK\n"); ++ } ++ else if (texImage->TexFormat == &_mesa_texformat_z16) { ++ rrb->cpp = 2; ++ rrb->base._ActualFormat = GL_DEPTH_COMPONENT16; ++ rrb->base._BaseFormat = GL_DEPTH_COMPONENT; ++ rrb->base.DataType = GL_UNSIGNED_SHORT; ++ DBG("Render to DEPTH16 texture OK\n"); ++ } ++ else if (texImage->TexFormat == &_mesa_texformat_s8_z24) { ++ rrb->cpp = 4; ++ rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; ++ rrb->base._BaseFormat = GL_DEPTH_STENCIL_EXT; ++ rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT; ++ DBG("Render to DEPTH_STENCIL texture OK\n"); ++ } ++ else { ++ /* try redoing the FBO */ ++ if (retry == 1) { ++ DBG("Render to texture BAD FORMAT %d\n", ++ texImage->TexFormat->MesaFormat); ++ return GL_FALSE; ++ } ++ texImage->TexFormat = radeonChooseTextureFormat(ctx, texImage->InternalFormat, 0, ++ texImage->TexFormat->DataType, ++ 1); ++ ++ retry++; ++ goto restart; ++ } ++ ++ rrb->pitch = texImage->Width * rrb->cpp; ++ rrb->base.InternalFormat = rrb->base._ActualFormat; ++ rrb->base.Width = texImage->Width; ++ rrb->base.Height = texImage->Height; ++ rrb->base.RedBits = texImage->TexFormat->RedBits; ++ rrb->base.GreenBits = texImage->TexFormat->GreenBits; ++ rrb->base.BlueBits = texImage->TexFormat->BlueBits; ++ rrb->base.AlphaBits = texImage->TexFormat->AlphaBits; ++ rrb->base.DepthBits = texImage->TexFormat->DepthBits; ++ ++ rrb->base.Delete = radeon_delete_renderbuffer; ++ rrb->base.AllocStorage = radeon_nop_alloc_storage; ++ ++ return GL_TRUE; ++} ++ ++ ++static struct radeon_renderbuffer * ++radeon_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) ++{ ++ const GLuint name = ~0; /* not significant, but distinct for debugging */ ++ struct radeon_renderbuffer *rrb; ++ ++ /* make an radeon_renderbuffer to wrap the texture image */ ++ rrb = CALLOC_STRUCT(radeon_renderbuffer); ++ if (!rrb) { ++ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); ++ return NULL; ++ } ++ ++ _mesa_init_renderbuffer(&rrb->base, name); ++ rrb->base.ClassID = RADEON_RB_CLASS; ++ ++ if (!radeon_update_wrapper(ctx, rrb, texImage)) { ++ _mesa_free(rrb); ++ return NULL; ++ } ++ ++ return rrb; ++ ++} ++static void ++radeon_render_texture(GLcontext * ctx, ++ struct gl_framebuffer *fb, ++ struct gl_renderbuffer_attachment *att) ++{ ++ struct gl_texture_image *newImage ++ = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; ++ struct radeon_renderbuffer *rrb = radeon_renderbuffer(att->Renderbuffer); ++ radeon_texture_image *radeon_image; ++ GLuint imageOffset; ++ ++ (void) fb; ++ ++ ASSERT(newImage); ++ ++ if (newImage->Border != 0) { ++ /* Fallback on drawing to a texture with a border, which won't have a ++ * miptree. ++ */ ++ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); ++ _mesa_render_texture(ctx, fb, att); ++ return; ++ } ++ else if (!rrb) { ++ rrb = radeon_wrap_texture(ctx, newImage); ++ if (rrb) { ++ /* bind the wrapper to the attachment point */ ++ _mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base); ++ } ++ else { ++ /* fallback to software rendering */ ++ _mesa_render_texture(ctx, fb, att); ++ return; ++ } ++ } ++ ++ if (!radeon_update_wrapper(ctx, rrb, newImage)) { ++ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); ++ _mesa_render_texture(ctx, fb, att); ++ return; ++ } ++ ++ DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", ++ _glthread_GetID(), ++ att->Texture->Name, newImage->Width, newImage->Height, ++ rrb->base.RefCount); ++ ++ /* point the renderbufer's region to the texture image region */ ++ radeon_image = (radeon_texture_image *)newImage; ++ if (rrb->bo != radeon_image->mt->bo) { ++ if (rrb->bo) ++ radeon_bo_unref(rrb->bo); ++ rrb->bo = radeon_image->mt->bo; ++ radeon_bo_ref(rrb->bo); ++ } ++ ++ /* compute offset of the particular 2D image within the texture region */ ++ imageOffset = radeon_miptree_image_offset(radeon_image->mt, ++ att->CubeMapFace, ++ att->TextureLevel); ++ ++ if (att->Texture->Target == GL_TEXTURE_3D) { ++ GLuint offsets[6]; ++ radeon_miptree_depth_offsets(radeon_image->mt, att->TextureLevel, ++ offsets); ++ imageOffset += offsets[att->Zoffset]; ++ } ++ ++ /* store that offset in the region */ ++ rrb->draw_offset = imageOffset; ++ ++ /* update drawing region, etc */ ++ radeon_draw_buffer(ctx, fb); ++} ++ ++static void ++radeon_finish_render_texture(GLcontext * ctx, ++ struct gl_renderbuffer_attachment *att) ++{ ++ ++} ++static void ++radeon_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) ++{ ++} ++ ++static void ++radeon_blit_framebuffer(GLcontext *ctx, ++ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, ++ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, ++ GLbitfield mask, GLenum filter) ++{ ++} ++ ++void radeon_fbo_init(struct radeon_context *radeon) ++{ ++ radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer; ++ radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer; ++ radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer; ++ radeon->glCtx->Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer; ++ radeon->glCtx->Driver.RenderTexture = radeon_render_texture; ++ radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture; ++ radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers; ++ radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer; ++ radeon->glCtx->Driver.BlitFramebuffer = radeon_blit_framebuffer; ++} ++ ++ ++void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, ++ struct radeon_bo *bo) ++{ ++ struct radeon_bo *old; ++ old = rb->bo; ++ rb->bo = bo; ++ radeon_bo_ref(bo); ++ if (old) ++ radeon_bo_unref(old); ++} +diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c +index 09acf6b..b5fde6d 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c ++++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c +@@ -37,12 +37,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include + #include + ++#include "main/attrib.h" ++#include "main/enable.h" ++#include "main/blend.h" ++#include "main/bufferobj.h" ++#include "main/buffers.h" ++#include "main/depth.h" ++#include "main/shaders.h" ++#include "main/texstate.h" ++#include "main/varray.h" ++#include "glapi/dispatch.h" ++#include "swrast/swrast.h" ++#include "main/stencil.h" ++#include "main/matrix.h" ++ + #include "main/glheader.h" + #include "main/imports.h" + #include "main/simple_list.h" + #include "swrast/swrast.h" + + #include "radeon_context.h" ++#include "radeon_common.h" + #include "radeon_state.h" + #include "radeon_ioctl.h" + #include "radeon_tcl.h" +@@ -58,75 +73,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define RADEON_IDLE_RETRY 16 + + +-static void radeonWaitForIdle( radeonContextPtr rmesa ); +-static int radeonFlushCmdBufLocked( radeonContextPtr rmesa, +- const char * caller ); +- +-static void print_state_atom( struct radeon_state_atom *state ) +-{ +- int i; +- +- fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); +- +- if (RADEON_DEBUG & DEBUG_VERBOSE) +- for (i = 0 ; i < state->cmd_size ; i++) +- fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); +- +-} +- +-static void radeonSaveHwState( radeonContextPtr rmesa ) +-{ +- struct radeon_state_atom *atom; +- char * dest = rmesa->backup_store.cmd_buf; +- +- if (RADEON_DEBUG & DEBUG_STATE) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- rmesa->backup_store.cmd_used = 0; +- +- foreach( atom, &rmesa->hw.atomlist ) { +- if ( atom->check( rmesa->glCtx ) ) { +- int size = atom->cmd_size * 4; +- memcpy( dest, atom->cmd, size); +- dest += size; +- rmesa->backup_store.cmd_used += size; +- if (RADEON_DEBUG & DEBUG_STATE) +- print_state_atom( atom ); +- } +- } +- +- assert( rmesa->backup_store.cmd_used <= RADEON_CMD_BUF_SZ ); +- if (RADEON_DEBUG & DEBUG_STATE) +- fprintf(stderr, "Returning to radeonEmitState\n"); +-} +- +-/* At this point we were in FlushCmdBufLocked but we had lost our context, so +- * we need to unwire our current cmdbuf, hook the one with the saved state in +- * it, flush it, and then put the current one back. This is so commands at the +- * start of a cmdbuf can rely on the state being kept from the previous one. +- */ +-static void radeonBackUpAndEmitLostStateLocked( radeonContextPtr rmesa ) +-{ +- GLuint nr_released_bufs; +- struct radeon_store saved_store; +- +- if (rmesa->backup_store.cmd_used == 0) +- return; +- +- if (RADEON_DEBUG & DEBUG_STATE) +- fprintf(stderr, "Emitting backup state on lost context\n"); +- +- rmesa->lost_context = GL_FALSE; +- +- nr_released_bufs = rmesa->dma.nr_released_bufs; +- saved_store = rmesa->store; +- rmesa->dma.nr_released_bufs = 0; +- rmesa->store = rmesa->backup_store; +- radeonFlushCmdBufLocked( rmesa, __FUNCTION__ ); +- rmesa->dma.nr_released_bufs = nr_released_bufs; +- rmesa->store = saved_store; +-} +- + /* ============================================================= + * Kernel command buffer handling + */ +@@ -134,965 +80,360 @@ static void radeonBackUpAndEmitLostStateLocked( radeonContextPtr rmesa ) + /* The state atoms will be emitted in the order they appear in the atom list, + * so this step is important. + */ +-void radeonSetUpAtomList( radeonContextPtr rmesa ) ++void radeonSetUpAtomList( r100ContextPtr rmesa ) + { +- int i, mtu = rmesa->glCtx->Const.MaxTextureUnits; +- +- make_empty_list(&rmesa->hw.atomlist); +- rmesa->hw.atomlist.name = "atom-list"; +- +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ctx); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.set); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lin); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msk); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.vpt); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tcl); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msc); ++ int i, mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits; ++ ++ make_empty_list(&rmesa->radeon.hw.atomlist); ++ rmesa->radeon.hw.atomlist.name = "atom-list"; ++ ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ctx); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.set); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lin); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msk); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.vpt); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tcl); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msc); + for (i = 0; i < mtu; ++i) { +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tex[i]); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.txr[i]); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.cube[i]); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i]); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.txr[i]); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i]); + } +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.zbs); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mtl); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.zbs); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mtl); + for (i = 0; i < 3 + mtu; ++i) +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mat[i]); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i]); + for (i = 0; i < 8; ++i) +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lit[i]); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]); + for (i = 0; i < 6; ++i) +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ucp[i]); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.eye); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.grd); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.fog); +- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.glt); +-} +- +-void radeonEmitState( radeonContextPtr rmesa ) +-{ +- struct radeon_state_atom *atom; +- char *dest; +- +- if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- if (rmesa->save_on_next_emit) { +- radeonSaveHwState(rmesa); +- rmesa->save_on_next_emit = GL_FALSE; +- } +- +- /* this code used to return here but now it emits zbs */ +- +- /* To avoid going across the entire set of states multiple times, just check +- * for enough space for the case of emitting all state, and inline the +- * radeonAllocCmdBuf code here without all the checks. +- */ +- radeonEnsureCmdBufSpace(rmesa, rmesa->hw.max_state_size); +- dest = rmesa->store.cmd_buf + rmesa->store.cmd_used; +- +- /* We always always emit zbs, this is due to a bug found by keithw in +- the hardware and rediscovered after Erics changes by me. +- if you ever touch this code make sure you emit zbs otherwise +- you get tcl lockups on at least M7/7500 class of chips - airlied */ +- rmesa->hw.zbs.dirty=1; +- +- if (RADEON_DEBUG & DEBUG_STATE) { +- foreach(atom, &rmesa->hw.atomlist) { +- if (atom->dirty || rmesa->hw.all_dirty) { +- if (atom->check(rmesa->glCtx)) +- print_state_atom(atom); +- else +- fprintf(stderr, "skip state %s\n", atom->name); +- } +- } +- } +- +- foreach(atom, &rmesa->hw.atomlist) { +- if (rmesa->hw.all_dirty) +- atom->dirty = GL_TRUE; +- if (!(rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) && +- atom->is_tcl) +- atom->dirty = GL_FALSE; +- if (atom->dirty) { +- if (atom->check(rmesa->glCtx)) { +- int size = atom->cmd_size * 4; +- memcpy(dest, atom->cmd, size); +- dest += size; +- rmesa->store.cmd_used += size; +- atom->dirty = GL_FALSE; +- } +- } +- } +- +- assert(rmesa->store.cmd_used <= RADEON_CMD_BUF_SZ); +- +- rmesa->hw.is_dirty = GL_FALSE; +- rmesa->hw.all_dirty = GL_FALSE; ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog); ++ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt); + } + + /* Fire a section of the retained (indexed_verts) buffer as a regular + * primtive. + */ +-extern void radeonEmitVbufPrim( radeonContextPtr rmesa, ++extern void radeonEmitVbufPrim( r100ContextPtr rmesa, + GLuint vertex_format, + GLuint primitive, + GLuint vertex_nr ) + { +- drm_radeon_cmd_header_t *cmd; +- ++ BATCH_LOCALS(&rmesa->radeon); + + assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); + +- radeonEmitState( rmesa ); ++ radeonEmitState(&rmesa->radeon); + +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s cmd_used/4: %d\n", __FUNCTION__, +- rmesa->store.cmd_used/4); +- +- cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VBUF_BUFSZ, +- __FUNCTION__ ); + #if RADEON_OLD_PACKETS +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; +- cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM | (3 << 16); +- cmd[2].i = rmesa->ioctl.vertex_offset; +- cmd[3].i = vertex_nr; +- cmd[4].i = vertex_format; +- cmd[5].i = (primitive | +- RADEON_CP_VC_CNTL_PRIM_WALK_LIST | +- RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | +- RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | +- (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT)); +- +- if (RADEON_DEBUG & DEBUG_PRIMS) +- fprintf(stderr, "%s: header 0x%x offt 0x%x vfmt 0x%x vfcntl %x \n", +- __FUNCTION__, +- cmd[1].i, cmd[2].i, cmd[4].i, cmd[5].i); +-#else +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; +- cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_VBUF | (1 << 16); +- cmd[2].i = vertex_format; +- cmd[3].i = (primitive | +- RADEON_CP_VC_CNTL_PRIM_WALK_LIST | +- RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | +- RADEON_CP_VC_CNTL_MAOS_ENABLE | +- RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | +- (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT)); +- +- +- if (RADEON_DEBUG & DEBUG_PRIMS) +- fprintf(stderr, "%s: header 0x%x vfmt 0x%x vfcntl %x \n", +- __FUNCTION__, +- cmd[1].i, cmd[2].i, cmd[3].i); ++ BEGIN_BATCH(8); ++ OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3); ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0); ++ } else { ++ OUT_BATCH(rmesa->ioctl.vertex_offset); ++ } ++ ++ OUT_BATCH(vertex_nr); ++ OUT_BATCH(vertex_format); ++ OUT_BATCH(primitive | RADEON_CP_VC_CNTL_PRIM_WALK_LIST | ++ RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | ++ RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | ++ (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT)); ++ ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->ioctl.bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++ ++ END_BATCH(); ++ ++#else ++ BEGIN_BATCH(4); ++ OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_DRAW_VBUF, 1); ++ OUT_BATCH(vertex_format); ++ OUT_BATCH(primitive | ++ RADEON_CP_VC_CNTL_PRIM_WALK_LIST | ++ RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | ++ RADEON_CP_VC_CNTL_MAOS_ENABLE | ++ RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | ++ (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT)); ++ END_BATCH(); + #endif + } + +- +-void radeonFlushElts( radeonContextPtr rmesa ) ++void radeonFlushElts( GLcontext *ctx ) + { +- int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start); +- int dwords; +-#if RADEON_OLD_PACKETS +- int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 24)) / 2; +-#else +- int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 16)) / 2; +-#endif +- ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ BATCH_LOCALS(&rmesa->radeon); ++ int nr; ++ uint32_t *cmd = (uint32_t *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_start); ++ int dwords = (rmesa->radeon.cmdbuf.cs->section_ndw - rmesa->radeon.cmdbuf.cs->section_cdw); ++ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + +- assert( rmesa->dma.flush == radeonFlushElts ); +- rmesa->dma.flush = NULL; ++ assert( rmesa->radeon.dma.flush == radeonFlushElts ); ++ rmesa->radeon.dma.flush = NULL; + +- /* Cope with odd number of elts: +- */ +- rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2; +- dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4; ++ nr = rmesa->tcl.elt_used; + + #if RADEON_OLD_PACKETS +- cmd[1] |= (dwords - 3) << 16; ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ dwords -= 2; ++ } ++#endif ++ ++#if RADEON_OLD_PACKETS ++ cmd[1] |= (dwords + 3) << 16; + cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT; + #else +- cmd[1] |= (dwords - 3) << 16; ++ cmd[1] |= (dwords + 2) << 16; + cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT; + #endif + ++ rmesa->radeon.cmdbuf.cs->cdw += dwords; ++ rmesa->radeon.cmdbuf.cs->section_cdw += dwords; ++ ++#if RADEON_OLD_PACKETS ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->ioctl.bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++#endif ++ ++ END_BATCH(); ++ + if (RADEON_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "%s: Syncing\n", __FUNCTION__); +- radeonFinish( rmesa->glCtx ); ++ radeonFinish( rmesa->radeon.glCtx ); + } +-} + ++} + +-GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa, ++GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa, + GLuint vertex_format, + GLuint primitive, + GLuint min_nr ) + { +- drm_radeon_cmd_header_t *cmd; + GLushort *retval; ++ int align_min_nr; ++ BATCH_LOCALS(&rmesa->radeon); + + if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s %d\n", __FUNCTION__, min_nr); ++ fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive); + + assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); + +- radeonEmitState( rmesa ); ++ radeonEmitState(&rmesa->radeon); + +- cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, +- ELTS_BUFSZ(min_nr), +- __FUNCTION__ ); ++ rmesa->tcl.elt_cmd_start = rmesa->radeon.cmdbuf.cs->cdw; ++ ++ /* round up min_nr to align the state */ ++ align_min_nr = (min_nr + 1) & ~1; ++ + #if RADEON_OLD_PACKETS +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; +- cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM; +- cmd[2].i = rmesa->ioctl.vertex_offset; +- cmd[3].i = 0xffff; +- cmd[4].i = vertex_format; +- cmd[5].i = (primitive | +- RADEON_CP_VC_CNTL_PRIM_WALK_IND | +- RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | +- RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE); +- +- retval = (GLushort *)(cmd+6); +-#else +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; +- cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_INDX; +- cmd[2].i = vertex_format; +- cmd[3].i = (primitive | +- RADEON_CP_VC_CNTL_PRIM_WALK_IND | +- RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | +- RADEON_CP_VC_CNTL_MAOS_ENABLE | +- RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE); +- +- retval = (GLushort *)(cmd+4); ++ BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(align_min_nr)/4); ++ OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 0); ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0); ++ } else { ++ OUT_BATCH(rmesa->ioctl.vertex_offset); ++ } ++ OUT_BATCH(0xffff); ++ OUT_BATCH(vertex_format); ++ OUT_BATCH(primitive | ++ RADEON_CP_VC_CNTL_PRIM_WALK_IND | ++ RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | ++ RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE); ++ ++#else ++ BEGIN_BATCH_NO_AUTOSTATE(ELTS_BUFSZ(align_min_nr)/4); ++ OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_DRAW_INDX, 0); ++ OUT_BATCH(vertex_format); ++ OUT_BATCH(primitive | ++ RADEON_CP_VC_CNTL_PRIM_WALK_IND | ++ RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | ++ RADEON_CP_VC_CNTL_MAOS_ENABLE | ++ RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE); + #endif + +- if (RADEON_DEBUG & DEBUG_PRIMS) +- fprintf(stderr, "%s: header 0x%x vfmt 0x%x prim %x \n", +- __FUNCTION__, +- cmd[1].i, vertex_format, primitive); + +- assert(!rmesa->dma.flush); +- rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; +- rmesa->dma.flush = radeonFlushElts; ++ rmesa->tcl.elt_cmd_offset = rmesa->radeon.cmdbuf.cs->cdw; ++ rmesa->tcl.elt_used = min_nr; ++ ++ retval = (GLushort *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_offset); ++ ++ if (RADEON_DEBUG & DEBUG_PRIMS) ++ fprintf(stderr, "%s: header prim %x \n", ++ __FUNCTION__, primitive); + +- rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf; ++ assert(!rmesa->radeon.dma.flush); ++ rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; ++ rmesa->radeon.dma.flush = radeonFlushElts; + + return retval; + } + +- +- +-void radeonEmitVertexAOS( radeonContextPtr rmesa, ++void radeonEmitVertexAOS( r100ContextPtr rmesa, + GLuint vertex_size, ++ struct radeon_bo *bo, + GLuint offset ) + { + #if RADEON_OLD_PACKETS +- rmesa->ioctl.vertex_size = vertex_size; + rmesa->ioctl.vertex_offset = offset; ++ rmesa->ioctl.bo = bo; + #else +- drm_radeon_cmd_header_t *cmd; ++ BATCH_LOCALS(&rmesa->radeon); + + if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL)) + fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n", + __FUNCTION__, vertex_size, offset); + +- cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VERT_AOS_BUFSZ, +- __FUNCTION__ ); ++ BEGIN_BATCH(7); ++ OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, 2); ++ OUT_BATCH(1); ++ OUT_BATCH(vertex_size | (vertex_size << 8)); ++ OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0); ++ END_BATCH(); + +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3; +- cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (2 << 16); +- cmd[2].i = 1; +- cmd[3].i = vertex_size | (vertex_size << 8); +- cmd[4].i = offset; + #endif + } + + +-void radeonEmitAOS( radeonContextPtr rmesa, +- struct radeon_dma_region **component, ++void radeonEmitAOS( r100ContextPtr rmesa, + GLuint nr, + GLuint offset ) + { + #if RADEON_OLD_PACKETS + assert( nr == 1 ); +- assert( component[0]->aos_size == component[0]->aos_stride ); +- rmesa->ioctl.vertex_size = component[0]->aos_size; ++ rmesa->ioctl.bo = rmesa->radeon.tcl.aos[0].bo; + rmesa->ioctl.vertex_offset = +- (component[0]->aos_start + offset * component[0]->aos_stride * 4); ++ (rmesa->radeon.tcl.aos[0].offset + offset * rmesa->radeon.tcl.aos[0].stride * 4); + #else +- drm_radeon_cmd_header_t *cmd; +- int sz = AOS_BUFSZ(nr); ++ BATCH_LOCALS(&rmesa->radeon); ++ uint32_t voffset; ++ // int sz = AOS_BUFSZ(nr); ++ int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2; + int i; +- int *tmp; + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + +- +- cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sz, +- __FUNCTION__ ); +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3; +- cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (((sz / sizeof(int))-3) << 16); +- cmd[2].i = nr; +- tmp = &cmd[0].i; +- cmd += 3; +- +- for (i = 0 ; i < nr ; i++) { +- if (i & 1) { +- cmd[0].i |= ((component[i]->aos_stride << 24) | +- (component[i]->aos_size << 16)); +- cmd[2].i = (component[i]->aos_start + +- offset * component[i]->aos_stride * 4); +- cmd += 3; +- } +- else { +- cmd[0].i = ((component[i]->aos_stride << 8) | +- (component[i]->aos_size << 0)); +- cmd[1].i = (component[i]->aos_start + +- offset * component[i]->aos_stride * 4); ++ BEGIN_BATCH(sz+2+(nr * 2)); ++ OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, sz - 1); ++ OUT_BATCH(nr); ++ ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ for (i = 0; i + 1 < nr; i += 2) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) | ++ (rmesa->radeon.tcl.aos[i].stride << 8) | ++ (rmesa->radeon.tcl.aos[i + 1].components << 16) | ++ (rmesa->radeon.tcl.aos[i + 1].stride << 24)); ++ ++ voffset = rmesa->radeon.tcl.aos[i + 0].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->radeon.tcl.aos[i].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ voffset = rmesa->radeon.tcl.aos[i + 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->radeon.tcl.aos[i+1].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); + } +- } +- +- if (RADEON_DEBUG & DEBUG_VERTS) { +- fprintf(stderr, "%s:\n", __FUNCTION__); +- for (i = 0 ; i < sz ; i++) +- fprintf(stderr, " %d: %x\n", i, tmp[i]); +- } +-#endif +-} +- +-/* using already shifted color_fmt! */ +-void radeonEmitBlit( radeonContextPtr rmesa, /* FIXME: which drmMinor is required? */ +- GLuint color_fmt, +- GLuint src_pitch, +- GLuint src_offset, +- GLuint dst_pitch, +- GLuint dst_offset, +- GLint srcx, GLint srcy, +- GLint dstx, GLint dsty, +- GLuint w, GLuint h ) +-{ +- drm_radeon_cmd_header_t *cmd; +- +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n", +- __FUNCTION__, +- src_pitch, src_offset, srcx, srcy, +- dst_pitch, dst_offset, dstx, dsty, +- w, h); +- +- assert( (src_pitch & 63) == 0 ); +- assert( (dst_pitch & 63) == 0 ); +- assert( (src_offset & 1023) == 0 ); +- assert( (dst_offset & 1023) == 0 ); +- assert( w < (1<<16) ); +- assert( h < (1<<16) ); +- +- cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 8 * sizeof(int), +- __FUNCTION__ ); +- +- +- cmd[0].i = 0; +- cmd[0].header.cmd_type = RADEON_CMD_PACKET3; +- cmd[1].i = RADEON_CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16); +- cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | +- RADEON_GMC_DST_PITCH_OFFSET_CNTL | +- RADEON_GMC_BRUSH_NONE | +- color_fmt | +- RADEON_GMC_SRC_DATATYPE_COLOR | +- RADEON_ROP3_S | +- RADEON_DP_SRC_SOURCE_MEMORY | +- RADEON_GMC_CLR_CMP_CNTL_DIS | +- RADEON_GMC_WR_MSK_DIS ); +- +- cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10); +- cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10); +- cmd[5].i = (srcx << 16) | srcy; +- cmd[6].i = (dstx << 16) | dsty; /* dst */ +- cmd[7].i = (w << 16) | h; +-} +- +- +-void radeonEmitWait( radeonContextPtr rmesa, GLuint flags ) +-{ +- drm_radeon_cmd_header_t *cmd; +- +- assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) ); +- +- cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 1 * sizeof(int), +- __FUNCTION__ ); +- cmd[0].i = 0; +- cmd[0].wait.cmd_type = RADEON_CMD_WAIT; +- cmd[0].wait.flags = flags; +-} +- +- +-static int radeonFlushCmdBufLocked( radeonContextPtr rmesa, +- const char * caller ) +-{ +- int ret, i; +- drm_radeon_cmd_buffer_t cmd; +- +- if (rmesa->lost_context) +- radeonBackUpAndEmitLostStateLocked(rmesa); +- +- if (RADEON_DEBUG & DEBUG_IOCTL) { +- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); +- +- if (RADEON_DEBUG & DEBUG_VERBOSE) +- for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 ) +- fprintf(stderr, "%d: %x\n", i/4, +- *(int *)(&rmesa->store.cmd_buf[i])); +- } +- +- if (RADEON_DEBUG & DEBUG_DMA) +- fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__, +- rmesa->dma.nr_released_bufs); +- +- +- if (RADEON_DEBUG & DEBUG_SANITY) { +- if (rmesa->state.scissor.enabled) +- ret = radeonSanityCmdBuffer( rmesa, +- rmesa->state.scissor.numClipRects, +- rmesa->state.scissor.pClipRects); +- else +- ret = radeonSanityCmdBuffer( rmesa, +- rmesa->numClipRects, +- rmesa->pClipRects); +- if (ret) { +- fprintf(stderr, "drmSanityCommandWrite: %d\n", ret); +- goto out; ++ ++ if (nr & 1) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | ++ (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); ++ voffset = rmesa->radeon.tcl.aos[nr - 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->radeon.tcl.aos[nr - 1].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); + } +- } +- +- +- cmd.bufsz = rmesa->store.cmd_used; +- cmd.buf = rmesa->store.cmd_buf; +- +- if (rmesa->state.scissor.enabled) { +- cmd.nbox = rmesa->state.scissor.numClipRects; +- cmd.boxes = rmesa->state.scissor.pClipRects; + } else { +- cmd.nbox = rmesa->numClipRects; +- cmd.boxes = rmesa->pClipRects; +- } +- +- ret = drmCommandWrite( rmesa->dri.fd, +- DRM_RADEON_CMDBUF, +- &cmd, sizeof(cmd) ); +- +- if (ret) +- fprintf(stderr, "drmCommandWrite: %d\n", ret); +- +- if (RADEON_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); +- radeonWaitForIdleLocked( rmesa ); +- } +- +- out: +- rmesa->store.primnr = 0; +- rmesa->store.statenr = 0; +- rmesa->store.cmd_used = 0; +- rmesa->dma.nr_released_bufs = 0; +- rmesa->save_on_next_emit = 1; +- +- return ret; +-} +- +- +-/* Note: does not emit any commands to avoid recursion on +- * radeonAllocCmdBuf. +- */ +-void radeonFlushCmdBuf( radeonContextPtr rmesa, const char *caller ) +-{ +- int ret; +- +- +- LOCK_HARDWARE( rmesa ); +- +- ret = radeonFlushCmdBufLocked( rmesa, caller ); +- +- UNLOCK_HARDWARE( rmesa ); +- +- if (ret) { +- fprintf(stderr, "drm_radeon_cmd_buffer_t: %d (exiting)\n", ret); +- exit(ret); +- } +-} +- +-/* ============================================================= +- * Hardware vertex buffer handling +- */ +- +- +-void radeonRefillCurrentDmaRegion( radeonContextPtr rmesa ) +-{ +- struct radeon_dma_buffer *dmabuf; +- int fd = rmesa->dri.fd; +- int index = 0; +- int size = 0; +- drmDMAReq dma; +- int ret; +- +- if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- if (rmesa->dma.flush) { +- rmesa->dma.flush( rmesa ); +- } +- +- if (rmesa->dma.current.buf) +- radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); +- +- if (rmesa->dma.nr_released_bufs > 4) +- radeonFlushCmdBuf( rmesa, __FUNCTION__ ); +- +- dma.context = rmesa->dri.hwContext; +- dma.send_count = 0; +- dma.send_list = NULL; +- dma.send_sizes = NULL; +- dma.flags = 0; +- dma.request_count = 1; +- dma.request_size = RADEON_BUFFER_SIZE; +- dma.request_list = &index; +- dma.request_sizes = &size; +- dma.granted_count = 0; +- +- LOCK_HARDWARE(rmesa); /* no need to validate */ +- +- ret = drmDMA( fd, &dma ); +- +- if (ret != 0) { +- /* Free some up this way? +- */ +- if (rmesa->dma.nr_released_bufs) { +- radeonFlushCmdBufLocked( rmesa, __FUNCTION__ ); ++ for (i = 0; i + 1 < nr; i += 2) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) | ++ (rmesa->radeon.tcl.aos[i].stride << 8) | ++ (rmesa->radeon.tcl.aos[i + 1].components << 16) | ++ (rmesa->radeon.tcl.aos[i + 1].stride << 24)); ++ ++ voffset = rmesa->radeon.tcl.aos[i + 0].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; ++ OUT_BATCH(voffset); ++ voffset = rmesa->radeon.tcl.aos[i + 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; ++ OUT_BATCH(voffset); + } + +- if (RADEON_DEBUG & DEBUG_DMA) +- fprintf(stderr, "Waiting for buffers\n"); +- +- radeonWaitForIdleLocked( rmesa ); +- ret = drmDMA( fd, &dma ); +- +- if ( ret != 0 ) { +- UNLOCK_HARDWARE( rmesa ); +- fprintf( stderr, "Error: Could not get dma buffer... exiting\n" ); +- exit( -1 ); ++ if (nr & 1) { ++ OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | ++ (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); ++ voffset = rmesa->radeon.tcl.aos[nr - 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; ++ OUT_BATCH(voffset); + } +- } +- +- UNLOCK_HARDWARE(rmesa); +- +- if (RADEON_DEBUG & DEBUG_DMA) +- fprintf(stderr, "Allocated buffer %d\n", index); +- +- dmabuf = CALLOC_STRUCT( radeon_dma_buffer ); +- dmabuf->buf = &rmesa->radeonScreen->buffers->list[index]; +- dmabuf->refcount = 1; +- +- rmesa->dma.current.buf = dmabuf; +- rmesa->dma.current.address = dmabuf->buf->address; +- rmesa->dma.current.end = dmabuf->buf->total; +- rmesa->dma.current.start = 0; +- rmesa->dma.current.ptr = 0; +- +- rmesa->c_vertexBuffers++; +-} +- +-void radeonReleaseDmaRegion( radeonContextPtr rmesa, +- struct radeon_dma_region *region, +- const char *caller ) +-{ +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); +- +- if (!region->buf) +- return; +- +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); +- +- if (--region->buf->refcount == 0) { +- drm_radeon_cmd_header_t *cmd; +- +- if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) +- fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__, +- region->buf->buf->idx); +- +- cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sizeof(*cmd), +- __FUNCTION__ ); +- cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD; +- cmd->dma.buf_idx = region->buf->buf->idx; +- FREE(region->buf); +- rmesa->dma.nr_released_bufs++; +- } +- +- region->buf = NULL; +- region->start = 0; +-} +- +-/* Allocates a region from rmesa->dma.current. If there isn't enough +- * space in current, grab a new buffer (and discard what was left of current) +- */ +-void radeonAllocDmaRegion( radeonContextPtr rmesa, +- struct radeon_dma_region *region, +- int bytes, +- int alignment ) +-{ +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); +- +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); +- +- if (region->buf) +- radeonReleaseDmaRegion( rmesa, region, __FUNCTION__ ); +- +- alignment--; +- rmesa->dma.current.start = rmesa->dma.current.ptr = +- (rmesa->dma.current.ptr + alignment) & ~alignment; +- +- if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) +- radeonRefillCurrentDmaRegion( rmesa ); +- +- region->start = rmesa->dma.current.start; +- region->ptr = rmesa->dma.current.start; +- region->end = rmesa->dma.current.start + bytes; +- region->address = rmesa->dma.current.address; +- region->buf = rmesa->dma.current.buf; +- region->buf->refcount++; +- +- rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ +- rmesa->dma.current.start = +- rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7; +-} +- +-/* ================================================================ +- * SwapBuffers with client-side throttling +- */ +- +-static uint32_t radeonGetLastFrame (radeonContextPtr rmesa) +-{ +- drm_radeon_getparam_t gp; +- int ret; +- uint32_t frame; +- +- gp.param = RADEON_PARAM_LAST_FRAME; +- gp.value = (int *)&frame; +- ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM, +- &gp, sizeof(gp) ); +- +- if ( ret ) { +- fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret ); +- exit(1); +- } +- +- return frame; +-} +- +-static void radeonEmitIrqLocked( radeonContextPtr rmesa ) +-{ +- drm_radeon_irq_emit_t ie; +- int ret; +- +- ie.irq_seq = &rmesa->iw.irq_seq; +- ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_IRQ_EMIT, +- &ie, sizeof(ie) ); +- if ( ret ) { +- fprintf( stderr, "%s: drm_radeon_irq_emit_t: %d\n", __FUNCTION__, ret ); +- exit(1); +- } +-} +- +- +-static void radeonWaitIrq( radeonContextPtr rmesa ) +-{ +- int ret; +- +- do { +- ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_IRQ_WAIT, +- &rmesa->iw, sizeof(rmesa->iw) ); +- } while (ret && (errno == EINTR || errno == EBUSY)); +- +- if ( ret ) { +- fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret ); +- exit(1); +- } +-} +- +- +-static void radeonWaitForFrameCompletion( radeonContextPtr rmesa ) +-{ +- drm_radeon_sarea_t *sarea = rmesa->sarea; +- +- if (rmesa->do_irqs) { +- if (radeonGetLastFrame(rmesa) < sarea->last_frame) { +- if (!rmesa->irqsEmitted) { +- while (radeonGetLastFrame (rmesa) < sarea->last_frame) +- ; +- } +- else { +- UNLOCK_HARDWARE( rmesa ); +- radeonWaitIrq( rmesa ); +- LOCK_HARDWARE( rmesa ); +- } +- rmesa->irqsEmitted = 10; +- } +- +- if (rmesa->irqsEmitted) { +- radeonEmitIrqLocked( rmesa ); +- rmesa->irqsEmitted--; +- } +- } +- else { +- while (radeonGetLastFrame (rmesa) < sarea->last_frame) { +- UNLOCK_HARDWARE( rmesa ); +- if (rmesa->do_usleeps) +- DO_USLEEP( 1 ); +- LOCK_HARDWARE( rmesa ); +- } +- } +-} +- +-/* Copy the back color buffer to the front color buffer. +- */ +-void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, +- const drm_clip_rect_t *rect) +-{ +- radeonContextPtr rmesa; +- GLint nbox, i, ret; +- GLboolean missed_target; +- int64_t ust; +- __DRIscreenPrivate *psp; +- +- assert(dPriv); +- assert(dPriv->driContextPriv); +- assert(dPriv->driContextPriv->driverPrivate); +- +- rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; +- +- if ( RADEON_DEBUG & DEBUG_IOCTL ) { +- fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); +- } +- +- RADEON_FIREVERTICES( rmesa ); +- LOCK_HARDWARE( rmesa ); +- +- /* Throttle the frame rate -- only allow one pending swap buffers +- * request at a time. +- */ +- radeonWaitForFrameCompletion( rmesa ); +- if (!rect) +- { +- UNLOCK_HARDWARE( rmesa ); +- driWaitForVBlank( dPriv, & missed_target ); +- LOCK_HARDWARE( rmesa ); +- } +- +- nbox = dPriv->numClipRects; /* must be in locked region */ +- +- for ( i = 0 ; i < nbox ; ) { +- GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); +- drm_clip_rect_t *box = dPriv->pClipRects; +- drm_clip_rect_t *b = rmesa->sarea->boxes; +- GLint n = 0; +- +- for ( ; i < nr ; i++ ) { +- +- *b = box[i]; +- +- if (rect) +- { +- if (rect->x1 > b->x1) +- b->x1 = rect->x1; +- if (rect->y1 > b->y1) +- b->y1 = rect->y1; +- if (rect->x2 < b->x2) +- b->x2 = rect->x2; +- if (rect->y2 < b->y2) +- b->y2 = rect->y2; +- +- if (b->x1 >= b->x2 || b->y1 >= b->y2) +- continue; +- } +- +- b++; +- n++; ++ for (i = 0; i + 1 < nr; i += 2) { ++ voffset = rmesa->radeon.tcl.aos[i + 0].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.aos[i+0].bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ voffset = rmesa->radeon.tcl.aos[i + 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.aos[i+1].bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); + } +- rmesa->sarea->nbox = n; +- +- if (!n) +- continue; +- +- ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP ); +- +- if ( ret ) { +- fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret ); +- UNLOCK_HARDWARE( rmesa ); +- exit( 1 ); ++ if (nr & 1) { ++ voffset = rmesa->radeon.tcl.aos[nr - 1].offset + ++ offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; ++ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, ++ rmesa->radeon.tcl.aos[nr-1].bo, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); + } + } ++ END_BATCH(); + +- UNLOCK_HARDWARE( rmesa ); +- if (!rect) +- { +- psp = dPriv->driScreenPriv; +- rmesa->swap_count++; +- (*psp->systemTime->getUST)( & ust ); +- if ( missed_target ) { +- rmesa->swap_missed_count++; +- rmesa->swap_missed_ust = ust - rmesa->swap_ust; +- } +- +- rmesa->swap_ust = ust; +- rmesa->hw.all_dirty = GL_TRUE; +- } +-} +- +-void radeonPageFlip( __DRIdrawablePrivate *dPriv ) +-{ +- radeonContextPtr rmesa; +- GLint ret; +- GLboolean missed_target; +- __DRIscreenPrivate *psp; +- +- assert(dPriv); +- assert(dPriv->driContextPriv); +- assert(dPriv->driContextPriv->driverPrivate); +- +- rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; +- psp = dPriv->driScreenPriv; +- +- if ( RADEON_DEBUG & DEBUG_IOCTL ) { +- fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, +- rmesa->sarea->pfCurrentPage); +- } +- +- RADEON_FIREVERTICES( rmesa ); +- LOCK_HARDWARE( rmesa ); +- +- /* Need to do this for the perf box placement: +- */ +- if (dPriv->numClipRects) +- { +- drm_clip_rect_t *box = dPriv->pClipRects; +- drm_clip_rect_t *b = rmesa->sarea->boxes; +- b[0] = box[0]; +- rmesa->sarea->nbox = 1; +- } +- +- /* Throttle the frame rate -- only allow a few pending swap buffers +- * request at a time. +- */ +- radeonWaitForFrameCompletion( rmesa ); +- UNLOCK_HARDWARE( rmesa ); +- driWaitForVBlank( dPriv, & missed_target ); +- if ( missed_target ) { +- rmesa->swap_missed_count++; +- (void) (*psp->systemTime->getUST)( & rmesa->swap_missed_ust ); +- } +- LOCK_HARDWARE( rmesa ); +- +- ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); +- +- UNLOCK_HARDWARE( rmesa ); +- +- if ( ret ) { +- fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); +- exit( 1 ); +- } +- +- rmesa->swap_count++; +- (void) (*psp->systemTime->getUST)( & rmesa->swap_ust ); +- +- /* Get ready for drawing next frame. Update the renderbuffers' +- * flippedOffset/Pitch fields so we draw into the right place. +- */ +- driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, +- rmesa->sarea->pfCurrentPage); +- +- radeonUpdateDrawBuffer(rmesa->glCtx); ++#endif + } + +- + /* ================================================================ + * Buffer clear + */ + #define RADEON_MAX_CLEARS 256 + +-static void radeonClear( GLcontext *ctx, GLbitfield mask ) ++static void radeonUserClear(GLcontext *ctx, GLuint mask) ++{ ++ radeon_clear_tris(ctx, mask); ++} ++ ++static void radeonKernelClear(GLcontext *ctx, GLuint flags) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; +- drm_radeon_sarea_t *sarea = rmesa->sarea; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; ++ drm_radeon_sarea_t *sarea = rmesa->radeon.sarea; + uint32_t clear; +- GLuint flags = 0; +- GLuint color_mask = 0; + GLint ret, i; + GLint cx, cy, cw, ch; + +- if ( RADEON_DEBUG & DEBUG_IOCTL ) { +- fprintf( stderr, "radeonClear\n"); +- } +- +- { +- LOCK_HARDWARE( rmesa ); +- UNLOCK_HARDWARE( rmesa ); +- if ( dPriv->numClipRects == 0 ) +- return; +- } +- +- radeonFlush( ctx ); +- +- if ( mask & BUFFER_BIT_FRONT_LEFT ) { +- flags |= RADEON_FRONT; +- color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; +- mask &= ~BUFFER_BIT_FRONT_LEFT; +- } +- +- if ( mask & BUFFER_BIT_BACK_LEFT ) { +- flags |= RADEON_BACK; +- color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; +- mask &= ~BUFFER_BIT_BACK_LEFT; +- } +- +- if ( mask & BUFFER_BIT_DEPTH ) { +- flags |= RADEON_DEPTH; +- mask &= ~BUFFER_BIT_DEPTH; +- } +- +- if ( (mask & BUFFER_BIT_STENCIL) && rmesa->state.stencil.hwBuffer ) { +- flags |= RADEON_STENCIL; +- mask &= ~BUFFER_BIT_STENCIL; +- } +- +- if ( mask ) { +- if (RADEON_DEBUG & DEBUG_FALLBACKS) +- fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); +- _swrast_Clear( ctx, mask ); +- } +- +- if ( !flags ) +- return; +- +- if (rmesa->using_hyperz) { +- flags |= RADEON_USE_COMP_ZBUF; +-/* if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) +- flags |= RADEON_USE_HIERZ; */ +- if (!(rmesa->state.stencil.hwBuffer) || +- ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && +- ((rmesa->state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) { +- flags |= RADEON_CLEAR_FASTZ; +- } +- } +- +- LOCK_HARDWARE( rmesa ); ++ LOCK_HARDWARE( &rmesa->radeon ); + + /* compute region after locking: */ + cx = ctx->DrawBuffer->_Xmin; +@@ -1112,7 +453,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) + + gp.param = RADEON_PARAM_LAST_CLEAR; + gp.value = (int *)&clear; +- ret = drmCommandWriteRead( rmesa->dri.fd, ++ ret = drmCommandWriteRead( rmesa->radeon.dri.fd, + DRM_RADEON_GETPARAM, &gp, sizeof(gp) ); + + if ( ret ) { +@@ -1124,20 +465,20 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) + break; + } + +- if ( rmesa->do_usleeps ) { +- UNLOCK_HARDWARE( rmesa ); ++ if ( rmesa->radeon.do_usleeps ) { ++ UNLOCK_HARDWARE( &rmesa->radeon ); + DO_USLEEP( 1 ); +- LOCK_HARDWARE( rmesa ); ++ LOCK_HARDWARE( &rmesa->radeon ); + } + } + + /* Send current state to the hardware */ +- radeonFlushCmdBufLocked( rmesa, __FUNCTION__ ); ++ rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ ); + + for ( i = 0 ; i < dPriv->numClipRects ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects ); + drm_clip_rect_t *box = dPriv->pClipRects; +- drm_clip_rect_t *b = rmesa->sarea->boxes; ++ drm_clip_rect_t *b = rmesa->radeon.sarea->boxes; + drm_radeon_clear_t clear; + drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; + GLint n = 0; +@@ -1172,105 +513,107 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) + } + } + +- rmesa->sarea->nbox = n; ++ rmesa->radeon.sarea->nbox = n; + + clear.flags = flags; +- clear.clear_color = rmesa->state.color.clear; +- clear.clear_depth = rmesa->state.depth.clear; ++ clear.clear_color = rmesa->radeon.state.color.clear; ++ clear.clear_depth = rmesa->radeon.state.depth.clear; + clear.color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; +- clear.depth_mask = rmesa->state.stencil.clear; ++ clear.depth_mask = rmesa->radeon.state.stencil.clear; + clear.depth_boxes = depth_boxes; + + n--; +- b = rmesa->sarea->boxes; ++ b = rmesa->radeon.sarea->boxes; + for ( ; n >= 0 ; n-- ) { + depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1; + depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1; + depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2; + depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2; + depth_boxes[n].f[CLEAR_DEPTH] = +- (float)rmesa->state.depth.clear; ++ (float)rmesa->radeon.state.depth.clear; + } + +- ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR, ++ ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_CLEAR, + &clear, sizeof(drm_radeon_clear_t)); + + if ( ret ) { +- UNLOCK_HARDWARE( rmesa ); ++ UNLOCK_HARDWARE( &rmesa->radeon ); + fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret ); + exit( 1 ); + } + } +- +- UNLOCK_HARDWARE( rmesa ); +- rmesa->hw.all_dirty = GL_TRUE; ++ UNLOCK_HARDWARE( &rmesa->radeon ); + } + +- +-void radeonWaitForIdleLocked( radeonContextPtr rmesa ) ++static void radeonClear( GLcontext *ctx, GLbitfield mask ) + { +- int fd = rmesa->dri.fd; +- int to = 0; +- int ret, i = 0; +- +- rmesa->c_drawWaits++; +- +- do { +- do { +- ret = drmCommandNone( fd, DRM_RADEON_CP_IDLE); +- } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY ); +- } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) ); +- +- if ( ret < 0 ) { +- UNLOCK_HARDWARE( rmesa ); +- fprintf( stderr, "Error: Radeon timed out... exiting\n" ); +- exit( -1 ); +- } +-} ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; ++ GLuint flags = 0; ++ GLuint color_mask = 0; ++ GLuint orig_mask = mask; ++ ++ if ( RADEON_DEBUG & DEBUG_IOCTL ) { ++ fprintf( stderr, "radeonClear\n"); ++ } + ++ { ++ LOCK_HARDWARE( &rmesa->radeon ); ++ UNLOCK_HARDWARE( &rmesa->radeon ); ++ if ( dPriv->numClipRects == 0 ) ++ return; ++ } ++ ++ radeon_firevertices(&rmesa->radeon); + +-static void radeonWaitForIdle( radeonContextPtr rmesa ) +-{ +- LOCK_HARDWARE(rmesa); +- radeonWaitForIdleLocked( rmesa ); +- UNLOCK_HARDWARE(rmesa); +-} ++ if ( mask & BUFFER_BIT_FRONT_LEFT ) { ++ flags |= RADEON_FRONT; ++ color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; ++ mask &= ~BUFFER_BIT_FRONT_LEFT; ++ } + ++ if ( mask & BUFFER_BIT_BACK_LEFT ) { ++ flags |= RADEON_BACK; ++ color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; ++ mask &= ~BUFFER_BIT_BACK_LEFT; ++ } + +-void radeonFlush( GLcontext *ctx ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); ++ if ( mask & BUFFER_BIT_DEPTH ) { ++ flags |= RADEON_DEPTH; ++ mask &= ~BUFFER_BIT_DEPTH; ++ } + +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s\n", __FUNCTION__); ++ if ( (mask & BUFFER_BIT_STENCIL) ) { ++ flags |= RADEON_STENCIL; ++ mask &= ~BUFFER_BIT_STENCIL; ++ } + +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); ++ if ( mask ) { ++ if (RADEON_DEBUG & DEBUG_FALLBACKS) ++ fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); ++ _swrast_Clear( ctx, mask ); ++ } + +- radeonEmitState( rmesa ); +- +- if (rmesa->store.cmd_used) +- radeonFlushCmdBuf( rmesa, __FUNCTION__ ); +-} ++ if ( !flags ) ++ return; + +-/* Make sure all commands have been sent to the hardware and have +- * completed processing. +- */ +-void radeonFinish( GLcontext *ctx ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- radeonFlush( ctx ); +- +- if (rmesa->do_irqs) { +- LOCK_HARDWARE( rmesa ); +- radeonEmitIrqLocked( rmesa ); +- UNLOCK_HARDWARE( rmesa ); +- radeonWaitIrq( rmesa ); ++ if (rmesa->using_hyperz) { ++ flags |= RADEON_USE_COMP_ZBUF; ++/* if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) ++ flags |= RADEON_USE_HIERZ; */ ++ if (((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && ++ ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) { ++ flags |= RADEON_CLEAR_FASTZ; ++ } + } +- else +- radeonWaitForIdle( rmesa ); +-} + ++ if (rmesa->radeon.radeonScreen->kernel_mm) ++ radeonUserClear(ctx, orig_mask); ++ else { ++ radeonKernelClear(ctx, flags); ++ rmesa->radeon.hw.all_dirty = GL_TRUE; ++ } ++} + + void radeonInitIoctlFuncs( GLcontext *ctx ) + { +diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.h b/src/mesa/drivers/dri/radeon/radeon_ioctl.h +index 4e3a44d..18805d4 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.h ++++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.h +@@ -38,31 +38,32 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #include "main/simple_list.h" + #include "radeon_lock.h" ++#include "radeon_bocs_wrapper.h" + +- +-extern void radeonEmitState( radeonContextPtr rmesa ); +-extern void radeonEmitVertexAOS( radeonContextPtr rmesa, ++extern void radeonEmitVertexAOS( r100ContextPtr rmesa, + GLuint vertex_size, ++ struct radeon_bo *bo, + GLuint offset ); + +-extern void radeonEmitVbufPrim( radeonContextPtr rmesa, ++extern void radeonEmitVbufPrim( r100ContextPtr rmesa, + GLuint vertex_format, + GLuint primitive, + GLuint vertex_nr ); + +-extern void radeonFlushElts( radeonContextPtr rmesa ); ++extern void radeonFlushElts( GLcontext *ctx ); ++ + +-extern GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa, ++extern GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa, + GLuint vertex_format, + GLuint primitive, + GLuint min_nr ); + +-extern void radeonEmitAOS( radeonContextPtr rmesa, +- struct radeon_dma_region **regions, ++ ++extern void radeonEmitAOS( r100ContextPtr rmesa, + GLuint n, + GLuint offset ); + +-extern void radeonEmitBlit( radeonContextPtr rmesa, ++extern void radeonEmitBlit( r100ContextPtr rmesa, + GLuint color_fmt, + GLuint src_pitch, + GLuint src_offset, +@@ -72,30 +73,15 @@ extern void radeonEmitBlit( radeonContextPtr rmesa, + GLint dstx, GLint dsty, + GLuint w, GLuint h ); + +-extern void radeonEmitWait( radeonContextPtr rmesa, GLuint flags ); +- +-extern void radeonFlushCmdBuf( radeonContextPtr rmesa, const char * ); +-extern void radeonRefillCurrentDmaRegion( radeonContextPtr rmesa ); ++extern void radeonEmitWait( r100ContextPtr rmesa, GLuint flags ); + +-extern void radeonAllocDmaRegion( radeonContextPtr rmesa, +- struct radeon_dma_region *region, +- int bytes, +- int alignment ); ++extern void radeonFlushCmdBuf( r100ContextPtr rmesa, const char * ); + +-extern void radeonReleaseDmaRegion( radeonContextPtr rmesa, +- struct radeon_dma_region *region, +- const char *caller ); +- +-extern void radeonCopyBuffer( __DRIdrawablePrivate *drawable, +- const drm_clip_rect_t *rect); +-extern void radeonPageFlip( __DRIdrawablePrivate *drawable ); + extern void radeonFlush( GLcontext *ctx ); + extern void radeonFinish( GLcontext *ctx ); +-extern void radeonWaitForIdleLocked( radeonContextPtr rmesa ); +-extern void radeonWaitForVBlank( radeonContextPtr rmesa ); + extern void radeonInitIoctlFuncs( GLcontext *ctx ); +-extern void radeonGetAllParams( radeonContextPtr rmesa ); +-extern void radeonSetUpAtomList( radeonContextPtr rmesa ); ++extern void radeonGetAllParams( r100ContextPtr rmesa ); ++extern void radeonSetUpAtomList( r100ContextPtr rmesa ); + + /* ================================================================ + * Helper macros: +@@ -105,33 +91,33 @@ extern void radeonSetUpAtomList( radeonContextPtr rmesa ); + */ + #define RADEON_NEWPRIM( rmesa ) \ + do { \ +- if ( rmesa->dma.flush ) \ +- rmesa->dma.flush( rmesa ); \ ++ if ( rmesa->radeon.dma.flush ) \ ++ rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); \ + } while (0) + + /* Can accomodate several state changes and primitive changes without + * actually firing the buffer. + */ ++ + #define RADEON_STATECHANGE( rmesa, ATOM ) \ + do { \ + RADEON_NEWPRIM( rmesa ); \ + rmesa->hw.ATOM.dirty = GL_TRUE; \ +- rmesa->hw.is_dirty = GL_TRUE; \ ++ rmesa->radeon.hw.is_dirty = GL_TRUE; \ + } while (0) + +-#define RADEON_DB_STATE( ATOM ) \ ++#define RADEON_DB_STATE( ATOM ) \ + memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \ + rmesa->hw.ATOM.cmd_size * 4) + +-static INLINE int RADEON_DB_STATECHANGE( +- radeonContextPtr rmesa, +- struct radeon_state_atom *atom ) ++static INLINE int RADEON_DB_STATECHANGE(r100ContextPtr rmesa, ++ struct radeon_state_atom *atom ) + { + if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size*4)) { +- int *tmp; ++ GLuint *tmp; + RADEON_NEWPRIM( rmesa ); + atom->dirty = GL_TRUE; +- rmesa->hw.is_dirty = GL_TRUE; ++ rmesa->radeon.hw.is_dirty = GL_TRUE; + tmp = atom->cmd; + atom->cmd = atom->lastcmd; + atom->lastcmd = tmp; +@@ -141,16 +127,6 @@ static INLINE int RADEON_DB_STATECHANGE( + return 0; + } + +- +-/* Fire the buffered vertices no matter what. +- */ +-#define RADEON_FIREVERTICES( rmesa ) \ +-do { \ +- if ( rmesa->store.cmd_used || rmesa->dma.flush ) { \ +- radeonFlush( rmesa->glCtx ); \ +- } \ +-} while (0) +- + /* Command lengths. Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ + * are available, you will also be adding an rmesa->state.max_state_size because + * r200EmitState is called from within r200EmitVbufPrim and r200FlushElts. +@@ -167,36 +143,37 @@ do { \ + #define VBUF_BUFSZ (4 * sizeof(int)) + #endif + +-/* Ensure that a minimum amount of space is available in the command buffer. +- * This is used to ensure atomicity of state updates with the rendering requests +- * that rely on them. +- * +- * An alternative would be to implement a "soft lock" such that when the buffer +- * wraps at an inopportune time, we grab the lock, flush the current buffer, +- * and hang on to the lock until the critical section is finished and we flush +- * the buffer again and unlock. +- */ +-static INLINE void radeonEnsureCmdBufSpace( radeonContextPtr rmesa, +- int bytes ) +-{ +- if (rmesa->store.cmd_used + bytes > RADEON_CMD_BUF_SZ) +- radeonFlushCmdBuf( rmesa, __FUNCTION__ ); +- assert( bytes <= RADEON_CMD_BUF_SZ ); +-} + +-/* Alloc space in the command buffer +- */ +-static INLINE char *radeonAllocCmdBuf( radeonContextPtr rmesa, +- int bytes, const char *where ) ++static inline uint32_t cmdpacket3(int cmd_type) + { +- if (rmesa->store.cmd_used + bytes > RADEON_CMD_BUF_SZ) +- radeonFlushCmdBuf( rmesa, __FUNCTION__ ); ++ drm_radeon_cmd_header_t cmd; ++ ++ cmd.i = 0; ++ cmd.header.cmd_type = cmd_type; ++ ++ return (uint32_t)cmd.i; + +- { +- char *head = rmesa->store.cmd_buf + rmesa->store.cmd_used; +- rmesa->store.cmd_used += bytes; +- return head; +- } + } + ++#define OUT_BATCH_PACKET3(packet, num_extra) do { \ ++ if (!b_l_rmesa->radeonScreen->kernel_mm) { \ ++ OUT_BATCH(cmdpacket3(RADEON_CMD_PACKET3)); \ ++ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ ++ } else { \ ++ OUT_BATCH(CP_PACKET2); \ ++ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ ++ } \ ++ } while(0) ++ ++#define OUT_BATCH_PACKET3_CLIP(packet, num_extra) do { \ ++ if (!b_l_rmesa->radeonScreen->kernel_mm) { \ ++ OUT_BATCH(cmdpacket3(RADEON_CMD_PACKET3_CLIP)); \ ++ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ ++ } else { \ ++ OUT_BATCH(CP_PACKET2); \ ++ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ ++ } \ ++ } while(0) ++ ++ + #endif /* __RADEON_IOCTL_H__ */ +diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c +index 64bb3ca..fe19218 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_lock.c ++++ b/src/mesa/drivers/dri/radeon/radeon_lock.c +@@ -41,30 +41,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #include "main/glheader.h" + #include "main/mtypes.h" +-#include "radeon_context.h" ++#include "main/colormac.h" ++#include "dri_util.h" ++#include "radeon_screen.h" ++#include "radeon_common.h" + #include "radeon_lock.h" +-#include "radeon_tex.h" +-#include "radeon_state.h" +-#include "radeon_ioctl.h" +- + #include "drirenderbuffer.h" + +-#if DEBUG_LOCKING +-char *prevLockFile = NULL; +-int prevLockLine = 0; +-#endif +- +-/* Turn on/off page flipping according to the flags in the sarea: +- */ +-static void radeonUpdatePageFlipping(radeonContextPtr rmesa) +-{ +- rmesa->doPageFlip = rmesa->sarea->pfState; +- if (rmesa->glCtx->WinSysDrawBuffer) { +- driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, +- rmesa->sarea->pfCurrentPage); +- } +-} +- + /* Update the hardware state. This is called if another context has + * grabbed the hardware lock, which includes the X server. This + * function also updates the driver's window state after the X server +@@ -78,7 +61,8 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) + __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; + __DRIdrawablePrivate *const readable = rmesa->dri.readable; + __DRIscreenPrivate *sPriv = rmesa->dri.screen; +- drm_radeon_sarea_t *sarea = rmesa->sarea; ++ ++ assert(drawable != NULL); + + drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); + +@@ -96,29 +80,42 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) + } + + if (rmesa->lastStamp != drawable->lastStamp) { +- radeonUpdatePageFlipping(rmesa); +- radeonSetCliprects(rmesa); +- radeonUpdateViewportOffset(rmesa->glCtx); +- driUpdateFramebufferSize(rmesa->glCtx, drawable); ++ radeon_window_moved(rmesa); ++ rmesa->lastStamp = drawable->lastStamp; + } + +- RADEON_STATECHANGE(rmesa, ctx); +- if (rmesa->sarea->tiling_enabled) { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= +- RADEON_COLOR_TILE_ENABLE; +- } else { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= +- ~RADEON_COLOR_TILE_ENABLE; +- } ++ rmesa->vtbl.get_lock(rmesa); ++ ++ rmesa->lost_context = GL_TRUE; ++} + +- if (sarea->ctx_owner != rmesa->dri.hwContext) { +- int i; +- sarea->ctx_owner = rmesa->dri.hwContext; ++void radeon_lock_hardware(radeonContextPtr radeon) ++{ ++ char ret = 0; ++ struct radeon_framebuffer *rfb = NULL; ++ struct radeon_renderbuffer *rrb = NULL; + +- for (i = 0; i < rmesa->nr_heaps; i++) { +- DRI_AGE_TEXTURES(rmesa->texture_heaps[i]); +- } ++ if (radeon->dri.drawable) { ++ rfb = radeon->dri.drawable->driverPrivate; ++ ++ if (rfb) ++ rrb = radeon_get_renderbuffer(&rfb->base, ++ rfb->base._ColorDrawBufferIndexes[0]); + } + +- rmesa->lost_context = GL_TRUE; ++ if (!radeon->radeonScreen->driScreen->dri2.enabled) { ++ DRM_CAS(radeon->dri.hwLock, radeon->dri.hwContext, ++ (DRM_LOCK_HELD | radeon->dri.hwContext), ret ); ++ if (ret) ++ radeonGetLock(radeon, 0); ++ } ++} ++ ++void radeon_unlock_hardware(radeonContextPtr radeon) ++{ ++ if (!radeon->radeonScreen->driScreen->dri2.enabled) { ++ DRM_UNLOCK( radeon->dri.fd, ++ radeon->dri.hwLock, ++ radeon->dri.hwContext ); ++ } + } +diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h +index 86e96aa..2817709 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_lock.h ++++ b/src/mesa/drivers/dri/radeon/radeon_lock.h +@@ -39,74 +39,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Kevin E. Martin + */ + +-#ifndef __RADEON_LOCK_H__ +-#define __RADEON_LOCK_H__ ++#ifndef COMMON_LOCK_H ++#define COMMON_LOCK_H + +-extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); +- +-/* Turn DEBUG_LOCKING on to find locking conflicts. +- */ +-#define DEBUG_LOCKING 0 +- +-#if DEBUG_LOCKING +-extern char *prevLockFile; +-extern int prevLockLine; +- +-#define DEBUG_LOCK() \ +- do { \ +- prevLockFile = (__FILE__); \ +- prevLockLine = (__LINE__); \ +- } while (0) +- +-#define DEBUG_RESET() \ +- do { \ +- prevLockFile = 0; \ +- prevLockLine = 0; \ +- } while (0) +- +-#define DEBUG_CHECK_LOCK() \ +- do { \ +- if ( prevLockFile ) { \ +- fprintf( stderr, \ +- "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ +- prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ +- exit( 1 ); \ +- } \ +- } while (0) +- +-#else ++#include "main/colormac.h" ++#include "radeon_screen.h" ++#include "radeon_common.h" + +-#define DEBUG_LOCK() +-#define DEBUG_RESET() +-#define DEBUG_CHECK_LOCK() ++extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); + +-#endif +- +-/* +- * !!! We may want to separate locks from locks with validation. This +- * could be used to improve performance for those things commands that +- * do not do any drawing !!! +- */ ++void radeon_lock_hardware(radeonContextPtr rmesa); ++void radeon_unlock_hardware(radeonContextPtr rmesa); + + /* Lock the hardware and validate our state. + */ +-#define LOCK_HARDWARE( rmesa ) \ +- do { \ +- char __ret = 0; \ +- DEBUG_CHECK_LOCK(); \ +- DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ +- (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ +- if ( __ret ) \ +- radeonGetLock( (rmesa), 0 ); \ +- DEBUG_LOCK(); \ +- } while (0) +- +-#define UNLOCK_HARDWARE( rmesa ) \ +- do { \ +- DRM_UNLOCK( (rmesa)->dri.fd, \ +- (rmesa)->dri.hwLock, \ +- (rmesa)->dri.hwContext ); \ +- DEBUG_RESET(); \ +- } while (0) ++#define LOCK_HARDWARE( rmesa ) radeon_lock_hardware(rmesa) ++#define UNLOCK_HARDWARE( rmesa ) radeon_unlock_hardware(rmesa) + +-#endif /* __RADEON_LOCK_H__ */ ++#endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_maos.h b/src/mesa/drivers/dri/radeon/radeon_maos.h +index b8935e8..b88eb19 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_maos.h ++++ b/src/mesa/drivers/dri/radeon/radeon_maos.h +@@ -38,6 +38,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "radeon_context.h" + + extern void radeonEmitArrays( GLcontext *ctx, GLuint inputs ); +-extern void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs ); + + #endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c +index 31eea13..7c6ea05 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c ++++ b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c +@@ -48,160 +48,35 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "radeon_maos.h" + #include "radeon_tcl.h" + +-#if 0 +-/* Usage: +- * - from radeon_tcl_render +- * - call radeonEmitArrays to ensure uptodate arrays in dma +- * - emit primitives (new type?) which reference the data +- * -- need to use elts for lineloop, quads, quadstrip/flat +- * -- other primitives are all well-formed (need tristrip-1,fake-poly) +- * +- */ +-static void emit_ubyte_rgba3( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int stride, +- int count ) ++static void emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, ++ GLvoid *data, int stride, int count) + { + int i; +- radeon_color_t *out = (radeon_color_t *)(rvb->start + rvb->address); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d out %p\n", +- __FUNCTION__, count, stride, (void *)out); +- +- for (i = 0; i < count; i++) { +- out->red = *data; +- out->green = *(data+1); +- out->blue = *(data+2); +- out->alpha = 0xFF; +- out++; +- data += stride; +- } +-} +- +-static void emit_ubyte_rgba4( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); ++ uint32_t *out; ++ int size = 1; ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); + +- if (stride == 4) +- COPY_DWORDS( out, data, count ); +- else +- for (i = 0; i < count; i++) { +- *out++ = LE32_TO_CPU(*(int *)data); +- data += stride; +- } +-} +- +- +-static void emit_ubyte_rgba( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int size, +- int stride, +- int count ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); +- +- assert (!rvb->buf); +- + if (stride == 0) { +- radeonAllocDmaRegion( rmesa, rvb, 4, 4 ); ++ radeonAllocDmaRegion( rmesa, &aos->bo, &aos->offset, size * 4, 32 ); + count = 1; +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 0; +- rvb->aos_size = 1; ++ aos->stride = 0; + } + else { +- radeonAllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */ +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 1; +- rvb->aos_size = 1; ++ radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); ++ aos->stride = size; + } + +- /* Emit the data +- */ +- switch (size) { +- case 3: +- emit_ubyte_rgba3( ctx, rvb, data, stride, count ); +- break; +- case 4: +- emit_ubyte_rgba4( ctx, rvb, data, stride, count ); +- break; +- default: +- assert(0); +- exit(1); +- break; +- } +-} +-#endif +- +-#if defined(USE_X86_ASM) +-#define COPY_DWORDS( dst, src, nr ) \ +-do { \ +- int __tmp; \ +- __asm__ __volatile__( "rep ; movsl" \ +- : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ +- : "0" (nr), \ +- "D" ((long)dst), \ +- "S" ((long)src) ); \ +-} while (0) +-#else +-#define COPY_DWORDS( dst, src, nr ) \ +-do { \ +- int j; \ +- for ( j = 0 ; j < nr ; j++ ) \ +- dst[j] = ((int *)src)[j]; \ +- dst += nr; \ +-} while (0) +-#endif +- +-static void emit_vecfog( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- GLfloat *out; ++ aos->components = size; ++ aos->count = count; + +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d\n", +- __FUNCTION__, count, stride); +- +- assert (!rvb->buf); +- +- if (stride == 0) { +- radeonAllocDmaRegion( rmesa, rvb, 4, 4 ); +- count = 1; +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 0; +- rvb->aos_size = 1; +- } +- else { +- radeonAllocDmaRegion( rmesa, rvb, count * 4, 4 ); /* alignment? */ +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 1; +- rvb->aos_size = 1; +- } + + /* Emit the data + */ +- out = (GLfloat *)(rvb->address + rvb->start); ++ out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); + for (i = 0; i < count; i++) { + out[0] = radeonComputeFogBlendFactor( ctx, *(GLfloat *)data ); + out++; +@@ -209,169 +84,9 @@ static void emit_vecfog( GLcontext *ctx, + } + } + +-static void emit_vec4( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d\n", +- __FUNCTION__, count, stride); +- +- if (stride == 4) +- COPY_DWORDS( out, data, count ); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out++; +- data += stride; +- } +-} +- +- +-static void emit_vec8( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d\n", +- __FUNCTION__, count, stride); +- +- if (stride == 8) +- COPY_DWORDS( out, data, count*2 ); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out[1] = *(int *)(data+4); +- out += 2; +- data += stride; +- } +-} +- +-static void emit_vec12( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d out %p data %p\n", +- __FUNCTION__, count, stride, (void *)out, (void *)data); +- +- if (stride == 12) +- COPY_DWORDS( out, data, count*3 ); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out[1] = *(int *)(data+4); +- out[2] = *(int *)(data+8); +- out += 3; +- data += stride; +- } +-} +- +-static void emit_vec16( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int stride, +- int count ) +-{ +- int i; +- int *out = (int *)(rvb->address + rvb->start); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d stride %d\n", +- __FUNCTION__, count, stride); +- +- if (stride == 16) +- COPY_DWORDS( out, data, count*4 ); +- else +- for (i = 0; i < count; i++) { +- out[0] = *(int *)data; +- out[1] = *(int *)(data+4); +- out[2] = *(int *)(data+8); +- out[3] = *(int *)(data+12); +- out += 4; +- data += stride; +- } +-} +- +- +-static void emit_vector( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int size, +- int stride, +- int count ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- +- if (RADEON_DEBUG & DEBUG_VERTS) +- fprintf(stderr, "%s count %d size %d stride %d\n", +- __FUNCTION__, count, size, stride); +- +- assert (!rvb->buf); +- +- if (stride == 0) { +- radeonAllocDmaRegion( rmesa, rvb, size * 4, 4 ); +- count = 1; +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 0; +- rvb->aos_size = size; +- } +- else { +- radeonAllocDmaRegion( rmesa, rvb, size * count * 4, 4 ); /* alignment? */ +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = size; +- rvb->aos_size = size; +- } +- +- /* Emit the data +- */ +- switch (size) { +- case 1: +- emit_vec4( ctx, rvb, data, stride, count ); +- break; +- case 2: +- emit_vec8( ctx, rvb, data, stride, count ); +- break; +- case 3: +- emit_vec12( ctx, rvb, data, stride, count ); +- break; +- case 4: +- emit_vec16( ctx, rvb, data, stride, count ); +- break; +- default: +- assert(0); +- exit(1); +- break; +- } +- +-} +- +- +- +-static void emit_s0_vec( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int stride, +- int count ) ++static void emit_s0_vec(uint32_t *out, GLvoid *data, int stride, int count) + { + int i; +- int *out = (int *)(rvb->address + rvb->start); +- + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); +@@ -384,14 +99,9 @@ static void emit_s0_vec( GLcontext *ctx, + } + } + +-static void emit_stq_vec( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int stride, +- int count ) ++static void emit_stq_vec(uint32_t *out, GLvoid *data, int stride, int count) + { + int i; +- int *out = (int *)(rvb->address + rvb->start); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", +@@ -409,21 +119,16 @@ static void emit_stq_vec( GLcontext *ctx, + + + +-static void emit_tex_vector( GLcontext *ctx, +- struct radeon_dma_region *rvb, +- char *data, +- int size, +- int stride, +- int count ) ++static void emit_tex_vector(GLcontext *ctx, struct radeon_aos *aos, ++ GLvoid *data, int size, int stride, int count) + { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int emitsize; ++ uint32_t *out; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); + +- assert (!rvb->buf); +- + switch (size) { + case 4: emitsize = 3; break; + case 3: emitsize = 3; break; +@@ -432,34 +137,33 @@ static void emit_tex_vector( GLcontext *ctx, + + + if (stride == 0) { +- radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize, 4 ); ++ radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, emitsize * 4, 32); + count = 1; +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = 0; +- rvb->aos_size = emitsize; ++ aos->stride = 0; + } + else { +- radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize * count, 4 ); +- rvb->aos_start = GET_START(rvb); +- rvb->aos_stride = emitsize; +- rvb->aos_size = emitsize; ++ radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, emitsize * count * 4, 32); ++ aos->stride = emitsize; + } + ++ aos->components = emitsize; ++ aos->count = count; + + /* Emit the data + */ ++ out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); + switch (size) { + case 1: +- emit_s0_vec( ctx, rvb, data, stride, count ); ++ emit_s0_vec( out, data, stride, count ); + break; + case 2: +- emit_vec8( ctx, rvb, data, stride, count ); ++ radeonEmitVec8( out, data, stride, count ); + break; + case 3: +- emit_vec12( ctx, rvb, data, stride, count ); ++ radeonEmitVec12( out, data, stride, count ); + break; + case 4: +- emit_stq_vec( ctx, rvb, data, stride, count ); ++ emit_stq_vec( out, data, stride, count ); + break; + default: + assert(0); +@@ -476,9 +180,8 @@ static void emit_tex_vector( GLcontext *ctx, + */ + void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); ++ r100ContextPtr rmesa = R100_CONTEXT( ctx ); + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; +- struct radeon_dma_region **component = rmesa->tcl.aos_components; + GLuint nr = 0; + GLuint vfmt = 0; + GLuint count = VB->Count; +@@ -491,12 +194,12 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + + if (1) { + if (!rmesa->tcl.obj.buf) +- emit_vector( ctx, +- &rmesa->tcl.obj, +- (char *)VB->ObjPtr->data, +- VB->ObjPtr->size, +- VB->ObjPtr->stride, +- count); ++ rcommon_emit_vector( ctx, ++ &(rmesa->tcl.aos[nr]), ++ (char *)VB->ObjPtr->data, ++ VB->ObjPtr->size, ++ VB->ObjPtr->stride, ++ count); + + switch( VB->ObjPtr->size ) { + case 4: vfmt |= RADEON_CP_VC_FRMT_W0; +@@ -505,21 +208,21 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + default: + break; + } +- component[nr++] = &rmesa->tcl.obj; ++ nr++; + } + + + if (inputs & VERT_BIT_NORMAL) { + if (!rmesa->tcl.norm.buf) +- emit_vector( ctx, +- &(rmesa->tcl.norm), +- (char *)VB->NormalPtr->data, +- 3, +- VB->NormalPtr->stride, +- count); ++ rcommon_emit_vector( ctx, ++ &(rmesa->tcl.aos[nr]), ++ (char *)VB->NormalPtr->data, ++ 3, ++ VB->NormalPtr->stride, ++ count); + + vfmt |= RADEON_CP_VC_FRMT_N0; +- component[nr++] = &rmesa->tcl.norm; ++ nr++; + } + + if (inputs & VERT_BIT_COLOR0) { +@@ -537,31 +240,30 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + } + + if (!rmesa->tcl.rgba.buf) +- emit_vector( ctx, +- &(rmesa->tcl.rgba), +- (char *)VB->ColorPtr[0]->data, +- emitsize, +- VB->ColorPtr[0]->stride, +- count); +- +- +- component[nr++] = &rmesa->tcl.rgba; ++ rcommon_emit_vector( ctx, ++ &(rmesa->tcl.aos[nr]), ++ (char *)VB->ColorPtr[0]->data, ++ emitsize, ++ VB->ColorPtr[0]->stride, ++ count); ++ ++ nr++; + } + + + if (inputs & VERT_BIT_COLOR1) { + if (!rmesa->tcl.spec.buf) { + +- emit_vector( ctx, +- &rmesa->tcl.spec, +- (char *)VB->SecondaryColorPtr[0]->data, +- 3, +- VB->SecondaryColorPtr[0]->stride, +- count); ++ rcommon_emit_vector( ctx, ++ &(rmesa->tcl.aos[nr]), ++ (char *)VB->SecondaryColorPtr[0]->data, ++ 3, ++ VB->SecondaryColorPtr[0]->stride, ++ count); + } + + vfmt |= RADEON_CP_VC_FRMT_FPSPEC; +- component[nr++] = &rmesa->tcl.spec; ++ nr++; + } + + /* FIXME: not sure if this is correct. May need to stitch this together with +@@ -570,13 +272,13 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + if (inputs & VERT_BIT_FOG) { + if (!rmesa->tcl.fog.buf) + emit_vecfog( ctx, +- &(rmesa->tcl.fog), ++ &(rmesa->tcl.aos[nr]), + (char *)VB->FogCoordPtr->data, + VB->FogCoordPtr->stride, + count); + + vfmt |= RADEON_CP_VC_FRMT_FPFOG; +- component[nr++] = &rmesa->tcl.fog; ++ nr++; + } + + +@@ -587,11 +289,12 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + if (inputs & VERT_BIT_TEX(unit)) { + if (!rmesa->tcl.tex[unit].buf) + emit_tex_vector( ctx, +- &(rmesa->tcl.tex[unit]), ++ &(rmesa->tcl.aos[nr]), + (char *)VB->TexCoordPtr[unit]->data, + VB->TexCoordPtr[unit]->size, + VB->TexCoordPtr[unit]->stride, + count ); ++ nr++; + + vfmt |= RADEON_ST_BIT(unit); + /* assume we need the 3rd coord if texgen is active for r/q OR at least +@@ -609,7 +312,6 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + (swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1))) + radeonUploadTexMatrix( rmesa, unit, swaptexmatcol ) ; + } +- component[nr++] = &rmesa->tcl.tex[unit]; + } + } + +@@ -622,34 +324,3 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + rmesa->tcl.vertex_format = vfmt; + } + +- +-void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); +- GLuint unit; +- +-#if 0 +- if (RADEON_DEBUG & DEBUG_VERTS) +- _tnl_print_vert_flags( __FUNCTION__, newinputs ); +-#endif +- +- if (newinputs & VERT_BIT_POS) +- radeonReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); +- +- if (newinputs & VERT_BIT_NORMAL) +- radeonReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); +- +- if (newinputs & VERT_BIT_COLOR0) +- radeonReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ ); +- +- if (newinputs & VERT_BIT_COLOR1) +- radeonReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ ); +- +- if (newinputs & VERT_BIT_FOG) +- radeonReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ ); +- +- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { +- if (newinputs & VERT_BIT_TEX(unit)) +- radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[unit], __FUNCTION__ ); +- } +-} +diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c +index 126d072..78ec119 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c ++++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c +@@ -310,7 +310,7 @@ static void init_tcl_verts( void ) + + void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint req = 0; + GLuint unit; +@@ -374,14 +374,15 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + break; + + if (rmesa->tcl.vertex_format == setup_tab[i].vertex_format && +- rmesa->tcl.indexed_verts.buf) ++ rmesa->radeon.tcl.aos[0].bo) + return; + +- if (rmesa->tcl.indexed_verts.buf) ++ if (rmesa->radeon.tcl.aos[0].bo) + radeonReleaseArrays( ctx, ~0 ); + +- radeonAllocDmaRegion( rmesa, +- &rmesa->tcl.indexed_verts, ++ radeonAllocDmaRegion( &rmesa->radeon, ++ &rmesa->radeon.tcl.aos[0].bo, ++ &rmesa->radeon.tcl.aos[0].offset, + VB->Count * setup_tab[i].vertex_size * 4, + 4); + +@@ -421,29 +422,12 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) + + + setup_tab[i].emit( ctx, 0, VB->Count, +- rmesa->tcl.indexed_verts.address + +- rmesa->tcl.indexed_verts.start ); ++ rmesa->radeon.tcl.aos[0].bo->ptr + rmesa->radeon.tcl.aos[0].offset); + ++ // rmesa->radeon.tcl.aos[0].size = setup_tab[i].vertex_size; ++ rmesa->radeon.tcl.aos[0].stride = setup_tab[i].vertex_size; + rmesa->tcl.vertex_format = setup_tab[i].vertex_format; +- rmesa->tcl.indexed_verts.aos_start = GET_START( &rmesa->tcl.indexed_verts ); +- rmesa->tcl.indexed_verts.aos_size = setup_tab[i].vertex_size; +- rmesa->tcl.indexed_verts.aos_stride = setup_tab[i].vertex_size; +- +- rmesa->tcl.aos_components[0] = &rmesa->tcl.indexed_verts; +- rmesa->tcl.nr_aos_components = 1; ++ rmesa->radeon.tcl.aos_count = 1; + } + + +- +-void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); +- +-#if 0 +- if (RADEON_DEBUG & DEBUG_VERTS) +- _tnl_print_vert_flags( __FUNCTION__, newinputs ); +-#endif +- +- if (newinputs) +- radeonReleaseDmaRegion( rmesa, &rmesa->tcl.indexed_verts, __FUNCTION__ ); +-} +diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +new file mode 100644 +index 0000000..34d6261 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +@@ -0,0 +1,386 @@ ++/* ++ * Copyright (C) 2008 Nicolai Haehnle. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "radeon_mipmap_tree.h" ++ ++#include ++#include ++ ++#include "main/simple_list.h" ++#include "main/texcompress.h" ++#include "main/texformat.h" ++ ++static GLuint radeon_compressed_texture_size(GLcontext *ctx, ++ GLsizei width, GLsizei height, GLsizei depth, ++ GLuint mesaFormat) ++{ ++ GLuint size = _mesa_compressed_texture_size(ctx, width, height, depth, mesaFormat); ++ ++ if (mesaFormat == MESA_FORMAT_RGB_DXT1 || ++ mesaFormat == MESA_FORMAT_RGBA_DXT1) { ++ if (width + 3 < 8) /* width one block */ ++ size = size * 4; ++ else if (width + 3 < 16) ++ size = size * 2; ++ } else { ++ /* DXT3/5, 16 bytes per block */ ++ // WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n"); ++ if (width + 3 < 8) ++ size = size * 2; ++ } ++ ++ return size; ++} ++ ++ ++static int radeon_compressed_num_bytes(GLuint mesaFormat) ++{ ++ int bytes = 0; ++ switch(mesaFormat) { ++ ++ case MESA_FORMAT_RGB_FXT1: ++ case MESA_FORMAT_RGBA_FXT1: ++ case MESA_FORMAT_RGB_DXT1: ++ case MESA_FORMAT_RGBA_DXT1: ++ bytes = 2; ++ break; ++ ++ case MESA_FORMAT_RGBA_DXT3: ++ case MESA_FORMAT_RGBA_DXT5: ++ bytes = 4; ++ default: ++ break; ++ } ++ ++ return bytes; ++} ++ ++/** ++ * Compute sizes and fill in offset and blit information for the given ++ * image (determined by \p face and \p level). ++ * ++ * \param curOffset points to the offset at which the image is to be stored ++ * and is updated by this function according to the size of the image. ++ */ ++static void compute_tex_image_offset(radeon_mipmap_tree *mt, ++ GLuint face, GLuint level, GLuint* curOffset) ++{ ++ radeon_mipmap_level *lvl = &mt->levels[level]; ++ ++ /* Find image size in bytes */ ++ if (mt->compressed) { ++ /* TODO: Is this correct? Need test cases for compressed textures! */ ++ lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63; ++ lvl->size = radeon_compressed_texture_size(mt->radeon->glCtx, ++ lvl->width, lvl->height, lvl->depth, mt->compressed); ++ } else if (mt->target == GL_TEXTURE_RECTANGLE_NV) { ++ lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63; ++ lvl->size = lvl->rowstride * lvl->height; ++ } else if (mt->tilebits & RADEON_TXO_MICRO_TILE) { ++ /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, ++ * though the actual offset may be different (if texture is less than ++ * 32 bytes width) to the untiled case */ ++ lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31; ++ lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth; ++ } else { ++ lvl->rowstride = (lvl->width * mt->bpp + 31) & ~31; ++ lvl->size = lvl->rowstride * lvl->height * lvl->depth; ++ } ++ assert(lvl->size > 0); ++ ++ /* All images are aligned to a 32-byte offset */ ++ *curOffset = (*curOffset + 0x1f) & ~0x1f; ++ lvl->faces[face].offset = *curOffset; ++ *curOffset += lvl->size; ++ ++ if (RADEON_DEBUG & DEBUG_TEXTURE) ++ fprintf(stderr, ++ "level %d, face %d: rs:%d %dx%d at %d\n", ++ level, face, lvl->rowstride, lvl->width, lvl->height, lvl->faces[face].offset); ++} ++ ++static GLuint minify(GLuint size, GLuint levels) ++{ ++ size = size >> levels; ++ if (size < 1) ++ size = 1; ++ return size; ++} ++ ++static void calculate_miptree_layout(radeon_mipmap_tree *mt) ++{ ++ GLuint curOffset; ++ GLuint numLevels; ++ GLuint i; ++ ++ numLevels = mt->lastLevel - mt->firstLevel + 1; ++ assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS); ++ ++ curOffset = 0; ++ for(i = 0; i < numLevels; i++) { ++ GLuint face; ++ ++ mt->levels[i].width = minify(mt->width0, i); ++ mt->levels[i].height = minify(mt->height0, i); ++ mt->levels[i].depth = minify(mt->depth0, i); ++ ++ for(face = 0; face < mt->faces; face++) ++ compute_tex_image_offset(mt, face, i, &curOffset); ++ } ++ ++ /* Note the required size in memory */ ++ mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; ++} ++ ++ ++/** ++ * Create a new mipmap tree, calculate its layout and allocate memory. ++ */ ++radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t, ++ GLenum target, GLuint firstLevel, GLuint lastLevel, ++ GLuint width0, GLuint height0, GLuint depth0, ++ GLuint bpp, GLuint tilebits, GLuint compressed) ++{ ++ radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree); ++ ++ mt->radeon = rmesa; ++ mt->refcount = 1; ++ mt->t = t; ++ mt->target = target; ++ mt->faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; ++ mt->firstLevel = firstLevel; ++ mt->lastLevel = lastLevel; ++ mt->width0 = width0; ++ mt->height0 = height0; ++ mt->depth0 = depth0; ++ mt->bpp = compressed ? radeon_compressed_num_bytes(compressed) : bpp; ++ mt->tilebits = tilebits; ++ mt->compressed = compressed; ++ ++ calculate_miptree_layout(mt); ++ ++ mt->bo = radeon_bo_open(rmesa->radeonScreen->bom, ++ 0, mt->totalsize, 1024, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ ++ return mt; ++} ++ ++void radeon_miptree_reference(radeon_mipmap_tree *mt) ++{ ++ mt->refcount++; ++ assert(mt->refcount > 0); ++} ++ ++void radeon_miptree_unreference(radeon_mipmap_tree *mt) ++{ ++ if (!mt) ++ return; ++ ++ assert(mt->refcount > 0); ++ mt->refcount--; ++ if (!mt->refcount) { ++ radeon_bo_unref(mt->bo); ++ free(mt); ++ } ++} ++ ++ ++/** ++ * Calculate first and last mip levels for the given texture object, ++ * where the dimensions are taken from the given texture image at ++ * the given level. ++ * ++ * Note: level is the OpenGL level number, which is not necessarily the same ++ * as the first level that is actually present. ++ * ++ * The base level image of the given texture face must be non-null, ++ * or this will fail. ++ */ ++static void calculate_first_last_level(struct gl_texture_object *tObj, ++ GLuint *pfirstLevel, GLuint *plastLevel, ++ GLuint face, GLuint level) ++{ ++ const struct gl_texture_image * const baseImage = ++ tObj->Image[face][level]; ++ ++ assert(baseImage); ++ ++ /* These must be signed values. MinLod and MaxLod can be negative numbers, ++ * and having firstLevel and lastLevel as signed prevents the need for ++ * extra sign checks. ++ */ ++ int firstLevel; ++ int lastLevel; ++ ++ /* Yes, this looks overly complicated, but it's all needed. ++ */ ++ switch (tObj->Target) { ++ case GL_TEXTURE_1D: ++ case GL_TEXTURE_2D: ++ case GL_TEXTURE_3D: ++ case GL_TEXTURE_CUBE_MAP: ++ if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { ++ /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. ++ */ ++ firstLevel = lastLevel = tObj->BaseLevel; ++ } else { ++ firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5); ++ firstLevel = MAX2(firstLevel, tObj->BaseLevel); ++ firstLevel = MIN2(firstLevel, level + baseImage->MaxLog2); ++ lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5); ++ lastLevel = MAX2(lastLevel, tObj->BaseLevel); ++ lastLevel = MIN2(lastLevel, level + baseImage->MaxLog2); ++ lastLevel = MIN2(lastLevel, tObj->MaxLevel); ++ lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ ++ } ++ break; ++ case GL_TEXTURE_RECTANGLE_NV: ++ case GL_TEXTURE_4D_SGIS: ++ firstLevel = lastLevel = 0; ++ break; ++ default: ++ return; ++ } ++ ++ /* save these values */ ++ *pfirstLevel = firstLevel; ++ *plastLevel = lastLevel; ++} ++ ++ ++/** ++ * Checks whether the given miptree can hold the given texture image at the ++ * given face and level. ++ */ ++GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, ++ struct gl_texture_image *texImage, GLuint face, GLuint level) ++{ ++ radeon_mipmap_level *lvl; ++ ++ if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel) ++ return GL_FALSE; ++ ++ if (texImage->IsCompressed != mt->compressed) ++ return GL_FALSE; ++ ++ if (!texImage->IsCompressed && ++ !mt->compressed && ++ texImage->TexFormat->TexelBytes != mt->bpp) ++ return GL_FALSE; ++ ++ lvl = &mt->levels[level - mt->firstLevel]; ++ if (lvl->width != texImage->Width || ++ lvl->height != texImage->Height || ++ lvl->depth != texImage->Depth) ++ return GL_FALSE; ++ ++ return GL_TRUE; ++} ++ ++ ++/** ++ * Checks whether the given miptree has the right format to store the given texture object. ++ */ ++GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj) ++{ ++ struct gl_texture_image *firstImage; ++ GLuint compressed; ++ GLuint numfaces = 1; ++ GLuint firstLevel, lastLevel; ++ ++ calculate_first_last_level(texObj, &firstLevel, &lastLevel, 0, texObj->BaseLevel); ++ if (texObj->Target == GL_TEXTURE_CUBE_MAP) ++ numfaces = 6; ++ ++ firstImage = texObj->Image[0][firstLevel]; ++ compressed = firstImage->IsCompressed ? firstImage->TexFormat->MesaFormat : 0; ++ ++ return (mt->firstLevel == firstLevel && ++ mt->lastLevel == lastLevel && ++ mt->width0 == firstImage->Width && ++ mt->height0 == firstImage->Height && ++ mt->depth0 == firstImage->Depth && ++ mt->bpp == firstImage->TexFormat->TexelBytes && ++ mt->compressed == compressed); ++} ++ ++ ++/** ++ * Try to allocate a mipmap tree for the given texture that will fit the ++ * given image in the given position. ++ */ ++void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t, ++ struct gl_texture_image *texImage, GLuint face, GLuint level) ++{ ++ GLuint compressed = texImage->IsCompressed ? texImage->TexFormat->MesaFormat : 0; ++ GLuint numfaces = 1; ++ GLuint firstLevel, lastLevel; ++ ++ assert(!t->mt); ++ ++ calculate_first_last_level(&t->base, &firstLevel, &lastLevel, face, level); ++ if (t->base.Target == GL_TEXTURE_CUBE_MAP) ++ numfaces = 6; ++ ++ if (level != firstLevel || face >= numfaces) ++ return; ++ ++ t->mt = radeon_miptree_create(rmesa, t, t->base.Target, ++ firstLevel, lastLevel, ++ texImage->Width, texImage->Height, texImage->Depth, ++ texImage->TexFormat->TexelBytes, t->tile_bits, compressed); ++} ++ ++/* Although we use the image_offset[] array to store relative offsets ++ * to cube faces, Mesa doesn't know anything about this and expects ++ * each cube face to be treated as a separate image. ++ * ++ * These functions present that view to mesa: ++ */ ++void ++radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets) ++{ ++ if (mt->target != GL_TEXTURE_3D || mt->faces == 1) ++ offsets[0] = 0; ++ else { ++ int i; ++ for (i = 0; i < 6; i++) ++ offsets[i] = mt->levels[level].faces[i].offset; ++ } ++} ++ ++GLuint ++radeon_miptree_image_offset(radeon_mipmap_tree *mt, ++ GLuint face, GLuint level) ++{ ++ if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) ++ return (mt->levels[level].faces[face].offset); ++ else ++ return mt->levels[level].faces[0].offset; ++} +diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +new file mode 100644 +index 0000000..697010b +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +@@ -0,0 +1,98 @@ ++/* ++ * Copyright (C) 2008 Nicolai Haehnle. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __RADEON_MIPMAP_TREE_H_ ++#define __RADEON_MIPMAP_TREE_H_ ++ ++#include "radeon_common.h" ++ ++typedef struct _radeon_mipmap_tree radeon_mipmap_tree; ++typedef struct _radeon_mipmap_level radeon_mipmap_level; ++typedef struct _radeon_mipmap_image radeon_mipmap_image; ++ ++struct _radeon_mipmap_image { ++ GLuint offset; /** Offset of this image from the start of mipmap tree buffer, in bytes */ ++}; ++ ++struct _radeon_mipmap_level { ++ GLuint width; ++ GLuint height; ++ GLuint depth; ++ GLuint size; /** Size of each image, in bytes */ ++ GLuint rowstride; /** in bytes */ ++ radeon_mipmap_image faces[6]; ++}; ++ ++ ++/** ++ * A mipmap tree contains texture images in the layout that the hardware ++ * expects. ++ * ++ * The meta-data of mipmap trees is immutable, i.e. you cannot change the ++ * layout on-the-fly; however, the texture contents (i.e. texels) can be ++ * changed. ++ */ ++struct _radeon_mipmap_tree { ++ radeonContextPtr radeon; ++ radeonTexObj *t; ++ struct radeon_bo *bo; ++ GLuint refcount; ++ ++ GLuint totalsize; /** total size of the miptree, in bytes */ ++ ++ GLenum target; /** GL_TEXTURE_xxx */ ++ GLuint faces; /** # of faces: 6 for cubemaps, 1 otherwise */ ++ GLuint firstLevel; /** First mip level stored in this mipmap tree */ ++ GLuint lastLevel; /** Last mip level stored in this mipmap tree */ ++ ++ GLuint width0; /** Width of firstLevel image */ ++ GLuint height0; /** Height of firstLevel image */ ++ GLuint depth0; /** Depth of firstLevel image */ ++ ++ GLuint bpp; /** Bytes per texel */ ++ GLuint tilebits; /** RADEON_TXO_xxx_TILE */ ++ GLuint compressed; /** MESA_FORMAT_xxx indicating a compressed format, or 0 if uncompressed */ ++ ++ radeon_mipmap_level levels[RADEON_MAX_TEXTURE_LEVELS]; ++}; ++ ++radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t, ++ GLenum target, GLuint firstLevel, GLuint lastLevel, ++ GLuint width0, GLuint height0, GLuint depth0, ++ GLuint bpp, GLuint tilebits, GLuint compressed); ++void radeon_miptree_reference(radeon_mipmap_tree *mt); ++void radeon_miptree_unreference(radeon_mipmap_tree *mt); ++ ++GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, ++ struct gl_texture_image *texImage, GLuint face, GLuint level); ++GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj); ++void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t, ++ struct gl_texture_image *texImage, GLuint face, GLuint level); ++GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, ++ GLuint face, GLuint level); ++void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets); ++#endif /* __RADEON_MIPMAP_TREE_H_ */ +diff --git a/src/mesa/drivers/dri/radeon/radeon_sanity.c b/src/mesa/drivers/dri/radeon/radeon_sanity.c +index 6613757..bbed838 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_sanity.c ++++ b/src/mesa/drivers/dri/radeon/radeon_sanity.c +@@ -973,7 +973,7 @@ static int radeon_emit_packet3_cliprect( drm_radeon_cmd_buffer_t *cmdbuf ) + } + + +-int radeonSanityCmdBuffer( radeonContextPtr rmesa, ++int radeonSanityCmdBuffer( r100ContextPtr rmesa, + int nbox, + drm_clip_rect_t *boxes ) + { +diff --git a/src/mesa/drivers/dri/radeon/radeon_sanity.h b/src/mesa/drivers/dri/radeon/radeon_sanity.h +index 1ec06bc..f30eb1c 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_sanity.h ++++ b/src/mesa/drivers/dri/radeon/radeon_sanity.h +@@ -1,7 +1,7 @@ + #ifndef RADEON_SANITY_H + #define RADEON_SANITY_H + +-extern int radeonSanityCmdBuffer( radeonContextPtr rmesa, ++extern int radeonSanityCmdBuffer( r100ContextPtr rmesa, + int nbox, + drm_clip_rect_t *boxes ); + +diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c +index e964feb..49c7eae 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_screen.c ++++ b/src/mesa/drivers/dri/radeon/radeon_screen.c +@@ -35,6 +35,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * \author Gareth Hughes + */ + ++#include + #include "main/glheader.h" + #include "main/imports.h" + #include "main/mtypes.h" +@@ -45,32 +46,39 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "radeon_chipset.h" + #include "radeon_macros.h" + #include "radeon_screen.h" ++#include "radeon_common.h" ++#include "radeon_span.h" + #if !RADEON_COMMON + #include "radeon_context.h" +-#include "radeon_span.h" + #include "radeon_tex.h" + #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) + #include "r200_context.h" + #include "r200_ioctl.h" +-#include "r200_span.h" + #include "r200_tex.h" + #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) + #include "r300_context.h" + #include "r300_fragprog.h" + #include "r300_tex.h" +-#include "radeon_span.h" + #endif + + #include "utils.h" + #include "vblank.h" + #include "drirenderbuffer.h" + ++#include "radeon_bocs_wrapper.h" ++ + #include "GL/internal/dri_interface.h" + + /* Radeon configuration + */ + #include "xmlpool.h" + ++#define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \ ++DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \ ++ DRI_CONF_DESC(en,"Size of command buffer (in KB)") \ ++ DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \ ++DRI_CONF_OPT_END ++ + #if !RADEON_COMMON /* R100 */ + PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN +@@ -80,6 +88,7 @@ DRI_CONF_BEGIN + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_MAX_TEXTURE_UNITS(3,2,3) + DRI_CONF_HYPERZ(false) ++ DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32) + DRI_CONF_SECTION_END + DRI_CONF_SECTION_QUALITY + DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) +@@ -95,7 +104,7 @@ DRI_CONF_BEGIN + DRI_CONF_NO_RAST(false) + DRI_CONF_SECTION_END + DRI_CONF_END; +-static const GLuint __driNConfigOptions = 14; ++static const GLuint __driNConfigOptions = 15; + + #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) + +@@ -107,6 +116,7 @@ DRI_CONF_BEGIN + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_MAX_TEXTURE_UNITS(6,2,6) + DRI_CONF_HYPERZ(false) ++ DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32) + DRI_CONF_SECTION_END + DRI_CONF_SECTION_QUALITY + DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) +@@ -126,7 +136,7 @@ DRI_CONF_BEGIN + DRI_CONF_NV_VERTEX_PROGRAM(false) + DRI_CONF_SECTION_END + DRI_CONF_END; +-static const GLuint __driNConfigOptions = 16; ++static const GLuint __driNConfigOptions = 17; + + extern const struct dri_extension blend_extensions[]; + extern const struct dri_extension ARB_vp_extension[]; +@@ -149,11 +159,7 @@ DRI_CONF_OPT_BEGIN_V(texture_coord_units,int,def, # min ":" # max ) \ + DRI_CONF_DESC(de,"Anzahl der Texturkoordinateneinheiten") \ + DRI_CONF_OPT_END + +-#define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \ +-DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \ +- DRI_CONF_DESC(en,"Size of command buffer (in KB)") \ +- DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \ +-DRI_CONF_OPT_END ++ + + #define DRI_CONF_DISABLE_S3TC(def) \ + DRI_CONF_OPT_BEGIN(disable_s3tc,bool,def) \ +@@ -209,7 +215,6 @@ static const GLuint __driNConfigOptions = 17; + extern const struct dri_extension gl_20_extension[]; + + #ifndef RADEON_DEBUG +-int RADEON_DEBUG = 0; + + static const struct dri_debug_control debug_control[] = { + {"fall", DEBUG_FALLBACKS}, +@@ -236,19 +241,36 @@ static const struct dri_debug_control debug_control[] = { + #endif /* RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) */ + + extern const struct dri_extension card_extensions[]; ++extern const struct dri_extension mm_extensions[]; + + static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ); + + static int +-radeonGetParam(int fd, int param, void *value) ++radeonGetParam(__DRIscreenPrivate *sPriv, int param, void *value) + { + int ret; + drm_radeon_getparam_t gp; ++ struct drm_radeon_info info; ++ ++ if (sPriv->drm_version.major >= 2) { ++ info.value = (uint64_t)value; ++ switch (param) { ++ case RADEON_PARAM_DEVICE_ID: ++ info.request = RADEON_INFO_DEVICE_ID; ++ break; ++ case RADEON_PARAM_NUM_GB_PIPES: ++ info.request = RADEON_INFO_NUM_GB_PIPES; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_INFO, &info, sizeof(info)); ++ } else { ++ gp.param = param; ++ gp.value = value; + +- gp.param = param; +- gp.value = value; +- +- ret = drmCommandWriteRead( fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); ++ ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); ++ } + return ret; + } + +@@ -330,6 +352,12 @@ static const __DRItexOffsetExtension radeonTexOffsetExtension = { + { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION }, + radeonSetTexOffset, + }; ++ ++static const __DRItexBufferExtension radeonTexBufferExtension = { ++ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, ++ radeonSetTexBuffer, ++ radeonSetTexBuffer2, ++}; + #endif + + #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +@@ -344,6 +372,12 @@ static const __DRItexOffsetExtension r200texOffsetExtension = { + { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION }, + r200SetTexOffset, + }; ++ ++static const __DRItexBufferExtension r200TexBufferExtension = { ++ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, ++ r200SetTexBuffer, ++ r200SetTexBuffer2, ++}; + #endif + + #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +@@ -351,137 +385,18 @@ static const __DRItexOffsetExtension r300texOffsetExtension = { + { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION }, + r300SetTexOffset, + }; +-#endif + +-/* Create the device specific screen private data struct. +- */ +-static radeonScreenPtr +-radeonCreateScreen( __DRIscreenPrivate *sPriv ) +-{ +- radeonScreenPtr screen; +- RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv; +- unsigned char *RADEONMMIO; +- int i; +- int ret; +- uint32_t temp = 0; +- +- if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) { +- fprintf(stderr,"\nERROR! sizeof(RADEONDRIRec) does not match passed size from device driver\n"); +- return GL_FALSE; +- } +- +- /* Allocate the private area */ +- screen = (radeonScreenPtr) CALLOC( sizeof(*screen) ); +- if ( !screen ) { +- __driUtilMessage("%s: Could not allocate memory for screen structure", +- __FUNCTION__); +- return NULL; +- } +- +-#if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +- RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control); ++static const __DRItexBufferExtension r300TexBufferExtension = { ++ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, ++ r300SetTexBuffer, ++ r300SetTexBuffer2, ++}; + #endif + +- /* parse information in __driConfigOptions */ +- driParseOptionInfo (&screen->optionCache, +- __driConfigOptions, __driNConfigOptions); +- +- /* This is first since which regions we map depends on whether or +- * not we are using a PCI card. +- */ +- screen->card_type = (dri_priv->IsPCI ? RADEON_CARD_PCI : RADEON_CARD_AGP); +- { +- int ret; +- ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BUFFER_OFFSET, +- &screen->gart_buffer_offset); +- +- if (ret) { +- FREE( screen ); +- fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret); +- return NULL; +- } +- +- ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BASE, +- &screen->gart_base); +- if (ret) { +- FREE( screen ); +- fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BASE): %d\n", ret); +- return NULL; +- } +- +- ret = radeonGetParam( sPriv->fd, RADEON_PARAM_IRQ_NR, +- &screen->irq); +- if (ret) { +- FREE( screen ); +- fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret); +- return NULL; +- } +- screen->drmSupportsCubeMapsR200 = (sPriv->drm_version.minor >= 7); +- screen->drmSupportsBlendColor = (sPriv->drm_version.minor >= 11); +- screen->drmSupportsTriPerf = (sPriv->drm_version.minor >= 16); +- screen->drmSupportsFragShader = (sPriv->drm_version.minor >= 18); +- screen->drmSupportsPointSprites = (sPriv->drm_version.minor >= 13); +- screen->drmSupportsCubeMapsR100 = (sPriv->drm_version.minor >= 15); +- screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25); +- } +- +- screen->mmio.handle = dri_priv->registerHandle; +- screen->mmio.size = dri_priv->registerSize; +- if ( drmMap( sPriv->fd, +- screen->mmio.handle, +- screen->mmio.size, +- &screen->mmio.map ) ) { +- FREE( screen ); +- __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ ); +- return NULL; +- } +- +- RADEONMMIO = screen->mmio.map; +- +- screen->status.handle = dri_priv->statusHandle; +- screen->status.size = dri_priv->statusSize; +- if ( drmMap( sPriv->fd, +- screen->status.handle, +- screen->status.size, +- &screen->status.map ) ) { +- drmUnmap( screen->mmio.map, screen->mmio.size ); +- FREE( screen ); +- __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ ); +- return NULL; +- } +- screen->scratch = (__volatile__ uint32_t *) +- ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET); +- +- screen->buffers = drmMapBufs( sPriv->fd ); +- if ( !screen->buffers ) { +- drmUnmap( screen->status.map, screen->status.size ); +- drmUnmap( screen->mmio.map, screen->mmio.size ); +- FREE( screen ); +- __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ ); +- return NULL; +- } +- +- if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) { +- screen->gartTextures.handle = dri_priv->gartTexHandle; +- screen->gartTextures.size = dri_priv->gartTexMapSize; +- if ( drmMap( sPriv->fd, +- screen->gartTextures.handle, +- screen->gartTextures.size, +- (drmAddressPtr)&screen->gartTextures.map ) ) { +- drmUnmapBufs( screen->buffers ); +- drmUnmap( screen->status.map, screen->status.size ); +- drmUnmap( screen->mmio.map, screen->mmio.size ); +- FREE( screen ); +- __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__); +- return NULL; +- } +- +- screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base; +- } +- ++static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) ++{ + screen->chip_flags = 0; +- /* XXX: add more chipsets */ +- switch ( dri_priv->deviceID ) { ++ switch ( device_id ) { + case PCI_CHIP_RADEON_LY: + case PCI_CHIP_RADEON_LZ: + case PCI_CHIP_RADEON_QY: +@@ -819,9 +734,161 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) + + default: + fprintf(stderr, "unknown chip id 0x%x, can't guess.\n", +- dri_priv->deviceID); ++ device_id); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++/* Create the device specific screen private data struct. ++ */ ++static radeonScreenPtr ++radeonCreateScreen( __DRIscreenPrivate *sPriv ) ++{ ++ radeonScreenPtr screen; ++ RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv; ++ unsigned char *RADEONMMIO = NULL; ++ int i; ++ int ret; ++ uint32_t temp = 0; ++ ++ if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) { ++ fprintf(stderr,"\nERROR! sizeof(RADEONDRIRec) does not match passed size from device driver\n"); ++ return GL_FALSE; ++ } ++ ++ /* Allocate the private area */ ++ screen = (radeonScreenPtr) CALLOC( sizeof(*screen) ); ++ if ( !screen ) { ++ __driUtilMessage("%s: Could not allocate memory for screen structure", ++ __FUNCTION__); + return NULL; + } ++ ++#if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) ++ RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control); ++#endif ++ ++ /* parse information in __driConfigOptions */ ++ driParseOptionInfo (&screen->optionCache, ++ __driConfigOptions, __driNConfigOptions); ++ ++ /* This is first since which regions we map depends on whether or ++ * not we are using a PCI card. ++ */ ++ screen->card_type = (dri_priv->IsPCI ? RADEON_CARD_PCI : RADEON_CARD_AGP); ++ { ++ int ret; ++ ++#ifdef RADEON_PARAM_KERNEL_MM ++ ret = radeonGetParam(sPriv, RADEON_PARAM_KERNEL_MM, &screen->kernel_mm); ++ ++ if (ret && ret != -EINVAL) { ++ FREE( screen ); ++ fprintf(stderr, "drm_radeon_getparam_t (RADEON_OFFSET): %d\n", ret); ++ return NULL; ++ } ++ ++ if (ret == -EINVAL) ++ screen->kernel_mm = 0; ++#endif ++ ++ ret = radeonGetParam(sPriv, RADEON_PARAM_GART_BUFFER_OFFSET, ++ &screen->gart_buffer_offset); ++ ++ if (ret) { ++ FREE( screen ); ++ fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret); ++ return NULL; ++ } ++ ++ ret = radeonGetParam(sPriv, RADEON_PARAM_GART_BASE, ++ &screen->gart_base); ++ if (ret) { ++ FREE( screen ); ++ fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BASE): %d\n", ret); ++ return NULL; ++ } ++ ++ ret = radeonGetParam(sPriv, RADEON_PARAM_IRQ_NR, ++ &screen->irq); ++ if (ret) { ++ FREE( screen ); ++ fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret); ++ return NULL; ++ } ++ screen->drmSupportsCubeMapsR200 = (sPriv->drm_version.minor >= 7); ++ screen->drmSupportsBlendColor = (sPriv->drm_version.minor >= 11); ++ screen->drmSupportsTriPerf = (sPriv->drm_version.minor >= 16); ++ screen->drmSupportsFragShader = (sPriv->drm_version.minor >= 18); ++ screen->drmSupportsPointSprites = (sPriv->drm_version.minor >= 13); ++ screen->drmSupportsCubeMapsR100 = (sPriv->drm_version.minor >= 15); ++ screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25); ++ } ++ ++ if (!screen->kernel_mm) { ++ screen->mmio.handle = dri_priv->registerHandle; ++ screen->mmio.size = dri_priv->registerSize; ++ if ( drmMap( sPriv->fd, ++ screen->mmio.handle, ++ screen->mmio.size, ++ &screen->mmio.map ) ) { ++ FREE( screen ); ++ __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ ); ++ return NULL; ++ } ++ ++ RADEONMMIO = screen->mmio.map; ++ ++ screen->status.handle = dri_priv->statusHandle; ++ screen->status.size = dri_priv->statusSize; ++ if ( drmMap( sPriv->fd, ++ screen->status.handle, ++ screen->status.size, ++ &screen->status.map ) ) { ++ drmUnmap( screen->mmio.map, screen->mmio.size ); ++ FREE( screen ); ++ __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ ); ++ return NULL; ++ } ++ screen->scratch = (__volatile__ uint32_t *) ++ ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET); ++ ++ screen->buffers = drmMapBufs( sPriv->fd ); ++ if ( !screen->buffers ) { ++ drmUnmap( screen->status.map, screen->status.size ); ++ drmUnmap( screen->mmio.map, screen->mmio.size ); ++ FREE( screen ); ++ __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ ); ++ return NULL; ++ } ++ ++ if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) { ++ screen->gartTextures.handle = dri_priv->gartTexHandle; ++ screen->gartTextures.size = dri_priv->gartTexMapSize; ++ if ( drmMap( sPriv->fd, ++ screen->gartTextures.handle, ++ screen->gartTextures.size, ++ (drmAddressPtr)&screen->gartTextures.map ) ) { ++ drmUnmapBufs( screen->buffers ); ++ drmUnmap( screen->status.map, screen->status.size ); ++ drmUnmap( screen->mmio.map, screen->mmio.size ); ++ FREE( screen ); ++ __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__); ++ return NULL; ++ } ++ ++ screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base; ++ } ++ } ++ ++ ++ ret = radeon_set_screen_flags(screen, dri_priv->deviceID); ++ if (ret == -1) ++ return NULL; ++ + if ((screen->chip_family == CHIP_FAMILY_R350 || screen->chip_family == CHIP_FAMILY_R300) && + sPriv->ddx_version.minor < 2) { + fprintf(stderr, "xf86-video-ati-6.6.2 or newer needed for Radeon 9500/9700/9800 cards.\n"); +@@ -846,10 +913,9 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) + screen->cpp = dri_priv->bpp / 8; + screen->AGPMode = dri_priv->AGPMode; + +- ret = radeonGetParam( sPriv->fd, RADEON_PARAM_FB_LOCATION, +- &temp); ++ ret = radeonGetParam(sPriv, RADEON_PARAM_FB_LOCATION, &temp); + if (ret) { +- if (screen->chip_family < CHIP_FAMILY_RS600) ++ if (screen->chip_family < CHIP_FAMILY_RS600 && !screen->kernel_mm) + screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff) << 16; + else { + FREE( screen ); +@@ -861,8 +927,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) + } + + if (screen->chip_family >= CHIP_FAMILY_R300) { +- ret = radeonGetParam( sPriv->fd, RADEON_PARAM_NUM_GB_PIPES, +- &temp); ++ ret = radeonGetParam(sPriv, RADEON_PARAM_NUM_GB_PIPES, &temp); + if (ret) { + fprintf(stderr, "Unable to get num_pipes, need newer drm\n"); + switch (screen->chip_family) { +@@ -951,26 +1016,158 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) + screen->extensions[i++] = &driMediaStreamCounterExtension.base; + } + ++ if (!screen->kernel_mm) { ++#if !RADEON_COMMON ++ screen->extensions[i++] = &radeonTexOffsetExtension.base; ++#endif ++ ++#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) ++ if (IS_R200_CLASS(screen)) ++ screen->extensions[i++] = &r200AllocateExtension.base; ++ ++ screen->extensions[i++] = &r200texOffsetExtension.base; ++#endif ++ ++#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) ++ screen->extensions[i++] = &r300texOffsetExtension.base; ++#endif ++ } ++ ++ screen->extensions[i++] = NULL; ++ sPriv->extensions = screen->extensions; ++ ++ screen->driScreen = sPriv; ++ screen->sarea_priv_offset = dri_priv->sarea_priv_offset; ++ screen->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + ++ screen->sarea_priv_offset); ++ ++ if (screen->kernel_mm) ++ screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd); ++ else ++ screen->bom = radeon_bo_manager_legacy_ctor(screen); ++ if (screen->bom == NULL) { ++ free(screen); ++ return NULL; ++ } ++ ++ return screen; ++} ++ ++static radeonScreenPtr ++radeonCreateScreen2(__DRIscreenPrivate *sPriv) ++{ ++ radeonScreenPtr screen; ++ int i; ++ int ret; ++ uint32_t device_id; ++ uint32_t temp = 0; ++ ++ /* Allocate the private area */ ++ screen = (radeonScreenPtr) CALLOC( sizeof(*screen) ); ++ if ( !screen ) { ++ __driUtilMessage("%s: Could not allocate memory for screen structure", ++ __FUNCTION__); ++ fprintf(stderr, "leaving here\n"); ++ return NULL; ++ } ++ ++#if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) ++ RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control); ++#endif ++ ++ /* parse information in __driConfigOptions */ ++ driParseOptionInfo (&screen->optionCache, ++ __driConfigOptions, __driNConfigOptions); ++ ++ screen->kernel_mm = 1; ++ screen->chip_flags = 0; ++ ++ ret = radeonGetParam(sPriv, RADEON_PARAM_IRQ_NR, &screen->irq); ++ ++ ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id); ++ if (ret) { ++ FREE( screen ); ++ fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret); ++ return NULL; ++ } ++ ++ ret = radeon_set_screen_flags(screen, device_id); ++ if (ret == -1) ++ return NULL; ++ ++ if (screen->chip_family >= CHIP_FAMILY_R300) { ++ ret = radeonGetParam(sPriv, RADEON_PARAM_NUM_GB_PIPES, &temp); ++ if (ret) { ++ fprintf(stderr, "Unable to get num_pipes, need newer drm\n"); ++ switch (screen->chip_family) { ++ case CHIP_FAMILY_R300: ++ case CHIP_FAMILY_R350: ++ screen->num_gb_pipes = 2; ++ break; ++ case CHIP_FAMILY_R420: ++ case CHIP_FAMILY_R520: ++ case CHIP_FAMILY_R580: ++ case CHIP_FAMILY_RV560: ++ case CHIP_FAMILY_RV570: ++ screen->num_gb_pipes = 4; ++ break; ++ case CHIP_FAMILY_RV350: ++ case CHIP_FAMILY_RV515: ++ case CHIP_FAMILY_RV530: ++ case CHIP_FAMILY_RV410: ++ default: ++ screen->num_gb_pipes = 1; ++ break; ++ } ++ } else { ++ screen->num_gb_pipes = temp; ++ } ++ } ++ ++ if (screen->chip_family <= CHIP_FAMILY_RS200) ++ screen->chip_flags |= RADEON_CLASS_R100; ++ else if (screen->chip_family <= CHIP_FAMILY_RV280) ++ screen->chip_flags |= RADEON_CLASS_R200; ++ else ++ screen->chip_flags |= RADEON_CLASS_R300; ++ ++ if (getenv("R300_NO_TCL")) ++ screen->chip_flags &= ~RADEON_CHIPSET_TCL; ++ ++ i = 0; ++ screen->extensions[i++] = &driCopySubBufferExtension.base; ++ screen->extensions[i++] = &driFrameTrackingExtension.base; ++ screen->extensions[i++] = &driReadDrawableExtension; ++ ++ if ( screen->irq != 0 ) { ++ screen->extensions[i++] = &driSwapControlExtension.base; ++ screen->extensions[i++] = &driMediaStreamCounterExtension.base; ++ } ++ + #if !RADEON_COMMON +- screen->extensions[i++] = &radeonTexOffsetExtension.base; ++ screen->extensions[i++] = &radeonTexBufferExtension.base; + #endif + + #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) + if (IS_R200_CLASS(screen)) + screen->extensions[i++] = &r200AllocateExtension.base; + +- screen->extensions[i++] = &r200texOffsetExtension.base; ++ screen->extensions[i++] = &r200TexBufferExtension.base; + #endif + + #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +- screen->extensions[i++] = &r300texOffsetExtension.base; ++ screen->extensions[i++] = &r300TexBufferExtension.base; + #endif + + screen->extensions[i++] = NULL; + sPriv->extensions = screen->extensions; + + screen->driScreen = sPriv; +- screen->sarea_priv_offset = dri_priv->sarea_priv_offset; ++ screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd); ++ if (screen->bom == NULL) { ++ free(screen); ++ return NULL; ++ } + return screen; + } + +@@ -979,23 +1176,32 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) + static void + radeonDestroyScreen( __DRIscreenPrivate *sPriv ) + { +- radeonScreenPtr screen = (radeonScreenPtr)sPriv->private; ++ radeonScreenPtr screen = (radeonScreenPtr)sPriv->private; + +- if (!screen) +- return; ++ if (!screen) ++ return; + +- if ( screen->gartTextures.map ) { +- drmUnmap( screen->gartTextures.map, screen->gartTextures.size ); +- } +- drmUnmapBufs( screen->buffers ); +- drmUnmap( screen->status.map, screen->status.size ); +- drmUnmap( screen->mmio.map, screen->mmio.size ); ++ if (screen->kernel_mm) { ++#ifdef RADEON_BO_TRACK ++ radeon_tracker_print(&screen->bom->tracker, stderr); ++#endif ++ radeon_bo_manager_gem_dtor(screen->bom); ++ } else { ++ radeon_bo_manager_legacy_dtor(screen->bom); ++ ++ if ( screen->gartTextures.map ) { ++ drmUnmap( screen->gartTextures.map, screen->gartTextures.size ); ++ } ++ drmUnmapBufs( screen->buffers ); ++ drmUnmap( screen->status.map, screen->status.size ); ++ drmUnmap( screen->mmio.map, screen->mmio.size ); ++ } + +- /* free all option information */ +- driDestroyOptionInfo (&screen->optionCache); ++ /* free all option information */ ++ driDestroyOptionInfo (&screen->optionCache); + +- FREE( screen ); +- sPriv->private = NULL; ++ FREE( screen ); ++ sPriv->private = NULL; + } + + +@@ -1004,16 +1210,21 @@ radeonDestroyScreen( __DRIscreenPrivate *sPriv ) + static GLboolean + radeonInitDriver( __DRIscreenPrivate *sPriv ) + { +- sPriv->private = (void *) radeonCreateScreen( sPriv ); +- if ( !sPriv->private ) { +- radeonDestroyScreen( sPriv ); +- return GL_FALSE; +- } ++ if (sPriv->dri2.enabled) { ++ sPriv->private = (void *) radeonCreateScreen2( sPriv ); ++ } else { ++ sPriv->private = (void *) radeonCreateScreen( sPriv ); ++ } ++ if ( !sPriv->private ) { ++ radeonDestroyScreen( sPriv ); ++ return GL_FALSE; ++ } + +- return GL_TRUE; ++ return GL_TRUE; + } + + ++ + /** + * Create the Mesa framebuffer and renderbuffers for a given window/drawable. + * +@@ -1026,101 +1237,111 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) + { +- radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private; ++ radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private; ++ ++ const GLboolean swDepth = GL_FALSE; ++ const GLboolean swAlpha = GL_FALSE; ++ const GLboolean swAccum = mesaVis->accumRedBits > 0; ++ const GLboolean swStencil = mesaVis->stencilBits > 0 && ++ mesaVis->depthBits != 24; ++ GLenum rgbFormat; ++ struct radeon_framebuffer *rfb; + +- if (isPixmap) { ++ if (isPixmap) + return GL_FALSE; /* not implemented */ +- } +- else { +- const GLboolean swDepth = GL_FALSE; +- const GLboolean swAlpha = GL_FALSE; +- const GLboolean swAccum = mesaVis->accumRedBits > 0; +- const GLboolean swStencil = mesaVis->stencilBits > 0 && +- mesaVis->depthBits != 24; +- struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); +- +- /* front color renderbuffer */ +- { +- driRenderbuffer *frontRb +- = driNewRenderbuffer(GL_RGBA, +- driScrnPriv->pFB + screen->frontOffset, +- screen->cpp, +- screen->frontOffset, screen->frontPitch, +- driDrawPriv); +- radeonSetSpanFunctions(frontRb, mesaVis); +- _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); +- } + +- /* back color renderbuffer */ +- if (mesaVis->doubleBufferMode) { +- driRenderbuffer *backRb +- = driNewRenderbuffer(GL_RGBA, +- driScrnPriv->pFB + screen->backOffset, +- screen->cpp, +- screen->backOffset, screen->backPitch, +- driDrawPriv); +- radeonSetSpanFunctions(backRb, mesaVis); +- _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); +- } ++ rfb = CALLOC_STRUCT(radeon_framebuffer); ++ if (!rfb) ++ return GL_FALSE; + +- /* depth renderbuffer */ +- if (mesaVis->depthBits == 16) { +- driRenderbuffer *depthRb +- = driNewRenderbuffer(GL_DEPTH_COMPONENT16, +- driScrnPriv->pFB + screen->depthOffset, +- screen->cpp, +- screen->depthOffset, screen->depthPitch, +- driDrawPriv); +- radeonSetSpanFunctions(depthRb, mesaVis); +- _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); +- depthRb->depthHasSurface = screen->depthHasSurface; +- } +- else if (mesaVis->depthBits == 24) { +- driRenderbuffer *depthRb +- = driNewRenderbuffer(GL_DEPTH_COMPONENT24, +- driScrnPriv->pFB + screen->depthOffset, +- screen->cpp, +- screen->depthOffset, screen->depthPitch, +- driDrawPriv); +- radeonSetSpanFunctions(depthRb, mesaVis); +- _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); +- depthRb->depthHasSurface = screen->depthHasSurface; +- } ++ _mesa_initialize_framebuffer(&rfb->base, mesaVis); ++ ++ if (mesaVis->redBits == 5) ++ rgbFormat = GL_RGB5; ++ else if (mesaVis->alphaBits == 0) ++ rgbFormat = GL_RGB8; ++ else ++ rgbFormat = GL_RGBA8; ++ ++ /* front color renderbuffer */ ++ rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); ++ _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base); ++ rfb->color_rb[0]->has_surface = 1; ++ ++ /* back color renderbuffer */ ++ if (mesaVis->doubleBufferMode) { ++ rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); ++ _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base); ++ rfb->color_rb[1]->has_surface = 1; ++ } + +- /* stencil renderbuffer */ +- if (mesaVis->stencilBits > 0 && !swStencil) { +- driRenderbuffer *stencilRb +- = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, +- driScrnPriv->pFB + screen->depthOffset, +- screen->cpp, +- screen->depthOffset, screen->depthPitch, +- driDrawPriv); +- radeonSetSpanFunctions(stencilRb, mesaVis); +- _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); +- stencilRb->depthHasSurface = screen->depthHasSurface; ++ if (mesaVis->depthBits == 24) { ++ if (mesaVis->stencilBits == 8) { ++ struct radeon_renderbuffer *depthStencilRb = radeon_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, driDrawPriv); ++ _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base); ++ _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base); ++ depthStencilRb->has_surface = screen->depthHasSurface; ++ } else { ++ /* depth renderbuffer */ ++ struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT24, driDrawPriv); ++ _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base); ++ depth->has_surface = screen->depthHasSurface; + } ++ } else if (mesaVis->depthBits == 16) { ++ /* just 16-bit depth buffer, no hw stencil */ ++ struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT16, driDrawPriv); ++ _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base); ++ depth->has_surface = screen->depthHasSurface; ++ } + +- _mesa_add_soft_renderbuffers(fb, +- GL_FALSE, /* color */ +- swDepth, +- swStencil, +- swAccum, +- swAlpha, +- GL_FALSE /* aux */); +- driDrawPriv->driverPrivate = (void *) fb; ++ _mesa_add_soft_renderbuffers(&rfb->base, ++ GL_FALSE, /* color */ ++ swDepth, ++ swStencil, ++ swAccum, ++ swAlpha, ++ GL_FALSE /* aux */); ++ driDrawPriv->driverPrivate = (void *) rfb; + +- return (driDrawPriv->driverPrivate != NULL); +- } ++ return (driDrawPriv->driverPrivate != NULL); + } + + +-static void ++static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb) ++{ ++ struct radeon_renderbuffer *rb; ++ ++ rb = rfb->color_rb[0]; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = rfb->color_rb[1]; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++} ++ ++void + radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) + { +- _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL); ++ struct radeon_framebuffer *rfb; ++ if (!driDrawPriv) ++ return; ++ ++ rfb = (void*)driDrawPriv->driverPrivate; ++ if (!rfb) ++ return; ++ radeon_cleanup_renderbuffers(rfb); ++ _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL); + } + +-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) + /** + * Choose the appropriate CreateContext function based on the chipset. + * Eventually, all drivers will go through this process. +@@ -1131,25 +1352,21 @@ static GLboolean radeonCreateContext(const __GLcontextModes * glVisual, + { + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); +- ++#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) + if (IS_R300_CLASS(screen)) + return r300CreateContext(glVisual, driContextPriv, sharedContextPriv); +- return GL_FALSE; +-} +- +-/** +- * Choose the appropriate DestroyContext function based on the chipset. +- */ +-static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv) +-{ +- radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; +- +- if (IS_R300_CLASS(radeon->radeonScreen)) +- return r300DestroyContext(driContextPriv); +-} ++#endif + ++#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) ++ if (IS_R200_CLASS(screen)) ++ return r200CreateContext(glVisual, driContextPriv, sharedContextPriv); ++#endif + ++#if !RADEON_COMMON ++ return r100CreateContext(glVisual, driContextPriv, sharedContextPriv); + #endif ++ return GL_FALSE; ++} + + + /** +@@ -1211,13 +1428,103 @@ radeonInitScreen(__DRIscreenPrivate *psp) + if (!radeonInitDriver(psp)) + return NULL; + ++ /* for now fill in all modes */ + return radeonFillInModes( psp, + dri_priv->bpp, + (dri_priv->bpp == 16) ? 16 : 24, +- (dri_priv->bpp == 16) ? 0 : 8, +- (dri_priv->backOffset != dri_priv->depthOffset) ); ++ (dri_priv->bpp == 16) ? 0 : 8, 1); + } ++#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) ++ ++/** ++ * This is the driver specific part of the createNewScreen entry point. ++ * Called when using DRI2. ++ * ++ * \return the __GLcontextModes supported by this driver ++ */ ++static const ++__DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp) ++{ ++ GLenum fb_format[3]; ++ GLenum fb_type[3]; ++ /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't ++ * support pageflipping at all. ++ */ ++ static const GLenum back_buffer_modes[] = { ++ GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/ ++ }; ++ uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; ++ int color; ++ __DRIconfig **configs = NULL; ++ ++ /* Calling driInitExtensions here, with a NULL context pointer, ++ * does not actually enable the extensions. It just makes sure ++ * that all the dispatch offsets for all the extensions that ++ * *might* be enables are known. This is needed because the ++ * dispatch offsets need to be known when _mesa_context_create ++ * is called, but we can't enable the extensions until we have a ++ * context pointer. ++ * ++ * Hello chicken. Hello egg. How are you two today? ++ */ ++ driInitExtensions( NULL, card_extensions, GL_FALSE ); ++ driInitExtensions( NULL, mm_extensions, GL_FALSE ); ++#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) ++ driInitExtensions( NULL, blend_extensions, GL_FALSE ); ++ driInitSingleExtension( NULL, ARB_vp_extension ); ++ driInitSingleExtension( NULL, NV_vp_extension ); ++ driInitSingleExtension( NULL, ATI_fs_extension ); ++ driInitExtensions( NULL, point_extensions, GL_FALSE ); ++#endif + ++ if (!radeonInitDriver(psp)) { ++ return NULL; ++ } ++ depth_bits[0] = 0; ++ stencil_bits[0] = 0; ++ depth_bits[1] = 16; ++ stencil_bits[1] = 0; ++ depth_bits[2] = 24; ++ stencil_bits[2] = 0; ++ depth_bits[3] = 24; ++ stencil_bits[3] = 8; ++ ++ msaa_samples_array[0] = 0; ++ ++ fb_format[0] = GL_RGB; ++ fb_type[0] = GL_UNSIGNED_SHORT_5_6_5; ++ ++ fb_format[1] = GL_BGR; ++ fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV; ++ ++ fb_format[2] = GL_BGRA; ++ fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV; ++ ++ for (color = 0; color < ARRAY_SIZE(fb_format); color++) { ++ __DRIconfig **new_configs; ++ ++ new_configs = driCreateConfigs(fb_format[color], fb_type[color], ++ depth_bits, ++ stencil_bits, ++ ARRAY_SIZE(depth_bits), ++ back_buffer_modes, ++ ARRAY_SIZE(back_buffer_modes), ++ msaa_samples_array, ++ ARRAY_SIZE(msaa_samples_array)); ++ if (configs == NULL) ++ configs = new_configs; ++ else ++ configs = driConcatConfigs(configs, new_configs); ++ } ++ ++ if (configs == NULL) { ++ fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, ++ __LINE__); ++ return NULL; ++ } ++ ++ return (const __DRIconfig **)configs; ++} + + /** + * Get information about previous buffer swaps. +@@ -1225,31 +1532,26 @@ radeonInitScreen(__DRIscreenPrivate *psp) + static int + getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ) + { +-#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)) +- radeonContextPtr rmesa; +-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +- r200ContextPtr rmesa; +-#endif ++ struct radeon_framebuffer *rfb; + +- if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) +- || (dPriv->driContextPriv->driverPrivate == NULL) +- || (sInfo == NULL) ) { +- return -1; ++ if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) ++ || (dPriv->driContextPriv->driverPrivate == NULL) ++ || (sInfo == NULL) ) { ++ return -1; + } + +- rmesa = dPriv->driContextPriv->driverPrivate; +- sInfo->swap_count = rmesa->swap_count; +- sInfo->swap_ust = rmesa->swap_ust; +- sInfo->swap_missed_count = rmesa->swap_missed_count; ++ rfb = dPriv->driverPrivate; ++ sInfo->swap_count = rfb->swap_count; ++ sInfo->swap_ust = rfb->swap_ust; ++ sInfo->swap_missed_count = rfb->swap_missed_count; + + sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) +- ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust ) ++ ? driCalculateSwapUsage( dPriv, 0, rfb->swap_missed_ust ) + : 0.0; + + return 0; + } + +-#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)) + const struct __DriverAPIRec driDriverAPI = { + .InitScreen = radeonInitScreen, + .DestroyScreen = radeonDestroyScreen, +@@ -1266,23 +1568,7 @@ const struct __DriverAPIRec driDriverAPI = { + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = radeonCopySubBuffer, ++ /* DRI2 */ ++ .InitScreen2 = radeonInitScreen2, + }; +-#else +-const struct __DriverAPIRec driDriverAPI = { +- .InitScreen = radeonInitScreen, +- .DestroyScreen = radeonDestroyScreen, +- .CreateContext = r200CreateContext, +- .DestroyContext = r200DestroyContext, +- .CreateBuffer = radeonCreateBuffer, +- .DestroyBuffer = radeonDestroyBuffer, +- .SwapBuffers = r200SwapBuffers, +- .MakeCurrent = r200MakeCurrent, +- .UnbindContext = r200UnbindContext, +- .GetSwapInfo = getSwapInfo, +- .GetDrawableMSC = driDrawableGetMSC32, +- .WaitForMSC = driWaitForMSC32, +- .WaitForSBC = NULL, +- .SwapBuffersMSC = NULL, +- .CopySubBuffer = r200CopySubBuffer, +-}; +-#endif ++ +diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h +index b84c70b..8605eb4 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_screen.h ++++ b/src/mesa/drivers/dri/radeon/radeon_screen.h +@@ -54,7 +54,7 @@ typedef struct { + drmAddress map; /* Mapping of the DRM region */ + } radeonRegionRec, *radeonRegionPtr; + +-typedef struct { ++typedef struct radeon_screen { + int chip_family; + int chip_flags; + int cpp; +@@ -103,9 +103,12 @@ typedef struct { + /* Configuration cache with default values for all contexts */ + driOptionCache optionCache; + +- const __DRIextension *extensions[8]; ++ const __DRIextension *extensions[16]; + + int num_gb_pipes; ++ int kernel_mm; ++ drm_radeon_sarea_t *sarea; /* Private SAREA data */ ++ struct radeon_bo_manager *bom; + } radeonScreenRec, *radeonScreenPtr; + + #define IS_R100_CLASS(screen) \ +@@ -115,4 +118,5 @@ typedef struct { + #define IS_R300_CLASS(screen) \ + ((screen->chip_flags & RADEON_CLASS_MASK) == RADEON_CLASS_R300) + ++extern void radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv); + #endif /* __RADEON_SCREEN_H__ */ +diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c +index 12051ff..e28f286 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_span.c ++++ b/src/mesa/drivers/dri/radeon/radeon_span.c +@@ -43,46 +43,203 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/glheader.h" + #include "swrast/swrast.h" + +-#include "radeon_context.h" +-#include "radeon_ioctl.h" +-#include "radeon_state.h" ++#include "radeon_common.h" ++#include "radeon_lock.h" + #include "radeon_span.h" +-#include "radeon_tex.h" +- +-#include "drirenderbuffer.h" + + #define DBG 0 + ++static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb); ++ ++static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, ++ GLint x, GLint y) ++{ ++ GLubyte *ptr = rrb->bo->ptr; ++ uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; ++ GLint offset; ++ GLint nmacroblkpl; ++ GLint nmicroblkpl; ++ ++ if (rrb->has_surface || !(rrb->bo->flags & mask)) { ++ offset = x * rrb->cpp + y * rrb->pitch; ++ } else { ++ offset = 0; ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { ++ nmacroblkpl = rrb->pitch >> 5; ++ offset += ((y >> 4) * nmacroblkpl) << 11; ++ offset += ((y & 15) >> 1) << 8; ++ offset += (y & 1) << 4; ++ offset += (x >> 5) << 11; ++ offset += ((x & 31) >> 2) << 5; ++ offset += (x & 3) << 2; ++ } else { ++ nmacroblkpl = rrb->pitch >> 6; ++ offset += ((y >> 3) * nmacroblkpl) << 11; ++ offset += (y & 7) << 8; ++ offset += (x >> 6) << 11; ++ offset += ((x & 63) >> 3) << 5; ++ offset += (x & 7) << 2; ++ } ++ } else { ++ nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; ++ offset += (y * nmicroblkpl) << 5; ++ offset += (x >> 3) << 5; ++ offset += (x & 7) << 2; ++ } ++ } ++ return &ptr[offset]; ++} ++ ++static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, ++ GLint x, GLint y) ++{ ++ GLubyte *ptr = rrb->bo->ptr; ++ uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; ++ GLint offset; ++ GLint nmacroblkpl; ++ GLint nmicroblkpl; ++ ++ if (rrb->has_surface || !(rrb->bo->flags & mask)) { ++ offset = x * rrb->cpp + y * rrb->pitch; ++ } else { ++ offset = 0; ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { ++ nmacroblkpl = rrb->pitch >> 6; ++ offset += ((y >> 4) * nmacroblkpl) << 11; ++ offset += ((y & 15) >> 1) << 8; ++ offset += (y & 1) << 4; ++ offset += (x >> 6) << 11; ++ offset += ((x & 63) >> 3) << 5; ++ offset += (x & 7) << 1; ++ } else { ++ nmacroblkpl = rrb->pitch >> 7; ++ offset += ((y >> 3) * nmacroblkpl) << 11; ++ offset += (y & 7) << 8; ++ offset += (x >> 7) << 11; ++ offset += ((x & 127) >> 4) << 5; ++ offset += (x & 15) << 2; ++ } ++ } else { ++ nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; ++ offset += (y * nmicroblkpl) << 5; ++ offset += (x >> 4) << 5; ++ offset += (x & 15) << 2; ++ } ++ } ++ return &ptr[offset]; ++} ++ ++static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, ++ GLint x, GLint y) ++{ ++ GLubyte *ptr = rrb->bo->ptr; ++ uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; ++ GLint offset; ++ GLint microblkxs; ++ GLint macroblkxs; ++ GLint nmacroblkpl; ++ GLint nmicroblkpl; ++ ++ if (rrb->has_surface || !(rrb->bo->flags & mask)) { ++ offset = x * rrb->cpp + y * rrb->pitch; ++ } else { ++ offset = 0; ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { ++ microblkxs = 16 / rrb->cpp; ++ macroblkxs = 128 / rrb->cpp; ++ nmacroblkpl = rrb->pitch / macroblkxs; ++ offset += ((y >> 4) * nmacroblkpl) << 11; ++ offset += ((y & 15) >> 1) << 8; ++ offset += (y & 1) << 4; ++ offset += (x / macroblkxs) << 11; ++ offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; ++ offset += (x & (microblkxs - 1)) * rrb->cpp; ++ } else { ++ microblkxs = 32 / rrb->cpp; ++ macroblkxs = 256 / rrb->cpp; ++ nmacroblkpl = rrb->pitch / macroblkxs; ++ offset += ((y >> 3) * nmacroblkpl) << 11; ++ offset += (y & 7) << 8; ++ offset += (x / macroblkxs) << 11; ++ offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; ++ offset += (x & (microblkxs - 1)) * rrb->cpp; ++ } ++ } else { ++ microblkxs = 32 / rrb->cpp; ++ nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; ++ offset += (y * nmicroblkpl) << 5; ++ offset += (x / microblkxs) << 5; ++ offset += (x & (microblkxs - 1)) * rrb->cpp; ++ } ++ } ++ return &ptr[offset]; ++} ++ ++#ifndef COMPILE_R300 ++static uint32_t ++z24s8_to_s8z24(uint32_t val) ++{ ++ return (val << 24) | (val >> 8); ++} ++ ++static uint32_t ++s8z24_to_z24s8(uint32_t val) ++{ ++ return (val >> 24) | (val << 8); ++} ++#endif ++ + /* + * Note that all information needed to access pixels in a renderbuffer + * should be obtained through the gl_renderbuffer parameter, not per-context + * information. + */ + #define LOCAL_VARS \ +- driRenderbuffer *drb = (driRenderbuffer *) rb; \ +- const __DRIdrawablePrivate *dPriv = drb->dPriv; \ +- const GLuint bottom = dPriv->h - 1; \ +- GLubyte *buf = (GLubyte *) drb->flippedData \ +- + (dPriv->y * drb->flippedPitch + dPriv->x) * drb->cpp; \ +- GLuint p; \ +- (void) p; ++ struct radeon_context *radeon = RADEON_CONTEXT(ctx); \ ++ struct radeon_renderbuffer *rrb = (void *) rb; \ ++ const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ ++ const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\ ++ unsigned int num_cliprects; \ ++ struct drm_clip_rect *cliprects; \ ++ int x_off, y_off; \ ++ GLuint p; \ ++ (void)p; \ ++ radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off); + + #define LOCAL_DEPTH_VARS \ +- driRenderbuffer *drb = (driRenderbuffer *) rb; \ +- const __DRIdrawablePrivate *dPriv = drb->dPriv; \ +- const GLuint bottom = dPriv->h - 1; \ +- GLuint xo = dPriv->x; \ +- GLuint yo = dPriv->y; \ +- GLubyte *buf = (GLubyte *) drb->Base.Data; ++ struct radeon_context *radeon = RADEON_CONTEXT(ctx); \ ++ struct radeon_renderbuffer *rrb = (void *) rb; \ ++ const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ ++ const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\ ++ unsigned int num_cliprects; \ ++ struct drm_clip_rect *cliprects; \ ++ int x_off, y_off; \ ++ radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off); + + #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + +-#define Y_FLIP(Y) (bottom - (Y)) ++#define Y_FLIP(_y) ((_y) * yScale + yBias) + + #define HW_LOCK() + + #define HW_UNLOCK() + ++/* XXX FBO: this is identical to the macro in spantmp2.h except we get ++ * the cliprect info from the context, not the driDrawable. ++ * Move this into spantmp2.h someday. ++ */ ++#define HW_CLIPLOOP() \ ++ do { \ ++ int _nc = num_cliprects; \ ++ while ( _nc-- ) { \ ++ int minx = cliprects[_nc].x1 - x_off; \ ++ int miny = cliprects[_nc].y1 - y_off; \ ++ int maxx = cliprects[_nc].x2 - x_off; \ ++ int maxy = cliprects[_nc].y2 - y_off; ++ + /* ================================================================ + * Color buffer + */ +@@ -94,7 +251,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #define TAG(x) radeon##x##_RGB565 + #define TAG2(x,y) radeon##x##_RGB565##y +-#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 2) ++#define GET_PTR(X,Y) radeon_ptr16(rrb, (X) + x_off, (Y) + y_off) ++#include "spantmp2.h" ++ ++/* 32 bit, xRGB8888 color spanline and pixel functions ++ */ ++#define SPANTMP_PIXEL_FMT GL_BGRA ++#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV ++ ++#define TAG(x) radeon##x##_xRGB8888 ++#define TAG2(x,y) radeon##x##_xRGB8888##y ++#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) | 0xff000000)) ++#define PUT_VALUE(_x, _y, d) { \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ ++ *_ptr = d; \ ++} while (0) + #include "spantmp2.h" + + /* 32 bit, ARGB8888 color spanline and pixel functions +@@ -104,7 +275,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #define TAG(x) radeon##x##_ARGB8888 + #define TAG2(x,y) radeon##x##_ARGB8888##y +-#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 4) ++#define GET_PTR(X,Y) radeon_ptr32(rrb, (X) + x_off, (Y) + y_off) + #include "spantmp2.h" + + /* ================================================================ +@@ -121,70 +292,20 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * too... + */ + +-static GLuint radeon_mba_z32(const driRenderbuffer * drb, GLint x, GLint y) +-{ +- GLuint pitch = drb->pitch; +- if (drb->depthHasSurface) { +- return 4 * (x + y * pitch); +- } else { +- GLuint ba, address = 0; /* a[0..1] = 0 */ +- +-#ifdef COMPILE_R300 +- ba = (y / 8) * (pitch / 8) + (x / 8); +-#else +- ba = (y / 16) * (pitch / 16) + (x / 16); +-#endif +- +- address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */ +- address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ +- address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */ +- address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ +- +- address |= (y & 0x8) << 7; /* a[10] = y[3] */ +- address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */ +- address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ +- +- return address; +- } +-} +- +-static INLINE GLuint +-radeon_mba_z16(const driRenderbuffer * drb, GLint x, GLint y) +-{ +- GLuint pitch = drb->pitch; +- if (drb->depthHasSurface) { +- return 2 * (x + y * pitch); +- } else { +- GLuint ba, address = 0; /* a[0] = 0 */ +- +- ba = (y / 16) * (pitch / 32) + (x / 32); +- +- address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ +- address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ +- address |= (x & 0x8) << 4; /* a[7] = x[3] */ +- address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ +- address |= (y & 0x8) << 7; /* a[10] = y[3] */ +- address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ +- address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ +- +- return address; +- } +-} +- + /* 16-bit depth buffer functions + */ + #define VALUE_TYPE GLushort + + #define WRITE_DEPTH( _x, _y, d ) \ +- *(GLushort *)(buf + radeon_mba_z16( drb, _x + xo, _y + yo )) = d; ++ *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off) = d + + #define READ_DEPTH( d, _x, _y ) \ +- d = *(GLushort *)(buf + radeon_mba_z16( drb, _x + xo, _y + yo )); ++ d = *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off) + + #define TAG(x) radeon##x##_z16 + #include "depthtmp.h" + +-/* 24 bit depth, 8 bit stencil depthbuffer functions ++/* 24 bit depth + * + * Careful: It looks like the R300 uses ZZZS byte order while the R200 + * uses SZZZ for 24 bit depth, 8 bit stencil mode. +@@ -194,35 +315,76 @@ radeon_mba_z16(const driRenderbuffer * drb, GLint x, GLint y) + #ifdef COMPILE_R300 + #define WRITE_DEPTH( _x, _y, d ) \ + do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ ++ GLuint tmp = *_ptr; \ + tmp &= 0x000000ff; \ + tmp |= ((d << 8) & 0xffffff00); \ +- *(GLuint *)(buf + offset) = tmp; \ ++ *_ptr = tmp; \ + } while (0) + #else + #define WRITE_DEPTH( _x, _y, d ) \ + do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ ++ GLuint tmp = *_ptr; \ + tmp &= 0xff000000; \ + tmp |= ((d) & 0x00ffffff); \ +- *(GLuint *)(buf + offset) = tmp; \ ++ *_ptr = tmp; \ + } while (0) + #endif + + #ifdef COMPILE_R300 + #define READ_DEPTH( d, _x, _y ) \ +- do { \ +- d = (*(GLuint *)(buf + radeon_mba_z32( drb, _x + xo, \ +- _y + yo )) & 0xffffff00) >> 8; \ ++ do { \ ++ d = (*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \ + }while(0) + #else +-#define READ_DEPTH( d, _x, _y ) \ +- d = *(GLuint *)(buf + radeon_mba_z32( drb, _x + xo, \ +- _y + yo )) & 0x00ffffff; ++#define READ_DEPTH( d, _x, _y ) \ ++ d = *(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) & 0x00ffffff; ++#endif ++/* ++ fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\ ++ d = *(GLuint*)(radeon_ptr(rrb, _x, _y )) & 0x00ffffff; ++*/ ++#define TAG(x) radeon##x##_z24 ++#include "depthtmp.h" ++ ++/* 24 bit depth, 8 bit stencil depthbuffer functions ++ * EXT_depth_stencil ++ * ++ * Careful: It looks like the R300 uses ZZZS byte order while the R200 ++ * uses SZZZ for 24 bit depth, 8 bit stencil mode. ++ */ ++#define VALUE_TYPE GLuint ++ ++#ifdef COMPILE_R300 ++#define WRITE_DEPTH( _x, _y, d ) \ ++do { \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ ++ *_ptr = d; \ ++} while (0) ++#else ++#define WRITE_DEPTH( _x, _y, d ) \ ++do { \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ ++ GLuint tmp = z24s8_to_s8z24(d); \ ++ *_ptr = tmp; \ ++} while (0) + #endif + ++#ifdef COMPILE_R300 ++#define READ_DEPTH( d, _x, _y ) \ ++ do { \ ++ d = (*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off))); \ ++ }while(0) ++#else ++#define READ_DEPTH( d, _x, _y ) do { \ ++ d = s8z24_to_z24s8(*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off ))); \ ++ } while (0) ++#endif ++/* ++ fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\ ++ d = *(GLuint*)(radeon_ptr(rrb, _x, _y )) & 0x00ffffff; ++*/ + #define TAG(x) radeon##x##_z24_s8 + #include "depthtmp.h" + +@@ -235,35 +397,35 @@ do { \ + #ifdef COMPILE_R300 + #define WRITE_STENCIL( _x, _y, d ) \ + do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off); \ ++ GLuint tmp = *_ptr; \ + tmp &= 0xffffff00; \ + tmp |= (d) & 0xff; \ +- *(GLuint *)(buf + offset) = tmp; \ ++ *_ptr = tmp; \ + } while (0) + #else + #define WRITE_STENCIL( _x, _y, d ) \ + do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off); \ ++ GLuint tmp = *_ptr; \ + tmp &= 0x00ffffff; \ + tmp |= (((d) & 0xff) << 24); \ +- *(GLuint *)(buf + offset) = tmp; \ ++ *_ptr = tmp; \ + } while (0) + #endif + + #ifdef COMPILE_R300 + #define READ_STENCIL( d, _x, _y ) \ + do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ ++ GLuint tmp = *_ptr; \ + d = tmp & 0x000000ff; \ + } while (0) + #else + #define READ_STENCIL( d, _x, _y ) \ + do { \ +- GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ ++ GLuint tmp = *_ptr; \ + d = (tmp & 0xff000000) >> 24; \ + } while (0) + #endif +@@ -271,29 +433,105 @@ do { \ + #define TAG(x) radeon##x##_z24_s8 + #include "stenciltmp.h" + +-/* Move locking out to get reasonable span performance (10x better +- * than doing this in HW_LOCK above). WaitForIdle() is the main +- * culprit. +- */ + ++static void map_unmap_rb(struct gl_renderbuffer *rb, int flag) ++{ ++ struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); ++ int r; ++ ++ if (rrb == NULL || !rrb->bo) ++ return; ++ ++ if (flag) { ++ r = radeon_bo_map(rrb->bo, 1); ++ if (r) { ++ fprintf(stderr, "(%s) error(%d) mapping buffer.\n", ++ __FUNCTION__, r); ++ } ++ ++ radeonSetSpanFunctions(rrb); ++ } else { ++ radeon_bo_unmap(rrb->bo); ++ rb->GetRow = NULL; ++ rb->PutRow = NULL; ++ } ++} ++ ++static void ++radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map) ++{ ++ GLuint i, j; ++ ++ /* color draw buffers */ ++ for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) ++ map_unmap_rb(ctx->DrawBuffer->_ColorDrawBuffers[j], map); ++ ++ /* check for render to textures */ ++ for (i = 0; i < BUFFER_COUNT; i++) { ++ struct gl_renderbuffer_attachment *att = ++ ctx->DrawBuffer->Attachment + i; ++ struct gl_texture_object *tex = att->Texture; ++ if (tex) { ++ /* render to texture */ ++ ASSERT(att->Renderbuffer); ++ if (map) ++ ctx->Driver.MapTexture(ctx, tex); ++ else ++ ctx->Driver.UnmapTexture(ctx, tex); ++ } ++ } ++ ++ map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map); ++ ++ /* depth buffer (Note wrapper!) */ ++ if (ctx->DrawBuffer->_DepthBuffer) ++ map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map); ++ ++ if (ctx->DrawBuffer->_StencilBuffer) ++ map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map); ++ ++} + static void radeonSpanRenderStart(GLcontext * ctx) + { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +-#ifdef COMPILE_R300 +- r300ContextPtr r300 = (r300ContextPtr) rmesa; +- R300_FIREVERTICES(r300); +-#else +- RADEON_FIREVERTICES(rmesa); +-#endif +- LOCK_HARDWARE(rmesa); +- radeonWaitForIdleLocked(rmesa); ++ int i; ++ ++ radeon_firevertices(rmesa); ++ ++ /* The locking and wait for idle should really only be needed in classic mode. ++ * In a future memory manager based implementation, this should become ++ * unnecessary due to the fact that mapping our buffers, textures, etc. ++ * should implicitly wait for any previous rendering commands that must ++ * be waited on. */ ++ if (!rmesa->radeonScreen->driScreen->dri2.enabled) { ++ LOCK_HARDWARE(rmesa); ++ radeonWaitForIdleLocked(rmesa); ++ } ++ for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { ++ if (ctx->Texture.Unit[i]._ReallyEnabled) ++ ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current); ++ } ++ ++ radeon_map_unmap_buffers(ctx, 1); ++ ++ ++ + } + + static void radeonSpanRenderFinish(GLcontext * ctx) + { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ int i; + _swrast_flush(ctx); +- UNLOCK_HARDWARE(rmesa); ++ if (!rmesa->radeonScreen->driScreen->dri2.enabled) { ++ UNLOCK_HARDWARE(rmesa); ++ } ++ for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { ++ if (ctx->Texture.Unit[i]._ReallyEnabled) ++ ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current); ++ } ++ ++ radeon_map_unmap_buffers(ctx, 0); + } + + void radeonInitSpanFuncs(GLcontext * ctx) +@@ -307,20 +545,21 @@ void radeonInitSpanFuncs(GLcontext * ctx) + /** + * Plug in the Get/Put routines for the given driRenderbuffer. + */ +-void radeonSetSpanFunctions(driRenderbuffer * drb, const GLvisual * vis) ++static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb) + { +- if (drb->Base.InternalFormat == GL_RGBA) { +- if (vis->redBits == 5 && vis->greenBits == 6 +- && vis->blueBits == 5) { +- radeonInitPointers_RGB565(&drb->Base); +- } else { +- radeonInitPointers_ARGB8888(&drb->Base); +- } +- } else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) { +- radeonInitDepthPointers_z16(&drb->Base); +- } else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) { +- radeonInitDepthPointers_z24_s8(&drb->Base); +- } else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) { +- radeonInitStencilPointers_z24_s8(&drb->Base); ++ if (rrb->base._ActualFormat == GL_RGB5) { ++ radeonInitPointers_RGB565(&rrb->base); ++ } else if (rrb->base._ActualFormat == GL_RGB8) { ++ radeonInitPointers_xRGB8888(&rrb->base); ++ } else if (rrb->base._ActualFormat == GL_RGBA8) { ++ radeonInitPointers_ARGB8888(&rrb->base); ++ } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT16) { ++ radeonInitDepthPointers_z16(&rrb->base); ++ } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) { ++ radeonInitDepthPointers_z24(&rrb->base); ++ } else if (rrb->base._ActualFormat == GL_DEPTH24_STENCIL8_EXT) { ++ radeonInitDepthPointers_z24_s8(&rrb->base); ++ } else if (rrb->base._ActualFormat == GL_STENCIL_INDEX8_EXT) { ++ radeonInitStencilPointers_z24_s8(&rrb->base); + } + } +diff --git a/src/mesa/drivers/dri/radeon/radeon_span.h b/src/mesa/drivers/dri/radeon/radeon_span.h +index 9abe086..ea6a2e7 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_span.h ++++ b/src/mesa/drivers/dri/radeon/radeon_span.h +@@ -42,9 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #ifndef __RADEON_SPAN_H__ + #define __RADEON_SPAN_H__ + +-#include "drirenderbuffer.h" +- + extern void radeonInitSpanFuncs(GLcontext * ctx); +-extern void radeonSetSpanFunctions(driRenderbuffer * rb, const GLvisual * vis); + + #endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c +index 32bcff3..28eea44 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_state.c ++++ b/src/mesa/drivers/dri/radeon/radeon_state.c +@@ -47,6 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "swrast_setup/swrast_setup.h" + + #include "radeon_context.h" ++#include "radeon_mipmap_tree.h" + #include "radeon_ioctl.h" + #include "radeon_state.h" + #include "radeon_tcl.h" +@@ -62,7 +63,7 @@ static void radeonUpdateSpecular( GLcontext *ctx ); + + static void radeonAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC]; + GLubyte refByte; + +@@ -106,7 +107,7 @@ static void radeonAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref ) + static void radeonBlendEquationSeparate( GLcontext *ctx, + GLenum modeRGB, GLenum modeA ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK; + GLboolean fallback = GL_FALSE; + +@@ -147,7 +148,7 @@ static void radeonBlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & + ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK); + GLboolean fallback = GL_FALSE; +@@ -257,7 +258,7 @@ static void radeonBlendFuncSeparate( GLcontext *ctx, + + static void radeonDepthFunc( GLcontext *ctx, GLenum func ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK; +@@ -293,7 +294,7 @@ static void radeonDepthFunc( GLcontext *ctx, GLenum func ) + + static void radeonDepthMask( GLcontext *ctx, GLboolean flag ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + RADEON_STATECHANGE( rmesa, ctx ); + + if ( ctx->Depth.Mask ) { +@@ -305,16 +306,16 @@ static void radeonDepthMask( GLcontext *ctx, GLboolean flag ) + + static void radeonClearDepth( GLcontext *ctx, GLclampd d ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint format = (rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] & + RADEON_DEPTH_FORMAT_MASK); + + switch ( format ) { + case RADEON_DEPTH_FORMAT_16BIT_INT_Z: +- rmesa->state.depth.clear = d * 0x0000ffff; ++ rmesa->radeon.state.depth.clear = d * 0x0000ffff; + break; + case RADEON_DEPTH_FORMAT_24BIT_INT_Z: +- rmesa->state.depth.clear = d * 0x00ffffff; ++ rmesa->radeon.state.depth.clear = d * 0x00ffffff; + break; + } + } +@@ -327,7 +328,7 @@ static void radeonClearDepth( GLcontext *ctx, GLclampd d ) + + static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + union { int i; float f; } c, d; + GLchan col[4]; + +@@ -406,109 +407,13 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) + } + } + +- +-/* ============================================================= +- * Scissoring +- */ +- +- +-static GLboolean intersect_rect( drm_clip_rect_t *out, +- drm_clip_rect_t *a, +- drm_clip_rect_t *b ) +-{ +- *out = *a; +- if ( b->x1 > out->x1 ) out->x1 = b->x1; +- if ( b->y1 > out->y1 ) out->y1 = b->y1; +- if ( b->x2 < out->x2 ) out->x2 = b->x2; +- if ( b->y2 < out->y2 ) out->y2 = b->y2; +- if ( out->x1 >= out->x2 ) return GL_FALSE; +- if ( out->y1 >= out->y2 ) return GL_FALSE; +- return GL_TRUE; +-} +- +- +-void radeonRecalcScissorRects( radeonContextPtr rmesa ) +-{ +- drm_clip_rect_t *out; +- int i; +- +- /* Grow cliprect store? +- */ +- if (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { +- while (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { +- rmesa->state.scissor.numAllocedClipRects += 1; /* zero case */ +- rmesa->state.scissor.numAllocedClipRects *= 2; +- } +- +- if (rmesa->state.scissor.pClipRects) +- FREE(rmesa->state.scissor.pClipRects); +- +- rmesa->state.scissor.pClipRects = +- MALLOC( rmesa->state.scissor.numAllocedClipRects * +- sizeof(drm_clip_rect_t) ); +- +- if ( rmesa->state.scissor.pClipRects == NULL ) { +- rmesa->state.scissor.numAllocedClipRects = 0; +- return; +- } +- } +- +- out = rmesa->state.scissor.pClipRects; +- rmesa->state.scissor.numClipRects = 0; +- +- for ( i = 0 ; i < rmesa->numClipRects ; i++ ) { +- if ( intersect_rect( out, +- &rmesa->pClipRects[i], +- &rmesa->state.scissor.rect ) ) { +- rmesa->state.scissor.numClipRects++; +- out++; +- } +- } +-} +- +- +-static void radeonUpdateScissor( GLcontext *ctx ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- +- if ( rmesa->dri.drawable ) { +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; +- +- int x = ctx->Scissor.X; +- int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; +- int w = ctx->Scissor.X + ctx->Scissor.Width - 1; +- int h = dPriv->h - ctx->Scissor.Y - 1; +- +- rmesa->state.scissor.rect.x1 = x + dPriv->x; +- rmesa->state.scissor.rect.y1 = y + dPriv->y; +- rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; +- rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; +- +- radeonRecalcScissorRects( rmesa ); +- } +-} +- +- +-static void radeonScissor( GLcontext *ctx, +- GLint x, GLint y, GLsizei w, GLsizei h ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- +- if ( ctx->Scissor.Enabled ) { +- RADEON_FIREVERTICES( rmesa ); /* don't pipeline cliprect changes */ +- radeonUpdateScissor( ctx ); +- } +- +-} +- +- + /* ============================================================= + * Culling + */ + + static void radeonCullFace( GLcontext *ctx, GLenum unused ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; + GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL]; + +@@ -545,7 +450,7 @@ static void radeonCullFace( GLcontext *ctx, GLenum unused ) + + static void radeonFrontFace( GLcontext *ctx, GLenum mode ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + + RADEON_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK; +@@ -570,7 +475,7 @@ static void radeonFrontFace( GLcontext *ctx, GLenum mode ) + */ + static void radeonLineWidth( GLcontext *ctx, GLfloat widthf ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + + RADEON_STATECHANGE( rmesa, lin ); + RADEON_STATECHANGE( rmesa, set ); +@@ -587,7 +492,7 @@ static void radeonLineWidth( GLcontext *ctx, GLfloat widthf ) + + static void radeonLineStipple( GLcontext *ctx, GLint factor, GLushort pattern ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + + RADEON_STATECHANGE( rmesa, lin ); + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = +@@ -602,8 +507,8 @@ static void radeonColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- GLuint mask = radeonPackColor( rmesa->radeonScreen->cpp, ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ GLuint mask = radeonPackColor( rmesa->radeon.radeonScreen->cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], +@@ -623,8 +528,9 @@ static void radeonColorMask( GLcontext *ctx, + static void radeonPolygonOffset( GLcontext *ctx, + GLfloat factor, GLfloat units ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- float_ui32_type constant = { units * rmesa->state.depth.scale }; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; ++ float_ui32_type constant = { units * depthScale }; + float_ui32_type factoru = { factor }; + + RADEON_STATECHANGE( rmesa, zbs ); +@@ -634,7 +540,7 @@ static void radeonPolygonOffset( GLcontext *ctx, + + static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint i; + drm_radeon_stipple_t stipple; + +@@ -646,27 +552,27 @@ static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask ) + + /* TODO: push this into cmd mechanism + */ +- RADEON_FIREVERTICES( rmesa ); +- LOCK_HARDWARE( rmesa ); ++ radeon_firevertices(&rmesa->radeon); ++ LOCK_HARDWARE( &rmesa->radeon ); + + /* FIXME: Use window x,y offsets into stipple RAM. + */ + stipple.mask = rmesa->state.stipple.mask; +- drmCommandWrite( rmesa->dri.fd, DRM_RADEON_STIPPLE, ++ drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE, + &stipple, sizeof(drm_radeon_stipple_t) ); +- UNLOCK_HARDWARE( rmesa ); ++ UNLOCK_HARDWARE( &rmesa->radeon ); + } + + static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0; + + /* Can't generally do unfilled via tcl, but some good special + * cases work. + */ + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag); +- if (rmesa->TclFallback) { ++ if (rmesa->radeon.TclFallback) { + radeonChooseRenderState( ctx ); + radeonChooseVertexState( ctx ); + } +@@ -686,7 +592,7 @@ static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode ) + */ + static void radeonUpdateSpecular( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL]; + GLuint flag = 0; + +@@ -757,7 +663,7 @@ static void radeonUpdateSpecular( GLcontext *ctx ) + + /* Update vertex/render formats + */ +- if (rmesa->TclFallback) { ++ if (rmesa->radeon.TclFallback) { + radeonChooseRenderState( ctx ); + radeonChooseVertexState( ctx ); + } +@@ -774,7 +680,7 @@ static void radeonUpdateSpecular( GLcontext *ctx ) + */ + static void update_global_ambient( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + float *fcmd = (float *)RADEON_DB_STATE( glt ); + + /* Need to do more if both emmissive & ambient are PREMULT: +@@ -809,7 +715,7 @@ static void update_light_colors( GLcontext *ctx, GLuint p ) + /* fprintf(stderr, "%s\n", __FUNCTION__); */ + + if (l->Enabled) { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + float *fcmd = (float *)RADEON_DB_STATE( lit[p] ); + + COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient ); +@@ -849,7 +755,7 @@ static void check_twoside_fallback( GLcontext *ctx ) + + static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; + + light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | +@@ -913,7 +819,7 @@ static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ) + + void radeonUpdateMaterial( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLfloat (*mat)[4] = ctx->Light.Material.Attrib; + GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl ); + GLuint mask = ~0; +@@ -978,7 +884,7 @@ void radeonUpdateMaterial( GLcontext *ctx ) + */ + static void update_light( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + + /* Have to check these, or have an automatic shortcircuit mechanism + * to remove noop statechanges. (Or just do a better job on the +@@ -1043,7 +949,7 @@ static void update_light( GLcontext *ctx ) + static void radeonLightfv( GLcontext *ctx, GLenum light, + GLenum pname, const GLfloat *params ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLint p = light - GL_LIGHT0; + struct gl_light *l = &ctx->Light.Light[p]; + GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd; +@@ -1164,7 +1070,7 @@ static void radeonLightfv( GLcontext *ctx, GLenum light, + static void radeonLightModelfv( GLcontext *ctx, GLenum pname, + const GLfloat *param ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + + switch (pname) { + case GL_LIGHT_MODEL_AMBIENT: +@@ -1188,7 +1094,7 @@ static void radeonLightModelfv( GLcontext *ctx, GLenum pname, + + check_twoside_fallback( ctx ); + +- if (rmesa->TclFallback) { ++ if (rmesa->radeon.TclFallback) { + radeonChooseRenderState( ctx ); + radeonChooseVertexState( ctx ); + } +@@ -1205,7 +1111,7 @@ static void radeonLightModelfv( GLcontext *ctx, GLenum pname, + + static void radeonShadeModel( GLcontext *ctx, GLenum mode ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; + + s &= ~(RADEON_DIFFUSE_SHADE_MASK | +@@ -1244,7 +1150,7 @@ static void radeonShadeModel( GLcontext *ctx, GLenum mode ) + static void radeonClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) + { + GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0; +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; + + RADEON_STATECHANGE( rmesa, ucp[p] ); +@@ -1256,7 +1162,7 @@ static void radeonClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) + + static void radeonUpdateClipPlanes( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint p; + + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { +@@ -1281,7 +1187,7 @@ static void + radeonStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) | + ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT)); + +@@ -1325,7 +1231,7 @@ radeonStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func, + static void + radeonStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + + RADEON_STATECHANGE( rmesa, msk ); + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK; +@@ -1336,7 +1242,7 @@ radeonStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask ) + static void radeonStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + + /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP, + and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC, +@@ -1349,7 +1255,7 @@ static void radeonStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail, + GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP; + GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP; + +- if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) { ++ if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) { + tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC; + tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC; + tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC; +@@ -1455,9 +1361,9 @@ static void radeonStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail, + + static void radeonClearStencil( GLcontext *ctx, GLint s ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + +- rmesa->state.stencil.clear = ++ rmesa->radeon.state.stencil.clear = + ((GLuint) (ctx->Stencil.Clear & 0xff) | + (0xff << RADEON_STENCIL_MASK_SHIFT) | + ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT)); +@@ -1481,20 +1387,30 @@ static void radeonClearStencil( GLcontext *ctx, GLint s ) + */ + void radeonUpdateWindow( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; +- GLfloat xoffset = (GLfloat)dPriv->x; +- GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; ++ GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0; ++ GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0; + const GLfloat *v = ctx->Viewport._WindowMap.m; ++ const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0); ++ const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; ++ GLfloat y_scale, y_bias; ++ ++ if (render_to_fbo) { ++ y_scale = 1.0; ++ y_bias = 0; ++ } else { ++ y_scale = -1.0; ++ y_bias = yoffset; ++ } + + float_ui32_type sx = { v[MAT_SX] }; + float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X }; +- float_ui32_type sy = { - v[MAT_SY] }; +- float_ui32_type ty = { (- v[MAT_TY]) + yoffset + SUBPIXEL_Y }; +- float_ui32_type sz = { v[MAT_SZ] * rmesa->state.depth.scale }; +- float_ui32_type tz = { v[MAT_TZ] * rmesa->state.depth.scale }; ++ float_ui32_type sy = { v[MAT_SY] * y_scale }; ++ float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y }; ++ float_ui32_type sz = { v[MAT_SZ] * depthScale }; ++ float_ui32_type tz = { v[MAT_TZ] * depthScale }; + +- RADEON_FIREVERTICES( rmesa ); + RADEON_STATECHANGE( rmesa, vpt ); + + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32; +@@ -1514,6 +1430,8 @@ static void radeonViewport( GLcontext *ctx, GLint x, GLint y, + * values, or keep the originals hanging around. + */ + radeonUpdateWindow( ctx ); ++ ++ radeon_viewport(ctx, x, y, width, height); + } + + static void radeonDepthRange( GLcontext *ctx, GLclampd nearval, +@@ -1524,8 +1442,8 @@ static void radeonDepthRange( GLcontext *ctx, GLclampd nearval, + + void radeonUpdateViewportOffset( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; + GLfloat xoffset = (GLfloat)dPriv->x; + GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; + const GLfloat *v = ctx->Viewport._WindowMap.m; +@@ -1555,8 +1473,8 @@ void radeonUpdateViewportOffset( GLcontext *ctx ) + RADEON_STIPPLE_Y_OFFSET_MASK); + + /* add magic offsets, then invert */ +- stx = 31 - ((rmesa->dri.drawable->x - 1) & RADEON_STIPPLE_COORD_MASK); +- sty = 31 - ((rmesa->dri.drawable->y + rmesa->dri.drawable->h - 1) ++ stx = 31 - ((rmesa->radeon.dri.drawable->x - 1) & RADEON_STIPPLE_COORD_MASK); ++ sty = 31 - ((rmesa->radeon.dri.drawable->y + rmesa->radeon.dri.drawable->h - 1) + & RADEON_STIPPLE_COORD_MASK); + + m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) | +@@ -1580,20 +1498,20 @@ void radeonUpdateViewportOffset( GLcontext *ctx ) + + static void radeonClearColor( GLcontext *ctx, const GLfloat color[4] ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLubyte c[4]; + CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); +- rmesa->state.color.clear = radeonPackColor( rmesa->radeonScreen->cpp, ++ rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp, + c[0], c[1], c[2], c[3] ); + } + + + static void radeonRenderMode( GLcontext *ctx, GLenum mode ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) ); + } + +@@ -1619,7 +1537,7 @@ static GLuint radeon_rop_tab[] = { + + static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint rop = (GLuint)opcode - GL_CLEAR; + + ASSERT( rop < 16 ); +@@ -1628,105 +1546,13 @@ static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode ) + rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop]; + } + +- +-/** +- * Set up the cliprects for either front or back-buffer drawing. +- */ +-void radeonSetCliprects( radeonContextPtr rmesa ) +-{ +- __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; +- __DRIdrawablePrivate *const readable = rmesa->dri.readable; +- GLframebuffer *const draw_fb = (GLframebuffer*) drawable->driverPrivate; +- GLframebuffer *const read_fb = (GLframebuffer*) readable->driverPrivate; +- +- if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { +- /* Can't ignore 2d windows if we are page flipping. +- */ +- if ( drawable->numBackClipRects == 0 || rmesa->doPageFlip ) { +- rmesa->numClipRects = drawable->numClipRects; +- rmesa->pClipRects = drawable->pClipRects; +- } +- else { +- rmesa->numClipRects = drawable->numBackClipRects; +- rmesa->pClipRects = drawable->pBackClipRects; +- } +- } +- else { +- /* front buffer (or none, or multiple buffers */ +- rmesa->numClipRects = drawable->numClipRects; +- rmesa->pClipRects = drawable->pClipRects; +- } +- +- if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { +- _mesa_resize_framebuffer(rmesa->glCtx, draw_fb, +- drawable->w, drawable->h); +- draw_fb->Initialized = GL_TRUE; +- } +- +- if (drawable != readable) { +- if ((read_fb->Width != readable->w) || (read_fb->Height != readable->h)) { +- _mesa_resize_framebuffer(rmesa->glCtx, read_fb, +- readable->w, readable->h); +- read_fb->Initialized = GL_TRUE; +- } +- } +- +- if (rmesa->state.scissor.enabled) +- radeonRecalcScissorRects( rmesa ); +- +- rmesa->lastStamp = drawable->lastStamp; +-} +- +- +-/** +- * Called via glDrawBuffer. +- */ +-static void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- +- if (RADEON_DEBUG & DEBUG_DRI) +- fprintf(stderr, "%s %s\n", __FUNCTION__, +- _mesa_lookup_enum_by_nr( mode )); +- +- RADEON_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */ +- +- if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { +- /* 0 (GL_NONE) buffers or multiple color drawing buffers */ +- FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE ); +- return; +- } +- +- switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) { +- case BUFFER_FRONT_LEFT: +- case BUFFER_BACK_LEFT: +- FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE ); +- break; +- default: +- FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE ); +- return; +- } +- +- radeonSetCliprects( rmesa ); +- +- /* We'll set the drawing engine's offset/pitch parameters later +- * when we update other state. +- */ +-} +- +-static void radeonReadBuffer( GLcontext *ctx, GLenum mode ) +-{ +- /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ +-} +- +- + /* ============================================================= + * State enable/disable + */ + + static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint p, flag; + + if ( RADEON_DEBUG & DEBUG_STATE ) +@@ -1821,10 +1647,10 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) + RADEON_STATECHANGE(rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE; +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->state.color.roundEnable; ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE; +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; + } + break; + +@@ -1971,21 +1797,30 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) + } + + case GL_SCISSOR_TEST: +- RADEON_FIREVERTICES( rmesa ); +- rmesa->state.scissor.enabled = state; ++ radeon_firevertices(&rmesa->radeon); ++ rmesa->radeon.state.scissor.enabled = state; + radeonUpdateScissor( ctx ); + break; + + case GL_STENCIL_TEST: +- if ( rmesa->state.stencil.hwBuffer ) { +- RADEON_STATECHANGE( rmesa, ctx ); +- if ( state ) { +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE; ++ { ++ GLboolean hw_stencil = GL_FALSE; ++ if (ctx->DrawBuffer) { ++ struct radeon_renderbuffer *rrbStencil ++ = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); ++ hw_stencil = (rrbStencil && rrbStencil->bo); ++ } ++ ++ if (hw_stencil) { ++ RADEON_STATECHANGE( rmesa, ctx ); ++ if ( state ) { ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE; ++ } else { ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE; ++ } + } else { +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE; ++ FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state ); + } +- } else { +- FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state ); + } + break; + +@@ -2010,7 +1845,7 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) + + static void radeonLightingSpaceChange( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLboolean tmp; + RADEON_STATECHANGE( rmesa, tcl ); + +@@ -2039,7 +1874,7 @@ static void radeonLightingSpaceChange( GLcontext *ctx ) + */ + + +-void radeonUploadTexMatrix( radeonContextPtr rmesa, ++void radeonUploadTexMatrix( r100ContextPtr rmesa, + int unit, GLboolean swapcols ) + { + /* Here's how this works: on r100, only 3 tex coords can be submitted, so the +@@ -2065,7 +1900,7 @@ void radeonUploadTexMatrix( radeonContextPtr rmesa, + int idx = TEXMAT_0 + unit; + float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0; + int i; +- struct gl_texture_unit tUnit = rmesa->glCtx->Texture.Unit[unit]; ++ struct gl_texture_unit tUnit = rmesa->radeon.glCtx->Texture.Unit[unit]; + GLfloat *src = rmesa->tmpmat[unit].m; + + rmesa->TexMatColSwap &= ~(1 << unit); +@@ -2119,7 +1954,7 @@ void radeonUploadTexMatrix( radeonContextPtr rmesa, + } + + +-static void upload_matrix( radeonContextPtr rmesa, GLfloat *src, int idx ) ++static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx ) + { + float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0; + int i; +@@ -2135,7 +1970,7 @@ static void upload_matrix( radeonContextPtr rmesa, GLfloat *src, int idx ) + RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] ); + } + +-static void upload_matrix_t( radeonContextPtr rmesa, GLfloat *src, int idx ) ++static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx ) + { + float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0; + memcpy(dest, src, 16*sizeof(float)); +@@ -2145,7 +1980,7 @@ static void upload_matrix_t( radeonContextPtr rmesa, GLfloat *src, int idx ) + + static void update_texturematrix( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); ++ r100ContextPtr rmesa = R100_CONTEXT( ctx ); + GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL]; + GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]; + int unit; +@@ -2209,61 +2044,72 @@ static void update_texturematrix( GLcontext *ctx ) + } + } + +- +-/** +- * Tell the card where to render (offset, pitch). +- * Effected by glDrawBuffer, etc +- */ +-void +-radeonUpdateDrawBuffer(GLcontext *ctx) ++static GLboolean r100ValidateBuffers(GLcontext *ctx) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- struct gl_framebuffer *fb = ctx->DrawBuffer; +- driRenderbuffer *drb; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ struct radeon_renderbuffer *rrb; ++ int i; + +- if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { +- /* draw to front */ +- drb = (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; +- } +- else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { +- /* draw to back */ +- drb = (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; +- } +- else { +- /* drawing to multiple buffers, or none */ +- return; ++ radeon_validate_reset_bos(&rmesa->radeon); ++ ++ rrb = radeon_get_colorbuffer(&rmesa->radeon); ++ /* color buffer */ ++ if (rrb && rrb->bo) { ++ radeon_validate_bo(&rmesa->radeon, rrb->bo, ++ 0, RADEON_GEM_DOMAIN_VRAM); + } + +- assert(drb); +- assert(drb->flippedPitch); ++ /* depth buffer */ ++ rrb = radeon_get_depthbuffer(&rmesa->radeon); ++ /* color buffer */ ++ if (rrb && rrb->bo) { ++ radeon_validate_bo(&rmesa->radeon, rrb->bo, ++ 0, RADEON_GEM_DOMAIN_VRAM); ++ } + +- RADEON_STATECHANGE( rmesa, ctx ); ++ for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { ++ radeonTexObj *t; ++ ++ if (!ctx->Texture.Unit[i]._ReallyEnabled) ++ continue; + +- /* Note: we used the (possibly) page-flipped values */ +- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] +- = ((drb->flippedOffset + rmesa->radeonScreen->fbLocation) +- & RADEON_COLOROFFSET_MASK); +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch; +- if (rmesa->sarea->tiling_enabled) { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE; ++ t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); ++ if (t->image_override && t->bo) ++ radeon_validate_bo(&rmesa->radeon, t->bo, ++ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); ++ else if (t->mt->bo) ++ radeon_validate_bo(&rmesa->radeon, t->mt->bo, ++ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + } +-} + ++ if (rmesa->radeon.dma.current) ++ radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, ++ RADEON_GEM_DOMAIN_GTT, 0); + +-void radeonValidateState( GLcontext *ctx ) ++ return radeon_revalidate_bos(ctx); ++} ++ ++GLboolean radeonValidateState( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- GLuint new_state = rmesa->NewGLState; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ GLuint new_state = rmesa->radeon.NewGLState; + + if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { +- radeonUpdateDrawBuffer(ctx); ++ _mesa_update_framebuffer(ctx); ++ /* this updates the DrawBuffer's Width/Height if it's a FBO */ ++ _mesa_update_draw_buffer_bounds(ctx); ++ RADEON_STATECHANGE(rmesa, ctx); + } + + if (new_state & _NEW_TEXTURE) { + radeonUpdateTextureState( ctx ); +- new_state |= rmesa->NewGLState; /* may add TEXTURE_MATRIX */ ++ new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */ + } + ++ /* we need to do a space check here */ ++ if (!r100ValidateBuffers(ctx)) ++ return GL_FALSE; ++ + /* Need an event driven matrix update? + */ + if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) +@@ -2295,7 +2141,7 @@ void radeonValidateState( GLcontext *ctx ) + } + + +- rmesa->NewGLState = 0; ++ rmesa->radeon.NewGLState = 0; + } + + +@@ -2306,7 +2152,7 @@ static void radeonInvalidateState( GLcontext *ctx, GLuint new_state ) + _vbo_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + _ae_invalidate_state( ctx, new_state ); +- RADEON_CONTEXT(ctx)->NewGLState |= new_state; ++ R100_CONTEXT(ctx)->radeon.NewGLState |= new_state; + } + + +@@ -2330,16 +2176,17 @@ static GLboolean check_material( GLcontext *ctx ) + + static void radeonWrapRunPipeline( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLboolean has_material; + + if (0) +- fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->NewGLState); ++ fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState); + + /* Validate state: + */ +- if (rmesa->NewGLState) +- radeonValidateState( ctx ); ++ if (rmesa->radeon.NewGLState) ++ if (!radeonValidateState( ctx )) ++ FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE); + + has_material = (ctx->Light.Enabled && check_material( ctx )); + +diff --git a/src/mesa/drivers/dri/radeon/radeon_state.h b/src/mesa/drivers/dri/radeon/radeon_state.h +index 2171879..a7c8eef 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_state.h ++++ b/src/mesa/drivers/dri/radeon/radeon_state.h +@@ -39,30 +39,25 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #include "radeon_context.h" + +-extern void radeonInitState( radeonContextPtr rmesa ); ++extern void radeonInitState( r100ContextPtr rmesa ); + extern void radeonInitStateFuncs( GLcontext *ctx ); + + extern void radeonUpdateMaterial( GLcontext *ctx ); + +-extern void radeonSetCliprects( radeonContextPtr rmesa ); +-extern void radeonRecalcScissorRects( radeonContextPtr rmesa ); + extern void radeonUpdateViewportOffset( GLcontext *ctx ); + extern void radeonUpdateWindow( GLcontext *ctx ); + extern void radeonUpdateDrawBuffer( GLcontext *ctx ); +-extern void radeonUploadTexMatrix( radeonContextPtr rmesa, ++extern void radeonUploadTexMatrix( r100ContextPtr rmesa, + int unit, GLboolean swapcols ); + +-extern void radeonValidateState( GLcontext *ctx ); +- +-extern void radeonPrintDirty( radeonContextPtr rmesa, +- const char *msg ); ++extern GLboolean radeonValidateState( GLcontext *ctx ); + + + extern void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); + #define FALLBACK( rmesa, bit, mode ) do { \ + if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \ + __FUNCTION__, bit, mode ); \ +- radeonFallback( rmesa->glCtx, bit, mode ); \ ++ radeonFallback( rmesa->radeon.glCtx, bit, mode ); \ + } while (0) + + +diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c +index 57dc380..174a7e1 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_state_init.c ++++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c +@@ -38,39 +38,140 @@ + #include "swrast_setup/swrast_setup.h" + + #include "radeon_context.h" ++#include "radeon_mipmap_tree.h" + #include "radeon_ioctl.h" + #include "radeon_state.h" + #include "radeon_tcl.h" + #include "radeon_tex.h" + #include "radeon_swtcl.h" + ++#include "../r200/r200_reg.h" ++ + #include "xmlpool.h" + ++/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in ++ * 1.3 cmdbuffers allow all previous state to be updated as well as ++ * the tcl scalar and vector areas. ++ */ ++static struct { ++ int start; ++ int len; ++ const char *name; ++} packet[RADEON_MAX_STATE_PACKETS] = { ++ {RADEON_PP_MISC, 7, "RADEON_PP_MISC"}, ++ {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"}, ++ {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"}, ++ {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"}, ++ {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"}, ++ {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"}, ++ {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"}, ++ {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"}, ++ {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"}, ++ {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"}, ++ {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"}, ++ {RADEON_RE_MISC, 1, "RADEON_RE_MISC"}, ++ {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"}, ++ {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"}, ++ {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"}, ++ {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"}, ++ {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"}, ++ {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"}, ++ {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"}, ++ {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"}, ++ {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17, ++ "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"}, ++ {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"}, ++ {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"}, ++ {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"}, ++ {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"}, ++ {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"}, ++ {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"}, ++ {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"}, ++ {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"}, ++ {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"}, ++ {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"}, ++ {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"}, ++ {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"}, ++ {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"}, ++ {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"}, ++ {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"}, ++ {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"}, ++ {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"}, ++ {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"}, ++ {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"}, ++ {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"}, ++ {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"}, ++ {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"}, ++ {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"}, ++ {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"}, ++ {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"}, ++ {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, ++ {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, ++ {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, ++ {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, ++ "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, ++ {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, ++ {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, ++ {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, ++ {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"}, ++ {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"}, ++ {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"}, ++ {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"}, ++ {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"}, ++ {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"}, ++ {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"}, ++ {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, ++ "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, ++ {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ ++ {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ ++ {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, ++ {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, ++ {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, ++ {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"}, ++ {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"}, ++ {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"}, ++ {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"}, ++ {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"}, ++ {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"}, ++ {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"}, ++ {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"}, ++ {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"}, ++ {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"}, ++ {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"}, ++ {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"}, ++ {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"}, ++ {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"}, ++ {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"}, ++ {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"}, ++ {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, ++ {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, ++ {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, ++ {R200_PP_TXCBLEND_8, 32, "R200_PP_AFS_0"}, /* 85 */ ++ {R200_PP_TXCBLEND_0, 32, "R200_PP_AFS_1"}, ++ {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, ++ {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, ++ {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"}, ++ {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"}, ++ {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, ++ {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, ++ {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, ++ {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"}, ++}; ++ + /* ============================================================= + * State initialization + */ +- +-void radeonPrintDirty( radeonContextPtr rmesa, const char *msg ) ++static int cmdpkt( r100ContextPtr rmesa, int id ) + { +- struct radeon_state_atom *l; +- +- fprintf(stderr, msg); +- fprintf(stderr, ": "); ++ drm_radeon_cmd_header_t h; + +- foreach(l, &rmesa->hw.atomlist) { +- if (l->dirty || rmesa->hw.all_dirty) +- fprintf(stderr, "%s, ", l->name); ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ return CP_PACKET0(packet[id].start, packet[id].len - 1); ++ } else { ++ h.i = 0; ++ h.packet.cmd_type = RADEON_CMD_PACKET; ++ h.packet.packet_id = id; + } +- +- fprintf(stderr, "\n"); +-} +- +-static int cmdpkt( int id ) +-{ +- drm_radeon_cmd_header_t h; +- h.i = 0; +- h.packet.cmd_type = RADEON_CMD_PACKET; +- h.packet.packet_id = id; + return h.i; + } + +@@ -96,17 +197,17 @@ static int cmdscl( int offset, int stride, int count ) + return h.i; + } + +-#define CHECK( NM, FLAG ) \ +-static GLboolean check_##NM( GLcontext *ctx ) \ +-{ \ +- return FLAG; \ ++#define CHECK( NM, FLAG ) \ ++static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom ) \ ++{ \ ++ return FLAG ? atom->cmd_size : 0; \ + } + + #define TCL_CHECK( NM, FLAG ) \ +-static GLboolean check_##NM( GLcontext *ctx ) \ ++static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom ) \ + { \ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ +- return !rmesa->TclFallback && (FLAG); \ ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); \ ++ return (!rmesa->radeon.TclFallback && (FLAG)) ? atom->cmd_size : 0; \ + } + + +@@ -146,81 +247,373 @@ CHECK( txr0, (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_RECT_BIT)) + CHECK( txr1, (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_RECT_BIT)) + CHECK( txr2, (ctx->Texture.Unit[2]._ReallyEnabled & TEXTURE_RECT_BIT)) + ++#define OUT_VEC(hdr, data) do { \ ++ drm_radeon_cmd_header_t h; \ ++ h.i = hdr; \ ++ OUT_BATCH(CP_PACKET0(RADEON_SE_TCL_STATE_FLUSH, 0)); \ ++ OUT_BATCH(0); \ ++ OUT_BATCH(CP_PACKET0(R200_SE_TCL_VECTOR_INDX_REG, 0)); \ ++ OUT_BATCH(h.vectors.offset | (h.vectors.stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); \ ++ OUT_BATCH(CP_PACKET0_ONE(R200_SE_TCL_VECTOR_DATA_REG, h.vectors.count - 1)); \ ++ OUT_BATCH_TABLE((data), h.vectors.count); \ ++ } while(0) ++ ++#define OUT_SCL(hdr, data) do { \ ++ drm_radeon_cmd_header_t h; \ ++ h.i = hdr; \ ++ OUT_BATCH(CP_PACKET0(R200_SE_TCL_SCALAR_INDX_REG, 0)); \ ++ OUT_BATCH((h.scalars.offset) | (h.scalars.stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); \ ++ OUT_BATCH(CP_PACKET0_ONE(R200_SE_TCL_SCALAR_DATA_REG, h.scalars.count - 1)); \ ++ OUT_BATCH_TABLE((data), h.scalars.count); \ ++ } while(0) ++ ++static void scl_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r100ContextPtr r100 = R100_CONTEXT(ctx); ++ BATCH_LOCALS(&r100->radeon); ++ uint32_t dwords = atom->cmd_size; ++ ++ dwords += 2; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_SCL(atom->cmd[0], atom->cmd+1); ++ END_BATCH(); ++} + + +-/* Initialize the context's hardware state. +- */ +-void radeonInitState( radeonContextPtr rmesa ) ++static void vec_emit(GLcontext *ctx, struct radeon_state_atom *atom) + { +- GLcontext *ctx = rmesa->glCtx; +- GLuint color_fmt, depth_fmt, i; +- GLint drawPitch, drawOffset; ++ r100ContextPtr r100 = R100_CONTEXT(ctx); ++ BATCH_LOCALS(&r100->radeon); ++ uint32_t dwords = atom->cmd_size; ++ ++ dwords += 4; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_VEC(atom->cmd[0], atom->cmd+1); ++ END_BATCH(); ++} + +- switch ( rmesa->radeonScreen->cpp ) { +- case 2: +- color_fmt = RADEON_COLOR_FORMAT_RGB565; +- break; +- case 4: +- color_fmt = RADEON_COLOR_FORMAT_ARGB8888; +- break; +- default: +- fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); +- exit( -1 ); ++ ++static void lit_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r100ContextPtr r100 = R100_CONTEXT(ctx); ++ BATCH_LOCALS(&r100->radeon); ++ uint32_t dwords = atom->cmd_size; ++ ++ dwords += 6; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_VEC(atom->cmd[LIT_CMD_0], atom->cmd+1); ++ OUT_SCL(atom->cmd[LIT_CMD_1], atom->cmd+LIT_CMD_1+1); ++ END_BATCH(); ++} ++ ++static void ctx_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r100ContextPtr r100 = R100_CONTEXT(ctx); ++ BATCH_LOCALS(&r100->radeon); ++ struct radeon_renderbuffer *rrb; ++ uint32_t cbpitch; ++ uint32_t zbpitch, depth_fmt; ++ uint32_t dwords = atom->cmd_size; ++ ++ /* output the first 7 bytes of context */ ++ BEGIN_BATCH_NO_AUTOSTATE(dwords + 4); ++ OUT_BATCH_TABLE(atom->cmd, 5); ++ ++ rrb = radeon_get_depthbuffer(&r100->radeon); ++ if (!rrb) { ++ OUT_BATCH(0); ++ OUT_BATCH(0); ++ } else { ++ zbpitch = (rrb->pitch / rrb->cpp); ++ if (r100->using_hyperz) ++ zbpitch |= RADEON_DEPTH_HYPERZ; ++ ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ OUT_BATCH(zbpitch); ++ if (rrb->cpp == 4) ++ depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; ++ else ++ depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; ++ atom->cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_DEPTH_FORMAT_MASK; ++ atom->cmd[CTX_RB3D_ZSTENCILCNTL] |= depth_fmt; ++ } ++ ++ OUT_BATCH(atom->cmd[CTX_RB3D_ZSTENCILCNTL]); ++ OUT_BATCH(atom->cmd[CTX_CMD_1]); ++ OUT_BATCH(atom->cmd[CTX_PP_CNTL]); ++ ++ rrb = radeon_get_colorbuffer(&r100->radeon); ++ if (!rrb || !rrb->bo) { ++ OUT_BATCH(atom->cmd[CTX_RB3D_CNTL]); ++ OUT_BATCH(atom->cmd[CTX_RB3D_COLOROFFSET]); ++ } else { ++ atom->cmd[CTX_RB3D_CNTL] &= ~(0xf << 10); ++ if (rrb->cpp == 4) ++ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB8888; ++ else ++ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_RGB565; ++ ++ OUT_BATCH(atom->cmd[CTX_RB3D_CNTL]); ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ } ++ ++ OUT_BATCH(atom->cmd[CTX_CMD_2]); ++ ++ if (!rrb || !rrb->bo) { ++ OUT_BATCH(atom->cmd[CTX_RB3D_COLORPITCH]); ++ } else { ++ cbpitch = (rrb->pitch / rrb->cpp); ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) ++ cbpitch |= RADEON_COLOR_TILE_ENABLE; ++ OUT_BATCH(cbpitch); ++ } ++ ++ END_BATCH(); ++} ++ ++static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r100ContextPtr r100 = R100_CONTEXT(ctx); ++ BATCH_LOCALS(&r100->radeon); ++ struct radeon_renderbuffer *rrb, *drb; ++ uint32_t cbpitch = 0; ++ uint32_t zbpitch = 0; ++ uint32_t dwords = atom->cmd_size; ++ uint32_t depth_fmt; ++ ++ rrb = radeon_get_colorbuffer(&r100->radeon); ++ if (!rrb || !rrb->bo) { ++ fprintf(stderr, "no rrb\n"); ++ return; ++ } ++ ++ atom->cmd[CTX_RB3D_CNTL] &= ~(0xf << 10); ++ if (rrb->cpp == 4) ++ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB8888; ++ else ++ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_RGB565; ++ ++ cbpitch = (rrb->pitch / rrb->cpp); ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) ++ cbpitch |= R200_COLOR_TILE_ENABLE; ++ ++ drb = radeon_get_depthbuffer(&r100->radeon); ++ if (drb) { ++ zbpitch = (drb->pitch / drb->cpp); ++ if (drb->cpp == 4) ++ depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; ++ else ++ depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; ++ atom->cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_DEPTH_FORMAT_MASK; ++ atom->cmd[CTX_RB3D_ZSTENCILCNTL] |= depth_fmt; ++ ++ } ++ ++ /* output the first 7 bytes of context */ ++ dwords = 10; ++ if (drb) ++ dwords += 6; ++ if (rrb) ++ dwords += 6; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ ++ /* In the CS case we need to split this up */ ++ OUT_BATCH(CP_PACKET0(packet[0].start, 3)); ++ OUT_BATCH_TABLE((atom->cmd + 1), 4); ++ ++ if (drb) { ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_DEPTHOFFSET, 0)); ++ OUT_BATCH_RELOC(0, drb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_DEPTHPITCH, 0)); ++ OUT_BATCH(zbpitch); ++ } ++ ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZSTENCILCNTL, 0)); ++ OUT_BATCH(atom->cmd[CTX_RB3D_ZSTENCILCNTL]); ++ OUT_BATCH(CP_PACKET0(RADEON_PP_CNTL, 1)); ++ OUT_BATCH(atom->cmd[CTX_PP_CNTL]); ++ OUT_BATCH(atom->cmd[CTX_RB3D_CNTL]); ++ ++ if (rrb) { ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_COLOROFFSET, 0)); ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ ++ OUT_BATCH(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0)); ++ OUT_BATCH(cbpitch); + } + +- rmesa->state.color.clear = 0x00000000; ++ // if (atom->cmd_size == CTX_STATE_SIZE_NEWDRM) { ++ // OUT_BATCH_TABLE((atom->cmd + 14), 4); ++ // } ++ ++ END_BATCH(); ++} ++ ++static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r100ContextPtr r100 = R100_CONTEXT(ctx); ++ BATCH_LOCALS(&r100->radeon); ++ uint32_t dwords = atom->cmd_size; ++ int i = atom->idx, j; ++ radeonTexObj *t = r100->state.texture.unit[i].texobj; ++ radeon_mipmap_level *lvl; ++ ++ if (!(ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT)) ++ return; ++ ++ if (!t) ++ return; ++ ++ if (!t->mt) ++ return; ++ ++ BEGIN_BATCH_NO_AUTOSTATE(dwords + 10); ++ OUT_BATCH_TABLE(atom->cmd, 3); ++ lvl = &t->mt->levels[0]; ++ for (j = 0; j < 5; j++) { ++ OUT_BATCH_RELOC(lvl->faces[j].offset, t->mt->bo, lvl->faces[j].offset, ++ RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } ++ END_BATCH(); ++} ++ ++static void tex_emit(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r100ContextPtr r100 = R100_CONTEXT(ctx); ++ BATCH_LOCALS(&r100->radeon); ++ uint32_t dwords = atom->cmd_size; ++ int i = atom->idx; ++ radeonTexObj *t = r100->state.texture.unit[i].texobj; ++ radeon_mipmap_level *lvl; ++ ++ if (t && t->mt && !t->image_override) ++ dwords += 2; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ ++ OUT_BATCH_TABLE(atom->cmd, 3); ++ if (t && t->mt && !t->image_override) { ++ if ((ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT)) { ++ lvl = &t->mt->levels[0]; ++ OUT_BATCH_RELOC(lvl->faces[5].offset, t->mt->bo, lvl->faces[5].offset, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } else { ++ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } ++ } else if (!t) { ++ /* workaround for old CS mechanism */ ++ OUT_BATCH(r100->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]); ++ // OUT_BATCH(r100->radeon.radeonScreen); ++ } else { ++ OUT_BATCH(t->override_offset); ++ } ++ ++ OUT_BATCH_TABLE((atom->cmd+4), 5); ++ END_BATCH(); ++} ++ ++static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) ++{ ++ r100ContextPtr r100 = R100_CONTEXT(ctx); ++ BATCH_LOCALS(&r100->radeon); ++ uint32_t dwords = atom->cmd_size; ++ int i = atom->idx; ++ radeonTexObj *t = r100->state.texture.unit[i].texobj; ++ radeon_mipmap_level *lvl; ++ int hastexture = 1; ++ ++ if (!t) ++ hastexture = 0; ++ else { ++ if (!t->mt && !t->bo) ++ hastexture = 0; ++ } ++ dwords += 1; ++ if (hastexture) ++ dwords += 2; ++ else ++ dwords -= 2; ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ ++ OUT_BATCH(CP_PACKET0(RADEON_PP_TXFILTER_0 + (24 * i), 1)); ++ OUT_BATCH_TABLE((atom->cmd + 1), 2); ++ ++ if (hastexture) { ++ OUT_BATCH(CP_PACKET0(RADEON_PP_TXOFFSET_0 + (24 * i), 0)); ++ if (t->mt && !t->image_override) { ++ if ((ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT)) { ++ lvl = &t->mt->levels[0]; ++ OUT_BATCH_RELOC(lvl->faces[5].offset, t->mt->bo, lvl->faces[5].offset, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } else { ++ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } ++ } else { ++ if (t->bo) ++ OUT_BATCH_RELOC(t->tile_bits, t->bo, 0, ++ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } ++ } ++ ++ OUT_BATCH(CP_PACKET0(RADEON_PP_TXCBLEND_0 + (i * 24), 1)); ++ OUT_BATCH_TABLE((atom->cmd+4), 2); ++ OUT_BATCH(CP_PACKET0(RADEON_PP_BORDER_COLOR_0 + (i * 4), 0)); ++ OUT_BATCH((atom->cmd[TEX_PP_BORDER_COLOR])); ++ END_BATCH(); ++} ++ ++/* Initialize the context's hardware state. ++ */ ++void radeonInitState( r100ContextPtr rmesa ) ++{ ++ GLcontext *ctx = rmesa->radeon.glCtx; ++ GLuint i; ++ ++ rmesa->radeon.state.color.clear = 0x00000000; + + switch ( ctx->Visual.depthBits ) { + case 16: +- rmesa->state.depth.clear = 0x0000ffff; +- rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff; +- depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; +- rmesa->state.stencil.clear = 0x00000000; ++ rmesa->radeon.state.depth.clear = 0x0000ffff; ++ rmesa->radeon.state.stencil.clear = 0x00000000; + break; + case 24: +- rmesa->state.depth.clear = 0x00ffffff; +- rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff; +- depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; +- rmesa->state.stencil.clear = 0xffff0000; ++ rmesa->radeon.state.depth.clear = 0x00ffffff; ++ rmesa->radeon.state.stencil.clear = 0xffff0000; + break; + default: +- fprintf( stderr, "Error: Unsupported depth %d... exiting\n", +- ctx->Visual.depthBits ); +- exit( -1 ); ++ break; + } + +- /* Only have hw stencil when depth buffer is 24 bits deep */ +- rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && +- ctx->Visual.depthBits == 24 ); ++ rmesa->radeon.Fallback = 0; + +- rmesa->Fallback = 0; +- +- if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { +- drawOffset = rmesa->radeonScreen->backOffset; +- drawPitch = rmesa->radeonScreen->backPitch; +- } else { +- drawOffset = rmesa->radeonScreen->frontOffset; +- drawPitch = rmesa->radeonScreen->frontPitch; +- } + +- rmesa->hw.max_state_size = 0; ++ rmesa->radeon.hw.max_state_size = 0; + +-#define ALLOC_STATE( ATOM, CHK, SZ, NM, FLAG ) \ ++#define ALLOC_STATE_IDX( ATOM, CHK, SZ, NM, FLAG, IDX ) \ + do { \ + rmesa->hw.ATOM.cmd_size = SZ; \ +- rmesa->hw.ATOM.cmd = (int *)CALLOC(SZ * sizeof(int)); \ +- rmesa->hw.ATOM.lastcmd = (int *)CALLOC(SZ * sizeof(int)); \ +- rmesa->hw.ATOM.name = NM; \ ++ rmesa->hw.ATOM.cmd = (GLuint *)CALLOC(SZ * sizeof(int)); \ ++ rmesa->hw.ATOM.lastcmd = (GLuint *)CALLOC(SZ * sizeof(int)); \ ++ rmesa->hw.ATOM.name = NM; \ + rmesa->hw.ATOM.is_tcl = FLAG; \ + rmesa->hw.ATOM.check = check_##CHK; \ +- rmesa->hw.ATOM.dirty = GL_TRUE; \ +- rmesa->hw.max_state_size += SZ * sizeof(int); \ ++ rmesa->hw.ATOM.dirty = GL_TRUE; \ ++ rmesa->hw.ATOM.idx = IDX; \ ++ rmesa->radeon.hw.max_state_size += SZ * sizeof(int); \ + } while (0) +- +- ++ ++#define ALLOC_STATE( ATOM, CHK, SZ, NM, FLAG ) \ ++ ALLOC_STATE_IDX(ATOM, CHK, SZ, NM, FLAG, 0) ++ + /* Allocate state buffers: + */ + ALLOC_STATE( ctx, always, CTX_STATE_SIZE, "CTX/context", 0 ); ++ if (rmesa->radeon.radeonScreen->kernel_mm) ++ rmesa->hw.ctx.emit = ctx_emit_cs; ++ else ++ rmesa->hw.ctx.emit = ctx_emit; + ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 ); + ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 ); + ALLOC_STATE( vpt, always, VPT_STATE_SIZE, "VPT/viewport", 0 ); +@@ -233,20 +626,29 @@ void radeonInitState( radeonContextPtr rmesa ) + ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 1 ); + ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 1 ); + ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 1 ); +- ALLOC_STATE( tex[0], tex0, TEX_STATE_SIZE, "TEX/tex-0", 0 ); +- ALLOC_STATE( tex[1], tex1, TEX_STATE_SIZE, "TEX/tex-1", 0 ); +- ALLOC_STATE( tex[2], tex2, TEX_STATE_SIZE, "TEX/tex-2", 0 ); +- if (rmesa->radeonScreen->drmSupportsCubeMapsR100) ++ ALLOC_STATE_IDX( tex[0], tex0, TEX_STATE_SIZE, "TEX/tex-0", 0, 0); ++ ALLOC_STATE_IDX( tex[1], tex1, TEX_STATE_SIZE, "TEX/tex-1", 0, 1); ++ ALLOC_STATE_IDX( tex[2], tex2, TEX_STATE_SIZE, "TEX/tex-2", 0, 2); ++ ++ for (i = 0; i < 3; i++) { ++ if (rmesa->radeon.radeonScreen->kernel_mm) ++ rmesa->hw.tex[i].emit = tex_emit_cs; ++ else ++ rmesa->hw.tex[i].emit = tex_emit; ++ } ++ if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR100) + { +- ALLOC_STATE( cube[0], cube0, CUBE_STATE_SIZE, "CUBE/cube-0", 0 ); +- ALLOC_STATE( cube[1], cube1, CUBE_STATE_SIZE, "CUBE/cube-1", 0 ); +- ALLOC_STATE( cube[2], cube2, CUBE_STATE_SIZE, "CUBE/cube-2", 0 ); ++ ALLOC_STATE_IDX( cube[0], cube0, CUBE_STATE_SIZE, "CUBE/cube-0", 0, 0 ); ++ ALLOC_STATE_IDX( cube[1], cube1, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 ); ++ ALLOC_STATE_IDX( cube[2], cube2, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 ); ++ for (i = 0; i < 3; i++) ++ rmesa->hw.cube[i].emit = cube_emit; + } + else + { +- ALLOC_STATE( cube[0], never, CUBE_STATE_SIZE, "CUBE/cube-0", 0 ); +- ALLOC_STATE( cube[1], never, CUBE_STATE_SIZE, "CUBE/cube-1", 0 ); +- ALLOC_STATE( cube[2], never, CUBE_STATE_SIZE, "CUBE/cube-2", 0 ); ++ ALLOC_STATE_IDX( cube[0], never, CUBE_STATE_SIZE, "CUBE/cube-0", 0, 0 ); ++ ALLOC_STATE_IDX( cube[1], never, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 ); ++ ALLOC_STATE_IDX( cube[2], never, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 ); + } + ALLOC_STATE( mat[0], tcl, MAT_STATE_SIZE, "MAT/modelproject", 1 ); + ALLOC_STATE( mat[1], tcl_eyespace_or_fog, MAT_STATE_SIZE, "MAT/modelview", 1 ); +@@ -268,43 +670,43 @@ void radeonInitState( radeonContextPtr rmesa ) + ALLOC_STATE( lit[5], tcl_lit5, LIT_STATE_SIZE, "LIT/light-5", 1 ); + ALLOC_STATE( lit[6], tcl_lit6, LIT_STATE_SIZE, "LIT/light-6", 1 ); + ALLOC_STATE( lit[7], tcl_lit7, LIT_STATE_SIZE, "LIT/light-7", 1 ); +- ALLOC_STATE( txr[0], txr0, TXR_STATE_SIZE, "TXR/txr-0", 0 ); +- ALLOC_STATE( txr[1], txr1, TXR_STATE_SIZE, "TXR/txr-1", 0 ); +- ALLOC_STATE( txr[2], txr2, TXR_STATE_SIZE, "TXR/txr-2", 0 ); ++ ALLOC_STATE_IDX( txr[0], txr0, TXR_STATE_SIZE, "TXR/txr-0", 0, 0 ); ++ ALLOC_STATE_IDX( txr[1], txr1, TXR_STATE_SIZE, "TXR/txr-1", 0, 1 ); ++ ALLOC_STATE_IDX( txr[2], txr2, TXR_STATE_SIZE, "TXR/txr-2", 0, 2 ); + + radeonSetUpAtomList( rmesa ); + + /* Fill in the packet headers: + */ +- rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(RADEON_EMIT_PP_MISC); +- rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(RADEON_EMIT_PP_CNTL); +- rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(RADEON_EMIT_RB3D_COLORPITCH); +- rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(RADEON_EMIT_RE_LINE_PATTERN); +- rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(RADEON_EMIT_SE_LINE_WIDTH); +- rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(RADEON_EMIT_RB3D_STENCILREFMASK); +- rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(RADEON_EMIT_SE_VPORT_XSCALE); +- rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(RADEON_EMIT_SE_CNTL); +- rmesa->hw.set.cmd[SET_CMD_1] = cmdpkt(RADEON_EMIT_SE_CNTL_STATUS); +- rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(RADEON_EMIT_RE_MISC); +- rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(RADEON_EMIT_PP_TXFILTER_0); +- rmesa->hw.tex[0].cmd[TEX_CMD_1] = cmdpkt(RADEON_EMIT_PP_BORDER_COLOR_0); +- rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(RADEON_EMIT_PP_TXFILTER_1); +- rmesa->hw.tex[1].cmd[TEX_CMD_1] = cmdpkt(RADEON_EMIT_PP_BORDER_COLOR_1); +- rmesa->hw.tex[2].cmd[TEX_CMD_0] = cmdpkt(RADEON_EMIT_PP_TXFILTER_2); +- rmesa->hw.tex[2].cmd[TEX_CMD_1] = cmdpkt(RADEON_EMIT_PP_BORDER_COLOR_2); +- rmesa->hw.cube[0].cmd[CUBE_CMD_0] = cmdpkt(RADEON_EMIT_PP_CUBIC_FACES_0); +- rmesa->hw.cube[0].cmd[CUBE_CMD_1] = cmdpkt(RADEON_EMIT_PP_CUBIC_OFFSETS_T0); +- rmesa->hw.cube[1].cmd[CUBE_CMD_0] = cmdpkt(RADEON_EMIT_PP_CUBIC_FACES_1); +- rmesa->hw.cube[1].cmd[CUBE_CMD_1] = cmdpkt(RADEON_EMIT_PP_CUBIC_OFFSETS_T1); +- rmesa->hw.cube[2].cmd[CUBE_CMD_0] = cmdpkt(RADEON_EMIT_PP_CUBIC_FACES_2); +- rmesa->hw.cube[2].cmd[CUBE_CMD_1] = cmdpkt(RADEON_EMIT_PP_CUBIC_OFFSETS_T2); +- rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(RADEON_EMIT_SE_ZBIAS_FACTOR); +- rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT); ++ rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_MISC); ++ rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_CNTL); ++ rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(rmesa, RADEON_EMIT_RB3D_COLORPITCH); ++ rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_RE_LINE_PATTERN); ++ rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_SE_LINE_WIDTH); ++ rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_RB3D_STENCILREFMASK); ++ rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_VPORT_XSCALE); ++ rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_CNTL); ++ rmesa->hw.set.cmd[SET_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_SE_CNTL_STATUS); ++ rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_RE_MISC); ++ rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TXFILTER_0); ++ rmesa->hw.tex[0].cmd[TEX_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_BORDER_COLOR_0); ++ rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TXFILTER_1); ++ rmesa->hw.tex[1].cmd[TEX_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_BORDER_COLOR_1); ++ rmesa->hw.tex[2].cmd[TEX_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TXFILTER_2); ++ rmesa->hw.tex[2].cmd[TEX_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_BORDER_COLOR_2); ++ rmesa->hw.cube[0].cmd[CUBE_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_FACES_0); ++ rmesa->hw.cube[0].cmd[CUBE_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_OFFSETS_T0); ++ rmesa->hw.cube[1].cmd[CUBE_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_FACES_1); ++ rmesa->hw.cube[1].cmd[CUBE_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_OFFSETS_T1); ++ rmesa->hw.cube[2].cmd[CUBE_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_FACES_2); ++ rmesa->hw.cube[2].cmd[CUBE_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_OFFSETS_T2); ++ rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_ZBIAS_FACTOR); ++ rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT); + rmesa->hw.mtl.cmd[MTL_CMD_0] = +- cmdpkt(RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED); +- rmesa->hw.txr[0].cmd[TXR_CMD_0] = cmdpkt(RADEON_EMIT_PP_TEX_SIZE_0); +- rmesa->hw.txr[1].cmd[TXR_CMD_0] = cmdpkt(RADEON_EMIT_PP_TEX_SIZE_1); +- rmesa->hw.txr[2].cmd[TXR_CMD_0] = cmdpkt(RADEON_EMIT_PP_TEX_SIZE_2); ++ cmdpkt(rmesa, RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED); ++ rmesa->hw.txr[0].cmd[TXR_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TEX_SIZE_0); ++ rmesa->hw.txr[1].cmd[TXR_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TEX_SIZE_1); ++ rmesa->hw.txr[2].cmd[TXR_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TEX_SIZE_2); + rmesa->hw.grd.cmd[GRD_CMD_0] = + cmdscl( RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 ); + rmesa->hw.fog.cmd[FOG_CMD_0] = +@@ -331,6 +733,22 @@ void radeonInitState( radeonContextPtr rmesa ) + cmdvec( RADEON_VS_UCP_ADDR + i, 1, 4 ); + } + ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ rmesa->hw.grd.emit = scl_emit; ++ rmesa->hw.fog.emit = vec_emit; ++ rmesa->hw.glt.emit = vec_emit; ++ rmesa->hw.eye.emit = vec_emit; ++ ++ for (i = 0; i <= 6; i++) ++ rmesa->hw.mat[i].emit = vec_emit; ++ ++ for (i = 0; i < 8; i++) ++ rmesa->hw.lit[i].emit = lit_emit; ++ ++ for (i = 0; i < 6; i++) ++ rmesa->hw.ucp[i].emit = vec_emit; ++ } ++ + rmesa->last_ReallyEnabled = -1; + + /* Initial Harware state: +@@ -352,19 +770,7 @@ void radeonInitState( radeonContextPtr rmesa ) + RADEON_SRC_BLEND_GL_ONE | + RADEON_DST_BLEND_GL_ZERO ); + +- rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHOFFSET] = +- rmesa->radeonScreen->depthOffset + rmesa->radeonScreen->fbLocation; +- +- rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHPITCH] = +- ((rmesa->radeonScreen->depthPitch & +- RADEON_DEPTHPITCH_MASK) | +- RADEON_DEPTH_ENDIAN_NO_SWAP); +- +- if (rmesa->using_hyperz) +- rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHPITCH] |= RADEON_DEPTH_HYPERZ; +- +- rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (depth_fmt | +- RADEON_Z_TEST_LESS | ++ rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (RADEON_Z_TEST_LESS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_FAIL_KEEP | + RADEON_STENCIL_ZPASS_KEEP | +@@ -374,7 +780,7 @@ void radeonInitState( radeonContextPtr rmesa ) + if (rmesa->using_hyperz) { + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_COMPRESSION_ENABLE | + RADEON_Z_DECOMPRESSION_ENABLE; +- if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { ++ if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { + /* works for q3, but slight rendering errors with glxgears ? */ + /* rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_HIERARCHY_ENABLE;*/ + /* need this otherwise get lots of lockups with q3 ??? */ +@@ -386,10 +792,9 @@ void radeonInitState( radeonContextPtr rmesa ) + RADEON_ANTI_ALIAS_NONE); + + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = (RADEON_PLANE_MASK_ENABLE | +- color_fmt | + RADEON_ZBLOCK16); + +- switch ( driQueryOptioni( &rmesa->optionCache, "dither_mode" ) ) { ++ switch ( driQueryOptioni( &rmesa->radeon.optionCache, "dither_mode" ) ) { + case DRI_CONF_DITHER_XERRORDIFFRESET: + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_INIT; + break; +@@ -397,31 +802,18 @@ void radeonInitState( radeonContextPtr rmesa ) + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_SCALE_DITHER_ENABLE; + break; + } +- if ( driQueryOptioni( &rmesa->optionCache, "round_mode" ) == ++ if ( driQueryOptioni( &rmesa->radeon.optionCache, "round_mode" ) == + DRI_CONF_ROUND_ROUND ) +- rmesa->state.color.roundEnable = RADEON_ROUND_ENABLE; ++ rmesa->radeon.state.color.roundEnable = RADEON_ROUND_ENABLE; + else +- rmesa->state.color.roundEnable = 0; +- if ( driQueryOptioni (&rmesa->optionCache, "color_reduction" ) == ++ rmesa->radeon.state.color.roundEnable = 0; ++ if ( driQueryOptioni (&rmesa->radeon.optionCache, "color_reduction" ) == + DRI_CONF_COLOR_REDUCTION_DITHER ) + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE; + else +- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; +- +- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((drawOffset + +- rmesa->radeonScreen->fbLocation) +- & RADEON_COLOROFFSET_MASK); +- +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((drawPitch & +- RADEON_COLORPITCH_MASK) | +- RADEON_COLOR_ENDIAN_NO_SWAP); ++ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; + + +- /* (fixed size) sarea is initialized to zero afaics so can omit version check. Phew! */ +- if (rmesa->sarea->tiling_enabled) { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE; +- } +- + rmesa->hw.set.cmd[SET_SE_CNTL] = (RADEON_FFACE_CULL_CCW | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | +@@ -444,7 +836,7 @@ void radeonInitState( radeonContextPtr rmesa ) + RADEON_VC_NO_SWAP; + #endif + +- if (!(rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { ++ if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { + rmesa->hw.set.cmd[SET_SE_CNTL_STATUS] |= RADEON_TCL_BYPASS; + } + +@@ -491,8 +883,8 @@ void radeonInitState( radeonContextPtr rmesa ) + (2 << RADEON_TXFORMAT_HEIGHT_SHIFT)); + + /* Initialize the texture offset to the start of the card texture heap */ +- rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET] = +- rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ // rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET] = ++ // rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + + rmesa->hw.tex[i].cmd[TEX_PP_BORDER_COLOR] = 0; + rmesa->hw.tex[i].cmd[TEX_PP_TXCBLEND] = +@@ -513,15 +905,15 @@ void radeonInitState( radeonContextPtr rmesa ) + + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_FACES] = 0; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_0] = +- rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_1] = +- rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_2] = +- rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_3] = +- rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_4] = +- rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; ++ rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; + } + + /* Can only add ST1 at the time of doing some multitex but can keep +@@ -613,5 +1005,7 @@ void radeonInitState( radeonContextPtr rmesa ) + rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE; + rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE; + +- rmesa->hw.all_dirty = GL_TRUE; ++ rmesa->radeon.hw.all_dirty = GL_TRUE; ++ ++ rcommonInitCmdBuf(&rmesa->radeon); + } +diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c +index ebea1fe..e31f045 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c ++++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c +@@ -52,8 +52,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "radeon_tcl.h" + + +-static void flush_last_swtcl_prim( radeonContextPtr rmesa ); +- + /* R100: xyzw, c0, c1/fog, stq[0..2] = 4+1+1+3*3 = 15 right? */ + /* R200: xyzw, c0, c1/fog, strq[0..5] = 4+1+1+4*6 = 30 */ + #define RADEON_MAX_TNL_VERTEX_SIZE (15 * sizeof(GLfloat)) /* for mesa _tnl stage */ +@@ -64,18 +62,18 @@ static void flush_last_swtcl_prim( radeonContextPtr rmesa ); + + #define EMIT_ATTR( ATTR, STYLE, F0 ) \ + do { \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR); \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = (STYLE); \ +- rmesa->swtcl.vertex_attr_count++; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \ ++ rmesa->radeon.swtcl.vertex_attr_count++; \ + fmt_0 |= F0; \ + } while (0) + + #define EMIT_PAD( N ) \ + do { \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = 0; \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = EMIT_PAD; \ +- rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].offset = (N); \ +- rmesa->swtcl.vertex_attr_count++; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = 0; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = EMIT_PAD; \ ++ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].offset = (N); \ ++ rmesa->radeon.swtcl.vertex_attr_count++; \ + } while (0) + + static GLuint radeon_cp_vc_frmts[3][2] = +@@ -87,7 +85,7 @@ static GLuint radeon_cp_vc_frmts[3][2] = + + static void radeonSetVertexFormat( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); ++ r100ContextPtr rmesa = R100_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + DECLARE_RENDERINPUTS(index_bitset); +@@ -106,7 +104,7 @@ static void radeonSetVertexFormat( GLcontext *ctx ) + } + + assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL ); +- rmesa->swtcl.vertex_attr_count = 0; ++ rmesa->radeon.swtcl.vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. +@@ -204,33 +202,33 @@ static void radeonSetVertexFormat( GLcontext *ctx ) + } + } + +- if (!RENDERINPUTS_EQUAL( rmesa->tnl_index_bitset, index_bitset ) || ++ if (!RENDERINPUTS_EQUAL( rmesa->radeon.tnl_index_bitset, index_bitset ) || + fmt_0 != rmesa->swtcl.vertex_format) { + RADEON_NEWPRIM(rmesa); + rmesa->swtcl.vertex_format = fmt_0; +- rmesa->swtcl.vertex_size = ++ rmesa->radeon.swtcl.vertex_size = + _tnl_install_attrs( ctx, +- rmesa->swtcl.vertex_attrs, +- rmesa->swtcl.vertex_attr_count, ++ rmesa->radeon.swtcl.vertex_attrs, ++ rmesa->radeon.swtcl.vertex_attr_count, + NULL, 0 ); +- rmesa->swtcl.vertex_size /= 4; +- RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset ); ++ rmesa->radeon.swtcl.vertex_size /= 4; ++ RENDERINPUTS_COPY( rmesa->radeon.tnl_index_bitset, index_bitset ); + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf( stderr, "%s: vertex_size= %d floats\n", +- __FUNCTION__, rmesa->swtcl.vertex_size); ++ __FUNCTION__, rmesa->radeon.swtcl.vertex_size); + } + } + + + static void radeonRenderStart( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); ++ r100ContextPtr rmesa = R100_CONTEXT( ctx ); + + radeonSetVertexFormat( ctx ); + +- if (rmesa->dma.flush != 0 && +- rmesa->dma.flush != flush_last_swtcl_prim) +- rmesa->dma.flush( rmesa ); ++ if (rmesa->radeon.dma.flush != 0 && ++ rmesa->radeon.dma.flush != rcommon_flush_last_swtcl_prim) ++ rmesa->radeon.dma.flush( ctx ); + } + + +@@ -241,7 +239,7 @@ static void radeonRenderStart( GLcontext *ctx ) + */ + void radeonChooseVertexState( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); ++ r100ContextPtr rmesa = R100_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT]; +@@ -254,7 +252,7 @@ void radeonChooseVertexState( GLcontext *ctx ) + * rasterization fallback. As this function will be called again when we + * leave a rasterization fallback, we can just skip it for now. + */ +- if (rmesa->Fallback != 0) ++ if (rmesa->radeon.Fallback != 0) + return; + + /* HW perspective divide is a win, but tiny vertex formats are a +@@ -281,80 +279,29 @@ void radeonChooseVertexState( GLcontext *ctx ) + } + } + +- +-/* Flush vertices in the current dma region. +- */ +-static void flush_last_swtcl_prim( radeonContextPtr rmesa ) ++void r100_swtcl_flush(GLcontext *ctx, uint32_t current_offset) + { +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- rmesa->dma.flush = NULL; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + +- if (rmesa->dma.current.buf) { +- struct radeon_dma_region *current = &rmesa->dma.current; +- GLuint current_offset = (rmesa->radeonScreen->gart_buffer_offset + +- current->buf->buf->idx * RADEON_BUFFER_SIZE + +- current->start); ++ rcommonEnsureCmdBufSpace(&rmesa->radeon, ++ rmesa->radeon.hw.max_state_size + (12*sizeof(int)), ++ __FUNCTION__); + +- assert (!(rmesa->swtcl.hw_primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); + +- assert (current->start + +- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == +- current->ptr); ++ radeonEmitState(&rmesa->radeon); ++ radeonEmitVertexAOS( rmesa, ++ rmesa->radeon.swtcl.vertex_size, ++ rmesa->radeon.dma.current, ++ current_offset); + +- if (rmesa->dma.current.start != rmesa->dma.current.ptr) { +- radeonEnsureCmdBufSpace( rmesa, VERT_AOS_BUFSZ + +- rmesa->hw.max_state_size + VBUF_BUFSZ ); +- +- radeonEmitVertexAOS( rmesa, +- rmesa->swtcl.vertex_size, +- current_offset); +- +- radeonEmitVbufPrim( rmesa, +- rmesa->swtcl.vertex_format, +- rmesa->swtcl.hw_primitive, +- rmesa->swtcl.numverts); +- } ++ ++ radeonEmitVbufPrim( rmesa, ++ rmesa->swtcl.vertex_format, ++ rmesa->radeon.swtcl.hw_primitive, ++ rmesa->radeon.swtcl.numverts); + +- rmesa->swtcl.numverts = 0; +- current->start = current->ptr; +- } + } + +- +-/* Alloc space in the current dma region. +- */ +-static INLINE void * +-radeonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) +-{ +- GLuint bytes = vsize * nverts; +- +- if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) +- radeonRefillCurrentDmaRegion( rmesa ); +- +- if (!rmesa->dma.flush) { +- rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; +- rmesa->dma.flush = flush_last_swtcl_prim; +- } +- +- assert( vsize == rmesa->swtcl.vertex_size * 4 ); +- assert( rmesa->dma.flush == flush_last_swtcl_prim ); +- assert (rmesa->dma.current.start + +- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == +- rmesa->dma.current.ptr); +- +- +- { +- GLubyte *head = (GLubyte *)(rmesa->dma.current.address + rmesa->dma.current.ptr); +- rmesa->dma.current.ptr += bytes; +- rmesa->swtcl.numverts += nverts; +- return head; +- } +- +-} +- +- + /* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. +@@ -387,22 +334,22 @@ static const GLuint hw_prim[GL_POLYGON+1] = { + }; + + static INLINE void +-radeonDmaPrimitive( radeonContextPtr rmesa, GLenum prim ) ++radeonDmaPrimitive( r100ContextPtr rmesa, GLenum prim ) + { + RADEON_NEWPRIM( rmesa ); +- rmesa->swtcl.hw_primitive = hw_prim[prim]; +- assert(rmesa->dma.current.ptr == rmesa->dma.current.start); ++ rmesa->radeon.swtcl.hw_primitive = hw_prim[prim]; ++ // assert(rmesa->radeon.dma.current.ptr == rmesa->radeon.dma.current.start); + } + +-#define LOCAL_VARS radeonContextPtr rmesa = RADEON_CONTEXT(ctx) ++#define LOCAL_VARS r100ContextPtr rmesa = R100_CONTEXT(ctx) + #define INIT( prim ) radeonDmaPrimitive( rmesa, prim ) + #define FLUSH() RADEON_NEWPRIM( rmesa ) +-#define GET_CURRENT_VB_MAX_VERTS() \ +- (((int)rmesa->dma.current.end - (int)rmesa->dma.current.ptr) / (rmesa->swtcl.vertex_size*4)) ++#define GET_CURRENT_VB_MAX_VERTS() 10\ ++// (((int)rmesa->radeon.dma.current.end - (int)rmesa->radeon.dma.current.ptr) / (rmesa->radeon.swtcl.vertex_size*4)) + #define GET_SUBSEQUENT_VB_MAX_VERTS() \ +- ((RADEON_BUFFER_SIZE) / (rmesa->swtcl.vertex_size*4)) ++ ((RADEON_BUFFER_SIZE) / (rmesa->radeon.swtcl.vertex_size*4)) + #define ALLOC_VERTS( nr ) \ +- radeonAllocDmaLowVerts( rmesa, nr, rmesa->swtcl.vertex_size * 4 ) ++ rcommonAllocDmaLowVerts( &rmesa->radeon, nr, rmesa->radeon.swtcl.vertex_size * 4 ) + #define EMIT_VERTS( ctx, j, nr, buf ) \ + _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf) + +@@ -418,16 +365,13 @@ radeonDmaPrimitive( radeonContextPtr rmesa, GLenum prim ) + static GLboolean radeon_run_render( GLcontext *ctx, + struct tnl_pipeline_stage *stage ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + tnl_render_func *tab = TAG(render_tab_verts); + GLuint i; + +- if (rmesa->swtcl.indexed_verts.buf) +- RELEASE_ELT_VERTS(); +- +- if (rmesa->swtcl.RenderIndex != 0 || ++ if (rmesa->radeon.swtcl.RenderIndex != 0 || + !radeon_dma_validate_render( ctx, VB )) + return GL_TRUE; + +@@ -496,13 +440,13 @@ static void radeonResetLineStipple( GLcontext *ctx ); + + #undef LOCAL_VARS + #undef ALLOC_VERTS +-#define CTX_ARG radeonContextPtr rmesa +-#define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size +-#define ALLOC_VERTS( n, size ) radeonAllocDmaLowVerts( rmesa, n, (size) * 4 ) ++#define CTX_ARG r100ContextPtr rmesa ++#define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size ++#define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, (size) * 4 ) + #undef LOCAL_VARS + #define LOCAL_VARS \ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ +- const char *radeonverts = (char *)rmesa->swtcl.verts; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); \ ++ const char *radeonverts = (char *)rmesa->radeon.swtcl.verts; + #define VERT(x) (radeonVertex *)(radeonverts + ((x) * (vertsize) * sizeof(int))) + #define VERTEX radeonVertex + #undef TAG +@@ -560,7 +504,7 @@ static struct { + #define VERT_Y(_v) _v->v.y + #define VERT_Z(_v) _v->v.z + #define AREA_IS_CCW( a ) (a < 0) +-#define GET_VERTEX(e) (rmesa->swtcl.verts + ((e) * rmesa->swtcl.vertex_size * sizeof(int))) ++#define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + ((e) * rmesa->radeon.swtcl.vertex_size * sizeof(int))) + + #define VERT_SET_RGBA( v, c ) \ + do { \ +@@ -606,7 +550,7 @@ do { \ + #undef INIT + + #define LOCAL_VARS(n) \ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = rmesa->swtcl.coloroffset; \ + GLuint specoffset = rmesa->swtcl.specoffset; \ +@@ -617,7 +561,7 @@ do { \ + ***********************************************************************/ + + #define RASTERIZE(x) radeonRasterPrimitive( ctx, reduced_hw_prim[x] ) +-#define RENDER_PRIMITIVE rmesa->swtcl.render_primitive ++#define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive + #undef TAG + #define TAG(x) x + #include "tnl_dd/t_dd_unfilled.h" +@@ -673,9 +617,9 @@ static void init_rast_tab( void ) + } while (0) + #undef LOCAL_VARS + #define LOCAL_VARS \ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ +- const GLuint vertsize = rmesa->swtcl.vertex_size; \ +- const char *radeonverts = (char *)rmesa->swtcl.verts; \ ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); \ ++ const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \ ++ const char *radeonverts = (char *)rmesa->radeon.swtcl.verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) elt; (void) stipple; +@@ -700,17 +644,17 @@ static void init_rast_tab( void ) + void radeonChooseRenderState( GLcontext *ctx ) + { + TNLcontext *tnl = TNL_CONTEXT(ctx); +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint index = 0; + GLuint flags = ctx->_TriangleCaps; + +- if (!rmesa->TclFallback || rmesa->Fallback) ++ if (!rmesa->radeon.TclFallback || rmesa->radeon.Fallback) + return; + + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= RADEON_TWOSIDE_BIT; + if (flags & DD_TRI_UNFILLED) index |= RADEON_UNFILLED_BIT; + +- if (index != rmesa->swtcl.RenderIndex) { ++ if (index != rmesa->radeon.swtcl.RenderIndex) { + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; +@@ -727,7 +671,7 @@ void radeonChooseRenderState( GLcontext *ctx ) + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + } + +- rmesa->swtcl.RenderIndex = index; ++ rmesa->radeon.swtcl.RenderIndex = index; + } + } + +@@ -739,18 +683,18 @@ void radeonChooseRenderState( GLcontext *ctx ) + + static void radeonRasterPrimitive( GLcontext *ctx, GLuint hwprim ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + +- if (rmesa->swtcl.hw_primitive != hwprim) { ++ if (rmesa->radeon.swtcl.hw_primitive != hwprim) { + RADEON_NEWPRIM( rmesa ); +- rmesa->swtcl.hw_primitive = hwprim; ++ rmesa->radeon.swtcl.hw_primitive = hwprim; + } + } + + static void radeonRenderPrimitive( GLcontext *ctx, GLenum prim ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- rmesa->swtcl.render_primitive = prim; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ rmesa->radeon.swtcl.render_primitive = prim; + if (prim < GL_TRIANGLES || !(ctx->_TriangleCaps & DD_TRI_UNFILLED)) + radeonRasterPrimitive( ctx, reduced_hw_prim[prim] ); + } +@@ -761,7 +705,7 @@ static void radeonRenderFinish( GLcontext *ctx ) + + static void radeonResetLineStipple( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + RADEON_STATECHANGE( rmesa, lin ); + } + +@@ -795,17 +739,17 @@ static const char *getFallbackString(GLuint bit) + + void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); +- GLuint oldfallback = rmesa->Fallback; ++ GLuint oldfallback = rmesa->radeon.Fallback; + + if (mode) { +- rmesa->Fallback |= bit; ++ rmesa->radeon.Fallback |= bit; + if (oldfallback == 0) { +- RADEON_FIREVERTICES( rmesa ); ++ radeon_firevertices(&rmesa->radeon); + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_TRUE ); + _swsetup_Wakeup( ctx ); +- rmesa->swtcl.RenderIndex = ~0; ++ rmesa->radeon.swtcl.RenderIndex = ~0; + if (RADEON_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "Radeon begin rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); +@@ -813,7 +757,7 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + } + } + else { +- rmesa->Fallback &= ~bit; ++ rmesa->radeon.Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + tnl->Driver.Render.Start = radeonRenderStart; +@@ -826,14 +770,14 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + + tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple; + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_FALSE ); +- if (rmesa->TclFallback) { +- /* These are already done if rmesa->TclFallback goes to ++ if (rmesa->radeon.TclFallback) { ++ /* These are already done if rmesa->radeon.TclFallback goes to + * zero above. But not if it doesn't (RADEON_NO_TCL for + * example?) + */ + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); +- RENDERINPUTS_ZERO( rmesa->tnl_index_bitset ); ++ RENDERINPUTS_ZERO( rmesa->radeon.tnl_index_bitset ); + radeonChooseVertexState( ctx ); + radeonChooseRenderState( ctx ); + } +@@ -853,7 +797,7 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + void radeonInitSwtcl( GLcontext *ctx ) + { + TNLcontext *tnl = TNL_CONTEXT(ctx); +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { +@@ -872,18 +816,9 @@ void radeonInitSwtcl( GLcontext *ctx ) + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, + RADEON_MAX_TNL_VERTEX_SIZE); + +- rmesa->swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf; +- rmesa->swtcl.RenderIndex = ~0; +- rmesa->swtcl.render_primitive = GL_TRIANGLES; +- rmesa->swtcl.hw_primitive = 0; ++ rmesa->radeon.swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf; ++ rmesa->radeon.swtcl.RenderIndex = ~0; ++ rmesa->radeon.swtcl.render_primitive = GL_TRIANGLES; ++ rmesa->radeon.swtcl.hw_primitive = 0; + } + +- +-void radeonDestroySwtcl( GLcontext *ctx ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- +- if (rmesa->swtcl.indexed_verts.buf) +- radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, +- __FUNCTION__ ); +-} +diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.h b/src/mesa/drivers/dri/radeon/radeon_swtcl.h +index e485052..da89158 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.h ++++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.h +@@ -40,7 +40,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "radeon_context.h" + + extern void radeonInitSwtcl( GLcontext *ctx ); +-extern void radeonDestroySwtcl( GLcontext *ctx ); + + extern void radeonChooseRenderState( GLcontext *ctx ); + extern void radeonChooseVertexState( GLcontext *ctx ); +@@ -63,5 +62,5 @@ extern void radeon_translate_vertex( GLcontext *ctx, + + extern void radeon_print_vertex( GLcontext *ctx, const radeonVertex *v ); + +- ++extern void r100_swtcl_flush(GLcontext *ctx, uint32_t current_offset); + #endif +diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c +index 779e9ae..df6708f 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_tcl.c ++++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c +@@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "tnl/tnl.h" + #include "tnl/t_pipeline.h" + ++#include "radeon_common.h" + #include "radeon_context.h" + #include "radeon_state.h" + #include "radeon_ioctl.h" +@@ -104,7 +105,7 @@ static GLboolean discrete_prim[0x10] = { + }; + + +-#define LOCAL_VARS radeonContextPtr rmesa = RADEON_CONTEXT(ctx) ++#define LOCAL_VARS r100ContextPtr rmesa = R100_CONTEXT(ctx) + #define ELT_TYPE GLushort + + #define ELT_INIT(prim, hw_prim) \ +@@ -125,7 +126,7 @@ static GLboolean discrete_prim[0x10] = { + + #define RESET_STIPPLE() do { \ + RADEON_STATECHANGE( rmesa, lin ); \ +- radeonEmitState( rmesa ); \ ++ radeonEmitState(&rmesa->radeon); \ + } while (0) + + #define AUTO_STIPPLE( mode ) do { \ +@@ -136,31 +137,29 @@ static GLboolean discrete_prim[0x10] = { + else \ + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \ + ~RADEON_LINE_PATTERN_AUTO_RESET; \ +- radeonEmitState( rmesa ); \ ++ radeonEmitState(&rmesa->radeon); \ + } while (0) + + + + #define ALLOC_ELTS(nr) radeonAllocElts( rmesa, nr ) + +-static GLushort *radeonAllocElts( radeonContextPtr rmesa, GLuint nr ) ++static GLushort *radeonAllocElts( r100ContextPtr rmesa, GLuint nr ) + { +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); ++ if (rmesa->radeon.dma.flush) ++ rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); + +- radeonEnsureCmdBufSpace(rmesa, AOS_BUFSZ(rmesa->tcl.nr_aos_components) + +- rmesa->hw.max_state_size + ELTS_BUFSZ(nr)); ++ rcommonEnsureCmdBufSpace(&rmesa->radeon, rmesa->radeon.hw.max_state_size + ELTS_BUFSZ(nr) + ++ AOS_BUFSZ(rmesa->radeon.tcl.aos_count), __FUNCTION__); + +- radeonEmitAOS( rmesa, +- rmesa->tcl.aos_components, +- rmesa->tcl.nr_aos_components, 0 ); ++ radeonEmitAOS( rmesa, ++ rmesa->radeon.tcl.aos_count, 0 ); + +- return radeonAllocEltsOpenEnded( rmesa, +- rmesa->tcl.vertex_format, +- rmesa->tcl.hw_primitive, nr ); ++ return radeonAllocEltsOpenEnded( rmesa, rmesa->tcl.vertex_format, ++ rmesa->tcl.hw_primitive, nr ); + } + +-#define CLOSE_ELTS() RADEON_NEWPRIM( rmesa ) ++#define CLOSE_ELTS() if (0) RADEON_NEWPRIM( rmesa ) + + + +@@ -174,15 +173,15 @@ static void radeonEmitPrim( GLcontext *ctx, + GLuint start, + GLuint count) + { +- radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); ++ r100ContextPtr rmesa = R100_CONTEXT( ctx ); + radeonTclPrimitive( ctx, prim, hwprim ); + +- radeonEnsureCmdBufSpace( rmesa, AOS_BUFSZ(rmesa->tcl.nr_aos_components) + +- rmesa->hw.max_state_size + VBUF_BUFSZ ); ++ rcommonEnsureCmdBufSpace( &rmesa->radeon, ++ AOS_BUFSZ(rmesa->radeon.tcl.aos_count) + ++ rmesa->radeon.hw.max_state_size + VBUF_BUFSZ, __FUNCTION__ ); + + radeonEmitAOS( rmesa, +- rmesa->tcl.aos_components, +- rmesa->tcl.nr_aos_components, ++ rmesa->radeon.tcl.aos_count, + start ); + + /* Why couldn't this packet have taken an offset param? +@@ -254,7 +253,7 @@ void radeonTclPrimitive( GLcontext *ctx, + GLenum prim, + int hw_prim ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint se_cntl; + GLuint newprim = hw_prim | RADEON_CP_VC_CNTL_TCL_ENABLE; + +@@ -371,7 +370,7 @@ radeonComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord ) + static GLboolean radeon_run_tcl_render( GLcontext *ctx, + struct tnl_pipeline_stage *stage ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0; +@@ -379,7 +378,7 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx, + + /* TODO: separate this from the swtnl pipeline + */ +- if (rmesa->TclFallback) ++ if (rmesa->radeon.TclFallback) + return GL_TRUE; /* fallback to software t&l */ + + if (VB->Count == 0) +@@ -461,7 +460,7 @@ const struct tnl_pipeline_stage _radeon_tcl_stage = + + static void transition_to_swtnl( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint se_cntl; + +@@ -490,7 +489,7 @@ static void transition_to_swtnl( GLcontext *ctx ) + + static void transition_to_hwtnl( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT]; + +@@ -509,15 +508,15 @@ static void transition_to_hwtnl( GLcontext *ctx ) + + tnl->Driver.NotifyMaterialChange = radeonUpdateMaterial; + +- if ( rmesa->dma.flush ) +- rmesa->dma.flush( rmesa ); ++ if ( rmesa->radeon.dma.flush ) ++ rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); + +- rmesa->dma.flush = NULL; ++ rmesa->radeon.dma.flush = NULL; + rmesa->swtcl.vertex_format = 0; + +- if (rmesa->swtcl.indexed_verts.buf) +- radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, +- __FUNCTION__ ); ++ // if (rmesa->swtcl.indexed_verts.buf) ++ // radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, ++ // __FUNCTION__ ); + + if (RADEON_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "Radeon end tcl fallback\n"); +@@ -550,11 +549,11 @@ static char *getFallbackString(GLuint bit) + + void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- GLuint oldfallback = rmesa->TclFallback; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ GLuint oldfallback = rmesa->radeon.TclFallback; + + if (mode) { +- rmesa->TclFallback |= bit; ++ rmesa->radeon.TclFallback |= bit; + if (oldfallback == 0) { + if (RADEON_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "Radeon begin tcl fallback %s\n", +@@ -563,7 +562,7 @@ void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) + } + } + else { +- rmesa->TclFallback &= ~bit; ++ rmesa->radeon.TclFallback &= ~bit; + if (oldfallback == bit) { + if (RADEON_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "Radeon end tcl fallback %s\n", +diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c +index b0aec21..21509c6 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_tex.c ++++ b/src/mesa/drivers/dri/radeon/radeon_tex.c +@@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/texobj.h" + + #include "radeon_context.h" ++#include "radeon_mipmap_tree.h" + #include "radeon_state.h" + #include "radeon_ioctl.h" + #include "radeon_swtcl.h" +@@ -170,10 +171,13 @@ static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf ) + { + GLuint anisotropy = (t->pp_txfilter & RADEON_MAX_ANISO_MASK); + ++ /* Force revalidation to account for switches from/to mipmapping. */ ++ t->validated = GL_FALSE; ++ + t->pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK); + + /* r100 chips can't handle mipmaps/aniso for cubemap/volume textures */ +- if ( t->base.tObj->Target == GL_TEXTURE_CUBE_MAP ) { ++ if ( t->base.Target == GL_TEXTURE_CUBE_MAP ) { + switch ( minf ) { + case GL_NEAREST: + case GL_NEAREST_MIPMAP_NEAREST: +@@ -244,433 +248,13 @@ static void radeonSetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] ) + t->pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); + } + +- +-/** +- * Allocate space for and load the mesa images into the texture memory block. +- * This will happen before drawing with a new texture, or drawing with a +- * texture after it was swapped out or teximaged again. +- */ +- +-static radeonTexObjPtr radeonAllocTexObj( struct gl_texture_object *texObj ) +-{ +- radeonTexObjPtr t; +- +- t = CALLOC_STRUCT( radeon_tex_obj ); +- texObj->DriverData = t; +- if ( t != NULL ) { +- if ( RADEON_DEBUG & DEBUG_TEXTURE ) { +- fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, (void *)texObj, (void *)t ); +- } +- +- /* Initialize non-image-dependent parts of the state: +- */ +- t->base.tObj = texObj; +- t->border_fallback = GL_FALSE; +- +- t->pp_txfilter = RADEON_BORDER_MODE_OGL; +- t->pp_txformat = (RADEON_TXFORMAT_ENDIAN_NO_SWAP | +- RADEON_TXFORMAT_PERSPECTIVE_ENABLE); +- +- make_empty_list( & t->base ); +- +- radeonSetTexWrap( t, texObj->WrapS, texObj->WrapT ); +- radeonSetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); +- radeonSetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); +- radeonSetTexBorderColor( t, texObj->_BorderChan ); +- } +- +- return t; +-} +- +- +-static const struct gl_texture_format * +-radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, +- GLenum format, GLenum type ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- const GLboolean do32bpt = +- ( rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32 ); +- const GLboolean force16bpt = +- ( rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16 ); +- (void) format; +- +- switch ( internalFormat ) { +- case 4: +- case GL_RGBA: +- case GL_COMPRESSED_RGBA: +- switch ( type ) { +- case GL_UNSIGNED_INT_10_10_10_2: +- case GL_UNSIGNED_INT_2_10_10_10_REV: +- return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_argb1555; +- case GL_UNSIGNED_SHORT_4_4_4_4: +- case GL_UNSIGNED_SHORT_4_4_4_4_REV: +- return _dri_texformat_argb4444; +- case GL_UNSIGNED_SHORT_5_5_5_1: +- case GL_UNSIGNED_SHORT_1_5_5_5_REV: +- return _dri_texformat_argb1555; +- default: +- return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_argb4444; +- } +- +- case 3: +- case GL_RGB: +- case GL_COMPRESSED_RGB: +- switch ( type ) { +- case GL_UNSIGNED_SHORT_4_4_4_4: +- case GL_UNSIGNED_SHORT_4_4_4_4_REV: +- return _dri_texformat_argb4444; +- case GL_UNSIGNED_SHORT_5_5_5_1: +- case GL_UNSIGNED_SHORT_1_5_5_5_REV: +- return _dri_texformat_argb1555; +- case GL_UNSIGNED_SHORT_5_6_5: +- case GL_UNSIGNED_SHORT_5_6_5_REV: +- return _dri_texformat_rgb565; +- default: +- return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565; +- } +- +- case GL_RGBA8: +- case GL_RGB10_A2: +- case GL_RGBA12: +- case GL_RGBA16: +- return !force16bpt ? +- _dri_texformat_argb8888 : _dri_texformat_argb4444; +- +- case GL_RGBA4: +- case GL_RGBA2: +- return _dri_texformat_argb4444; +- +- case GL_RGB5_A1: +- return _dri_texformat_argb1555; +- +- case GL_RGB8: +- case GL_RGB10: +- case GL_RGB12: +- case GL_RGB16: +- return !force16bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565; +- +- case GL_RGB5: +- case GL_RGB4: +- case GL_R3_G3_B2: +- return _dri_texformat_rgb565; +- +- case GL_ALPHA: +- case GL_ALPHA4: +- case GL_ALPHA8: +- case GL_ALPHA12: +- case GL_ALPHA16: +- case GL_COMPRESSED_ALPHA: +- return _dri_texformat_a8; +- +- case 1: +- case GL_LUMINANCE: +- case GL_LUMINANCE4: +- case GL_LUMINANCE8: +- case GL_LUMINANCE12: +- case GL_LUMINANCE16: +- case GL_COMPRESSED_LUMINANCE: +- return _dri_texformat_l8; +- +- case 2: +- case GL_LUMINANCE_ALPHA: +- case GL_LUMINANCE4_ALPHA4: +- case GL_LUMINANCE6_ALPHA2: +- case GL_LUMINANCE8_ALPHA8: +- case GL_LUMINANCE12_ALPHA4: +- case GL_LUMINANCE12_ALPHA12: +- case GL_LUMINANCE16_ALPHA16: +- case GL_COMPRESSED_LUMINANCE_ALPHA: +- return _dri_texformat_al88; +- +- case GL_INTENSITY: +- case GL_INTENSITY4: +- case GL_INTENSITY8: +- case GL_INTENSITY12: +- case GL_INTENSITY16: +- case GL_COMPRESSED_INTENSITY: +- return _dri_texformat_i8; +- +- case GL_YCBCR_MESA: +- if (type == GL_UNSIGNED_SHORT_8_8_APPLE || +- type == GL_UNSIGNED_BYTE) +- return &_mesa_texformat_ycbcr; +- else +- return &_mesa_texformat_ycbcr_rev; +- +- case GL_RGB_S3TC: +- case GL_RGB4_S3TC: +- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: +- return &_mesa_texformat_rgb_dxt1; +- +- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: +- return &_mesa_texformat_rgba_dxt1; +- +- case GL_RGBA_S3TC: +- case GL_RGBA4_S3TC: +- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: +- return &_mesa_texformat_rgba_dxt3; +- +- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: +- return &_mesa_texformat_rgba_dxt5; +- +- default: +- _mesa_problem(ctx, "unexpected texture format in %s", __FUNCTION__); +- return NULL; +- } +- +- return NULL; /* never get here */ +-} +- +- +-static void radeonTexImage1D( GLcontext *ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint border, +- GLenum format, GLenum type, const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) radeonAllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); +- return; +- } +- } +- +- /* Note, this will call ChooseTextureFormat */ +- _mesa_store_teximage1d(ctx, target, level, internalFormat, +- width, border, format, type, pixels, +- &ctx->Unpack, texObj, texImage); +- +- t->dirty_images[0] |= (1 << level); +-} +- +- +-static void radeonTexSubImage1D( GLcontext *ctx, GLenum target, GLint level, +- GLint xoffset, +- GLsizei width, +- GLenum format, GLenum type, +- const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- +- assert( t ); /* this _should_ be true */ +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) radeonAllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); +- return; +- } +- } +- +- _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, +- format, type, pixels, packing, texObj, +- texImage); +- +- t->dirty_images[0] |= (1 << level); +-} +- +- +-static void radeonTexImage2D( GLcontext *ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint height, GLint border, +- GLenum format, GLenum type, const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- if ( t != NULL ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) radeonAllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); +- return; +- } +- } +- +- /* Note, this will call ChooseTextureFormat */ +- _mesa_store_teximage2d(ctx, target, level, internalFormat, +- width, height, border, format, type, pixels, +- &ctx->Unpack, texObj, texImage); +- +- t->dirty_images[face] |= (1 << level); +-} +- +- +-static void radeonTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, +- GLint xoffset, GLint yoffset, +- GLsizei width, GLsizei height, +- GLenum format, GLenum type, +- const GLvoid *pixels, +- const struct gl_pixelstore_attrib *packing, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- assert( t ); /* this _should_ be true */ +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) radeonAllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); +- return; +- } +- } +- +- _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, +- height, format, type, pixels, packing, texObj, +- texImage); +- +- t->dirty_images[face] |= (1 << level); +-} +- +-static void radeonCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, +- GLint internalFormat, +- GLint width, GLint height, GLint border, +- GLsizei imageSize, const GLvoid *data, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- if ( t != NULL ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) radeonAllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); +- return; +- } +- } +- +- /* Note, this will call ChooseTextureFormat */ +- _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width, +- height, border, imageSize, data, texObj, texImage); +- +- t->dirty_images[face] |= (1 << level); +-} +- +- +-static void radeonCompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, +- GLint xoffset, GLint yoffset, +- GLsizei width, GLsizei height, +- GLenum format, +- GLsizei imageSize, const GLvoid *data, +- struct gl_texture_object *texObj, +- struct gl_texture_image *texImage ) +-{ +- driTextureObject * t = (driTextureObject *) texObj->DriverData; +- GLuint face; +- +- +- /* which cube face or ordinary 2D image */ +- switch (target) { +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: +- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; +- ASSERT(face < 6); +- break; +- default: +- face = 0; +- } +- +- assert( t ); /* this _should_ be true */ +- if ( t ) { +- driSwapOutTextureObject( t ); +- } +- else { +- t = (driTextureObject *) radeonAllocTexObj( texObj ); +- if (!t) { +- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D"); +- return; +- } +- } +- +- _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width, +- height, format, imageSize, data, texObj, texImage); +- +- t->dirty_images[face] |= (1 << level); +-} +- + #define SCALED_FLOAT_TO_BYTE( x, scale ) \ + (((GLuint)((255.0F / scale) * (x))) / 2) + + static void radeonTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + +@@ -701,7 +285,7 @@ static void radeonTexEnv( GLcontext *ctx, GLenum target, + * functions, one mapping [-1.0,0.0] to [-128,0] and one mapping + * [0.0,4.0] to [0,127]. + */ +- min = driQueryOptionb (&rmesa->optionCache, "no_neg_lod_bias") ? ++ min = driQueryOptionb (&rmesa->radeon.optionCache, "no_neg_lod_bias") ? + 0.0 : -1.0; + bias = CLAMP( *param, min, 4.0 ); + if ( bias == 0 ) { +@@ -734,7 +318,7 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params ) + { +- radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; ++ radeonTexObj* t = radeon_tex_obj(texObj); + + if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { + fprintf( stderr, "%s( %s )\n", __FUNCTION__, +@@ -762,57 +346,51 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target, + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: ++ + /* This isn't the most efficient solution but there doesn't appear to + * be a nice alternative. Since there's no LOD clamping, + * we just have to rely on loading the right subset of mipmap levels + * to simulate a clamped LOD. + */ +- driSwapOutTextureObject( (driTextureObject *) t ); ++ if (t->mt) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = 0; ++ t->validated = GL_FALSE; ++ } + break; + + default: + return; + } +- +- /* Mark this texobj as dirty (one bit per tex unit) +- */ +- t->dirty_state = TEX_ALL; +-} +- +- +-static void radeonBindTexture( GLcontext *ctx, GLenum target, +- struct gl_texture_object *texObj ) +-{ +- if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { +- fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, (void *)texObj, +- ctx->Texture.CurrentUnit ); +- } +- +- assert( (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D && +- target != GL_TEXTURE_RECTANGLE_NV && target != GL_TEXTURE_CUBE_MAP) || +- (texObj->DriverData != NULL) ); + } + +- + static void radeonDeleteTexture( GLcontext *ctx, + struct gl_texture_object *texObj ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- driTextureObject * t = (driTextureObject *) texObj->DriverData; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ radeonTexObj* t = radeon_tex_obj(texObj); ++ int i; + + if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { + fprintf( stderr, "%s( %p (target = %s) )\n", __FUNCTION__, (void *)texObj, + _mesa_lookup_enum_by_nr( texObj->Target ) ); + } + +- if ( t != NULL ) { +- if ( rmesa ) { +- RADEON_FIREVERTICES( rmesa ); +- } +- +- driDestroyTextureObject( t ); ++ if ( rmesa ) { ++ radeon_firevertices(&rmesa->radeon); ++ for ( i = 0 ; i < rmesa->radeon.glCtx->Const.MaxTextureUnits ; i++ ) { ++ if ( t == rmesa->state.texture.unit[i].texobj ) { ++ rmesa->state.texture.unit[i].texobj = NULL; ++ rmesa->hw.tex[i].dirty = GL_FALSE; ++ rmesa->hw.cube[i].dirty = GL_FALSE; ++ } ++ } + } + ++ if (t->mt) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = 0; ++ } + /* Free mipmap images and the texture object itself */ + _mesa_delete_texture_object(ctx, texObj); + } +@@ -832,7 +410,7 @@ static void radeonTexGen( GLcontext *ctx, + GLenum pname, + const GLfloat *params ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint unit = ctx->Texture.CurrentUnit; + rmesa->recheck_texgen[unit] = GL_TRUE; + } +@@ -846,29 +424,40 @@ static void radeonTexGen( GLcontext *ctx, + static struct gl_texture_object * + radeonNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- struct gl_texture_object *obj; +- obj = _mesa_new_texture_object(ctx, name, target); +- if (!obj) +- return NULL; +- obj->MaxAnisotropy = rmesa->initialMaxAnisotropy; +- radeonAllocTexObj( obj ); +- return obj; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj); ++ ++ _mesa_initialize_texture_object(&t->base, name, target); ++ t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy; ++ ++ t->border_fallback = GL_FALSE; ++ ++ t->pp_txfilter = RADEON_BORDER_MODE_OGL; ++ t->pp_txformat = (RADEON_TXFORMAT_ENDIAN_NO_SWAP | ++ RADEON_TXFORMAT_PERSPECTIVE_ENABLE); ++ ++ radeonSetTexWrap( t, t->base.WrapS, t->base.WrapT ); ++ radeonSetTexMaxAnisotropy( t, t->base.MaxAnisotropy ); ++ radeonSetTexFilter( t, t->base.MinFilter, t->base.MagFilter ); ++ radeonSetTexBorderColor( t, t->base._BorderChan ); ++ return &t->base; + } + + ++ + void radeonInitTextureFuncs( struct dd_function_table *functions ) + { +- functions->ChooseTextureFormat = radeonChooseTextureFormat; ++ functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; + functions->TexImage1D = radeonTexImage1D; + functions->TexImage2D = radeonTexImage2D; + functions->TexSubImage1D = radeonTexSubImage1D; + functions->TexSubImage2D = radeonTexSubImage2D; ++ functions->GetTexImage = radeonGetTexImage; ++ functions->GetCompressedTexImage = radeonGetCompressedTexImage; + + functions->NewTextureObject = radeonNewTextureObject; +- functions->BindTexture = radeonBindTexture; ++ // functions->BindTexture = radeonBindTexture; + functions->DeleteTexture = radeonDeleteTexture; +- functions->IsTextureResident = driIsTextureResident; + + functions->TexEnv = radeonTexEnv; + functions->TexParameter = radeonTexParameter; +@@ -877,5 +466,12 @@ void radeonInitTextureFuncs( struct dd_function_table *functions ) + functions->CompressedTexImage2D = radeonCompressedTexImage2D; + functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + ++ functions->GenerateMipmap = radeonGenerateMipmap; ++ ++ functions->NewTextureImage = radeonNewTextureImage; ++ functions->FreeTexImageData = radeonFreeTexImageData; ++ functions->MapTexture = radeonMapTexture; ++ functions->UnmapTexture = radeonUnmapTexture; ++ + driInitTextureFormats(); + } +diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.h b/src/mesa/drivers/dri/radeon/radeon_tex.h +index 8000880..a4aaddc 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_tex.h ++++ b/src/mesa/drivers/dri/radeon/radeon_tex.h +@@ -41,12 +41,16 @@ extern void radeonSetTexOffset(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, + GLuint pitch); + ++extern void radeonSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv); ++extern void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, ++ __DRIdrawable *dPriv); ++ + extern void radeonUpdateTextureState( GLcontext *ctx ); + +-extern int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, ++extern int radeonUploadTexImages( r100ContextPtr rmesa, radeonTexObjPtr t, + GLuint face ); + +-extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ); ++extern void radeonDestroyTexObj( r100ContextPtr rmesa, radeonTexObjPtr t ); + + extern void radeonInitTextureFuncs( struct dd_function_table *functions ); + +diff --git a/src/mesa/drivers/dri/radeon/radeon_texmem.c b/src/mesa/drivers/dri/radeon/radeon_texmem.c +deleted file mode 100644 +index 5f7bbe6..0000000 +--- a/src/mesa/drivers/dri/radeon/radeon_texmem.c ++++ /dev/null +@@ -1,404 +0,0 @@ +-/************************************************************************** +- +-Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and +- VA Linux Systems Inc., Fremont, California. +- +-All Rights Reserved. +- +-Permission is hereby granted, free of charge, to any person obtaining +-a copy of this software and associated documentation files (the +-"Software"), to deal in the Software without restriction, including +-without limitation on the rights to use, copy, modify, merge, publish, +-distribute, sub license, and/or sell copies of the Software, and to +-permit persons to whom the Software is furnished to do so, subject to +-the following conditions: +- +-The above copyright notice and this permission notice (including the +-next paragraph) shall be included in all copies or substantial +-portions of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +-NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR THEIR +-SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-SOFTWARE. +- +-**************************************************************************/ +- +-/* +- * Authors: +- * Kevin E. Martin +- * Gareth Hughes +- * +- */ +-#include +- +-#include "main/glheader.h" +-#include "main/imports.h" +-#include "main/context.h" +-#include "main/macros.h" +- +-#include "radeon_context.h" +-#include "radeon_ioctl.h" +-#include "radeon_tex.h" +- +-#include /* for usleep() */ +- +- +-/** +- * Destroy any device-dependent state associated with the texture. This may +- * include NULLing out hardware state that points to the texture. +- */ +-void +-radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) +-{ +- if ( RADEON_DEBUG & DEBUG_TEXTURE ) { +- fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, (void *)t, (void *)t->base.tObj ); +- } +- +- if ( rmesa != NULL ) { +- unsigned i; +- +- +- for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) { +- if ( t == rmesa->state.texture.unit[i].texobj ) { +- rmesa->state.texture.unit[i].texobj = NULL; +- } +- } +- } +-} +- +- +-/* ------------------------------------------------------------ +- * Texture image conversions +- */ +- +- +-static void radeonUploadRectSubImage( radeonContextPtr rmesa, +- radeonTexObjPtr t, +- struct gl_texture_image *texImage, +- GLint x, GLint y, +- GLint width, GLint height ) +-{ +- const struct gl_texture_format *texFormat = texImage->TexFormat; +- int blit_format, dstPitch, done; +- +- switch ( texFormat->TexelBytes ) { +- case 1: +- blit_format = RADEON_GMC_DST_8BPP_CI; +- break; +- case 2: +- blit_format = RADEON_GMC_DST_16BPP; +- break; +- case 4: +- blit_format = RADEON_GMC_DST_32BPP; +- break; +- default: +- fprintf( stderr, "radeonUploadRectSubImage: unknown blit_format (texelbytes=%d)\n", +- texFormat->TexelBytes); +- return; +- } +- +- t->image[0][0].data = texImage->Data; +- +- /* Currently don't need to cope with small pitches. +- */ +- width = texImage->Width; +- height = texImage->Height; +- dstPitch = t->pp_txpitch + 32; +- +- { /* FIXME: prefer GART-texturing if possible */ +- /* Data not in GART memory, or bad pitch. +- */ +- for (done = 0; done < height ; ) { +- struct radeon_dma_region region; +- int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch ); +- int src_pitch; +- char *tex; +- +- src_pitch = texImage->RowStride * texFormat->TexelBytes; +- +- tex = (char *)texImage->Data + done * src_pitch; +- +- memset(®ion, 0, sizeof(region)); +- radeonAllocDmaRegion( rmesa, ®ion, lines * dstPitch, 1024 ); +- +- /* Copy texdata to dma: +- */ +- if (0) +- fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n", +- __FUNCTION__, src_pitch, dstPitch); +- +- if (src_pitch == dstPitch) { +- memcpy( region.address + region.start, tex, lines * src_pitch ); +- } +- else { +- char *buf = region.address + region.start; +- int i; +- for (i = 0 ; i < lines ; i++) { +- memcpy( buf, tex, src_pitch ); +- buf += dstPitch; +- tex += src_pitch; +- } +- } +- +- radeonEmitWait( rmesa, RADEON_WAIT_3D ); +- +- +- +- /* Blit to framebuffer +- */ +- radeonEmitBlit( rmesa, +- blit_format, +- dstPitch, GET_START( ®ion ), +- dstPitch, t->bufAddr, +- 0, 0, +- 0, done, +- width, lines ); +- +- radeonEmitWait( rmesa, RADEON_WAIT_2D ); +- +- radeonReleaseDmaRegion( rmesa, ®ion, __FUNCTION__ ); +- done += lines; +- } +- } +-} +- +- +-/** +- * Upload the texture image associated with texture \a t at the specified +- * level at the address relative to \a start. +- */ +-static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t, +- GLint hwlevel, +- GLint x, GLint y, GLint width, GLint height, +- GLuint face ) +-{ +- struct gl_texture_image *texImage = NULL; +- GLuint offset; +- GLint imageWidth, imageHeight; +- GLint ret; +- drm_radeon_texture_t tex; +- drm_radeon_tex_image_t tmp; +- const int level = hwlevel + t->base.firstLevel; +- +- if ( RADEON_DEBUG & DEBUG_TEXTURE ) { +- fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n", +- __FUNCTION__, (void *)t, (void *)t->base.tObj, level, width, height, face ); +- } +- +- ASSERT(face < 6); +- +- /* Ensure we have a valid texture to upload */ +- if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) { +- _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__); +- return; +- } +- +- texImage = t->base.tObj->Image[face][level]; +- +- if ( !texImage ) { +- if ( RADEON_DEBUG & DEBUG_TEXTURE ) +- fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level ); +- return; +- } +- if ( !texImage->Data ) { +- if ( RADEON_DEBUG & DEBUG_TEXTURE ) +- fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ ); +- return; +- } +- +- +- if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) { +- assert(level == 0); +- assert(hwlevel == 0); +- if ( RADEON_DEBUG & DEBUG_TEXTURE ) +- fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__); +- radeonUploadRectSubImage( rmesa, t, texImage, x, y, width, height ); +- return; +- } +- +- imageWidth = texImage->Width; +- imageHeight = texImage->Height; +- +- offset = t->bufAddr + t->base.totalSize * face / 6; +- +- if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { +- GLint imageX = 0; +- GLint imageY = 0; +- GLint blitX = t->image[face][hwlevel].x; +- GLint blitY = t->image[face][hwlevel].y; +- GLint blitWidth = t->image[face][hwlevel].width; +- GLint blitHeight = t->image[face][hwlevel].height; +- fprintf( stderr, " upload image: %d,%d at %d,%d\n", +- imageWidth, imageHeight, imageX, imageY ); +- fprintf( stderr, " upload blit: %d,%d at %d,%d\n", +- blitWidth, blitHeight, blitX, blitY ); +- fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n", +- (GLuint)offset, hwlevel, level ); +- } +- +- t->image[face][hwlevel].data = texImage->Data; +- +- /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct. +- * NOTE: we're always use a 1KB-wide blit and I8 texture format. +- * We used to use 1, 2 and 4-byte texels and used to use the texture +- * width to dictate the blit width - but that won't work for compressed +- * textures. (Brian) +- * NOTE: can't do that with texture tiling. (sroland) +- */ +- tex.offset = offset; +- tex.image = &tmp; +- /* copy (x,y,width,height,data) */ +- memcpy( &tmp, &t->image[face][hwlevel], sizeof(drm_radeon_tex_image_t) ); +- +- if (texImage->TexFormat->TexelBytes) { +- /* use multi-byte upload scheme */ +- tex.height = imageHeight; +- tex.width = imageWidth; +- tex.format = t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK; +- tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1); +- tex.offset += tmp.x & ~1023; +- tmp.x = tmp.x % 1024; +- if (t->tile_bits & RADEON_TXO_MICRO_TILE_X2) { +- /* need something like "tiled coordinates" ? */ +- tmp.y = tmp.x / (tex.pitch * 128) * 2; +- tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes; +- tex.pitch |= RADEON_DST_TILE_MICRO >> 22; +- } +- else { +- tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1); +- } +- if ((t->tile_bits & RADEON_TXO_MACRO_TILE) && +- (texImage->Width * texImage->TexFormat->TexelBytes >= 256)) { +- /* radeon switches off macro tiling for small textures/mipmaps it seems */ +- tex.pitch |= RADEON_DST_TILE_MACRO >> 22; +- } +- } +- else { +- /* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is +- needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */ +- /* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed +- so the kernel module reads the right amount of data. */ +- tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */ +- tex.pitch = (BLIT_WIDTH_BYTES / 64); +- tex.height = (imageHeight + 3) / 4; +- tex.width = (imageWidth + 3) / 4; +- switch (t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) { +- case RADEON_TXFORMAT_DXT1: +- tex.width *= 8; +- break; +- case RADEON_TXFORMAT_DXT23: +- case RADEON_TXFORMAT_DXT45: +- tex.width *= 16; +- break; +- } +- } +- +- LOCK_HARDWARE( rmesa ); +- do { +- ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE, +- &tex, sizeof(drm_radeon_texture_t) ); +- } while ( ret == -EAGAIN ); +- +- UNLOCK_HARDWARE( rmesa ); +- +- if ( ret ) { +- fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret ); +- fprintf( stderr, " offset=0x%08x\n", +- offset ); +- fprintf( stderr, " image width=%d height=%d\n", +- imageWidth, imageHeight ); +- fprintf( stderr, " blit width=%d height=%d data=%p\n", +- t->image[face][hwlevel].width, t->image[face][hwlevel].height, +- t->image[face][hwlevel].data ); +- exit( 1 ); +- } +-} +- +- +-/** +- * Upload the texture images associated with texture \a t. This might +- * require the allocation of texture memory. +- * +- * \param rmesa Context pointer +- * \param t Texture to be uploaded +- * \param face Cube map face to be uploaded. Zero for non-cube maps. +- */ +- +-int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, GLuint face ) +-{ +- int numLevels; +- +- if ( !t || t->base.totalSize == 0 || t->image_override ) +- return 0; +- +- if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { +- fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, +- (void *)rmesa->glCtx, (void *)t->base.tObj, t->base.totalSize, +- t->base.firstLevel, t->base.lastLevel ); +- } +- +- numLevels = t->base.lastLevel - t->base.firstLevel + 1; +- +- if (RADEON_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "%s: Syncing\n", __FUNCTION__ ); +- radeonFinish( rmesa->glCtx ); +- } +- +- LOCK_HARDWARE( rmesa ); +- +- if ( t->base.memBlock == NULL ) { +- int heap; +- +- heap = driAllocateTexture( rmesa->texture_heaps, rmesa->nr_heaps, +- (driTextureObject *) t ); +- if ( heap == -1 ) { +- UNLOCK_HARDWARE( rmesa ); +- return -1; +- } +- +- /* Set the base offset of the texture image */ +- t->bufAddr = rmesa->radeonScreen->texOffset[heap] +- + t->base.memBlock->ofs; +- t->pp_txoffset = t->bufAddr; +- +- if (!(t->base.tObj->Image[0][0]->IsClientData)) { +- /* hope it's safe to add that here... */ +- t->pp_txoffset |= t->tile_bits; +- } +- +- /* Mark this texobj as dirty on all units: +- */ +- t->dirty_state = TEX_ALL; +- } +- +- +- /* Let the world know we've used this memory recently. +- */ +- driUpdateTextureLRU( (driTextureObject *) t ); +- UNLOCK_HARDWARE( rmesa ); +- +- +- /* Upload any images that are new */ +- if (t->base.dirty_images[face]) { +- int i; +- for ( i = 0 ; i < numLevels ; i++ ) { +- if ( (t->base.dirty_images[face] & (1 << (i+t->base.firstLevel))) != 0 ) { +- uploadSubImage( rmesa, t, i, 0, 0, t->image[face][i].width, +- t->image[face][i].height, face ); +- } +- } +- t->base.dirty_images[face] = 0; +- } +- +- if (RADEON_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "%s: Syncing\n", __FUNCTION__ ); +- radeonFinish( rmesa->glCtx ); +- } +- +- return 0; +-} +diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c +index b165205..e4df337 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_texstate.c ++++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c +@@ -39,10 +39,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/context.h" + #include "main/macros.h" + #include "main/texformat.h" ++#include "main/teximage.h" + #include "main/texobj.h" + #include "main/enums.h" + + #include "radeon_context.h" ++#include "radeon_mipmap_tree.h" + #include "radeon_state.h" + #include "radeon_ioctl.h" + #include "radeon_swtcl.h" +@@ -75,10 +77,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \ + && (tx_table[f].format != 0xffffffff) ) + +-static const struct { ++struct tx_table { + GLuint format, filter; +-} +-tx_table[] = ++}; ++ ++static const struct tx_table tx_table[] = + { + _ALPHA(RGBA8888), + _ALPHA_REV(RGBA8888), +@@ -111,252 +114,6 @@ tx_table[] = + #undef _ALPHA + #undef _INVALID + +-/** +- * This function computes the number of bytes of storage needed for +- * the given texture object (all mipmap levels, all cube faces). +- * The \c image[face][level].x/y/width/height parameters for upload/blitting +- * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here +- * too. +- * +- * \param rmesa Context pointer +- * \param tObj GL texture object whose images are to be posted to +- * hardware state. +- */ +-static void radeonSetTexImages( radeonContextPtr rmesa, +- struct gl_texture_object *tObj ) +-{ +- radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; +- const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; +- GLint curOffset, blitWidth; +- GLint i, texelBytes; +- GLint numLevels; +- GLint log2Width, log2Height, log2Depth; +- +- /* Set the hardware texture format +- */ +- if ( !t->image_override ) { +- t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | +- RADEON_TXFORMAT_ALPHA_IN_MAP); +- t->pp_txfilter &= ~RADEON_YUV_TO_RGB; +- +- if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { +- t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format; +- t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter; +- } +- else { +- _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); +- return; +- } +- } +- +- texelBytes = baseImage->TexFormat->TexelBytes; +- +- /* Compute which mipmap levels we really want to send to the hardware. +- */ +- +- if (tObj->Target != GL_TEXTURE_CUBE_MAP) +- driCalculateTextureFirstLastLevel( (driTextureObject *) t ); +- else { +- /* r100 can't handle mipmaps for cube/3d textures, so don't waste +- memory for them */ +- t->base.firstLevel = t->base.lastLevel = tObj->BaseLevel; +- } +- log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2; +- log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2; +- log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2; +- +- numLevels = t->base.lastLevel - t->base.firstLevel + 1; +- +- assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS); +- +- /* Calculate mipmap offsets and dimensions for blitting (uploading) +- * The idea is that we lay out the mipmap levels within a block of +- * memory organized as a rectangle of width BLIT_WIDTH_BYTES. +- */ +- curOffset = 0; +- blitWidth = BLIT_WIDTH_BYTES; +- t->tile_bits = 0; +- +- /* figure out if this texture is suitable for tiling. */ +- if (texelBytes && (tObj->Target != GL_TEXTURE_RECTANGLE_NV)) { +- if (rmesa->texmicrotile && (baseImage->Height > 1)) { +- /* allow 32 (bytes) x 1 mip (which will use two times the space +- the non-tiled version would use) max if base texture is large enough */ +- if ((numLevels == 1) || +- (((baseImage->Width * texelBytes / baseImage->Height) <= 32) && +- (baseImage->Width * texelBytes > 64)) || +- ((baseImage->Width * texelBytes / baseImage->Height) <= 16)) { +- /* R100 has two microtile bits (only the txoffset reg, not the blitter) +- weird: X2 + OPT: 32bit correct, 16bit completely hosed +- X2: 32bit correct, 16bit correct +- OPT: 32bit large mips correct, small mips hosed, 16bit completely hosed */ +- t->tile_bits |= RADEON_TXO_MICRO_TILE_X2 /*| RADEON_TXO_MICRO_TILE_OPT*/; +- } +- } +- if ((baseImage->Width * texelBytes >= 256) && (baseImage->Height >= 16)) { +- /* R100 disables macro tiling only if mip width is smaller than 256 bytes, and not +- in the case if height is smaller than 16 (not 100% sure), as does the r200, +- so need to disable macro tiling in that case */ +- if ((numLevels == 1) || ((baseImage->Width * texelBytes / baseImage->Height) <= 4)) { +- t->tile_bits |= RADEON_TXO_MACRO_TILE; +- } +- } +- } +- +- for (i = 0; i < numLevels; i++) { +- const struct gl_texture_image *texImage; +- GLuint size; +- +- texImage = tObj->Image[0][i + t->base.firstLevel]; +- if ( !texImage ) +- break; +- +- /* find image size in bytes */ +- if (texImage->IsCompressed) { +- /* need to calculate the size AFTER padding even though the texture is +- submitted without padding. +- Only handle pot textures currently - don't know if npot is even possible, +- size calculation would certainly need (trivial) adjustments. +- Align (and later pad) to 32byte, not sure what that 64byte blit width is +- good for? */ +- if ((t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) == RADEON_TXFORMAT_DXT1) { +- /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */ +- if ((texImage->Width + 3) < 8) /* width one block */ +- size = texImage->CompressedSize * 4; +- else if ((texImage->Width + 3) < 16) +- size = texImage->CompressedSize * 2; +- else size = texImage->CompressedSize; +- } +- else /* DXT3/5, 16 bytes per block */ +- if ((texImage->Width + 3) < 8) +- size = texImage->CompressedSize * 2; +- else size = texImage->CompressedSize; +- } +- else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { +- size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height; +- } +- else if (t->tile_bits & RADEON_TXO_MICRO_TILE_X2) { +- /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, +- though the actual offset may be different (if texture is less than +- 32 bytes width) to the untiled case */ +- int w = (texImage->Width * texelBytes * 2 + 31) & ~31; +- size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth; +- blitWidth = MAX2(texImage->Width, 64 / texelBytes); +- } +- else { +- int w = (texImage->Width * texelBytes + 31) & ~31; +- size = w * texImage->Height * texImage->Depth; +- blitWidth = MAX2(texImage->Width, 64 / texelBytes); +- } +- assert(size > 0); +- +- /* Align to 32-byte offset. It is faster to do this unconditionally +- * (no branch penalty). +- */ +- +- curOffset = (curOffset + 0x1f) & ~0x1f; +- +- if (texelBytes) { +- t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */ +- t->image[0][i].y = 0; +- t->image[0][i].width = MIN2(size / texelBytes, blitWidth); +- t->image[0][i].height = (size / texelBytes) / t->image[0][i].width; +- } +- else { +- t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES; +- t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES; +- t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES); +- t->image[0][i].height = size / t->image[0][i].width; +- } +- +-#if 0 +- /* for debugging only and only applicable to non-rectangle targets */ +- assert(size % t->image[0][i].width == 0); +- assert(t->image[0][i].x == 0 +- || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1)); +-#endif +- +- if (0) +- fprintf(stderr, +- "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n", +- i, texImage->Width, texImage->Height, +- t->image[0][i].x, t->image[0][i].y, +- t->image[0][i].width, t->image[0][i].height, size, curOffset); +- +- curOffset += size; +- +- } +- +- /* Align the total size of texture memory block. +- */ +- t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; +- +- /* Setup remaining cube face blits, if needed */ +- if (tObj->Target == GL_TEXTURE_CUBE_MAP) { +- const GLuint faceSize = t->base.totalSize; +- GLuint face; +- /* reuse face 0 x/y/width/height - just update the offset when uploading */ +- for (face = 1; face < 6; face++) { +- for (i = 0; i < numLevels; i++) { +- t->image[face][i].x = t->image[0][i].x; +- t->image[face][i].y = t->image[0][i].y; +- t->image[face][i].width = t->image[0][i].width; +- t->image[face][i].height = t->image[0][i].height; +- } +- } +- t->base.totalSize = 6 * faceSize; /* total texmem needed */ +- } +- +- /* Hardware state: +- */ +- t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK; +- t->pp_txfilter |= (numLevels - 1) << RADEON_MAX_MIP_LEVEL_SHIFT; +- +- t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK | +- RADEON_TXFORMAT_HEIGHT_MASK | +- RADEON_TXFORMAT_CUBIC_MAP_ENABLE | +- RADEON_TXFORMAT_F5_WIDTH_MASK | +- RADEON_TXFORMAT_F5_HEIGHT_MASK); +- t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) | +- (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT)); +- +- if (tObj->Target == GL_TEXTURE_CUBE_MAP) { +- assert(log2Width == log2Height); +- t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) | +- (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) | +- (RADEON_TXFORMAT_CUBIC_MAP_ENABLE)); +- t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) | +- (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) | +- (log2Width << RADEON_FACE_WIDTH_2_SHIFT) | +- (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) | +- (log2Width << RADEON_FACE_WIDTH_3_SHIFT) | +- (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) | +- (log2Width << RADEON_FACE_WIDTH_4_SHIFT) | +- (log2Height << RADEON_FACE_HEIGHT_4_SHIFT)); +- } +- +- t->pp_txsize = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << 0) | +- ((tObj->Image[0][t->base.firstLevel]->Height - 1) << 16)); +- +- /* Only need to round to nearest 32 for textures, but the blitter +- * requires 64-byte aligned pitches, and we may/may not need the +- * blitter. NPOT only! +- */ +- if ( !t->image_override ) { +- if (baseImage->IsCompressed) +- t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63); +- else +- t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63); +- t->pp_txpitch -= 32; +- } +- +- t->dirty_state = TEX_ALL; +- +- /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */ +-} +- +- +- + /* ================================================================ + * Texture combine functions + */ +@@ -503,7 +260,7 @@ do { \ + + static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint color_combine, alpha_combine; + const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO +@@ -846,22 +603,21 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) + void radeonSetTexOffset(__DRIcontext * pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch) + { +- radeonContextPtr rmesa = pDRICtx->driverPrivate; ++ r100ContextPtr rmesa = pDRICtx->driverPrivate; + struct gl_texture_object *tObj = +- _mesa_lookup_texture(rmesa->glCtx, texname); +- radeonTexObjPtr t; ++ _mesa_lookup_texture(rmesa->radeon.glCtx, texname); ++ radeonTexObjPtr t = radeon_tex_obj(tObj); + + if (tObj == NULL) + return; + +- t = (radeonTexObjPtr) tObj->DriverData; +- + t->image_override = GL_TRUE; + + if (!offset) + return; +- +- t->pp_txoffset = offset; ++ ++ t->bo = NULL; ++ t->override_offset = offset; + t->pp_txpitch = pitch - 32; + + switch (depth) { +@@ -881,6 +637,122 @@ void radeonSetTexOffset(__DRIcontext * pDRICtx, GLint texname, + } + } + ++void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, ++ __DRIdrawable *dPriv) ++{ ++ struct gl_texture_unit *texUnit; ++ struct gl_texture_object *texObj; ++ struct gl_texture_image *texImage; ++ struct radeon_renderbuffer *rb; ++ radeon_texture_image *rImage; ++ radeonContextPtr radeon; ++ r100ContextPtr rmesa; ++ struct radeon_framebuffer *rfb; ++ radeonTexObjPtr t; ++ uint32_t pitch_val; ++ uint32_t internalFormat, type, format; ++ ++ type = GL_BGRA; ++ format = GL_UNSIGNED_BYTE; ++ internalFormat = (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT ? 3 : 4); ++ ++ radeon = pDRICtx->driverPrivate; ++ rmesa = pDRICtx->driverPrivate; ++ ++ rfb = dPriv->driverPrivate; ++ texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit]; ++ texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target); ++ texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0); ++ ++ rImage = get_radeon_texture_image(texImage); ++ t = radeon_tex_obj(texObj); ++ if (t == NULL) { ++ return; ++ } ++ ++ radeon_update_renderbuffers(pDRICtx, dPriv); ++ /* back & depth buffer are useless free them right away */ ++ rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = rfb->color_rb[0]; ++ if (rb->bo == NULL) { ++ /* Failed to BO for the buffer */ ++ return; ++ } ++ ++ _mesa_lock_texture(radeon->glCtx, texObj); ++ if (t->bo) { ++ radeon_bo_unref(t->bo); ++ t->bo = NULL; ++ } ++ if (rImage->bo) { ++ radeon_bo_unref(rImage->bo); ++ rImage->bo = NULL; ++ } ++ if (t->mt) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = NULL; ++ } ++ if (rImage->mt) { ++ radeon_miptree_unreference(rImage->mt); ++ rImage->mt = NULL; ++ } ++ _mesa_init_teximage_fields(radeon->glCtx, target, texImage, ++ rb->width, rb->height, 1, 0, rb->cpp); ++ texImage->RowStride = rb->pitch / rb->cpp; ++ texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx, ++ internalFormat, ++ type, format, 0); ++ rImage->bo = rb->bo; ++ radeon_bo_ref(rImage->bo); ++ t->bo = rb->bo; ++ radeon_bo_ref(t->bo); ++ t->tile_bits = 0; ++ t->image_override = GL_TRUE; ++ t->override_offset = 0; ++ t->pp_txpitch &= (1 << 13) -1; ++ pitch_val = rb->pitch; ++ switch (rb->cpp) { ++ case 4: ++ t->pp_txformat = tx_table[MESA_FORMAT_ARGB8888].format; ++ t->pp_txfilter |= tx_table[MESA_FORMAT_ARGB8888].filter; ++ break; ++ case 3: ++ default: ++ t->pp_txformat = tx_table[MESA_FORMAT_RGB888].format; ++ t->pp_txfilter |= tx_table[MESA_FORMAT_RGB888].filter; ++ break; ++ case 2: ++ t->pp_txformat = tx_table[MESA_FORMAT_RGB565].format; ++ t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter; ++ break; ++ } ++ t->pp_txsize = ((rb->width - 1) << RADEON_TEX_USIZE_SHIFT) ++ | ((rb->height - 1) << RADEON_TEX_VSIZE_SHIFT); ++ t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; ++ t->pp_txpitch = pitch_val; ++ t->pp_txpitch -= 32; ++ ++ t->validated = GL_TRUE; ++ _mesa_unlock_texture(radeon->glCtx, texObj); ++ return; ++} ++ ++ ++void radeonSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) ++{ ++ radeonSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); ++} ++ ++ + #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \ + RADEON_MIN_FILTER_MASK | \ + RADEON_MAG_FILTER_MASK | \ +@@ -901,12 +773,53 @@ void radeonSetTexOffset(__DRIcontext * pDRICtx, GLint texname, + RADEON_TXFORMAT_NON_POWER2) + + +-static void import_tex_obj_state( radeonContextPtr rmesa, ++static void disable_tex_obj_state( r100ContextPtr rmesa, ++ int unit ) ++{ ++ RADEON_STATECHANGE( rmesa, tex[unit] ); ++ ++ RADEON_STATECHANGE( rmesa, tcl ); ++ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) | ++ RADEON_Q_BIT(unit)); ++ ++ if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<radeon.glCtx, (RADEON_TCL_FALLBACK_TEXGEN_0<recheck_texgen[unit] = GL_TRUE; ++ } ++ ++ if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) { ++ /* this seems to be a genuine (r100 only?) hw bug. Need to remove the ++ cubic_map bit on unit 2 when the unit is disabled, otherwise every ++ 2nd (2d) mipmap on unit 0 will be broken (may not be needed for other ++ units, better be safe than sorry though).*/ ++ RADEON_STATECHANGE( rmesa, tex[unit] ); ++ rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE; ++ } ++ ++ { ++ GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4; ++ GLuint tmp = rmesa->TexGenEnabled; ++ ++ rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<TexGenNeedNormals[unit] = 0; ++ rmesa->TexGenEnabled |= ++ (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; ++ ++ if (tmp != rmesa->TexGenEnabled) { ++ rmesa->recheck_texgen[unit] = GL_TRUE; ++ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; ++ } ++ } ++} ++ ++static void import_tex_obj_state( r100ContextPtr rmesa, + int unit, + radeonTexObjPtr texobj ) + { + /* do not use RADEON_DB_STATE to avoid stale texture caches */ +- int *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0]; ++ uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0]; + GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT]; + + RADEON_STATECHANGE( rmesa, tex[unit] ); +@@ -915,10 +828,9 @@ static void import_tex_obj_state( radeonContextPtr rmesa, + cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; + cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; + cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; +- cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset; + cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; + +- if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) { ++ if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) { + GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] ); + txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */ + txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */ +@@ -928,22 +840,12 @@ static void import_tex_obj_state( radeonContextPtr rmesa, + else { + se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit); + +- if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) { +- int *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0]; +- GLuint bytesPerFace = texobj->base.totalSize / 6; +- ASSERT(texobj->base.totalSize % 6 == 0); ++ if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) { ++ uint32_t *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0]; + + RADEON_STATECHANGE( rmesa, cube[unit] ); + cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces; +- /* dont know if this setup conforms to OpenGL.. +- * at least it matches the behavior of mesa software renderer +- */ +- cube_cmd[CUBE_PP_CUBIC_OFFSET_0] = texobj->pp_txoffset; /* right */ +- cube_cmd[CUBE_PP_CUBIC_OFFSET_1] = texobj->pp_txoffset + 1 * bytesPerFace; /* left */ +- cube_cmd[CUBE_PP_CUBIC_OFFSET_2] = texobj->pp_txoffset + 2 * bytesPerFace; /* top */ +- cube_cmd[CUBE_PP_CUBIC_OFFSET_3] = texobj->pp_txoffset + 3 * bytesPerFace; /* bottom */ +- cube_cmd[CUBE_PP_CUBIC_OFFSET_4] = texobj->pp_txoffset + 4 * bytesPerFace; /* front */ +- cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset + 5 * bytesPerFace; /* back */ ++ /* state filled out in the cube_emit */ + } + } + +@@ -952,13 +854,11 @@ static void import_tex_obj_state( radeonContextPtr rmesa, + rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt; + } + +- texobj->dirty_state &= ~(1<radeon.NewGLState |= _NEW_TEXTURE_MATRIX; + } + + +- +- +-static void set_texgen_matrix( radeonContextPtr rmesa, ++static void set_texgen_matrix( r100ContextPtr rmesa, + GLuint unit, + const GLfloat *s_plane, + const GLfloat *t_plane, +@@ -986,14 +886,14 @@ static void set_texgen_matrix( radeonContextPtr rmesa, + rmesa->TexGenMatrix[unit].m[15] = q_plane[3]; + + rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit; +- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; ++ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; + } + + /* Returns GL_FALSE if fallback required. + */ + static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4; + GLuint tmp = rmesa->TexGenEnabled; +@@ -1094,283 +994,187 @@ static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit ) + } + + if (tmp != rmesa->TexGenEnabled) { +- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; ++ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; + } + + return GL_TRUE; + } + +- +-static void disable_tex( GLcontext *ctx, int unit ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- +- if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<state.texture.unit[unit].texobj != NULL ) { +- /* The old texture is no longer bound to this texture unit. +- * Mark it as such. +- */ +- +- rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit); +- rmesa->state.texture.unit[unit].texobj = NULL; +- } +- +- RADEON_STATECHANGE( rmesa, ctx ); +- rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= +- ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit); +- +- RADEON_STATECHANGE( rmesa, tcl ); +- rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) | +- RADEON_Q_BIT(unit)); +- +- if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<recheck_texgen[unit] = GL_TRUE; +- } +- +- if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) { +- /* this seems to be a genuine (r100 only?) hw bug. Need to remove the +- cubic_map bit on unit 2 when the unit is disabled, otherwise every +- 2nd (2d) mipmap on unit 0 will be broken (may not be needed for other +- units, better be safe than sorry though).*/ +- RADEON_STATECHANGE( rmesa, tex[unit] ); +- rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE; +- } +- +- { +- GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4; +- GLuint tmp = rmesa->TexGenEnabled; +- +- rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<TexGenNeedNormals[unit] = 0; +- rmesa->TexGenEnabled |= +- (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; +- +- if (tmp != rmesa->TexGenEnabled) { +- rmesa->recheck_texgen[unit] = GL_TRUE; +- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; +- } +- } +- } +-} +- +-static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; +- +- /* Need to load the 2d images associated with this unit. +- */ +- if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) { +- t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2; +- t->base.dirty_images[0] = ~0; +- } +- +- ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D); +- +- if ( t->base.dirty_images[0] ) { +- RADEON_FIREVERTICES( rmesa ); +- radeonSetTexImages( rmesa, tObj ); +- radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 ); +- if ( !t->base.memBlock && !t->image_override ) +- return GL_FALSE; +- } +- +- return GL_TRUE; +-} +- +-static GLboolean enable_tex_cube( GLcontext *ctx, int unit ) ++/** ++ * Compute the cached hardware register values for the given texture object. ++ * ++ * \param rmesa Context pointer ++ * \param t the r300 texture object ++ */ ++static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int unit) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; +- GLuint face; ++ const struct gl_texture_image *firstImage; ++ GLint log2Width, log2Height, log2Depth, texelBytes; + +- /* Need to load the 2d images associated with this unit. +- */ +- if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) { +- t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2; +- for (face = 0; face < 6; face++) +- t->base.dirty_images[face] = ~0; ++ if ( t->bo ) { ++ return GL_TRUE; + } + +- ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP); ++ firstImage = t->base.Image[0][t->mt->firstLevel]; + +- if ( t->base.dirty_images[0] || t->base.dirty_images[1] || +- t->base.dirty_images[2] || t->base.dirty_images[3] || +- t->base.dirty_images[4] || t->base.dirty_images[5] ) { +- /* flush */ +- RADEON_FIREVERTICES( rmesa ); +- /* layout memory space, once for all faces */ +- radeonSetTexImages( rmesa, tObj ); ++ if (firstImage->Border > 0) { ++ fprintf(stderr, "%s: border\n", __FUNCTION__); ++ return GL_FALSE; + } + +- /* upload (per face) */ +- for (face = 0; face < 6; face++) { +- if (t->base.dirty_images[face]) { +- radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, face ); ++ log2Width = firstImage->WidthLog2; ++ log2Height = firstImage->HeightLog2; ++ log2Depth = firstImage->DepthLog2; ++ texelBytes = firstImage->TexFormat->TexelBytes; ++ ++ if (!t->image_override) { ++ if (VALID_FORMAT(firstImage->TexFormat->MesaFormat)) { ++ const struct tx_table *table = tx_table; ++ ++ t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | ++ RADEON_TXFORMAT_ALPHA_IN_MAP); ++ t->pp_txfilter &= ~RADEON_YUV_TO_RGB; ++ ++ t->pp_txformat |= table[ firstImage->TexFormat->MesaFormat ].format; ++ t->pp_txfilter |= table[ firstImage->TexFormat->MesaFormat ].filter; ++ } else { ++ _mesa_problem(NULL, "unexpected texture format in %s", ++ __FUNCTION__); ++ return GL_FALSE; + } + } +- +- if ( !t->base.memBlock ) { +- /* texmem alloc failed, use s/w fallback */ +- return GL_FALSE; ++ ++ t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK; ++ t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << RADEON_MAX_MIP_LEVEL_SHIFT; ++ ++ t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK | ++ RADEON_TXFORMAT_HEIGHT_MASK | ++ RADEON_TXFORMAT_CUBIC_MAP_ENABLE | ++ RADEON_TXFORMAT_F5_WIDTH_MASK | ++ RADEON_TXFORMAT_F5_HEIGHT_MASK); ++ t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) | ++ (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT)); ++ ++ t->tile_bits = 0; ++ ++ if (t->base.Target == GL_TEXTURE_CUBE_MAP) { ++ ASSERT(log2Width == log2Height); ++ t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) | ++ (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) | ++ /* don't think we need this bit, if it exists at all - fglrx does not set it */ ++ (RADEON_TXFORMAT_CUBIC_MAP_ENABLE)); ++ t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) | ++ (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) | ++ (log2Width << RADEON_FACE_WIDTH_2_SHIFT) | ++ (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) | ++ (log2Width << RADEON_FACE_WIDTH_3_SHIFT) | ++ (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) | ++ (log2Width << RADEON_FACE_WIDTH_4_SHIFT) | ++ (log2Height << RADEON_FACE_HEIGHT_4_SHIFT)); + } + +- return GL_TRUE; +-} +- +-static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) +-{ +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; ++ t->pp_txsize = (((firstImage->Width - 1) << RADEON_TEX_USIZE_SHIFT) ++ | ((firstImage->Height - 1) << RADEON_TEX_VSIZE_SHIFT)); + +- if (!(t->pp_txformat & RADEON_TXFORMAT_NON_POWER2)) { +- t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; +- t->base.dirty_images[0] = ~0; ++ if ( !t->image_override ) { ++ if (firstImage->IsCompressed) ++ t->pp_txpitch = (firstImage->Width + 63) & ~(63); ++ else ++ t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63); ++ t->pp_txpitch -= 32; + } + +- ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV); +- +- if ( t->base.dirty_images[0] ) { +- RADEON_FIREVERTICES( rmesa ); +- radeonSetTexImages( rmesa, tObj ); +- radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 ); +- if ( !t->base.memBlock && +- !t->image_override /* && !rmesa->prefer_gart_client_texturing FIXME */ ) { +- fprintf(stderr, "%s: upload failed\n", __FUNCTION__); +- return GL_FALSE; +- } ++ if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) { ++ t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; + } + + return GL_TRUE; + } + +- +-static GLboolean update_tex_common( GLcontext *ctx, int unit ) ++static GLboolean radeon_validate_texture(GLcontext *ctx, struct gl_texture_object *texObj, int unit) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +- struct gl_texture_object *tObj = texUnit->_Current; +- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; +- GLenum format; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); ++ radeonTexObj *t = radeon_tex_obj(texObj); ++ int ret; + +- /* Fallback if there's a texture border */ +- if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) { +- fprintf(stderr, "%s: border\n", __FUNCTION__); ++ if (!radeon_validate_texture_miptree(ctx, texObj)) + return GL_FALSE; +- } ++ ++ ret = setup_hardware_state(rmesa, t, unit); ++ if (ret == GL_FALSE) ++ return GL_FALSE; ++ + /* yuv conversion only works in first unit */ + if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB)) + return GL_FALSE; + +- /* Update state if this is a different texture object to last +- * time. +- */ +- if ( rmesa->state.texture.unit[unit].texobj != t ) { +- if ( rmesa->state.texture.unit[unit].texobj != NULL ) { +- /* The old texture is no longer bound to this texture unit. +- * Mark it as such. +- */ +- +- rmesa->state.texture.unit[unit].texobj->base.bound &= +- ~(1UL << unit); +- } +- +- rmesa->state.texture.unit[unit].texobj = t; +- t->base.bound |= (1UL << unit); +- t->dirty_state |= 1<hw.ctx.cmd[CTX_PP_CNTL] |= ++ (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit; + ++ RADEON_STATECHANGE( rmesa, tcl ); ++ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit); + +- /* Newly enabled? +- */ +- if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<hw.ctx.cmd[CTX_PP_CNTL] |= +- (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit; ++ rmesa->recheck_texgen[unit] = GL_TRUE; + +- RADEON_STATECHANGE( rmesa, tcl ); +- +- rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit); +- +- rmesa->recheck_texgen[unit] = GL_TRUE; +- } +- +- if (t->dirty_state & (1<NewGLState |= _NEW_TEXTURE_MATRIX; +- } ++ import_tex_obj_state( rmesa, unit, t ); + + if (rmesa->recheck_texgen[unit]) { + GLboolean fallback = !radeon_validate_texgen( ctx, unit ); + TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<recheck_texgen[unit] = 0; +- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; ++ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; + } + +- format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; +- if ( rmesa->state.texture.unit[unit].format != format || +- rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) { +- rmesa->state.texture.unit[unit].format = format; +- rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode; +- if ( ! radeonUpdateTextureEnv( ctx, unit ) ) { +- return GL_FALSE; +- } ++ if ( ! radeonUpdateTextureEnv( ctx, unit ) ) { ++ return GL_FALSE; + } +- + FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback ); ++ ++ t->validated = GL_TRUE; + return !t->border_fallback; + } + +- +- + static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) + { +- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + +- if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) { +- return (enable_tex_rect( ctx, unit ) && +- update_tex_common( ctx, unit )); +- } +- else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) { +- return (enable_tex_2d( ctx, unit ) && +- update_tex_common( ctx, unit )); +- } +- else if ( texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT) ) { +- return (enable_tex_cube( ctx, unit ) && +- update_tex_common( ctx, unit )); ++ if (ctx->Texture.Unit[unit]._ReallyEnabled & TEXTURE_3D_BIT) { ++ return GL_FALSE; + } +- else if ( texUnit->_ReallyEnabled ) { +- return GL_FALSE; ++ ++ if (!ctx->Texture.Unit[unit]._ReallyEnabled) { ++ /* disable the unit */ ++ disable_tex_obj_state(rmesa, unit); ++ return GL_TRUE; + } +- else { +- disable_tex( ctx, unit ); +- return GL_TRUE; ++ ++ if (!radeon_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) { ++ _mesa_warning(ctx, ++ "failed to validate texture for unit %d.\n", ++ unit); ++ rmesa->state.texture.unit[unit].texobj = NULL; ++ return GL_FALSE; + } ++ rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current); ++ return GL_TRUE; + } + + void radeonUpdateTextureState( GLcontext *ctx ) + { +- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLboolean ok; + ++ /* set the ctx all textures off */ ++ RADEON_STATECHANGE( rmesa, ctx ); ++ rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((RADEON_TEX_ENABLE_MASK) | (RADEON_TEX_BLEND_ENABLE_MASK)); ++ + ok = (radeonUpdateTextureUnit( ctx, 0 ) && + radeonUpdateTextureUnit( ctx, 1 ) && + radeonUpdateTextureUnit( ctx, 2 )); + + FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok ); + +- if (rmesa->TclFallback) ++ if (rmesa->radeon.TclFallback) + radeonChooseVertexState( ctx ); + } +diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c +new file mode 100644 +index 0000000..35ed542 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_texture.c +@@ -0,0 +1,996 @@ ++/* ++ * Copyright (C) 2008 Nicolai Haehnle. ++ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. ++ * ++ * The Weather Channel (TM) funded Tungsten Graphics to develop the ++ * initial release of the Radeon 8500 driver under the XFree86 license. ++ * This notice must be preserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "main/glheader.h" ++#include "main/imports.h" ++#include "main/context.h" ++#include "main/convolve.h" ++#include "main/mipmap.h" ++#include "main/texcompress.h" ++#include "main/texformat.h" ++#include "main/texstore.h" ++#include "main/teximage.h" ++#include "main/texobj.h" ++ ++#include "xmlpool.h" /* for symbolic values of enum-type options */ ++ ++#include "radeon_common.h" ++ ++#include "radeon_mipmap_tree.h" ++ ++ ++static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, ++ GLuint numrows, GLuint rowsize) ++{ ++ assert(rowsize <= dststride); ++ assert(rowsize <= srcstride); ++ ++ if (rowsize == srcstride && rowsize == dststride) { ++ memcpy(dst, src, numrows*rowsize); ++ } else { ++ GLuint i; ++ for(i = 0; i < numrows; ++i) { ++ memcpy(dst, src, rowsize); ++ dst += dststride; ++ src += srcstride; ++ } ++ } ++} ++ ++/* textures */ ++/** ++ * Allocate an empty texture image object. ++ */ ++struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx) ++{ ++ return CALLOC(sizeof(radeon_texture_image)); ++} ++ ++/** ++ * Free memory associated with this texture image. ++ */ ++void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage) ++{ ++ radeon_texture_image* image = get_radeon_texture_image(timage); ++ ++ if (image->mt) { ++ radeon_miptree_unreference(image->mt); ++ image->mt = 0; ++ assert(!image->base.Data); ++ } else { ++ _mesa_free_texture_image_data(ctx, timage); ++ } ++ if (image->bo) { ++ radeon_bo_unref(image->bo); ++ image->bo = NULL; ++ } ++ if (timage->Data) { ++ _mesa_free_texmemory(timage->Data); ++ timage->Data = NULL; ++ } ++} ++ ++/* Set Data pointer and additional data for mapped texture image */ ++static void teximage_set_map_data(radeon_texture_image *image) ++{ ++ radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; ++ ++ image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; ++ image->base.RowStride = lvl->rowstride / image->mt->bpp; ++} ++ ++ ++/** ++ * Map a single texture image for glTexImage and friends. ++ */ ++void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) ++{ ++ if (image->mt) { ++ assert(!image->base.Data); ++ ++ radeon_bo_map(image->mt->bo, write_enable); ++ teximage_set_map_data(image); ++ } ++} ++ ++ ++void radeon_teximage_unmap(radeon_texture_image *image) ++{ ++ if (image->mt) { ++ assert(image->base.Data); ++ ++ image->base.Data = 0; ++ radeon_bo_unmap(image->mt->bo); ++ } ++} ++ ++static void map_override(GLcontext *ctx, radeonTexObj *t) ++{ ++ radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]); ++ ++ radeon_bo_map(t->bo, GL_FALSE); ++ ++ img->base.Data = t->bo->ptr; ++ _mesa_set_fetch_functions(&img->base, 2); ++} ++ ++static void unmap_override(GLcontext *ctx, radeonTexObj *t) ++{ ++ radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]); ++ ++ radeon_bo_unmap(t->bo); ++ ++ img->base.Data = NULL; ++} ++ ++/** ++ * Map a validated texture for reading during software rendering. ++ */ ++void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) ++{ ++ radeonTexObj* t = radeon_tex_obj(texObj); ++ int face, level; ++ ++ if (!radeon_validate_texture_miptree(ctx, texObj)) ++ return; ++ ++ /* for r100 3D sw fallbacks don't have mt */ ++ if (t->image_override && t->bo) ++ map_override(ctx, t); ++ ++ if (!t->mt) ++ return; ++ ++ radeon_bo_map(t->mt->bo, GL_FALSE); ++ for(face = 0; face < t->mt->faces; ++face) { ++ for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) ++ teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); ++ } ++} ++ ++void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) ++{ ++ radeonTexObj* t = radeon_tex_obj(texObj); ++ int face, level; ++ ++ if (t->image_override && t->bo) ++ unmap_override(ctx, t); ++ /* for r100 3D sw fallbacks don't have mt */ ++ if (!t->mt) ++ return; ++ ++ for(face = 0; face < t->mt->faces; ++face) { ++ for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) ++ texObj->Image[face][level]->Data = 0; ++ } ++ radeon_bo_unmap(t->mt->bo); ++} ++ ++GLuint radeon_face_for_target(GLenum target) ++{ ++ switch (target) { ++ case GL_TEXTURE_CUBE_MAP_POSITIVE_X: ++ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: ++ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: ++ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: ++ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: ++ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: ++ return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; ++ default: ++ return 0; ++ } ++} ++ ++/** ++ * Wraps Mesa's implementation to ensure that the base level image is mapped. ++ * ++ * This relies on internal details of _mesa_generate_mipmap, in particular ++ * the fact that the memory for recreated texture images is always freed. ++ */ ++static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, ++ struct gl_texture_object *texObj) ++{ ++ radeonTexObj* t = radeon_tex_obj(texObj); ++ GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; ++ int i, face; ++ ++ ++ _mesa_generate_mipmap(ctx, target, texObj); ++ ++ for (face = 0; face < nr_faces; face++) { ++ for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { ++ radeon_texture_image *image; ++ ++ image = get_radeon_texture_image(texObj->Image[face][i]); ++ ++ if (image == NULL) ++ break; ++ ++ image->mtlevel = i; ++ image->mtface = face; ++ ++ radeon_miptree_unreference(image->mt); ++ image->mt = NULL; ++ } ++ } ++ ++} ++ ++void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) ++{ ++ GLuint face = radeon_face_for_target(target); ++ radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); ++ ++ radeon_teximage_map(baseimage, GL_FALSE); ++ radeon_generate_mipmap(ctx, target, texObj); ++ radeon_teximage_unmap(baseimage); ++} ++ ++ ++/* try to find a format which will only need a memcopy */ ++static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa, ++ GLenum srcFormat, ++ GLenum srcType, GLboolean fbo) ++{ ++ const GLuint ui = 1; ++ const GLubyte littleEndian = *((const GLubyte *)&ui); ++ ++ /* r100 can only do this */ ++ if (IS_R100_CLASS(rmesa->radeonScreen) || fbo) ++ return _dri_texformat_argb8888; ++ ++ if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || ++ (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || ++ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || ++ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { ++ return &_mesa_texformat_rgba8888; ++ } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || ++ (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || ++ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || ++ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { ++ return &_mesa_texformat_rgba8888_rev; ++ } else if (IS_R200_CLASS(rmesa->radeonScreen)) { ++ return _dri_texformat_argb8888; ++ } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || ++ srcType == GL_UNSIGNED_INT_8_8_8_8)) { ++ return &_mesa_texformat_argb8888_rev; ++ } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || ++ srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { ++ return &_mesa_texformat_argb8888; ++ } else ++ return _dri_texformat_argb8888; ++} ++ ++const struct gl_texture_format *radeonChooseTextureFormat_mesa(GLcontext * ctx, ++ GLint internalFormat, ++ GLenum format, ++ GLenum type) ++{ ++ return radeonChooseTextureFormat(ctx, internalFormat, format, ++ type, 0); ++} ++ ++const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, ++ GLint internalFormat, ++ GLenum format, ++ GLenum type, GLboolean fbo) ++{ ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ const GLboolean do32bpt = ++ (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); ++ const GLboolean force16bpt = ++ (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); ++ (void)format; ++ ++#if 0 ++ fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", ++ _mesa_lookup_enum_by_nr(internalFormat), internalFormat, ++ _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); ++ fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); ++#endif ++ ++ switch (internalFormat) { ++ case 4: ++ case GL_RGBA: ++ case GL_COMPRESSED_RGBA: ++ switch (type) { ++ case GL_UNSIGNED_INT_10_10_10_2: ++ case GL_UNSIGNED_INT_2_10_10_10_REV: ++ return do32bpt ? _dri_texformat_argb8888 : ++ _dri_texformat_argb1555; ++ case GL_UNSIGNED_SHORT_4_4_4_4: ++ case GL_UNSIGNED_SHORT_4_4_4_4_REV: ++ return _dri_texformat_argb4444; ++ case GL_UNSIGNED_SHORT_5_5_5_1: ++ case GL_UNSIGNED_SHORT_1_5_5_5_REV: ++ return _dri_texformat_argb1555; ++ default: ++ return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) : ++ _dri_texformat_argb4444; ++ } ++ ++ case 3: ++ case GL_RGB: ++ case GL_COMPRESSED_RGB: ++ switch (type) { ++ case GL_UNSIGNED_SHORT_4_4_4_4: ++ case GL_UNSIGNED_SHORT_4_4_4_4_REV: ++ return _dri_texformat_argb4444; ++ case GL_UNSIGNED_SHORT_5_5_5_1: ++ case GL_UNSIGNED_SHORT_1_5_5_5_REV: ++ return _dri_texformat_argb1555; ++ case GL_UNSIGNED_SHORT_5_6_5: ++ case GL_UNSIGNED_SHORT_5_6_5_REV: ++ return _dri_texformat_rgb565; ++ default: ++ return do32bpt ? _dri_texformat_argb8888 : ++ _dri_texformat_rgb565; ++ } ++ ++ case GL_RGBA8: ++ case GL_RGB10_A2: ++ case GL_RGBA12: ++ case GL_RGBA16: ++ return !force16bpt ? ++ radeonChoose8888TexFormat(rmesa, format, type, fbo) : ++ _dri_texformat_argb4444; ++ ++ case GL_RGBA4: ++ case GL_RGBA2: ++ return _dri_texformat_argb4444; ++ ++ case GL_RGB5_A1: ++ return _dri_texformat_argb1555; ++ ++ case GL_RGB8: ++ case GL_RGB10: ++ case GL_RGB12: ++ case GL_RGB16: ++ return !force16bpt ? _dri_texformat_argb8888 : ++ _dri_texformat_rgb565; ++ ++ case GL_RGB5: ++ case GL_RGB4: ++ case GL_R3_G3_B2: ++ return _dri_texformat_rgb565; ++ ++ case GL_ALPHA: ++ case GL_ALPHA4: ++ case GL_ALPHA8: ++ case GL_ALPHA12: ++ case GL_ALPHA16: ++ case GL_COMPRESSED_ALPHA: ++ /* r200: can't use a8 format since interpreting hw I8 as a8 would result ++ in wrong rgb values (same as alpha value instead of 0). */ ++ if (IS_R200_CLASS(rmesa->radeonScreen)) ++ return _dri_texformat_al88; ++ else ++ return _dri_texformat_a8; ++ case 1: ++ case GL_LUMINANCE: ++ case GL_LUMINANCE4: ++ case GL_LUMINANCE8: ++ case GL_LUMINANCE12: ++ case GL_LUMINANCE16: ++ case GL_COMPRESSED_LUMINANCE: ++ return _dri_texformat_l8; ++ ++ case 2: ++ case GL_LUMINANCE_ALPHA: ++ case GL_LUMINANCE4_ALPHA4: ++ case GL_LUMINANCE6_ALPHA2: ++ case GL_LUMINANCE8_ALPHA8: ++ case GL_LUMINANCE12_ALPHA4: ++ case GL_LUMINANCE12_ALPHA12: ++ case GL_LUMINANCE16_ALPHA16: ++ case GL_COMPRESSED_LUMINANCE_ALPHA: ++ return _dri_texformat_al88; ++ ++ case GL_INTENSITY: ++ case GL_INTENSITY4: ++ case GL_INTENSITY8: ++ case GL_INTENSITY12: ++ case GL_INTENSITY16: ++ case GL_COMPRESSED_INTENSITY: ++ return _dri_texformat_i8; ++ ++ case GL_YCBCR_MESA: ++ if (type == GL_UNSIGNED_SHORT_8_8_APPLE || ++ type == GL_UNSIGNED_BYTE) ++ return &_mesa_texformat_ycbcr; ++ else ++ return &_mesa_texformat_ycbcr_rev; ++ ++ case GL_RGB_S3TC: ++ case GL_RGB4_S3TC: ++ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: ++ return &_mesa_texformat_rgb_dxt1; ++ ++ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: ++ return &_mesa_texformat_rgba_dxt1; ++ ++ case GL_RGBA_S3TC: ++ case GL_RGBA4_S3TC: ++ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: ++ return &_mesa_texformat_rgba_dxt3; ++ ++ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: ++ return &_mesa_texformat_rgba_dxt5; ++ ++ case GL_ALPHA16F_ARB: ++ return &_mesa_texformat_alpha_float16; ++ case GL_ALPHA32F_ARB: ++ return &_mesa_texformat_alpha_float32; ++ case GL_LUMINANCE16F_ARB: ++ return &_mesa_texformat_luminance_float16; ++ case GL_LUMINANCE32F_ARB: ++ return &_mesa_texformat_luminance_float32; ++ case GL_LUMINANCE_ALPHA16F_ARB: ++ return &_mesa_texformat_luminance_alpha_float16; ++ case GL_LUMINANCE_ALPHA32F_ARB: ++ return &_mesa_texformat_luminance_alpha_float32; ++ case GL_INTENSITY16F_ARB: ++ return &_mesa_texformat_intensity_float16; ++ case GL_INTENSITY32F_ARB: ++ return &_mesa_texformat_intensity_float32; ++ case GL_RGB16F_ARB: ++ return &_mesa_texformat_rgba_float16; ++ case GL_RGB32F_ARB: ++ return &_mesa_texformat_rgba_float32; ++ case GL_RGBA16F_ARB: ++ return &_mesa_texformat_rgba_float16; ++ case GL_RGBA32F_ARB: ++ return &_mesa_texformat_rgba_float32; ++ ++ case GL_DEPTH_COMPONENT: ++ case GL_DEPTH_COMPONENT16: ++ case GL_DEPTH_COMPONENT24: ++ case GL_DEPTH_COMPONENT32: ++ case GL_DEPTH_STENCIL_EXT: ++ case GL_DEPTH24_STENCIL8_EXT: ++ return &_mesa_texformat_s8_z24; ++ default: ++ _mesa_problem(ctx, ++ "unexpected internalFormat 0x%x in %s", ++ (int)internalFormat, __func__); ++ return NULL; ++ } ++ ++ return NULL; /* never get here */ ++} ++ ++/** ++ * All glTexImage calls go through this function. ++ */ ++static void radeon_teximage( ++ GLcontext *ctx, int dims, ++ GLint face, GLint level, ++ GLint internalFormat, ++ GLint width, GLint height, GLint depth, ++ GLsizei imageSize, ++ GLenum format, GLenum type, const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage, ++ int compressed) ++{ ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ radeonTexObj* t = radeon_tex_obj(texObj); ++ radeon_texture_image* image = get_radeon_texture_image(texImage); ++ GLuint dstRowStride; ++ GLint postConvWidth = width; ++ GLint postConvHeight = height; ++ GLuint texelBytes; ++ ++ radeon_firevertices(rmesa); ++ ++ t->validated = GL_FALSE; ++ ++ if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { ++ _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, ++ &postConvHeight); ++ } ++ ++ /* Choose and fill in the texture format for this image */ ++ texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type, 0); ++ _mesa_set_fetch_functions(texImage, dims); ++ ++ if (texImage->TexFormat->TexelBytes == 0) { ++ texelBytes = 0; ++ texImage->IsCompressed = GL_TRUE; ++ texImage->CompressedSize = ++ ctx->Driver.CompressedTextureSize(ctx, texImage->Width, ++ texImage->Height, texImage->Depth, ++ texImage->TexFormat->MesaFormat); ++ } else { ++ texImage->IsCompressed = GL_FALSE; ++ texImage->CompressedSize = 0; ++ ++ texelBytes = texImage->TexFormat->TexelBytes; ++ /* Minimum pitch of 32 bytes */ ++ if (postConvWidth * texelBytes < 32) { ++ postConvWidth = 32 / texelBytes; ++ texImage->RowStride = postConvWidth; ++ } ++ if (!image->mt) { ++ assert(texImage->RowStride == postConvWidth); ++ } ++ } ++ ++ /* Allocate memory for image */ ++ radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */ ++ ++ if (t->mt && ++ t->mt->firstLevel == level && ++ t->mt->lastLevel == level && ++ t->mt->target != GL_TEXTURE_CUBE_MAP_ARB && ++ !radeon_miptree_matches_image(t->mt, texImage, face, level)) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = NULL; ++ } ++ ++ if (!t->mt) ++ radeon_try_alloc_miptree(rmesa, t, texImage, face, level); ++ if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) { ++ radeon_mipmap_level *lvl; ++ image->mt = t->mt; ++ image->mtlevel = level - t->mt->firstLevel; ++ image->mtface = face; ++ radeon_miptree_reference(t->mt); ++ lvl = &image->mt->levels[image->mtlevel]; ++ dstRowStride = lvl->rowstride; ++ } else { ++ int size; ++ if (texImage->IsCompressed) { ++ size = texImage->CompressedSize; ++ } else { ++ size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes; ++ } ++ texImage->Data = _mesa_alloc_texmemory(size); ++ } ++ ++ /* Upload texture image; note that the spec allows pixels to be NULL */ ++ if (compressed) { ++ pixels = _mesa_validate_pbo_compressed_teximage( ++ ctx, imageSize, pixels, packing, "glCompressedTexImage"); ++ } else { ++ pixels = _mesa_validate_pbo_teximage( ++ ctx, dims, width, height, depth, ++ format, type, pixels, packing, "glTexImage"); ++ } ++ ++ if (pixels) { ++ radeon_teximage_map(image, GL_TRUE); ++ ++ if (compressed) { ++ memcpy(texImage->Data, pixels, imageSize); ++ } else { ++ GLuint dstRowStride; ++ if (image->mt) { ++ radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; ++ dstRowStride = lvl->rowstride; ++ } else { ++ dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; ++ } ++ ++ if (!texImage->TexFormat->StoreImage(ctx, dims, ++ texImage->_BaseFormat, ++ texImage->TexFormat, ++ texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ ++ dstRowStride, ++ texImage->ImageOffsets, ++ width, height, depth, ++ format, type, pixels, packing)) ++ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); ++ } ++ ++ } ++ ++ /* SGIS_generate_mipmap */ ++ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { ++ radeon_generate_mipmap(ctx, texObj->Target, texObj); ++ } ++ ++ _mesa_unmap_teximage_pbo(ctx, packing); ++ ++ if (pixels) ++ radeon_teximage_unmap(image); ++ ++ ++} ++ ++void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, ++ GLint internalFormat, ++ GLint width, GLint border, ++ GLenum format, GLenum type, const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++{ ++ radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1, ++ 0, format, type, pixels, packing, texObj, texImage, 0); ++} ++ ++void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, ++ GLint internalFormat, ++ GLint width, GLint height, GLint border, ++ GLenum format, GLenum type, const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++ ++{ ++ GLuint face = radeon_face_for_target(target); ++ ++ radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, ++ 0, format, type, pixels, packing, texObj, texImage, 0); ++} ++ ++void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, ++ GLint level, GLint internalFormat, ++ GLint width, GLint height, GLint border, ++ GLsizei imageSize, const GLvoid * data, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++{ ++ GLuint face = radeon_face_for_target(target); ++ ++ radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, ++ imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1); ++} ++ ++void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, ++ GLint internalFormat, ++ GLint width, GLint height, GLint depth, ++ GLint border, ++ GLenum format, GLenum type, const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++{ ++ radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth, ++ 0, format, type, pixels, packing, texObj, texImage, 0); ++} ++ ++/** ++ * Update a subregion of the given texture image. ++ */ ++static void radeon_texsubimage(GLcontext* ctx, int dims, int level, ++ GLint xoffset, GLint yoffset, GLint zoffset, ++ GLsizei width, GLsizei height, GLsizei depth, ++ GLsizei imageSize, ++ GLenum format, GLenum type, ++ const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage, ++ int compressed) ++{ ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ radeonTexObj* t = radeon_tex_obj(texObj); ++ radeon_texture_image* image = get_radeon_texture_image(texImage); ++ ++ radeon_firevertices(rmesa); ++ ++ t->validated = GL_FALSE; ++ if (compressed) { ++ pixels = _mesa_validate_pbo_compressed_teximage( ++ ctx, imageSize, pixels, packing, "glCompressedTexImage"); ++ } else { ++ pixels = _mesa_validate_pbo_teximage(ctx, dims, ++ width, height, depth, format, type, pixels, packing, "glTexSubImage1D"); ++ } ++ ++ if (pixels) { ++ GLint dstRowStride; ++ radeon_teximage_map(image, GL_TRUE); ++ ++ if (image->mt) { ++ radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; ++ dstRowStride = lvl->rowstride; ++ } else { ++ dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; ++ } ++ ++ if (compressed) { ++ uint32_t srcRowStride, bytesPerRow, rows; ++ dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width); ++ srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); ++ bytesPerRow = srcRowStride; ++ rows = height / 4; ++ ++ copy_rows(texImage->Data, dstRowStride, image->base.Data, srcRowStride, rows, ++ bytesPerRow); ++ ++ } else { ++ if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, ++ texImage->TexFormat, texImage->Data, ++ xoffset, yoffset, zoffset, ++ dstRowStride, ++ texImage->ImageOffsets, ++ width, height, depth, ++ format, type, pixels, packing)) ++ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); ++ } ++ ++ } ++ ++ /* GL_SGIS_generate_mipmap */ ++ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { ++ radeon_generate_mipmap(ctx, texObj->Target, texObj); ++ } ++ radeon_teximage_unmap(image); ++ ++ _mesa_unmap_teximage_pbo(ctx, packing); ++ ++ ++} ++ ++void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, ++ GLint xoffset, ++ GLsizei width, ++ GLenum format, GLenum type, ++ const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++{ ++ radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 0, ++ format, type, pixels, packing, texObj, texImage, 0); ++} ++ ++void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, ++ GLint xoffset, GLint yoffset, ++ GLsizei width, GLsizei height, ++ GLenum format, GLenum type, ++ const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++{ ++ radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, ++ 0, format, type, pixels, packing, texObj, texImage, ++ 0); ++} ++ ++void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, ++ GLint level, GLint xoffset, ++ GLint yoffset, GLsizei width, ++ GLsizei height, GLenum format, ++ GLsizei imageSize, const GLvoid * data, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++{ ++ radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, ++ imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1); ++} ++ ++ ++void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, ++ GLint xoffset, GLint yoffset, GLint zoffset, ++ GLsizei width, GLsizei height, GLsizei depth, ++ GLenum format, GLenum type, ++ const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++{ ++ radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 0, ++ format, type, pixels, packing, texObj, texImage, 0); ++} ++ ++ ++ ++/** ++ * Ensure that the given image is stored in the given miptree from now on. ++ */ ++static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level) ++{ ++ radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; ++ unsigned char *dest; ++ ++ assert(image->mt != mt); ++ assert(dstlvl->width == image->base.Width); ++ assert(dstlvl->height == image->base.Height); ++ assert(dstlvl->depth == image->base.Depth); ++ ++ ++ radeon_bo_map(mt->bo, GL_TRUE); ++ dest = mt->bo->ptr + dstlvl->faces[face].offset; ++ ++ if (image->mt) { ++ /* Format etc. should match, so we really just need a memcpy(). ++ * In fact, that memcpy() could be done by the hardware in many ++ * cases, provided that we have a proper memory manager. ++ */ ++ radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; ++ ++ assert(srclvl->size == dstlvl->size); ++ assert(srclvl->rowstride == dstlvl->rowstride); ++ ++ radeon_bo_map(image->mt->bo, GL_FALSE); ++ ++ memcpy(dest, ++ image->mt->bo->ptr + srclvl->faces[face].offset, ++ dstlvl->size); ++ radeon_bo_unmap(image->mt->bo); ++ ++ radeon_miptree_unreference(image->mt); ++ } else { ++ uint32_t srcrowstride; ++ uint32_t height; ++ /* need to confirm this value is correct */ ++ if (mt->compressed) { ++ height = image->base.Height / 4; ++ srcrowstride = image->base.RowStride * mt->bpp; ++ } else { ++ height = image->base.Height * image->base.Depth; ++ srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes; ++ } ++ ++// if (mt->tilebits) ++// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__); ++ ++ copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride, ++ height, srcrowstride); ++ ++ _mesa_free_texmemory(image->base.Data); ++ image->base.Data = 0; ++ } ++ ++ radeon_bo_unmap(mt->bo); ++ ++ image->mt = mt; ++ image->mtface = face; ++ image->mtlevel = level; ++ radeon_miptree_reference(image->mt); ++} ++ ++int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj) ++{ ++ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); ++ radeonTexObj *t = radeon_tex_obj(texObj); ++ radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]); ++ int face, level; ++ ++ if (t->validated || t->image_override) ++ return GL_TRUE; ++ ++ if (RADEON_DEBUG & DEBUG_TEXTURE) ++ fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj); ++ ++ if (baseimage->base.Border > 0) ++ return GL_FALSE; ++ ++ /* Ensure a matching miptree exists. ++ * ++ * Differing mipmap trees can result when the app uses TexImage to ++ * change texture dimensions. ++ * ++ * Prefer to use base image's miptree if it ++ * exists, since that most likely contains more valid data (remember ++ * that the base level is usually significantly larger than the rest ++ * of the miptree, so cubemaps are the only possible exception). ++ */ ++ if (baseimage->mt && ++ baseimage->mt != t->mt && ++ radeon_miptree_matches_texture(baseimage->mt, &t->base)) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = baseimage->mt; ++ radeon_miptree_reference(t->mt); ++ } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) { ++ radeon_miptree_unreference(t->mt); ++ t->mt = 0; ++ } ++ ++ if (!t->mt) { ++ if (RADEON_DEBUG & DEBUG_TEXTURE) ++ fprintf(stderr, " Allocate new miptree\n"); ++ radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel); ++ if (!t->mt) { ++ _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree"); ++ return GL_FALSE; ++ } ++ } ++ ++ /* Ensure all images are stored in the single main miptree */ ++ for(face = 0; face < t->mt->faces; ++face) { ++ for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) { ++ radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]); ++ if (RADEON_DEBUG & DEBUG_TEXTURE) ++ fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt); ++ if (t->mt == image->mt) { ++ if (RADEON_DEBUG & DEBUG_TEXTURE) ++ fprintf(stderr, "OK\n"); ++ continue; ++ } ++ ++ if (RADEON_DEBUG & DEBUG_TEXTURE) ++ fprintf(stderr, "migrating\n"); ++ migrate_image_to_miptree(t->mt, image, face, level); ++ } ++ } ++ ++ return GL_TRUE; ++} ++ ++ ++/** ++ * Need to map texture image into memory before copying image data, ++ * then unmap it. ++ */ ++static void ++radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level, ++ GLenum format, GLenum type, GLvoid * pixels, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage, int compressed) ++{ ++ radeon_texture_image *image = get_radeon_texture_image(texImage); ++ ++ if (image->mt) { ++ /* Map the texture image read-only */ ++ radeon_teximage_map(image, GL_FALSE); ++ } else { ++ /* Image hasn't been uploaded to a miptree yet */ ++ assert(image->base.Data); ++ } ++ ++ if (compressed) { ++ _mesa_get_compressed_teximage(ctx, target, level, pixels, ++ texObj, texImage); ++ } else { ++ _mesa_get_teximage(ctx, target, level, format, type, pixels, ++ texObj, texImage); ++ } ++ ++ if (image->mt) { ++ radeon_teximage_unmap(image); ++ } ++} ++ ++void ++radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level, ++ GLenum format, GLenum type, GLvoid * pixels, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++{ ++ radeon_get_tex_image(ctx, target, level, format, type, pixels, ++ texObj, texImage, 0); ++} ++ ++void ++radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, ++ GLvoid *pixels, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage) ++{ ++ radeon_get_tex_image(ctx, target, level, 0, 0, pixels, ++ texObj, texImage, 1); ++} +diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h +new file mode 100644 +index 0000000..888a55b +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_texture.h +@@ -0,0 +1,122 @@ ++/* ++ * Copyright (C) 2008 Nicolai Haehnle. ++ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. ++ * ++ * The Weather Channel (TM) funded Tungsten Graphics to develop the ++ * initial release of the Radeon 8500 driver under the XFree86 license. ++ * This notice must be preserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef RADEON_TEXTURE_H ++#define RADEON_TEXTURE_H ++struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx); ++void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage); ++ ++void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable); ++void radeon_teximage_unmap(radeon_texture_image *image); ++void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj); ++void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj); ++void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj); ++int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj); ++GLuint radeon_face_for_target(GLenum target); ++const struct gl_texture_format *radeonChooseTextureFormat_mesa(GLcontext * ctx, ++ GLint internalFormat, ++ GLenum format, ++ GLenum type); ++const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, ++ GLint internalFormat, ++ GLenum format, ++ GLenum type, GLboolean fbo); ++ ++void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, ++ GLint internalFormat, ++ GLint width, GLint border, ++ GLenum format, GLenum type, const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, ++ GLint internalFormat, ++ GLint width, GLint height, GLint border, ++ GLenum format, GLenum type, const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, ++ GLint level, GLint internalFormat, ++ GLint width, GLint height, GLint border, ++ GLsizei imageSize, const GLvoid * data, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, ++ GLint internalFormat, ++ GLint width, GLint height, GLint depth, ++ GLint border, ++ GLenum format, GLenum type, const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, ++ GLint xoffset, ++ GLsizei width, ++ GLenum format, GLenum type, ++ const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, ++ GLint xoffset, GLint yoffset, ++ GLsizei width, GLsizei height, ++ GLenum format, GLenum type, ++ const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, ++ GLint level, GLint xoffset, ++ GLint yoffset, GLsizei width, ++ GLsizei height, GLenum format, ++ GLsizei imageSize, const GLvoid * data, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++ ++void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, ++ GLint xoffset, GLint yoffset, GLint zoffset, ++ GLsizei width, GLsizei height, GLsizei depth, ++ GLenum format, GLenum type, ++ const GLvoid * pixels, ++ const struct gl_pixelstore_attrib *packing, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++ ++void radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level, ++ GLenum format, GLenum type, GLvoid * pixels, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++void radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, ++ GLvoid *pixels, ++ struct gl_texture_object *texObj, ++ struct gl_texture_image *texImage); ++ ++#endif +diff --git a/src/mesa/drivers/dri/radeon/server/radeon_reg.h b/src/mesa/drivers/dri/radeon/server/radeon_reg.h +index ae2ccdf..8668074 100644 +--- a/src/mesa/drivers/dri/radeon/server/radeon_reg.h ++++ b/src/mesa/drivers/dri/radeon/server/radeon_reg.h +@@ -2031,6 +2031,9 @@ + #define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 + #define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 + #define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 ++#define R200_CP_CMD_3D_DRAW_VBUF_2 0xC0003400 ++#define R200_CP_CMD_3D_DRAW_IMMD_2 0xC0003500 ++#define R200_CP_CMD_3D_DRAW_INDX_2 0xC0003600 + #define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 + #define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 + #define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 diff --git a/packages/graphics/Mesa/install b/packages/graphics/Mesa/install index 2874163899..85a64330c2 100755 --- a/packages/graphics/Mesa/install +++ b/packages/graphics/Mesa/install @@ -11,9 +11,10 @@ $SCRIPTS/install libXxf86vm $SCRIPTS/install libX11 mkdir -p $INSTALL/usr/lib -cp -PR $BUILD/$1*/src/mesa/libmesa.so* $INSTALL/usr/lib +#cp -PR $BUILD/$1*/src/mesa/libmesa.so* $INSTALL/usr/lib #cp -PR $BUILD/$1*/src/mesa/libglapi.so* $INSTALL/usr/lib cp -PR $BUILD/$1*/lib/libGL.so* $INSTALL/usr/lib +cp -PR $BUILD/$1*/lib/libdricore.so $INSTALL/usr/lib #cp -PR $BUILD/$1*/lib/libGLU.so* $INSTALL/usr/lib mkdir -p $INSTALL/usr/lib/dri diff --git a/packages/graphics/Mesa/patches/21_mesa-7.1-osmesa-version.diff b/packages/graphics/Mesa/patches/21_mesa-7.1-osmesa-version.diff new file mode 100644 index 0000000000..cd41ad252d --- /dev/null +++ b/packages/graphics/Mesa/patches/21_mesa-7.1-osmesa-version.diff @@ -0,0 +1,21 @@ +diff -up Mesa-7.1/src/mesa/drivers/osmesa/Makefile.jx Mesa-7.1/src/mesa/drivers/osmesa/Makefile +--- Mesa-7.1/src/mesa/drivers/osmesa/Makefile.jx 2008-08-28 14:05:47.000000000 -0400 ++++ Mesa-7.1/src/mesa/drivers/osmesa/Makefile 2008-08-28 14:07:13.000000000 -0400 +@@ -46,7 +46,7 @@ osmesa8: $(TOP)/lib/$(OSMESA_LIB_NAME) + + $(TOP)/lib/$(OSMESA_LIB_NAME): $(OBJECTS) + $(MKLIB) -o $(OSMESA_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ +- -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \ ++ -major 6 -minor 5 -patch 3 \ + -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ + -id $(INSTALL_LIB_DIR)/lib$(OSMESA_LIB).$(MESA_MAJOR).dylib \ + $(OSMESA_LIB_DEPS) $(OBJECTS) +@@ -58,7 +58,7 @@ $(TOP)/lib/$(OSMESA_LIB_NAME): $(OBJECTS + # with all the other Mesa sources (compiled with -DCHAN_BITS=16/32 + osmesa16: $(OBJECTS) $(CORE_MESA) + $(MKLIB) -o $(OSMESA_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ +- -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \ ++ -major 6 -minor 5 -patch 3 \ + -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ + -id $(INSTALL_LIB_DIR)/lib$(OSMESA_LIB).$(MESA_MAJOR).dylib \ + $(OSMESA_LIB_DEPS) $(OBJECTS) $(CORE_MESA) diff --git a/packages/graphics/Mesa/patches/22_mesa-7.1-nukeglthread-debug.diff b/packages/graphics/Mesa/patches/22_mesa-7.1-nukeglthread-debug.diff new file mode 100644 index 0000000000..3df6e9a32b --- /dev/null +++ b/packages/graphics/Mesa/patches/22_mesa-7.1-nukeglthread-debug.diff @@ -0,0 +1,15 @@ +diff -up Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c.intel-glthread Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c +--- Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c.intel-glthread 2008-08-25 10:49:40.000000000 -0400 ++++ Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c 2008-08-28 14:26:17.000000000 -0400 +@@ -633,11 +633,6 @@ intel_render_texture(GLcontext * ctx, + return; + } + +- DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", +- _glthread_GetID(), +- att->Texture->Name, newImage->Width, newImage->Height, +- irb->Base.RefCount); +- + /* point the renderbufer's region to the texture image region */ + intel_image = intel_texture_image(newImage); + if (irb->region != intel_image->mt->region) { diff --git a/packages/graphics/Mesa/patches/25_mesa-7.1-link-shared.diff b/packages/graphics/Mesa/patches/25_mesa-7.1-link-shared.diff new file mode 100644 index 0000000000..b06eaef17f --- /dev/null +++ b/packages/graphics/Mesa/patches/25_mesa-7.1-link-shared.diff @@ -0,0 +1,102 @@ +diff -Naur Mesa-7.4.1/src/mesa/drivers/dri/Makefile Mesa-7.4.1.patch/src/mesa/drivers/dri/Makefile +--- Mesa-7.4.1/src/mesa/drivers/dri/Makefile 2009-03-13 04:28:49.000000000 +0100 ++++ Mesa-7.4.1.patch/src/mesa/drivers/dri/Makefile 2009-04-25 22:26:13.000000000 +0200 +@@ -6,12 +6,16 @@ + + + +-default: $(TOP)/$(LIB_DIR) subdirs +- ++default: $(TOP)/$(LIB_DIR) $(TOP)/$(LIB_DIR)/libdricore.so subdirs + + $(TOP)/$(LIB_DIR): + -mkdir $(TOP)/$(LIB_DIR) + ++libdricore.so: ++ $(CC) -shared -o libdricore.so -Wl,--whole-archive ../../libmesa.a -Wl,--no-whole-archive -lm -lpthread -lc ++ ++$(TOP)/$(LIB_DIR)/libdricore.so: $(TOP)/$(LIB_DIR) libdricore.so ++ $(INSTALL) libdricore.so $(TOP)/$(LIB_DIR) + + subdirs: + @for dir in $(DRI_DIRS) ; do \ +@@ -32,12 +36,14 @@ + $(pcedit) $< > $@ + + +-install: dri.pc ++install: dri.pc $(TOP)/$(LIB_DIR)/libdricore.so + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1 ; \ + fi \ + done ++ $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) ++ $(INSTALL) -m 755 $(TOP)/$(LIB_DIR)/libdricore.so $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/GL/internal + $(INSTALL) -m 0644 $(TOP)/include/GL/internal/dri_interface.h \ + $(DESTDIR)$(INSTALL_INC_DIR)/GL/internal +@@ -51,5 +57,6 @@ + (cd $$dir && $(MAKE) clean) ; \ + fi \ + done ++ -rm -f libdricore.so $(TOP)/$(LIB_DIR)/libdricore.so + -rm -f common/*.o + -rm -f *.pc +diff -Naur Mesa-7.4.1/src/mesa/drivers/dri/Makefile.template Mesa-7.4.1.patch/src/mesa/drivers/dri/Makefile.template +--- Mesa-7.4.1/src/mesa/drivers/dri/Makefile.template 2009-03-13 04:28:49.000000000 +0100 ++++ Mesa-7.4.1.patch/src/mesa/drivers/dri/Makefile.template 2009-04-25 22:22:59.000000000 +0200 +@@ -1,6 +1,6 @@ + # -*-makefile-*- + +-MESA_MODULES = $(TOP)/src/mesa/libmesa.a ++MESA_MODULES = $(TOP)/$(LIB_DIR)/libdricore.so + + COMMON_SOURCES = \ + ../common/utils.c \ +@@ -61,7 +61,9 @@ + + $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template + $(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ +- $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) ++ $(OBJECTS) $(WINOBJ) \ ++ -L$(TOP)/$(LIB_DIR) -Wl,-R$(DRI_DRIVER_INSTALL_DIR) -ldricore \ ++ $(DRI_LIB_DEPS) + + + $(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) +diff -Naur Mesa-7.4.1/src/mesa/x86/read_rgba_span_x86.S Mesa-7.4.1.patch/src/mesa/x86/read_rgba_span_x86.S +--- Mesa-7.4.1/src/mesa/x86/read_rgba_span_x86.S 2008-08-25 16:46:47.000000000 +0200 ++++ Mesa-7.4.1.patch/src/mesa/x86/read_rgba_span_x86.S 2009-04-25 22:20:15.000000000 +0200 +@@ -77,7 +77,6 @@ + */ + + .globl _generic_read_RGBA_span_BGRA8888_REV_MMX +-.hidden _generic_read_RGBA_span_BGRA8888_REV_MMX + .type _generic_read_RGBA_span_BGRA8888_REV_MMX, @function + _generic_read_RGBA_span_BGRA8888_REV_MMX: + pushl %ebx +@@ -172,7 +171,6 @@ + */ + + .globl _generic_read_RGBA_span_BGRA8888_REV_SSE +-.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE + .type _generic_read_RGBA_span_BGRA8888_REV_SSE, @function + _generic_read_RGBA_span_BGRA8888_REV_SSE: + pushl %esi +@@ -335,7 +333,6 @@ + + .text + .globl _generic_read_RGBA_span_BGRA8888_REV_SSE2 +-.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE2 + .type _generic_read_RGBA_span_BGRA8888_REV_SSE2, @function + _generic_read_RGBA_span_BGRA8888_REV_SSE2: + pushl %esi +@@ -494,7 +491,6 @@ + + .text + .globl _generic_read_RGBA_span_RGB565_MMX +- .hidden _generic_read_RGBA_span_RGB565_MMX + .type _generic_read_RGBA_span_RGB565_MMX, @function + + _generic_read_RGBA_span_RGB565_MMX: diff --git a/packages/graphics/Mesa/patches/26_intel-revert-vbl.diff b/packages/graphics/Mesa/patches/26_intel-revert-vbl.diff new file mode 100644 index 0000000000..0394414736 --- /dev/null +++ b/packages/graphics/Mesa/patches/26_intel-revert-vbl.diff @@ -0,0 +1,21 @@ +commit 532d2051245a1d8afe7ca236f1d966d555bb121a +Author: Dave Airlie +Date: Fri Sep 12 17:21:25 2008 +1000 + + Revert "intel: sync to vblank by default" + + This reverts commit e9bf3e4cc9a7e4bcd4c45bd707541d26ecdf0409. + +diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c +index c193830..f02192d 100644 +--- a/src/mesa/drivers/dri/intel/intel_screen.c ++++ b/src/mesa/drivers/dri/intel/intel_screen.c +@@ -55,7 +55,7 @@ PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN + DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) +- DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC) ++ DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + /* Options correspond to DRI_CONF_BO_REUSE_DISABLED, + * DRI_CONF_BO_REUSE_ALL + */ diff --git a/packages/graphics/Mesa/patches/27_mesa-7.1-disable-intel-classic-warn.diff b/packages/graphics/Mesa/patches/27_mesa-7.1-disable-intel-classic-warn.diff new file mode 100644 index 0000000000..f0fa0c741e --- /dev/null +++ b/packages/graphics/Mesa/patches/27_mesa-7.1-disable-intel-classic-warn.diff @@ -0,0 +1,15 @@ +diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c +index cf09fad..572a28b 100644 +--- a/src/mesa/drivers/dri/intel/intel_screen.c ++++ b/src/mesa/drivers/dri/intel/intel_screen.c +@@ -583,8 +583,8 @@ intel_init_bufmgr(intelScreenPrivate *intelScreen) + if (gem_disable) { + fprintf(stderr, "GEM disabled. Using classic.\n"); + } else { +- fprintf(stderr, "Failed to initialize GEM. " +- "Falling back to classic.\n"); ++// fprintf(stderr, "Failed to initialize GEM. " ++// "Falling back to classic.\n"); + } + + if (intelScreen->tex.size == 0) { diff --git a/packages/linux/1813_drm-radeon-pm.diff b/packages/linux/1813_drm-radeon-pm.diff new file mode 100644 index 0000000000..df12ec8a8f --- /dev/null +++ b/packages/linux/1813_drm-radeon-pm.diff @@ -0,0 +1,586 @@ +diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/atombios_crtc.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/atombios_crtc.c +--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/atombios_crtc.c.mjg 2009-03-03 19:41:48.000000000 +0000 ++++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/atombios_crtc.c 2009-03-03 20:53:05.000000000 +0000 +@@ -441,14 +441,23 @@ static bool atombios_crtc_mode_fixup(str + + static void atombios_crtc_prepare(struct drm_crtc *crtc) + { ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ ++ mutex_lock(&dev_priv->mode_info.power.pll_mutex); ++ + atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); + atombios_lock_crtc(crtc, 1); + } + + static void atombios_crtc_commit(struct drm_crtc *crtc) + { ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ + atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); + atombios_lock_crtc(crtc, 0); ++ mutex_unlock(&dev_priv->mode_info.power.pll_mutex); + } + + static const struct drm_crtc_helper_funcs atombios_helper_funcs = { +diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_atombios.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_atombios.c +--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_atombios.c.mjg 2009-03-03 19:41:48.000000000 +0000 ++++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_atombios.c 2009-03-03 20:53:05.000000000 +0000 +@@ -620,6 +620,34 @@ void radeon_atom_static_pwrmgt_setup(str + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); + } + ++void radeon_atom_get_mc_arb_info(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct atom_context *ctx = mode_info->atom_context; ++ int index = GetIndexIntoMasterTable(DATA, MC_InitParameter); ++ uint8_t frev, crev; ++ uint16_t size, data_offset; ++ ++ atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); ++ dev_priv->mode_info.power.mc_arb_init_values = ++ kmalloc(size*sizeof(int), GFP_KERNEL); ++ memcpy(dev_priv->mode_info.power.mc_arb_init_values, ++ ctx->bios + data_offset, size * sizeof(int)); ++} ++ ++void radeon_atom_get_engine_clock(struct drm_device *dev, int *engine_clock) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct atom_context *ctx = mode_info->atom_context; ++ GET_ENGINE_CLOCK_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock); ++ ++ atom_execute_table(ctx, index, (uint32_t *)&args); ++ *engine_clock = args.ulReturnEngineClock; ++} ++ + void radeon_atom_set_engine_clock(struct drm_device *dev, int eng_clock) + { + struct drm_radeon_private *dev_priv = dev->dev_private; +@@ -633,6 +661,18 @@ void radeon_atom_set_engine_clock(struct + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); + } + ++void radeon_atom_get_memory_clock(struct drm_device *dev, int *mem_clock) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct atom_context *ctx = mode_info->atom_context; ++ GET_MEMORY_CLOCK_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock); ++ ++ atom_execute_table(ctx, index, (uint32_t *)&args); ++ *mem_clock = args.ulReturnMemoryClock; ++} ++ + void radeon_atom_set_memory_clock(struct drm_device *dev, int mem_clock) + { + struct drm_radeon_private *dev_priv = dev->dev_private; +@@ -646,6 +686,16 @@ void radeon_atom_set_memory_clock(struct + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); + } + ++void radeon_atom_initialize_memory_controller(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct atom_context *ctx = dev_priv->mode_info.atom_context; ++ int index = GetIndexIntoMasterTable(COMMAND, MemoryDeviceInit); ++ MEMORY_PLLINIT_PS_ALLOCATION args; ++ ++ atom_execute_table(ctx, index, (uint32_t *)&args); ++} ++ + void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) + { + struct drm_radeon_private *dev_priv = dev->dev_private; +diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cp.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cp.c +--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cp.c.mjg 2009-03-03 19:41:48.000000000 +0000 ++++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cp.c 2009-03-03 20:53:05.000000000 +0000 +@@ -3223,6 +3223,8 @@ int radeon_driver_load(struct drm_device + if (ret) + goto modeset_fail; + ++ mutex_init(&dev_priv->mode_info.power.pll_mutex); ++ + radeon_modeset_init(dev); + + radeon_modeset_cp_init(dev); +@@ -3231,7 +3233,7 @@ int radeon_driver_load(struct drm_device + drm_irq_install(dev); + } + +- ++ radeon_pm_init(dev); + return ret; + modeset_fail: + dev->driver->driver_features &= ~DRIVER_MODESET; +@@ -3303,6 +3305,8 @@ int radeon_driver_unload(struct drm_devi + { + drm_radeon_private_t *dev_priv = dev->dev_private; + ++ radeon_pm_exit(dev); ++ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + drm_irq_uninstall(dev); + radeon_modeset_cleanup(dev); +diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cs.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cs.c +--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cs.c.mjg 2009-03-03 19:41:48.000000000 +0000 ++++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cs.c 2009-03-03 20:53:05.000000000 +0000 +@@ -41,6 +41,8 @@ int radeon_cs_ioctl(struct drm_device *d + long size; + int r, i; + ++ radeon_pm_timer_reset(dev); ++ + mutex_lock(&dev_priv->cs.cs_mutex); + /* set command stream id to 0 which is fake id */ + cs_id = 0; +diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_drv.h.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_drv.h +--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_drv.h.mjg 2009-03-03 19:41:48.000000000 +0000 ++++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_drv.h 2009-03-03 20:53:05.000000000 +0000 +@@ -612,6 +612,9 @@ extern int radeon_modeset_cp_resume(stru + /* radeon_pm.c */ + int radeon_suspend(struct drm_device *dev, pm_message_t state); + int radeon_resume(struct drm_device *dev); ++void radeon_pm_init(struct drm_device *dev); ++void radeon_pm_exit(struct drm_device *dev); ++void radeon_pm_timer_reset(struct drm_device *dev); + + /* Flags for stats.boxes + */ +diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_irq.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_irq.c +--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_irq.c.mjg 2009-03-03 19:41:48.000000000 +0000 ++++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_irq.c 2009-03-03 20:53:05.000000000 +0000 +@@ -185,8 +185,10 @@ irqreturn_t radeon_driver_irq_handler(DR + struct drm_device *dev = (struct drm_device *) arg; + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *) dev->dev_private; ++ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power; + u32 stat; + u32 r500_disp_int; ++ unsigned long flags; + + /* Only consider the bits we're interested in - others could be used + * outside the DRM +@@ -206,15 +208,47 @@ irqreturn_t radeon_driver_irq_handler(DR + + /* VBLANK interrupt */ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { +- if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) ++ if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) { ++ spin_lock_irqsave(&power->power_lock, flags); ++ if (power->reclock_head & 1) { ++ power->reclock_head &= ~1; ++ schedule_work(&power->reclock_work); ++ drm_vblank_put(dev, 0); ++ } ++ spin_unlock_irqrestore(&power->power_lock, flags); + drm_handle_vblank(dev, 0); +- if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) ++ } ++ if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) { ++ spin_lock_irqsave(&power->power_lock, flags); ++ if (power->reclock_head & 2) { ++ power->reclock_head &= ~2; ++ schedule_work(&power->reclock_work); ++ drm_vblank_put(dev, 1); ++ } ++ spin_unlock_irqrestore(&power->power_lock, flags); + drm_handle_vblank(dev, 1); ++ } + } else { +- if (stat & RADEON_CRTC_VBLANK_STAT) ++ if (stat & RADEON_CRTC_VBLANK_STAT) { ++ spin_lock_irqsave(&power->power_lock, flags); ++ if (power->reclock_head & 1) { ++ power->reclock_head &= ~1; ++ schedule_work(&power->reclock_work); ++ drm_vblank_put(dev, 0); ++ } ++ spin_unlock_irqrestore(&power->power_lock, flags); + drm_handle_vblank(dev, 0); +- if (stat & RADEON_CRTC2_VBLANK_STAT) ++ } ++ if (stat & RADEON_CRTC2_VBLANK_STAT) { ++ spin_lock_irqsave(&power->power_lock, flags); ++ if (power->reclock_head & 2) { ++ power->reclock_head &= ~2; ++ schedule_work(&power->reclock_work); ++ drm_vblank_put(dev, 1); ++ } ++ spin_unlock_irqrestore(&power->power_lock, flags); + drm_handle_vblank(dev, 1); ++ } + } + return IRQ_HANDLED; + } +diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_mode.h.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_mode.h +--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_mode.h.mjg 2009-03-03 19:41:48.000000000 +0000 ++++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_mode.h 2009-03-03 20:53:05.000000000 +0000 +@@ -173,6 +173,22 @@ struct radeon_i2c_chan { + struct radeon_i2c_bus_rec rec; + }; + ++struct radeon_powermanagement_info { ++ struct timer_list idle_power_timer; ++ struct work_struct reclock_work; ++ struct drm_device *dev; ++ uint32_t orig_memory_clock; ++ uint32_t orig_engine_clock; ++ uint32_t *mc_arb_init_values; ++ uint8_t orig_fbdiv; ++ int new_mem_clock; ++ int new_engine_clock; ++ int current_clock_state; ++ int reclock_head; ++ struct mutex pll_mutex; ++ spinlock_t power_lock; ++}; ++ + struct radeon_mode_info { + struct atom_context *atom_context; + struct radeon_bios_connector bios_connector[RADEON_MAX_BIOS_CONNECTOR]; +@@ -182,6 +198,9 @@ struct radeon_mode_info { + struct radeon_pll mpll; + uint32_t mclk; + uint32_t sclk; ++ ++ /* power management */ ++ struct radeon_powermanagement_info power; + }; + + struct radeon_crtc { +@@ -307,6 +326,12 @@ extern int radeon_crtc_cursor_move(struc + + extern bool radeon_atom_get_clock_info(struct drm_device *dev); + extern bool radeon_combios_get_clock_info(struct drm_device *dev); ++extern void radeon_atom_get_engine_clock(struct drm_device *dev, int *engine_clock); ++extern void radeon_atom_get_memory_clock(struct drm_device *dev, int *memory_clock); ++extern void radeon_atom_set_engine_clock(struct drm_device *dev, int engine_clock); ++extern void radeon_atom_set_memory_clock(struct drm_device *dev, int memory_clock); ++extern void radeon_atom_initialize_memory_controller(struct drm_device *dev); ++extern void radeon_atom_get_mc_arb_info(struct drm_device *dev); + extern void radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); + extern void radeon_atombios_get_tmds_info(struct radeon_encoder *encoder); + extern bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder); +diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_pm.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_pm.c +--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_pm.c.mjg 2009-03-03 19:41:48.000000000 +0000 ++++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_pm.c 2009-03-03 20:53:05.000000000 +0000 +@@ -31,6 +31,8 @@ + + #include "drm_crtc_helper.h" + ++#define RADEON_DOWNCLOCK_IDLE_MS 30 ++ + int radeon_suspend(struct drm_device *dev, pm_message_t state) + { + struct drm_radeon_private *dev_priv = dev->dev_private; +@@ -255,3 +257,214 @@ bool radeon_set_pcie_lanes(struct drm_de + return false; + } + ++static void radeon_pm_set_engine_clock(struct drm_device *dev, int freq) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_set_engine_clock(dev, freq); ++} ++ ++static void radeon_pm_set_memory_clock(struct drm_device *dev, int freq) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power; ++ ++ mutex_lock(&power->pll_mutex); ++ radeon_do_cp_idle(dev_priv); ++ if (dev_priv->is_atom_bios) { ++ int mpll, spll, hclk, sclk, fbdiv, index, factor; ++ switch (dev_priv->chip_family) { ++ case CHIP_R520: ++ case CHIP_RV530: ++ case CHIP_RV560: ++ case CHIP_RV570: ++ case CHIP_R580: ++ mpll = RADEON_READ_PLL(dev_priv, MPLL_FUNC_CNTL); ++ fbdiv = (mpll & 0x1fe0) >> 5; ++ ++ /* Set new fbdiv */ ++ factor = power->orig_memory_clock / freq; ++ fbdiv = power->orig_fbdiv / factor; ++ ++ mpll &= ~0x1fe0; ++ mpll |= ((fbdiv << 5) | (1 << 24)); ++ mpll &= ~(1 << 25); ++ ++ spll = RADEON_READ_PLL(dev_priv, SPLL_FUNC_CNTL); ++ ++ hclk = fbdiv << 5; ++ hclk += 0x20; ++ hclk *= 8; ++ ++ sclk = spll & 0x1fe0; ++ sclk += 0x20; ++ sclk *= 6; ++ sclk = sclk >> 5; ++ ++ index = (hclk/sclk); ++ ++ R500_WRITE_MCIND(R530_MC_ARB_RATIO_CLK_SEQ, ++ power->mc_arb_init_values[index]); ++ RADEON_WRITE_PLL(dev_priv, MPLL_FUNC_CNTL, mpll); ++ radeon_atom_initialize_memory_controller(dev); ++ break; ++ } ++ } ++ ++ mutex_unlock(&power->pll_mutex); ++} ++ ++static int radeon_pm_get_active_crtcs(struct drm_device *dev, int *crtcs) ++{ ++ struct drm_crtc *crtc; ++ int count = 0; ++ struct radeon_crtc *radeon_crtc; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ radeon_crtc = to_radeon_crtc(crtc); ++ if (crtc->enabled) { ++ count++; ++ *crtcs |= (1 << radeon_crtc->crtc_id); ++ } ++ } ++ return count; ++} ++ ++ ++static void radeon_pm_perform_transition(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power; ++ int crtcs = 0, count; ++ unsigned long flags; ++ ++ count = radeon_pm_get_active_crtcs(dev, &crtcs); ++ ++ spin_lock_irqsave(&power->power_lock, flags); ++ switch (count) { ++ case 0: ++ schedule_work(&power->reclock_work); ++ break; ++ case 1: ++ if (power->reclock_head) ++ break; ++ if (crtcs & 1) { ++ power->reclock_head |= 1; ++ drm_vblank_get(dev, 0); ++ } else { ++ power->reclock_head |= 2; ++ drm_vblank_get(dev, 1); ++ } ++ break; ++ default: ++ /* Too many active heads */ ++ break; ++ } ++ spin_unlock_irqrestore(&power->power_lock, flags); ++} ++ ++ ++static int radeon_pm_set_runtime_power(struct drm_device *dev, int value) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power; ++ ++ if (power->current_clock_state == value) ++ return 1; ++ ++ switch (value) { ++ case 0: ++ power->new_engine_clock = 100*100; ++ power->new_mem_clock = 100*100; ++ break; ++ case 1: ++ power->new_engine_clock = power->orig_engine_clock; ++ power->new_mem_clock = power->orig_memory_clock; ++ break; ++ } ++ ++ power->current_clock_state = value; ++ radeon_pm_perform_transition(dev); ++ ++ return 0; ++} ++ ++static void radeon_pm_idle_timeout(unsigned long d) ++{ ++ struct drm_device *dev = (struct drm_device *)d; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ radeon_pm_set_runtime_power(dev, 0); ++} ++ ++static void radeon_pm_reclock_callback(struct work_struct *work) ++{ ++ struct radeon_powermanagement_info *power = ++ container_of(work, struct radeon_powermanagement_info, ++ reclock_work); ++ struct drm_device *dev = power->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ mutex_lock(&dev_priv->cs.cs_mutex); ++ radeon_pm_set_memory_clock(dev, power->new_mem_clock); ++ radeon_pm_set_engine_clock(dev, power->new_engine_clock); ++ mutex_unlock(&dev_priv->cs.cs_mutex); ++} ++ ++void radeon_pm_timer_reset(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power; ++ ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) ++ return; ++ ++ radeon_pm_set_runtime_power(dev, 1); ++ ++ mod_timer(&power->idle_power_timer, ++ jiffies + msecs_to_jiffies(RADEON_DOWNCLOCK_IDLE_MS)); ++} ++ ++void radeon_pm_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power; ++ ++ power->dev = dev; ++ ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) ++ return; ++ ++ if (dev_priv->is_atom_bios) { ++ int mpll; ++ radeon_atom_get_mc_arb_info(dev); ++ radeon_atom_get_engine_clock(dev, &power->orig_engine_clock); ++ radeon_atom_get_memory_clock(dev, &power->orig_memory_clock); ++ ++ mpll = RADEON_READ_PLL(dev_priv, MPLL_FUNC_CNTL); ++ dev_priv->mode_info.power.orig_fbdiv = (mpll & 0x1fe0) >> 5; ++ } ++ ++ setup_timer(&power->idle_power_timer, radeon_pm_idle_timeout, ++ (unsigned long)dev); ++ INIT_WORK(&power->reclock_work, radeon_pm_reclock_callback); ++ ++ spin_lock_init(&power->power_lock); ++ ++ power->current_clock_state = 1; ++ power->reclock_head = 0; ++ ++ radeon_pm_timer_reset(dev); ++} ++ ++void radeon_pm_exit(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power; ++ ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) ++ return; ++ ++ del_timer_sync(&power->idle_power_timer); ++} +diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_reg.h.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_reg.h +--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_reg.h.mjg 2009-03-03 19:41:48.000000000 +0000 ++++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_reg.h 2009-03-03 20:53:05.000000000 +0000 +@@ -303,6 +303,28 @@ + # define RADEON_PLL_WR_EN (1 << 7) + # define RADEON_PLL_DIV_SEL (3 << 8) + # define RADEON_PLL2_DIV_SEL_MASK ~(3 << 8) ++#define SPLL_FUNC_CNTL 0x0000 ++#define MPLL_FUNC_CNTL 0x0004 ++#define GENERAL_PWRMGT 0x0008 ++# define RADEON_GLOBAL_PWRMGT_EN (1 << 0) ++#define SCLK_PWRMGT_CNTL 0x0009 ++# define RADEON_SCLK_PWRMGT_OFF (1 << 0) ++#define MCLK_PWRMGT_CNTL 0x000a ++# define RADEON_MCLK_PWRMGT_OFF (1 << 0) ++#define DYN_PWRMGT_SCLK_CNTL 0x000b ++# define RADEON_ENGINE_DYNCLK_MODE (1 << 0) ++# define RADEON_STATIC_SCREEN_EN (1 << 20) ++# define RADEON_CLIENT_SELECT_POWER_EN (1 << 21) ++#define DYN_SCLK_PWMEN_PIPE 0x000d ++# define RADEON_PIPE_3D_NOT_AUTO (1 << 8) ++#define DYN_SCLK_VOL_CNTL 0x000e ++# define RADEON_IO_CG_VOLTAGE_DROP (1 << 0) ++# define RADEON_VOLTAGE_DROP_SYNC (1 << 2) ++#define CP_DYN_CNTL 0x000f ++# define RADEON_CP_FORCEON (1 << 0) ++# define RADEON_CP_LOWER_POWER_IGNORE (1 << 20) ++# define RADEON_CP_NORMAL_POWER_IGNORE (1 << 21) ++# define RADEON_CP_NORMAL_POWER_BUSY (1 << 24) + #define RADEON_CLK_PWRMGT_CNTL 0x0014 + # define RADEON_ENGIN_DYNCLK_MODE (1 << 12) + # define RADEON_ACTIVE_HILO_LAT_MASK (3 << 13) +@@ -3961,7 +3983,48 @@ + # define AVIVO_I2C_RESET (1 << 8) + + #define R600_GENERAL_PWRMGT 0x618 ++# define R600_GLOBAL_PWRMGT_EN (1 << 0) ++# define R600_STATIC_PM_EN (1 << 1) ++# define R600_MOBILE_SU (1 << 2) ++# define R600_THERMAL_PROTECTION_DIS (1 << 3) ++# define R600_THERMAL_PROTECTION_TYPE (1 << 4) ++# define R600_ENABLE_GEN2PCIE (1 << 5) ++# define R600_SW_GPIO_INDEX (1 << 6) ++# define R600_LOW_VOLT_D2_ACPI (1 << 8) ++# define R600_LOW_VOLT_D3_ACPI (1 << 9) ++# define R600_VOLT_PWRMGT_EN (1 << 10) + # define R600_OPEN_DRAIN_PADS (1 << 11) ++# define R600_AVP_SCLK_EN (1 << 12) ++# define R600_IDCT_SCLK_EN (1 << 13) ++# define R600_GPU_COUNTER_ACPI (1 << 14) ++# define R600_COUNTER_CLK (1 << 15) ++# define R600_BACKBIAS_PAD_EN (1 << 16) ++# define R600_BACKBIAS_VALUE (1 << 17) ++# define R600_BACKBIAS_DPM_CNTL (1 << 18) ++# define R600_SPREAD_SPECTRUM_INDEX (1 << 19) ++# define R600_DYN_SPREAD_SPECTRUM_EN (1 << 21) ++ ++#define R600_SCLK_PWRMGT_CNTL 0x620 ++# define R600_SCLK_PWRMGT_OFF (1 << 0) ++# define R600_SCLK_TURNOFF (1 << 1) ++# define R600_SPLL_TURNOFF (1 << 2) ++# define R600_SU_SCLK_USE_BCLK (1 << 3) ++# define R600_DYNAMIC_GFX_ISLAND_PWR_DOWN (1 << 4) ++# define R600_DYNAMIC_GFX_ISLAND_LP (1 << 5) ++# define R600_CLK_TURN_ON_STAGGER (1 << 6) ++# define R600_CLK_TURN_OFF_STAGGER (1 << 7) ++# define R600_FIR_FORCE_TREND_SEL (1 << 8) ++# define R600_FIR_TREND_MODE (1 << 9) ++# define R600_DYN_GFX_CLK_OFF_EN (1 << 10) ++# define R600_VDDC3D_TURNOFF_D1 (1 << 11) ++# define R600_VDDC3D_TURNOFF_D2 (1 << 12) ++# define R600_VDDC3D_TURNOFF_D3 (1 << 13) ++# define R600_SPLL_TURNOFF_D2 (1 << 14) ++# define R600_SCLK_LOW_D1 (1 << 15) ++# define R600_DYN_GFX_CLK_OFF_MC_EN (1 << 16) ++ ++#define R600_MCLK_PWRMGT_CNTL 0x624 ++# define R600_MPLL_PWRMGT_OFF (1 << 0) + + #define R600_LOWER_GPIO_ENABLE 0x710 + #define R600_CTXSW_VID_LOWER_GPIO_CNTL 0x718 +@@ -5331,5 +5394,6 @@ + # define R500_RS_IP_OFFSET_EN (1 << 31) + + #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ ++#define R530_MC_ARB_RATIO_CLK_SEQ 0x0016 /* MC */ + + #endif diff --git a/packages/linux/config/linux.i386.conf b/packages/linux/config/linux.i386.conf index e6f7b5f805..8f1ca3efbd 100644 --- a/packages/linux/config/linux.i386.conf +++ b/packages/linux/config/linux.i386.conf @@ -1196,11 +1196,11 @@ CONFIG_HPET_MMAP=y # CONFIG_TCG_TPM is not set # CONFIG_TELCLOCK is not set CONFIG_DEVPORT=y -CONFIG_I2C=m +CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOBIT=y # # I2C Hardware Bus support @@ -1386,7 +1386,9 @@ CONFIG_SSB_DRIVER_PCICORE=y # CONFIG_HTC_PASIC3 is not set # CONFIG_UCB1400_CORE is not set # CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set @@ -1711,7 +1713,7 @@ CONFIG_DAB=y # # Graphics support # -CONFIG_AGP=m +CONFIG_AGP=y CONFIG_AGP_ALI=m CONFIG_AGP_ATI=m CONFIG_AGP_AMD=m @@ -1722,18 +1724,21 @@ CONFIG_AGP_SIS=m CONFIG_AGP_SWORKS=m CONFIG_AGP_VIA=m CONFIG_AGP_EFFICEON=m -CONFIG_DRM=m +CONFIG_DRM=y # CONFIG_DRM_TDFX is not set # CONFIG_DRM_R128 is not set CONFIG_DRM_RADEON=m +CONFIG_DRM_RADEON_KMS=y CONFIG_DRM_I810=m CONFIG_DRM_I830=m CONFIG_DRM_I915=m -# CONFIG_DRM_I915_KMS is not set +CONFIG_DRM_I915_KMS=y # CONFIG_DRM_MGA is not set -CONFIG_DRM_SIS=m +# CONFIG_DRM_SIS is not set CONFIG_DRM_VIA=m -CONFIG_DRM_SAVAGE=m +# CONFIG_DRM_SAVAGE is not set +CONFIG_DRM_NOUVEAU=m +CONFIG_DRM_NOUVEAU_KMS=y # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y diff --git a/packages/linux/patches/1811_drm-next.diff b/packages/linux/patches/1811_drm-next.diff new file mode 100644 index 0000000000..063639475d --- /dev/null +++ b/packages/linux/patches/1811_drm-next.diff @@ -0,0 +1,36440 @@ +diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile +index 30022c4..4ec5061 100644 +--- a/drivers/gpu/drm/Makefile ++++ b/drivers/gpu/drm/Makefile +@@ -10,7 +10,8 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ + drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ + drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ + drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ +- drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o ++ drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \ ++ drm_info.o drm_debugfs.o + + drm-$(CONFIG_COMPAT) += drm_ioc32.o + +diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c +index c533d0c..628eae3 100644 +--- a/drivers/gpu/drm/ati_pcigart.c ++++ b/drivers/gpu/drm/ati_pcigart.c +@@ -77,7 +77,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info + if (!entry->busaddr[i]) + break; + pci_unmap_page(dev->pdev, entry->busaddr[i], +- PAGE_SIZE, PCI_DMA_TODEVICE); ++ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + } + + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) +@@ -95,13 +95,14 @@ EXPORT_SYMBOL(drm_ati_pcigart_cleanup); + + int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) + { ++ struct drm_local_map *map = &gart_info->mapping; + struct drm_sg_mem *entry = dev->sg; + void *address = NULL; + unsigned long pages; +- u32 *pci_gart, page_base; ++ u32 *pci_gart = NULL, page_base, gart_idx; + dma_addr_t bus_address = 0; + int i, j, ret = 0; +- int max_pages; ++ int max_ati_pages, max_real_pages; + + if (!entry) { + DRM_ERROR("no scatter/gather memory!\n"); +@@ -117,6 +118,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga + goto done; + } + ++ pci_gart = gart_info->table_handle->vaddr; + address = gart_info->table_handle->vaddr; + bus_address = gart_info->table_handle->busaddr; + } else { +@@ -127,18 +129,23 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga + (unsigned long)address); + } + +- pci_gart = (u32 *) address; + +- max_pages = (gart_info->table_size / sizeof(u32)); +- pages = (entry->pages <= max_pages) +- ? entry->pages : max_pages; ++ max_ati_pages = (gart_info->table_size / sizeof(u32)); ++ max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); ++ pages = (entry->pages <= max_real_pages) ++ ? entry->pages : max_real_pages; + +- memset(pci_gart, 0, max_pages * sizeof(u32)); ++ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { ++ memset(pci_gart, 0, max_ati_pages * sizeof(u32)); ++ } else { ++ memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u32)); ++ } + ++ gart_idx = 0; + for (i = 0; i < pages; i++) { + /* we need to support large memory configurations */ + entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i], +- 0, PAGE_SIZE, PCI_DMA_TODEVICE); ++ 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + if (entry->busaddr[i] == 0) { + DRM_ERROR("unable to map PCIGART pages!\n"); + drm_ati_pcigart_cleanup(dev, gart_info); +@@ -149,19 +156,26 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga + page_base = (u32) entry->busaddr[i]; + + for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { ++ u32 val; ++ + switch(gart_info->gart_reg_if) { + case DRM_ATI_GART_IGP: +- *pci_gart = cpu_to_le32((page_base) | 0xc); ++ val = page_base | 0xc; + break; + case DRM_ATI_GART_PCIE: +- *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); ++ val = (page_base >> 8) | 0xc; + break; + default: + case DRM_ATI_GART_PCI: +- *pci_gart = cpu_to_le32(page_base); ++ val = page_base; + break; + } +- pci_gart++; ++ if (gart_info->gart_table_location == ++ DRM_ATI_GART_MAIN) ++ pci_gart[gart_idx] = cpu_to_le32(val); ++ else ++ DRM_WRITE32(map, gart_idx * sizeof(u32), val); ++ gart_idx++; + page_base += ATI_PCIGART_PAGE_SIZE; + } + } +diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c +index 12715d3..6d80d17 100644 +--- a/drivers/gpu/drm/drm_bufs.c ++++ b/drivers/gpu/drm/drm_bufs.c +@@ -34,15 +34,17 @@ + */ + + #include ++#include ++#include + #include "drmP.h" + +-unsigned long drm_get_resource_start(struct drm_device *dev, unsigned int resource) ++resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource) + { + return pci_resource_start(dev->pdev, resource); + } + EXPORT_SYMBOL(drm_get_resource_start); + +-unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource) ++resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource) + { + return pci_resource_len(dev->pdev, resource); + } +@@ -50,24 +52,44 @@ unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource + EXPORT_SYMBOL(drm_get_resource_len); + + static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, +- drm_local_map_t *map) ++ struct drm_local_map *map) + { + struct drm_map_list *entry; + list_for_each_entry(entry, &dev->maplist, head) { +- if (entry->map && (entry->master == dev->primary->master) && (map->type == entry->map->type) && +- ((entry->map->offset == map->offset) || +- ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) { ++ /* ++ * Because the kernel-userspace ABI is fixed at a 32-bit offset ++ * while PCI resources may live above that, we ignore the map ++ * offset for maps of type _DRM_FRAMEBUFFER or _DRM_REGISTERS. ++ * It is assumed that each driver will have only one resource of ++ * each type. ++ */ ++ if (!entry->map || ++ map->type != entry->map->type || ++ entry->master != dev->primary->master) ++ continue; ++ switch (map->type) { ++ case _DRM_SHM: ++ if (map->flags != _DRM_CONTAINS_LOCK) ++ break; ++ case _DRM_REGISTERS: ++ case _DRM_FRAME_BUFFER: + return entry; ++ default: /* Make gcc happy */ ++ ; + } ++ if (entry->map->offset == map->offset) ++ return entry; + } + + return NULL; + } + + static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash, +- unsigned long user_token, int hashed_handle) ++ unsigned long user_token, int hashed_handle, int shm) + { +- int use_hashed_handle; ++ int use_hashed_handle, shift; ++ unsigned long add; ++ + #if (BITS_PER_LONG == 64) + use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle); + #elif (BITS_PER_LONG == 32) +@@ -83,30 +105,47 @@ static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash, + if (ret != -EINVAL) + return ret; + } ++ ++ shift = 0; ++ add = DRM_MAP_HASH_OFFSET >> PAGE_SHIFT; ++ if (shm && (SHMLBA > PAGE_SIZE)) { ++ int bits = ilog2(SHMLBA >> PAGE_SHIFT) + 1; ++ ++ /* For shared memory, we have to preserve the SHMLBA ++ * bits of the eventual vma->vm_pgoff value during ++ * mmap(). Otherwise we run into cache aliasing problems ++ * on some platforms. On these platforms, the pgoff of ++ * a mmap() request is used to pick a suitable virtual ++ * address for the mmap() region such that it will not ++ * cause cache aliasing problems. ++ * ++ * Therefore, make sure the SHMLBA relevant bits of the ++ * hash value we use are equal to those in the original ++ * kernel virtual address. ++ */ ++ shift = bits; ++ add |= ((user_token >> PAGE_SHIFT) & ((1UL << bits) - 1UL)); ++ } ++ + return drm_ht_just_insert_please(&dev->map_hash, hash, + user_token, 32 - PAGE_SHIFT - 3, +- 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT); ++ shift, add); + } + + /** +- * Ioctl to specify a range of memory that is available for mapping by a non-root process. +- * +- * \param inode device inode. +- * \param file_priv DRM file private. +- * \param cmd command. +- * \param arg pointer to a drm_map structure. +- * \return zero on success or a negative value on error. ++ * Core function to create a range of memory available for mapping by a ++ * non-root process. + * + * Adjusts the memory offset to its absolute value according to the mapping + * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where + * applicable and if supported by the kernel. + */ +-static int drm_addmap_core(struct drm_device * dev, unsigned int offset, ++static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, + unsigned int size, enum drm_map_type type, + enum drm_map_flags flags, + struct drm_map_list ** maplist) + { +- struct drm_map *map; ++ struct drm_local_map *map; + struct drm_map_list *list; + drm_dma_handle_t *dmah; + unsigned long user_token; +@@ -129,9 +168,9 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset, + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + return -EINVAL; + } +- DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", +- map->offset, map->size, map->type); +- if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) { ++ DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", ++ (unsigned long long)map->offset, map->size, map->type); ++ if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + return -EINVAL; + } +@@ -259,7 +298,8 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset, + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + return -EPERM; + } +- DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size); ++ DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n", ++ (unsigned long long)map->offset, map->size); + + break; + case _DRM_GEM: +@@ -309,7 +349,8 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset, + /* We do it here so that dev->struct_mutex protects the increment */ + user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle : + map->offset; +- ret = drm_map_handle(dev, &list->hash, user_token, 0); ++ ret = drm_map_handle(dev, &list->hash, user_token, 0, ++ (map->type == _DRM_SHM)); + if (ret) { + if (map->type == _DRM_REGISTERS) + iounmap(map->handle); +@@ -327,9 +368,9 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset, + return 0; + } + +-int drm_addmap(struct drm_device * dev, unsigned int offset, ++int drm_addmap(struct drm_device * dev, resource_size_t offset, + unsigned int size, enum drm_map_type type, +- enum drm_map_flags flags, drm_local_map_t ** map_ptr) ++ enum drm_map_flags flags, struct drm_local_map ** map_ptr) + { + struct drm_map_list *list; + int rc; +@@ -342,6 +383,17 @@ int drm_addmap(struct drm_device * dev, unsigned int offset, + + EXPORT_SYMBOL(drm_addmap); + ++/** ++ * Ioctl to specify a range of memory that is available for mapping by a ++ * non-root process. ++ * ++ * \param inode device inode. ++ * \param file_priv DRM file private. ++ * \param cmd command. ++ * \param arg pointer to a drm_map structure. ++ * \return zero on success or a negative value on error. ++ * ++ */ + int drm_addmap_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { +@@ -367,19 +419,13 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data, + * Remove a map private from list and deallocate resources if the mapping + * isn't in use. + * +- * \param inode device inode. +- * \param file_priv DRM file private. +- * \param cmd command. +- * \param arg pointer to a struct drm_map structure. +- * \return zero on success or a negative value on error. +- * + * Searches the map on drm_device::maplist, removes it from the list, see if + * its being used, and free any associate resource (such as MTRR's) if it's not + * being on use. + * + * \sa drm_addmap + */ +-int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map) ++int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) + { + struct drm_map_list *r_list = NULL, *list_t; + drm_dma_handle_t dmah; +@@ -442,7 +488,7 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map) + } + EXPORT_SYMBOL(drm_rmmap_locked); + +-int drm_rmmap(struct drm_device *dev, drm_local_map_t *map) ++int drm_rmmap(struct drm_device *dev, struct drm_local_map *map) + { + int ret; + +@@ -462,12 +508,18 @@ EXPORT_SYMBOL(drm_rmmap); + * One use case might be after addmap is allowed for normal users for SHM and + * gets used by drivers that the server doesn't need to care about. This seems + * unlikely. ++ * ++ * \param inode device inode. ++ * \param file_priv DRM file private. ++ * \param cmd command. ++ * \param arg pointer to a struct drm_map structure. ++ * \return zero on success or a negative value on error. + */ + int drm_rmmap_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { + struct drm_map *request = data; +- drm_local_map_t *map = NULL; ++ struct drm_local_map *map = NULL; + struct drm_map_list *r_list; + int ret; + +@@ -1534,7 +1586,7 @@ int drm_mapbufs(struct drm_device *dev, void *data, + && (dma->flags & _DRM_DMA_USE_SG)) + || (drm_core_check_feature(dev, DRIVER_FB_DMA) + && (dma->flags & _DRM_DMA_USE_FB))) { +- struct drm_map *map = dev->agp_buffer_map; ++ struct drm_local_map *map = dev->agp_buffer_map; + unsigned long token = dev->agp_buffer_token; + + if (!map) { +diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c +index 809ec0f..7d1e53c 100644 +--- a/drivers/gpu/drm/drm_context.c ++++ b/drivers/gpu/drm/drm_context.c +@@ -143,7 +143,7 @@ int drm_getsareactx(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { + struct drm_ctx_priv_map *request = data; +- struct drm_map *map; ++ struct drm_local_map *map; + struct drm_map_list *_entry; + + mutex_lock(&dev->struct_mutex); +@@ -186,7 +186,7 @@ int drm_setsareactx(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { + struct drm_ctx_priv_map *request = data; +- struct drm_map *map = NULL; ++ struct drm_local_map *map = NULL; + struct drm_map_list *r_list = NULL; + + mutex_lock(&dev->struct_mutex); +diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c +index 1c3a8c5..a04639d 100644 +--- a/drivers/gpu/drm/drm_crtc_helper.c ++++ b/drivers/gpu/drm/drm_crtc_helper.c +@@ -42,6 +42,26 @@ static struct drm_display_mode std_modes[] = { + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + }; + ++static void drm_mode_validate_flag(struct drm_connector *connector, ++ int flags) ++{ ++ struct drm_display_mode *mode, *t; ++ ++ if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE)) ++ return; ++ ++ list_for_each_entry_safe(mode, t, &connector->modes, head) { ++ if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && ++ !(flags & DRM_MODE_FLAG_INTERLACE)) ++ mode->status = MODE_NO_INTERLACE; ++ if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) && ++ !(flags & DRM_MODE_FLAG_DBLSCAN)) ++ mode->status = MODE_NO_DBLESCAN; ++ } ++ ++ return; ++} ++ + /** + * drm_helper_probe_connector_modes - get complete set of display modes + * @dev: DRM device +@@ -72,6 +92,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, + struct drm_connector_helper_funcs *connector_funcs = + connector->helper_private; + int count = 0; ++ int mode_flags = 0; + + DRM_DEBUG("%s\n", drm_get_connector_name(connector)); + /* set all modes to the unverified state */ +@@ -96,6 +117,13 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, + if (maxX && maxY) + drm_mode_validate_size(dev, &connector->modes, maxX, + maxY, 0); ++ ++ if (connector->interlace_allowed) ++ mode_flags |= DRM_MODE_FLAG_INTERLACE; ++ if (connector->doublescan_allowed) ++ mode_flags |= DRM_MODE_FLAG_DBLSCAN; ++ drm_mode_validate_flag(connector, mode_flags); ++ + list_for_each_entry_safe(mode, t, &connector->modes, head) { + if (mode->status == MODE_OK) + mode->status = connector_funcs->mode_valid(connector, +@@ -885,7 +913,6 @@ bool drm_helper_plugged_event(struct drm_device *dev) + /** + * drm_initial_config - setup a sane initial connector configuration + * @dev: DRM device +- * @can_grow: this configuration is growable + * + * LOCKING: + * Called at init time, must take mode config lock. +@@ -897,7 +924,7 @@ bool drm_helper_plugged_event(struct drm_device *dev) + * RETURNS: + * Zero if everything went ok, nonzero otherwise. + */ +-bool drm_helper_initial_config(struct drm_device *dev, bool can_grow) ++bool drm_helper_initial_config(struct drm_device *dev) + { + struct drm_connector *connector; + int count = 0; +diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c +new file mode 100644 +index 0000000..c77c6c6 +--- /dev/null ++++ b/drivers/gpu/drm/drm_debugfs.c +@@ -0,0 +1,235 @@ ++/** ++ * \file drm_debugfs.c ++ * debugfs support for DRM ++ * ++ * \author Ben Gamari ++ */ ++ ++/* ++ * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com ++ * ++ * Copyright 2008 Ben Gamari ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include ++#include ++#include "drmP.h" ++ ++#if defined(CONFIG_DEBUG_FS) ++ ++/*************************************************** ++ * Initialization, etc. ++ **************************************************/ ++ ++static struct drm_info_list drm_debugfs_list[] = { ++ {"name", drm_name_info, 0}, ++ {"vm", drm_vm_info, 0}, ++ {"clients", drm_clients_info, 0}, ++ {"queues", drm_queues_info, 0}, ++ {"bufs", drm_bufs_info, 0}, ++ {"gem_names", drm_gem_name_info, DRIVER_GEM}, ++ {"gem_objects", drm_gem_object_info, DRIVER_GEM}, ++#if DRM_DEBUG_CODE ++ {"vma", drm_vma_info, 0}, ++#endif ++}; ++#define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list) ++ ++ ++static int drm_debugfs_open(struct inode *inode, struct file *file) ++{ ++ struct drm_info_node *node = inode->i_private; ++ ++ return single_open(file, node->info_ent->show, node); ++} ++ ++ ++static const struct file_operations drm_debugfs_fops = { ++ .owner = THIS_MODULE, ++ .open = drm_debugfs_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++ ++/** ++ * Initialize a given set of debugfs files for a device ++ * ++ * \param files The array of files to create ++ * \param count The number of files given ++ * \param root DRI debugfs dir entry. ++ * \param minor device minor number ++ * \return Zero on success, non-zero on failure ++ * ++ * Create a given set of debugfs files represented by an array of ++ * gdm_debugfs_lists in the given root directory. ++ */ ++int drm_debugfs_create_files(struct drm_info_list *files, int count, ++ struct dentry *root, struct drm_minor *minor) ++{ ++ struct drm_device *dev = minor->dev; ++ struct dentry *ent; ++ struct drm_info_node *tmp; ++ char name[64]; ++ int i, ret; ++ ++ for (i = 0; i < count; i++) { ++ u32 features = files[i].driver_features; ++ ++ if (features != 0 && ++ (dev->driver->driver_features & features) != features) ++ continue; ++ ++ tmp = drm_alloc(sizeof(struct drm_info_node), ++ _DRM_DRIVER); ++ ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, ++ root, tmp, &drm_debugfs_fops); ++ if (!ent) { ++ DRM_ERROR("Cannot create /debugfs/dri/%s/%s\n", ++ name, files[i].name); ++ drm_free(tmp, sizeof(struct drm_info_node), ++ _DRM_DRIVER); ++ ret = -1; ++ goto fail; ++ } ++ ++ tmp->minor = minor; ++ tmp->dent = ent; ++ tmp->info_ent = &files[i]; ++ list_add(&(tmp->list), &(minor->debugfs_nodes.list)); ++ } ++ return 0; ++ ++fail: ++ drm_debugfs_remove_files(files, count, minor); ++ return ret; ++} ++EXPORT_SYMBOL(drm_debugfs_create_files); ++ ++/** ++ * Initialize the DRI debugfs filesystem for a device ++ * ++ * \param dev DRM device ++ * \param minor device minor number ++ * \param root DRI debugfs dir entry. ++ * ++ * Create the DRI debugfs root entry "/debugfs/dri", the device debugfs root entry ++ * "/debugfs/dri/%minor%/", and each entry in debugfs_list as ++ * "/debugfs/dri/%minor%/%name%". ++ */ ++int drm_debugfs_init(struct drm_minor *minor, int minor_id, ++ struct dentry *root) ++{ ++ struct drm_device *dev = minor->dev; ++ char name[64]; ++ int ret; ++ ++ INIT_LIST_HEAD(&minor->debugfs_nodes.list); ++ sprintf(name, "%d", minor_id); ++ minor->debugfs_root = debugfs_create_dir(name, root); ++ if (!minor->debugfs_root) { ++ DRM_ERROR("Cannot create /debugfs/dri/%s\n", name); ++ return -1; ++ } ++ ++ ret = drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES, ++ minor->debugfs_root, minor); ++ if (ret) { ++ debugfs_remove(minor->debugfs_root); ++ minor->debugfs_root = NULL; ++ DRM_ERROR("Failed to create core drm debugfs files\n"); ++ return ret; ++ } ++ ++ if (dev->driver->debugfs_init) { ++ ret = dev->driver->debugfs_init(minor); ++ if (ret) { ++ DRM_ERROR("DRM: Driver failed to initialize " ++ "/debugfs/dri.\n"); ++ return ret; ++ } ++ } ++ return 0; ++} ++ ++ ++/** ++ * Remove a list of debugfs files ++ * ++ * \param files The list of files ++ * \param count The number of files ++ * \param minor The minor of which we should remove the files ++ * \return always zero. ++ * ++ * Remove all debugfs entries created by debugfs_init(). ++ */ ++int drm_debugfs_remove_files(struct drm_info_list *files, int count, ++ struct drm_minor *minor) ++{ ++ struct list_head *pos, *q; ++ struct drm_info_node *tmp; ++ int i; ++ ++ for (i = 0; i < count; i++) { ++ list_for_each_safe(pos, q, &minor->debugfs_nodes.list) { ++ tmp = list_entry(pos, struct drm_info_node, list); ++ if (tmp->info_ent == &files[i]) { ++ debugfs_remove(tmp->dent); ++ list_del(pos); ++ drm_free(tmp, sizeof(struct drm_info_node), ++ _DRM_DRIVER); ++ } ++ } ++ } ++ return 0; ++} ++EXPORT_SYMBOL(drm_debugfs_remove_files); ++ ++/** ++ * Cleanup the debugfs filesystem resources. ++ * ++ * \param minor device minor number. ++ * \return always zero. ++ * ++ * Remove all debugfs entries created by debugfs_init(). ++ */ ++int drm_debugfs_cleanup(struct drm_minor *minor) ++{ ++ struct drm_device *dev = minor->dev; ++ ++ if (!minor->debugfs_root) ++ return 0; ++ ++ if (dev->driver->debugfs_cleanup) ++ dev->driver->debugfs_cleanup(minor); ++ ++ drm_debugfs_remove_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES, minor); ++ ++ debugfs_remove(minor->debugfs_root); ++ minor->debugfs_root = NULL; ++ ++ return 0; ++} ++ ++#endif /* CONFIG_DEBUG_FS */ ++ +diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c +index 14c7a23..c4ada8b 100644 +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -46,9 +46,11 @@ + * OTHER DEALINGS IN THE SOFTWARE. + */ + ++#include + #include "drmP.h" + #include "drm_core.h" + ++ + static int drm_version(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +@@ -178,7 +180,7 @@ int drm_lastclose(struct drm_device * dev) + + /* Clear AGP information */ + if (drm_core_has_AGP(dev) && dev->agp && +- !drm_core_check_feature(dev, DRIVER_MODESET)) { ++ !drm_core_check_feature(dev, DRIVER_MODESET)) { + struct drm_agp_mem *entry, *tempe; + + /* Remove AGP resources, but leave dev->agp +@@ -252,15 +254,19 @@ int drm_lastclose(struct drm_device * dev) + int drm_init(struct drm_driver *driver) + { + struct pci_dev *pdev = NULL; +- struct pci_device_id *pid; ++ const struct pci_device_id *pid; + int i; + + DRM_DEBUG("\n"); + + INIT_LIST_HEAD(&driver->device_list); + ++ if (driver->driver_features & DRIVER_MODESET) ++ return pci_register_driver(&driver->pci_driver); ++ ++ /* If not using KMS, fall back to stealth mode manual scanning. */ + for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { +- pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; ++ pid = &driver->pci_driver.id_table[i]; + + /* Loop around setting up a DRM device for each PCI device + * matching our ID and device class. If we had the internal +@@ -285,68 +291,17 @@ int drm_init(struct drm_driver *driver) + + EXPORT_SYMBOL(drm_init); + +-/** +- * Called via cleanup_module() at module unload time. +- * +- * Cleans up all DRM device, calling drm_lastclose(). +- * +- * \sa drm_init +- */ +-static void drm_cleanup(struct drm_device * dev) +-{ +- struct drm_map_list *r_list, *list_temp; +- DRM_DEBUG("\n"); +- +- if (!dev) { +- DRM_ERROR("cleanup called no dev\n"); +- return; +- } +- +- drm_vblank_cleanup(dev); +- +- drm_lastclose(dev); +- +- if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && +- dev->agp && dev->agp->agp_mtrr >= 0) { +- int retval; +- retval = mtrr_del(dev->agp->agp_mtrr, +- dev->agp->agp_info.aper_base, +- dev->agp->agp_info.aper_size * 1024 * 1024); +- DRM_DEBUG("mtrr_del=%d\n", retval); +- } +- +- if (dev->driver->unload) +- dev->driver->unload(dev); +- +- if (drm_core_has_AGP(dev) && dev->agp) { +- drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); +- dev->agp = NULL; +- } +- +- drm_ht_remove(&dev->map_hash); +- drm_ctxbitmap_cleanup(dev); +- +- list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) +- drm_rmmap(dev, r_list->map); +- +- if (drm_core_check_feature(dev, DRIVER_MODESET)) +- drm_put_minor(&dev->control); +- +- if (dev->driver->driver_features & DRIVER_GEM) +- drm_gem_destroy(dev); +- +- drm_put_minor(&dev->primary); +- if (drm_put_dev(dev)) +- DRM_ERROR("Cannot unload module\n"); +-} +- + void drm_exit(struct drm_driver *driver) + { + struct drm_device *dev, *tmp; + DRM_DEBUG("\n"); + +- list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) +- drm_cleanup(dev); ++ if (driver->driver_features & DRIVER_MODESET) { ++ pci_unregister_driver(&driver->pci_driver); ++ } else { ++ list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) ++ drm_put_dev(dev); ++ } + + DRM_INFO("Module unloaded\n"); + } +@@ -382,6 +337,13 @@ static int __init drm_core_init(void) + goto err_p3; + } + ++ drm_debugfs_root = debugfs_create_dir("dri", NULL); ++ if (!drm_debugfs_root) { ++ DRM_ERROR("Cannot create /debugfs/dri\n"); ++ ret = -1; ++ goto err_p3; ++ } ++ + drm_mem_init(); + + DRM_INFO("Initialized %s %d.%d.%d %s\n", +@@ -400,6 +362,7 @@ err_p1: + static void __exit drm_core_exit(void) + { + remove_proc_entry("dri", NULL); ++ debugfs_remove(drm_debugfs_root); + drm_sysfs_destroy(); + + unregister_chrdev(DRM_MAJOR, "drm"); +@@ -458,6 +421,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, + drm_ioctl_t *func; + unsigned int nr = DRM_IOCTL_NR(cmd); + int retcode = -EINVAL; ++ char stack_kdata[128]; + char *kdata = NULL; + + atomic_inc(&dev->ioctl_count); +@@ -496,10 +460,14 @@ int drm_ioctl(struct inode *inode, struct file *filp, + retcode = -EACCES; + } else { + if (cmd & (IOC_IN | IOC_OUT)) { +- kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); +- if (!kdata) { +- retcode = -ENOMEM; +- goto err_i1; ++ if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) { ++ kdata = stack_kdata; ++ } else { ++ kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); ++ if (!kdata) { ++ retcode = -ENOMEM; ++ goto err_i1; ++ } + } + } + +@@ -520,7 +488,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, + } + + err_i1: +- if (kdata) ++ if (kdata != stack_kdata) + kfree(kdata); + atomic_dec(&dev->ioctl_count); + if (retcode) +@@ -530,7 +498,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, + + EXPORT_SYMBOL(drm_ioctl); + +-drm_local_map_t *drm_getsarea(struct drm_device *dev) ++struct drm_local_map *drm_getsarea(struct drm_device *dev) + { + struct drm_map_list *entry; + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index a839a28..ca9c616 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -125,10 +125,8 @@ static bool edid_is_valid(struct edid *edid) + DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); + goto bad; + } +- if (edid->revision > 3) { +- DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision); +- goto bad; +- } ++ if (edid->revision > 4) ++ DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n"); + + for (i = 0; i < EDID_LENGTH; i++) + csum += raw_edid[i]; +@@ -162,7 +160,7 @@ static bool edid_vendor(struct edid *edid, char *vendor) + edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@'; + edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) | + ((edid->mfg_id[1] & 0xe0) >> 5)) + '@'; +- edid_vendor[2] = (edid->mfg_id[2] & 0x1f) + '@'; ++ edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@'; + + return !strncmp(edid_vendor, vendor, 3); + } +@@ -550,11 +548,20 @@ static int add_detailed_info(struct drm_connector *connector, + } + + #define DDC_ADDR 0x50 +- +-unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter) ++/** ++ * Get EDID information via I2C. ++ * ++ * \param adapter : i2c device adaptor ++ * \param buf : EDID data buffer to be filled ++ * \param len : EDID data buffer length ++ * \return 0 on success or -1 on failure. ++ * ++ * Try to fetch EDID information by calling i2c driver function. ++ */ ++int drm_do_probe_ddc_edid(struct i2c_adapter *adapter, ++ unsigned char *buf, int len) + { + unsigned char start = 0x0; +- unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL); + struct i2c_msg msgs[] = { + { + .addr = DDC_ADDR, +@@ -564,31 +571,36 @@ unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter) + }, { + .addr = DDC_ADDR, + .flags = I2C_M_RD, +- .len = EDID_LENGTH, ++ .len = len, + .buf = buf, + } + }; + +- if (!buf) { +- dev_warn(&adapter->dev, "unable to allocate memory for EDID " +- "block.\n"); +- return NULL; +- } +- + if (i2c_transfer(adapter, msgs, 2) == 2) +- return buf; ++ return 0; + + dev_info(&adapter->dev, "unable to read EDID block.\n"); +- kfree(buf); +- return NULL; ++ return -1; + } + EXPORT_SYMBOL(drm_do_probe_ddc_edid); + +-static unsigned char *drm_ddc_read(struct i2c_adapter *adapter) ++/** ++ * Get EDID information. ++ * ++ * \param adapter : i2c device adaptor. ++ * \param buf : EDID data buffer to be filled ++ * \param len : EDID data buffer length ++ * \return 0 on success or -1 on failure. ++ * ++ * Initialize DDC, then fetch EDID information ++ * by calling drm_do_probe_ddc_edid function. ++ */ ++static int drm_ddc_read(struct i2c_adapter *adapter, ++ unsigned char *buf, int len) + { + struct i2c_algo_bit_data *algo_data = adapter->algo_data; +- unsigned char *edid = NULL; + int i, j; ++ int ret = -1; + + algo_data->setscl(algo_data->data, 1); + +@@ -616,7 +628,7 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter) + msleep(15); + + /* Do the real work */ +- edid = drm_do_probe_ddc_edid(adapter); ++ ret = drm_do_probe_ddc_edid(adapter, buf, len); + algo_data->setsda(algo_data->data, 0); + algo_data->setscl(algo_data->data, 0); + msleep(15); +@@ -632,7 +644,7 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter) + msleep(15); + algo_data->setscl(algo_data->data, 0); + algo_data->setsda(algo_data->data, 0); +- if (edid) ++ if (ret == 0) + break; + } + /* Release the DDC lines when done or the Apple Cinema HD display +@@ -641,9 +653,31 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter) + algo_data->setsda(algo_data->data, 1); + algo_data->setscl(algo_data->data, 1); + +- return edid; ++ return ret; + } + ++static int drm_ddc_read_edid(struct drm_connector *connector, ++ struct i2c_adapter *adapter, ++ char *buf, int len) ++{ ++ int ret; ++ ++ ret = drm_ddc_read(adapter, buf, len); ++ if (ret != 0) { ++ dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n", ++ drm_get_connector_name(connector)); ++ goto end; ++ } ++ if (!edid_is_valid((struct edid *)buf)) { ++ dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n", ++ drm_get_connector_name(connector)); ++ ret = -1; ++ } ++end: ++ return ret; ++} ++ ++#define MAX_EDID_EXT_NUM 4 + /** + * drm_get_edid - get EDID data, if available + * @connector: connector we're probing +@@ -656,27 +690,118 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter) + struct edid *drm_get_edid(struct drm_connector *connector, + struct i2c_adapter *adapter) + { ++ int ret; + struct edid *edid; + +- edid = (struct edid *)drm_ddc_read(adapter); +- if (!edid) { +- dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n", +- drm_get_connector_name(connector)); +- return NULL; ++ edid = kmalloc(EDID_LENGTH * (MAX_EDID_EXT_NUM + 1), ++ GFP_KERNEL); ++ if (edid == NULL) { ++ dev_warn(&connector->dev->pdev->dev, ++ "Failed to allocate EDID\n"); ++ goto end; + } +- if (!edid_is_valid(edid)) { +- dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n", +- drm_get_connector_name(connector)); +- kfree(edid); +- return NULL; ++ ++ /* Read first EDID block */ ++ ret = drm_ddc_read_edid(connector, adapter, ++ (unsigned char *)edid, EDID_LENGTH); ++ if (ret != 0) ++ goto clean_up; ++ ++ /* There are EDID extensions to be read */ ++ if (edid->extensions != 0) { ++ int edid_ext_num = edid->extensions; ++ ++ if (edid_ext_num > MAX_EDID_EXT_NUM) { ++ dev_warn(&connector->dev->pdev->dev, ++ "The number of extension(%d) is " ++ "over max (%d), actually read number (%d)\n", ++ edid_ext_num, MAX_EDID_EXT_NUM, ++ MAX_EDID_EXT_NUM); ++ /* Reset EDID extension number to be read */ ++ edid_ext_num = MAX_EDID_EXT_NUM; ++ } ++ /* Read EDID including extensions too */ ++ ret = drm_ddc_read_edid(connector, adapter, (char *)edid, ++ EDID_LENGTH * (edid_ext_num + 1)); ++ if (ret != 0) ++ goto clean_up; ++ + } + + connector->display_info.raw_edid = (char *)edid; ++ goto end; + ++clean_up: ++ kfree(edid); ++ edid = NULL; ++end: + return edid; ++ + } + EXPORT_SYMBOL(drm_get_edid); + ++#define HDMI_IDENTIFIER 0x000C03 ++#define VENDOR_BLOCK 0x03 ++/** ++ * drm_detect_hdmi_monitor - detect whether monitor is hdmi. ++ * @edid: monitor EDID information ++ * ++ * Parse the CEA extension according to CEA-861-B. ++ * Return true if HDMI, false if not or unknown. ++ */ ++bool drm_detect_hdmi_monitor(struct edid *edid) ++{ ++ char *edid_ext = NULL; ++ int i, hdmi_id, edid_ext_num; ++ int start_offset, end_offset; ++ bool is_hdmi = false; ++ ++ /* No EDID or EDID extensions */ ++ if (edid == NULL || edid->extensions == 0) ++ goto end; ++ ++ /* Chose real EDID extension number */ ++ edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ? ++ MAX_EDID_EXT_NUM : edid->extensions; ++ ++ /* Find CEA extension */ ++ for (i = 0; i < edid_ext_num; i++) { ++ edid_ext = (char *)edid + EDID_LENGTH * (i + 1); ++ /* This block is CEA extension */ ++ if (edid_ext[0] == 0x02) ++ break; ++ } ++ ++ if (i == edid_ext_num) ++ goto end; ++ ++ /* Data block offset in CEA extension block */ ++ start_offset = 4; ++ end_offset = edid_ext[2]; ++ ++ /* ++ * Because HDMI identifier is in Vendor Specific Block, ++ * search it from all data blocks of CEA extension. ++ */ ++ for (i = start_offset; i < end_offset; ++ /* Increased by data block len */ ++ i += ((edid_ext[i] & 0x1f) + 1)) { ++ /* Find vendor specific block */ ++ if ((edid_ext[i] >> 5) == VENDOR_BLOCK) { ++ hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) | ++ edid_ext[i + 3] << 16; ++ /* Find HDMI identifier */ ++ if (hdmi_id == HDMI_IDENTIFIER) ++ is_hdmi = true; ++ break; ++ } ++ } ++ ++end: ++ return is_hdmi; ++} ++EXPORT_SYMBOL(drm_detect_hdmi_monitor); ++ + /** + * drm_add_edid_modes - add modes from EDID data, if available + * @connector: connector we're probing +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index f52663e..09a3571 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -274,6 +274,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, + /* create a new master */ + priv->minor->master = drm_master_create(priv->minor); + if (!priv->minor->master) { ++ mutex_unlock(&dev->struct_mutex); + ret = -ENOMEM; + goto out_free; + } +@@ -337,14 +338,10 @@ int drm_fasync(int fd, struct file *filp, int on) + { + struct drm_file *priv = filp->private_data; + struct drm_device *dev = priv->minor->dev; +- int retcode; + + DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, + (long)old_encode_dev(priv->minor->device)); +- retcode = fasync_helper(fd, filp, on, &dev->buf_async); +- if (retcode < 0) +- return retcode; +- return 0; ++ return fasync_helper(fd, filp, on, &dev->buf_async); + } + EXPORT_SYMBOL(drm_fasync); + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 88d3368..4984aa8 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -502,10 +502,9 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + struct drm_file *priv = filp->private_data; + struct drm_device *dev = priv->minor->dev; + struct drm_gem_mm *mm = dev->mm_private; +- struct drm_map *map = NULL; ++ struct drm_local_map *map = NULL; + struct drm_gem_object *obj; + struct drm_hash_item *hash; +- unsigned long prot; + int ret = 0; + + mutex_lock(&dev->struct_mutex); +@@ -538,11 +537,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + vma->vm_ops = obj->dev->driver->gem_vm_ops; + vma->vm_private_data = map->handle; + /* FIXME: use pgprot_writecombine when available */ +- prot = pgprot_val(vma->vm_page_prot); +-#ifdef CONFIG_X86 +- prot |= _PAGE_CACHE_WC; +-#endif +- vma->vm_page_prot = __pgprot(prot); ++ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + /* Take a ref for this mapping of the object, so that the fault + * handler can dereference the mmap offset's pointer to the object. +diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c +new file mode 100644 +index 0000000..f0f6c6b +--- /dev/null ++++ b/drivers/gpu/drm/drm_info.c +@@ -0,0 +1,328 @@ ++/** ++ * \file drm_info.c ++ * DRM info file implementations ++ * ++ * \author Ben Gamari ++ */ ++ ++/* ++ * Created: Sun Dec 21 13:09:50 2008 by bgamari@gmail.com ++ * ++ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. ++ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. ++ * Copyright 2008 Ben Gamari ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include ++#include "drmP.h" ++ ++/** ++ * Called when "/proc/dri/.../name" is read. ++ * ++ * Prints the device name together with the bus id if available. ++ */ ++int drm_name_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_minor *minor = node->minor; ++ struct drm_device *dev = minor->dev; ++ struct drm_master *master = minor->master; ++ ++ if (!master) ++ return 0; ++ ++ if (master->unique) { ++ seq_printf(m, "%s %s %s\n", ++ dev->driver->pci_driver.name, ++ pci_name(dev->pdev), master->unique); ++ } else { ++ seq_printf(m, "%s %s\n", dev->driver->pci_driver.name, ++ pci_name(dev->pdev)); ++ } ++ ++ return 0; ++} ++ ++/** ++ * Called when "/proc/dri/.../vm" is read. ++ * ++ * Prints information about all mappings in drm_device::maplist. ++ */ ++int drm_vm_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_local_map *map; ++ struct drm_map_list *r_list; ++ ++ /* Hardcoded from _DRM_FRAME_BUFFER, ++ _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and ++ _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ ++ const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; ++ const char *type; ++ int i; ++ ++ mutex_lock(&dev->struct_mutex); ++ seq_printf(m, "slot offset size type flags address mtrr\n\n"); ++ i = 0; ++ list_for_each_entry(r_list, &dev->maplist, head) { ++ map = r_list->map; ++ if (!map) ++ continue; ++ if (map->type < 0 || map->type > 5) ++ type = "??"; ++ else ++ type = types[map->type]; ++ ++ seq_printf(m, "%4d 0x%016llx 0x%08lx %4.4s 0x%02x 0x%08lx ", ++ i, ++ (unsigned long long)map->offset, ++ map->size, type, map->flags, ++ (unsigned long) r_list->user_token); ++ if (map->mtrr < 0) ++ seq_printf(m, "none\n"); ++ else ++ seq_printf(m, "%4d\n", map->mtrr); ++ i++; ++ } ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++} ++ ++/** ++ * Called when "/proc/dri/.../queues" is read. ++ */ ++int drm_queues_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ int i; ++ struct drm_queue *q; ++ ++ mutex_lock(&dev->struct_mutex); ++ seq_printf(m, " ctx/flags use fin" ++ " blk/rw/rwf wait flushed queued" ++ " locks\n\n"); ++ for (i = 0; i < dev->queue_count; i++) { ++ q = dev->queuelist[i]; ++ atomic_inc(&q->use_count); ++ seq_printf(m, "%5d/0x%03x %5d %5d" ++ " %5d/%c%c/%c%c%c %5Zd\n", ++ i, ++ q->flags, ++ atomic_read(&q->use_count), ++ atomic_read(&q->finalization), ++ atomic_read(&q->block_count), ++ atomic_read(&q->block_read) ? 'r' : '-', ++ atomic_read(&q->block_write) ? 'w' : '-', ++ waitqueue_active(&q->read_queue) ? 'r' : '-', ++ waitqueue_active(&q->write_queue) ? 'w' : '-', ++ waitqueue_active(&q->flush_queue) ? 'f' : '-', ++ DRM_BUFCOUNT(&q->waitlist)); ++ atomic_dec(&q->use_count); ++ } ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++} ++ ++/** ++ * Called when "/proc/dri/.../bufs" is read. ++ */ ++int drm_bufs_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_device_dma *dma; ++ int i, seg_pages; ++ ++ mutex_lock(&dev->struct_mutex); ++ dma = dev->dma; ++ if (!dma) { ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++ } ++ ++ seq_printf(m, " o size count free segs pages kB\n\n"); ++ for (i = 0; i <= DRM_MAX_ORDER; i++) { ++ if (dma->bufs[i].buf_count) { ++ seg_pages = dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order); ++ seq_printf(m, "%2d %8d %5d %5d %5d %5d %5ld\n", ++ i, ++ dma->bufs[i].buf_size, ++ dma->bufs[i].buf_count, ++ atomic_read(&dma->bufs[i].freelist.count), ++ dma->bufs[i].seg_count, ++ seg_pages, ++ seg_pages * PAGE_SIZE / 1024); ++ } ++ } ++ seq_printf(m, "\n"); ++ for (i = 0; i < dma->buf_count; i++) { ++ if (i && !(i % 32)) ++ seq_printf(m, "\n"); ++ seq_printf(m, " %d", dma->buflist[i]->list); ++ } ++ seq_printf(m, "\n"); ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++} ++ ++/** ++ * Called when "/proc/dri/.../vblank" is read. ++ */ ++int drm_vblank_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ int crtc; ++ ++ mutex_lock(&dev->struct_mutex); ++ for (crtc = 0; crtc < dev->num_crtcs; crtc++) { ++ seq_printf(m, "CRTC %d enable: %d\n", ++ crtc, atomic_read(&dev->vblank_refcount[crtc])); ++ seq_printf(m, "CRTC %d counter: %d\n", ++ crtc, drm_vblank_count(dev, crtc)); ++ seq_printf(m, "CRTC %d last wait: %d\n", ++ crtc, dev->last_vblank_wait[crtc]); ++ seq_printf(m, "CRTC %d in modeset: %d\n", ++ crtc, dev->vblank_inmodeset[crtc]); ++ } ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++} ++ ++/** ++ * Called when "/proc/dri/.../clients" is read. ++ * ++ */ ++int drm_clients_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_file *priv; ++ ++ mutex_lock(&dev->struct_mutex); ++ seq_printf(m, "a dev pid uid magic ioctls\n\n"); ++ list_for_each_entry(priv, &dev->filelist, lhead) { ++ seq_printf(m, "%c %3d %5d %5d %10u %10lu\n", ++ priv->authenticated ? 'y' : 'n', ++ priv->minor->index, ++ priv->pid, ++ priv->uid, priv->magic, priv->ioctl_count); ++ } ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++} ++ ++ ++int drm_gem_one_name_info(int id, void *ptr, void *data) ++{ ++ struct drm_gem_object *obj = ptr; ++ struct seq_file *m = data; ++ ++ seq_printf(m, "name %d size %zd\n", obj->name, obj->size); ++ ++ seq_printf(m, "%6d %8zd %7d %8d\n", ++ obj->name, obj->size, ++ atomic_read(&obj->handlecount.refcount), ++ atomic_read(&obj->refcount.refcount)); ++ return 0; ++} ++ ++int drm_gem_name_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ ++ seq_printf(m, " name size handles refcount\n"); ++ idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m); ++ return 0; ++} ++ ++int drm_gem_object_info(struct seq_file *m, void* data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ ++ seq_printf(m, "%d objects\n", atomic_read(&dev->object_count)); ++ seq_printf(m, "%d object bytes\n", atomic_read(&dev->object_memory)); ++ seq_printf(m, "%d pinned\n", atomic_read(&dev->pin_count)); ++ seq_printf(m, "%d pin bytes\n", atomic_read(&dev->pin_memory)); ++ seq_printf(m, "%d gtt bytes\n", atomic_read(&dev->gtt_memory)); ++ seq_printf(m, "%d gtt total\n", dev->gtt_total); ++ return 0; ++} ++ ++#if DRM_DEBUG_CODE ++ ++int drm_vma_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_vma_entry *pt; ++ struct vm_area_struct *vma; ++#if defined(__i386__) ++ unsigned int pgprot; ++#endif ++ ++ mutex_lock(&dev->struct_mutex); ++ seq_printf(m, "vma use count: %d, high_memory = %p, 0x%08llx\n", ++ atomic_read(&dev->vma_count), ++ high_memory, (u64)virt_to_phys(high_memory)); ++ ++ list_for_each_entry(pt, &dev->vmalist, head) { ++ vma = pt->vma; ++ if (!vma) ++ continue; ++ seq_printf(m, ++ "\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", ++ pt->pid, vma->vm_start, vma->vm_end, ++ vma->vm_flags & VM_READ ? 'r' : '-', ++ vma->vm_flags & VM_WRITE ? 'w' : '-', ++ vma->vm_flags & VM_EXEC ? 'x' : '-', ++ vma->vm_flags & VM_MAYSHARE ? 's' : 'p', ++ vma->vm_flags & VM_LOCKED ? 'l' : '-', ++ vma->vm_flags & VM_IO ? 'i' : '-', ++ vma->vm_pgoff); ++ ++#if defined(__i386__) ++ pgprot = pgprot_val(vma->vm_page_prot); ++ seq_printf(m, " %c%c%c%c%c%c%c%c%c", ++ pgprot & _PAGE_PRESENT ? 'p' : '-', ++ pgprot & _PAGE_RW ? 'w' : 'r', ++ pgprot & _PAGE_USER ? 'u' : 's', ++ pgprot & _PAGE_PWT ? 't' : 'b', ++ pgprot & _PAGE_PCD ? 'u' : 'c', ++ pgprot & _PAGE_ACCESSED ? 'a' : '-', ++ pgprot & _PAGE_DIRTY ? 'd' : '-', ++ pgprot & _PAGE_PSE ? 'm' : 'k', ++ pgprot & _PAGE_GLOBAL ? 'g' : 'l'); ++#endif ++ seq_printf(m, "\n"); ++ } ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++} ++ ++#endif ++ +diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c +index 920b72f..282d9fd 100644 +--- a/drivers/gpu/drm/drm_ioc32.c ++++ b/drivers/gpu/drm/drm_ioc32.c +@@ -954,6 +954,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd, + DRM_IOCTL_SG_FREE, (unsigned long)request); + } + ++#if defined(CONFIG_X86) || defined(CONFIG_IA64) + typedef struct drm_update_draw32 { + drm_drawable_t handle; + unsigned int type; +@@ -984,6 +985,7 @@ static int compat_drm_update_draw(struct file *file, unsigned int cmd, + DRM_IOCTL_UPDATE_DRAW, (unsigned long)request); + return err; + } ++#endif + + struct drm_wait_vblank_request32 { + enum drm_vblank_seq_type type; +@@ -1066,7 +1068,9 @@ drm_ioctl_compat_t *drm_compat_ioctls[] = { + #endif + [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc, + [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free, ++#if defined(CONFIG_X86) || defined(CONFIG_IA64) + [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw, ++#endif + [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, + }; + +diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c +index bcc869b..0c707f5 100644 +--- a/drivers/gpu/drm/drm_memory.c ++++ b/drivers/gpu/drm/drm_memory.c +@@ -159,7 +159,7 @@ static inline void *agp_remap(unsigned long offset, unsigned long size, + + #endif /* debug_memory */ + +-void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) ++void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) + { + if (drm_core_has_AGP(dev) && + dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) +@@ -169,7 +169,7 @@ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) + } + EXPORT_SYMBOL(drm_core_ioremap); + +-void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev) ++void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev) + { + if (drm_core_has_AGP(dev) && + dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) +@@ -179,7 +179,7 @@ void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev) + } + EXPORT_SYMBOL(drm_core_ioremap_wc); + +-void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev) ++void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev) + { + if (!map->handle || !map->size) + return; +diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c +index 8df849f..bae5391 100644 +--- a/drivers/gpu/drm/drm_proc.c ++++ b/drivers/gpu/drm/drm_proc.c +@@ -37,697 +37,195 @@ + * OTHER DEALINGS IN THE SOFTWARE. + */ + ++#include + #include "drmP.h" + +-static int drm_name_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data); +-static int drm_vm_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data); +-static int drm_clients_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data); +-static int drm_queues_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data); +-static int drm_bufs_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data); +-static int drm_vblank_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data); +-static int drm_gem_name_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data); +-static int drm_gem_object_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data); +-#if DRM_DEBUG_CODE +-static int drm_vma_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data); +-#endif ++/*************************************************** ++ * Initialization, etc. ++ **************************************************/ + + /** + * Proc file list. + */ +-static struct drm_proc_list { +- const char *name; /**< file name */ +- int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ +- u32 driver_features; /**< Required driver features for this entry */ +-} drm_proc_list[] = { ++static struct drm_info_list drm_proc_list[] = { + {"name", drm_name_info, 0}, +- {"mem", drm_mem_info, 0}, + {"vm", drm_vm_info, 0}, + {"clients", drm_clients_info, 0}, + {"queues", drm_queues_info, 0}, + {"bufs", drm_bufs_info, 0}, +- {"vblank", drm_vblank_info, 0}, + {"gem_names", drm_gem_name_info, DRIVER_GEM}, + {"gem_objects", drm_gem_object_info, DRIVER_GEM}, + #if DRM_DEBUG_CODE +- {"vma", drm_vma_info}, ++ {"vma", drm_vma_info, 0}, + #endif + }; +- + #define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list) + ++static int drm_proc_open(struct inode *inode, struct file *file) ++{ ++ struct drm_info_node* node = PDE(inode)->data; ++ ++ return single_open(file, node->info_ent->show, node); ++} ++ ++static const struct file_operations drm_proc_fops = { ++ .owner = THIS_MODULE, ++ .open = drm_proc_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++ + /** +- * Initialize the DRI proc filesystem for a device. ++ * Initialize a given set of proc files for a device + * +- * \param dev DRM device. +- * \param minor device minor number. ++ * \param files The array of files to create ++ * \param count The number of files given + * \param root DRI proc dir entry. +- * \param dev_root resulting DRI device proc dir entry. +- * \return root entry pointer on success, or NULL on failure. ++ * \param minor device minor number ++ * \return Zero on success, non-zero on failure + * +- * Create the DRI proc root entry "/proc/dri", the device proc root entry +- * "/proc/dri/%minor%/", and each entry in proc_list as +- * "/proc/dri/%minor%/%name%". ++ * Create a given set of proc files represented by an array of ++ * gdm_proc_lists in the given root directory. + */ +-int drm_proc_init(struct drm_minor *minor, int minor_id, +- struct proc_dir_entry *root) ++int drm_proc_create_files(struct drm_info_list *files, int count, ++ struct proc_dir_entry *root, struct drm_minor *minor) + { + struct drm_device *dev = minor->dev; + struct proc_dir_entry *ent; +- int i, j, ret; ++ struct drm_info_node *tmp; + char name[64]; ++ int i, ret; + +- sprintf(name, "%d", minor_id); +- minor->dev_root = proc_mkdir(name, root); +- if (!minor->dev_root) { +- DRM_ERROR("Cannot create /proc/dri/%s\n", name); +- return -1; +- } +- +- for (i = 0; i < DRM_PROC_ENTRIES; i++) { +- u32 features = drm_proc_list[i].driver_features; ++ for (i = 0; i < count; i++) { ++ u32 features = files[i].driver_features; + + if (features != 0 && + (dev->driver->driver_features & features) != features) + continue; + +- ent = create_proc_entry(drm_proc_list[i].name, +- S_IFREG | S_IRUGO, minor->dev_root); ++ tmp = drm_alloc(sizeof(struct drm_info_node), _DRM_DRIVER); ++ ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root); + if (!ent) { + DRM_ERROR("Cannot create /proc/dri/%s/%s\n", +- name, drm_proc_list[i].name); ++ name, files[i].name); ++ drm_free(tmp, sizeof(struct drm_info_node), ++ _DRM_DRIVER); + ret = -1; + goto fail; + } +- ent->read_proc = drm_proc_list[i].f; +- ent->data = minor; +- } + +- if (dev->driver->proc_init) { +- ret = dev->driver->proc_init(minor); +- if (ret) { +- DRM_ERROR("DRM: Driver failed to initialize " +- "/proc/dri.\n"); +- goto fail; +- } ++ ent->proc_fops = &drm_proc_fops; ++ ent->data = tmp; ++ tmp->minor = minor; ++ tmp->info_ent = &files[i]; ++ list_add(&(tmp->list), &(minor->proc_nodes.list)); + } +- + return 0; +- fail: + +- for (j = 0; j < i; j++) +- remove_proc_entry(drm_proc_list[i].name, +- minor->dev_root); +- remove_proc_entry(name, root); +- minor->dev_root = NULL; ++fail: ++ for (i = 0; i < count; i++) ++ remove_proc_entry(drm_proc_list[i].name, minor->proc_root); + return ret; + } + + /** +- * Cleanup the proc filesystem resources. ++ * Initialize the DRI proc filesystem for a device + * +- * \param minor device minor number. ++ * \param dev DRM device ++ * \param minor device minor number + * \param root DRI proc dir entry. +- * \param dev_root DRI device proc dir entry. +- * \return always zero. ++ * \param dev_root resulting DRI device proc dir entry. ++ * \return root entry pointer on success, or NULL on failure. + * +- * Remove all proc entries created by proc_init(). ++ * Create the DRI proc root entry "/proc/dri", the device proc root entry ++ * "/proc/dri/%minor%/", and each entry in proc_list as ++ * "/proc/dri/%minor%/%name%". + */ +-int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) ++int drm_proc_init(struct drm_minor *minor, int minor_id, ++ struct proc_dir_entry *root) + { + struct drm_device *dev = minor->dev; +- int i; + char name[64]; ++ int ret; + +- if (!root || !minor->dev_root) +- return 0; +- +- if (dev->driver->proc_cleanup) +- dev->driver->proc_cleanup(minor); +- +- for (i = 0; i < DRM_PROC_ENTRIES; i++) +- remove_proc_entry(drm_proc_list[i].name, minor->dev_root); +- sprintf(name, "%d", minor->index); +- remove_proc_entry(name, root); +- +- return 0; +-} +- +-/** +- * Called when "/proc/dri/.../name" is read. +- * +- * \param buf output buffer. +- * \param start start of output data. +- * \param offset requested start offset. +- * \param request requested number of bytes. +- * \param eof whether there is no more data to return. +- * \param data private data. +- * \return number of written bytes. +- * +- * Prints the device name together with the bus id if available. +- */ +-static int drm_name_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_master *master = minor->master; +- struct drm_device *dev = minor->dev; +- int len = 0; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; ++ INIT_LIST_HEAD(&minor->proc_nodes.list); ++ sprintf(name, "%d", minor_id); ++ minor->proc_root = proc_mkdir(name, root); ++ if (!minor->proc_root) { ++ DRM_ERROR("Cannot create /proc/dri/%s\n", name); ++ return -1; + } + +- if (!master) +- return 0; +- +- *start = &buf[offset]; +- *eof = 0; +- +- if (master->unique) { +- DRM_PROC_PRINT("%s %s %s\n", +- dev->driver->pci_driver.name, +- pci_name(dev->pdev), master->unique); +- } else { +- DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name, +- pci_name(dev->pdev)); ++ ret = drm_proc_create_files(drm_proc_list, DRM_PROC_ENTRIES, ++ minor->proc_root, minor); ++ if (ret) { ++ remove_proc_entry(name, root); ++ minor->proc_root = NULL; ++ DRM_ERROR("Failed to create core drm proc files\n"); ++ return ret; + } + +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-/** +- * Called when "/proc/dri/.../vm" is read. +- * +- * \param buf output buffer. +- * \param start start of output data. +- * \param offset requested start offset. +- * \param request requested number of bytes. +- * \param eof whether there is no more data to return. +- * \param data private data. +- * \return number of written bytes. +- * +- * Prints information about all mappings in drm_device::maplist. +- */ +-static int drm__vm_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int len = 0; +- struct drm_map *map; +- struct drm_map_list *r_list; +- +- /* Hardcoded from _DRM_FRAME_BUFFER, +- _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and +- _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ +- const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; +- const char *type; +- int i; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- +- DRM_PROC_PRINT("slot offset size type flags " +- "address mtrr\n\n"); +- i = 0; +- list_for_each_entry(r_list, &dev->maplist, head) { +- map = r_list->map; +- if (!map) +- continue; +- if (map->type < 0 || map->type > 5) +- type = "??"; +- else +- type = types[map->type]; +- DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", +- i, +- map->offset, +- map->size, type, map->flags, +- (unsigned long) r_list->user_token); +- if (map->mtrr < 0) { +- DRM_PROC_PRINT("none\n"); +- } else { +- DRM_PROC_PRINT("%4d\n", map->mtrr); ++ if (dev->driver->proc_init) { ++ ret = dev->driver->proc_init(minor); ++ if (ret) { ++ DRM_ERROR("DRM: Driver failed to initialize " ++ "/proc/dri.\n"); ++ return ret; + } +- i++; +- } +- +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-/** +- * Simply calls _vm_info() while holding the drm_device::struct_mutex lock. +- */ +-static int drm_vm_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int ret; +- +- mutex_lock(&dev->struct_mutex); +- ret = drm__vm_info(buf, start, offset, request, eof, data); +- mutex_unlock(&dev->struct_mutex); +- return ret; +-} +- +-/** +- * Called when "/proc/dri/.../queues" is read. +- * +- * \param buf output buffer. +- * \param start start of output data. +- * \param offset requested start offset. +- * \param request requested number of bytes. +- * \param eof whether there is no more data to return. +- * \param data private data. +- * \return number of written bytes. +- */ +-static int drm__queues_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int len = 0; +- int i; +- struct drm_queue *q; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; + } +- +- *start = &buf[offset]; +- *eof = 0; +- +- DRM_PROC_PRINT(" ctx/flags use fin" +- " blk/rw/rwf wait flushed queued" +- " locks\n\n"); +- for (i = 0; i < dev->queue_count; i++) { +- q = dev->queuelist[i]; +- atomic_inc(&q->use_count); +- DRM_PROC_PRINT_RET(atomic_dec(&q->use_count), +- "%5d/0x%03x %5d %5d" +- " %5d/%c%c/%c%c%c %5Zd\n", +- i, +- q->flags, +- atomic_read(&q->use_count), +- atomic_read(&q->finalization), +- atomic_read(&q->block_count), +- atomic_read(&q->block_read) ? 'r' : '-', +- atomic_read(&q->block_write) ? 'w' : '-', +- waitqueue_active(&q->read_queue) ? 'r' : '-', +- waitqueue_active(&q-> +- write_queue) ? 'w' : '-', +- waitqueue_active(&q-> +- flush_queue) ? 'f' : '-', +- DRM_BUFCOUNT(&q->waitlist)); +- atomic_dec(&q->use_count); +- } +- +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-/** +- * Simply calls _queues_info() while holding the drm_device::struct_mutex lock. +- */ +-static int drm_queues_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int ret; +- +- mutex_lock(&dev->struct_mutex); +- ret = drm__queues_info(buf, start, offset, request, eof, data); +- mutex_unlock(&dev->struct_mutex); +- return ret; ++ return 0; + } + +-/** +- * Called when "/proc/dri/.../bufs" is read. +- * +- * \param buf output buffer. +- * \param start start of output data. +- * \param offset requested start offset. +- * \param request requested number of bytes. +- * \param eof whether there is no more data to return. +- * \param data private data. +- * \return number of written bytes. +- */ +-static int drm__bufs_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) ++int drm_proc_remove_files(struct drm_info_list *files, int count, ++ struct drm_minor *minor) + { +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int len = 0; +- struct drm_device_dma *dma = dev->dma; ++ struct list_head *pos, *q; ++ struct drm_info_node *tmp; + int i; + +- if (!dma || offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- +- DRM_PROC_PRINT(" o size count free segs pages kB\n\n"); +- for (i = 0; i <= DRM_MAX_ORDER; i++) { +- if (dma->bufs[i].buf_count) +- DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n", +- i, +- dma->bufs[i].buf_size, +- dma->bufs[i].buf_count, +- atomic_read(&dma->bufs[i] +- .freelist.count), +- dma->bufs[i].seg_count, +- dma->bufs[i].seg_count +- * (1 << dma->bufs[i].page_order), +- (dma->bufs[i].seg_count +- * (1 << dma->bufs[i].page_order)) +- * PAGE_SIZE / 1024); +- } +- DRM_PROC_PRINT("\n"); +- for (i = 0; i < dma->buf_count; i++) { +- if (i && !(i % 32)) +- DRM_PROC_PRINT("\n"); +- DRM_PROC_PRINT(" %d", dma->buflist[i]->list); ++ for (i = 0; i < count; i++) { ++ list_for_each_safe(pos, q, &minor->proc_nodes.list) { ++ tmp = list_entry(pos, struct drm_info_node, list); ++ if (tmp->info_ent == &files[i]) { ++ remove_proc_entry(files[i].name, ++ minor->proc_root); ++ list_del(pos); ++ drm_free(tmp, sizeof(struct drm_info_node), ++ _DRM_DRIVER); ++ } ++ } + } +- DRM_PROC_PRINT("\n"); +- +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-/** +- * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock. +- */ +-static int drm_bufs_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int ret; +- +- mutex_lock(&dev->struct_mutex); +- ret = drm__bufs_info(buf, start, offset, request, eof, data); +- mutex_unlock(&dev->struct_mutex); +- return ret; ++ return 0; + } + + /** +- * Called when "/proc/dri/.../vblank" is read. ++ * Cleanup the proc filesystem resources. + * +- * \param buf output buffer. +- * \param start start of output data. +- * \param offset requested start offset. +- * \param request requested number of bytes. +- * \param eof whether there is no more data to return. +- * \param data private data. +- * \return number of written bytes. +- */ +-static int drm__vblank_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int len = 0; +- int crtc; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- +- for (crtc = 0; crtc < dev->num_crtcs; crtc++) { +- DRM_PROC_PRINT("CRTC %d enable: %d\n", +- crtc, atomic_read(&dev->vblank_refcount[crtc])); +- DRM_PROC_PRINT("CRTC %d counter: %d\n", +- crtc, drm_vblank_count(dev, crtc)); +- DRM_PROC_PRINT("CRTC %d last wait: %d\n", +- crtc, dev->last_vblank_wait[crtc]); +- DRM_PROC_PRINT("CRTC %d in modeset: %d\n", +- crtc, dev->vblank_inmodeset[crtc]); +- } +- +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-/** +- * Simply calls _vblank_info() while holding the drm_device::struct_mutex lock. +- */ +-static int drm_vblank_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int ret; +- +- mutex_lock(&dev->struct_mutex); +- ret = drm__vblank_info(buf, start, offset, request, eof, data); +- mutex_unlock(&dev->struct_mutex); +- return ret; +-} +- +-/** +- * Called when "/proc/dri/.../clients" is read. ++ * \param minor device minor number. ++ * \param root DRI proc dir entry. ++ * \param dev_root DRI device proc dir entry. ++ * \return always zero. + * +- * \param buf output buffer. +- * \param start start of output data. +- * \param offset requested start offset. +- * \param request requested number of bytes. +- * \param eof whether there is no more data to return. +- * \param data private data. +- * \return number of written bytes. ++ * Remove all proc entries created by proc_init(). + */ +-static int drm__clients_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) ++int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) + { +- struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; +- int len = 0; +- struct drm_file *priv; ++ char name[64]; + +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; ++ if (!root || !minor->proc_root) + return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- +- DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n"); +- list_for_each_entry(priv, &dev->filelist, lhead) { +- DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", +- priv->authenticated ? 'y' : 'n', +- priv->minor->index, +- priv->pid, +- priv->uid, priv->magic, priv->ioctl_count); +- } + +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-/** +- * Simply calls _clients_info() while holding the drm_device::struct_mutex lock. +- */ +-static int drm_clients_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int ret; +- +- mutex_lock(&dev->struct_mutex); +- ret = drm__clients_info(buf, start, offset, request, eof, data); +- mutex_unlock(&dev->struct_mutex); +- return ret; +-} +- +-struct drm_gem_name_info_data { +- int len; +- char *buf; +- int eof; +-}; ++ if (dev->driver->proc_cleanup) ++ dev->driver->proc_cleanup(minor); + +-static int drm_gem_one_name_info(int id, void *ptr, void *data) +-{ +- struct drm_gem_object *obj = ptr; +- struct drm_gem_name_info_data *nid = data; ++ drm_proc_remove_files(drm_proc_list, DRM_PROC_ENTRIES, minor); + +- DRM_INFO("name %d size %zd\n", obj->name, obj->size); +- if (nid->eof) +- return 0; ++ sprintf(name, "%d", minor->index); ++ remove_proc_entry(name, root); + +- nid->len += sprintf(&nid->buf[nid->len], +- "%6d %8zd %7d %8d\n", +- obj->name, obj->size, +- atomic_read(&obj->handlecount.refcount), +- atomic_read(&obj->refcount.refcount)); +- if (nid->len > DRM_PROC_LIMIT) { +- nid->eof = 1; +- return 0; +- } + return 0; + } + +-static int drm_gem_name_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- struct drm_gem_name_info_data nid; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- nid.len = sprintf(buf, " name size handles refcount\n"); +- nid.buf = buf; +- nid.eof = 0; +- idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid); +- +- *start = &buf[offset]; +- *eof = 0; +- if (nid.len > request + offset) +- return request; +- *eof = 1; +- return nid.len - offset; +-} +- +-static int drm_gem_object_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int len = 0; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count)); +- DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory)); +- DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count)); +- DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory)); +- DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory)); +- DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total); +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-#if DRM_DEBUG_CODE +- +-static int drm__vma_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int len = 0; +- struct drm_vma_entry *pt; +- struct vm_area_struct *vma; +-#if defined(__i386__) +- unsigned int pgprot; +-#endif +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- +- DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n", +- atomic_read(&dev->vma_count), +- high_memory, virt_to_phys(high_memory)); +- list_for_each_entry(pt, &dev->vmalist, head) { +- if (!(vma = pt->vma)) +- continue; +- DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", +- pt->pid, +- vma->vm_start, +- vma->vm_end, +- vma->vm_flags & VM_READ ? 'r' : '-', +- vma->vm_flags & VM_WRITE ? 'w' : '-', +- vma->vm_flags & VM_EXEC ? 'x' : '-', +- vma->vm_flags & VM_MAYSHARE ? 's' : 'p', +- vma->vm_flags & VM_LOCKED ? 'l' : '-', +- vma->vm_flags & VM_IO ? 'i' : '-', +- vma->vm_pgoff); +- +-#if defined(__i386__) +- pgprot = pgprot_val(vma->vm_page_prot); +- DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c", +- pgprot & _PAGE_PRESENT ? 'p' : '-', +- pgprot & _PAGE_RW ? 'w' : 'r', +- pgprot & _PAGE_USER ? 'u' : 's', +- pgprot & _PAGE_PWT ? 't' : 'b', +- pgprot & _PAGE_PCD ? 'u' : 'c', +- pgprot & _PAGE_ACCESSED ? 'a' : '-', +- pgprot & _PAGE_DIRTY ? 'd' : '-', +- pgprot & _PAGE_PSE ? 'm' : 'k', +- pgprot & _PAGE_GLOBAL ? 'g' : 'l'); +-#endif +- DRM_PROC_PRINT("\n"); +- } +- +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-static int drm_vma_info(char *buf, char **start, off_t offset, int request, +- int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- int ret; +- +- mutex_lock(&dev->struct_mutex); +- ret = drm__vma_info(buf, start, offset, request, eof, data); +- mutex_unlock(&dev->struct_mutex); +- return ret; +-} +-#endif +diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c +index 7c8b15b..d009661 100644 +--- a/drivers/gpu/drm/drm_stub.c ++++ b/drivers/gpu/drm/drm_stub.c +@@ -50,6 +50,7 @@ struct idr drm_minors_idr; + + struct class *drm_class; + struct proc_dir_entry *drm_proc_root; ++struct dentry *drm_debugfs_root; + + static int drm_minor_get_id(struct drm_device *dev, int type) + { +@@ -313,7 +314,15 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t + goto err_mem; + } + } else +- new_minor->dev_root = NULL; ++ new_minor->proc_root = NULL; ++ ++#if defined(CONFIG_DEBUG_FS) ++ ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root); ++ if (ret) { ++ DRM_ERROR("DRM: Failed to initialize /debugfs/dri.\n"); ++ goto err_g2; ++ } ++#endif + + ret = drm_sysfs_device_add(new_minor); + if (ret) { +@@ -372,6 +381,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, + } + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ pci_set_drvdata(pdev, dev); + ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); + if (ret) + goto err_g2; +@@ -395,9 +405,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, + + list_add_tail(&dev->driver_item, &driver->device_list); + +- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", ++ DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", + driver->name, driver->major, driver->minor, driver->patchlevel, +- driver->date, dev->primary->index); ++ driver->date, pci_name(pdev), dev->primary->index); + + return 0; + +@@ -409,29 +419,7 @@ err_g1: + drm_free(dev, sizeof(*dev), DRM_MEM_STUB); + return ret; + } +- +-/** +- * Put a device minor number. +- * +- * \param dev device data structure +- * \return always zero +- * +- * Cleans up the proc resources. If it is the last minor then release the foreign +- * "drm" data, otherwise unregisters the "drm" data, frees the dev list and +- * unregisters the character device. +- */ +-int drm_put_dev(struct drm_device * dev) +-{ +- DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name); +- +- if (dev->devname) { +- drm_free(dev->devname, strlen(dev->devname) + 1, +- DRM_MEM_DRIVER); +- dev->devname = NULL; +- } +- drm_free(dev, sizeof(*dev), DRM_MEM_STUB); +- return 0; +-} ++EXPORT_SYMBOL(drm_get_dev); + + /** + * Put a secondary minor number. +@@ -451,6 +439,10 @@ int drm_put_minor(struct drm_minor **minor_p) + + if (minor->type == DRM_MINOR_LEGACY) + drm_proc_cleanup(minor, drm_proc_root); ++#if defined(CONFIG_DEBUG_FS) ++ drm_debugfs_cleanup(minor); ++#endif ++ + drm_sysfs_device_remove(minor); + + idr_remove(&drm_minors_idr, minor->index); +@@ -459,3 +451,67 @@ int drm_put_minor(struct drm_minor **minor_p) + *minor_p = NULL; + return 0; + } ++ ++/** ++ * Called via drm_exit() at module unload time or when pci device is ++ * unplugged. ++ * ++ * Cleans up all DRM device, calling drm_lastclose(). ++ * ++ * \sa drm_init ++ */ ++void drm_put_dev(struct drm_device *dev) ++{ ++ struct drm_driver *driver = dev->driver; ++ struct drm_map_list *r_list, *list_temp; ++ ++ DRM_DEBUG("\n"); ++ ++ if (!dev) { ++ DRM_ERROR("cleanup called no dev\n"); ++ return; ++ } ++ ++ drm_vblank_cleanup(dev); ++ ++ drm_lastclose(dev); ++ ++ if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && ++ dev->agp && dev->agp->agp_mtrr >= 0) { ++ int retval; ++ retval = mtrr_del(dev->agp->agp_mtrr, ++ dev->agp->agp_info.aper_base, ++ dev->agp->agp_info.aper_size * 1024 * 1024); ++ DRM_DEBUG("mtrr_del=%d\n", retval); ++ } ++ ++ if (dev->driver->unload) ++ dev->driver->unload(dev); ++ ++ if (drm_core_has_AGP(dev) && dev->agp) { ++ drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); ++ dev->agp = NULL; ++ } ++ ++ drm_ht_remove(&dev->map_hash); ++ drm_ctxbitmap_cleanup(dev); ++ ++ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) ++ drm_rmmap(dev, r_list->map); ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_put_minor(&dev->control); ++ ++ if (driver->driver_features & DRIVER_GEM) ++ drm_gem_destroy(dev); ++ ++ drm_put_minor(&dev->primary); ++ ++ if (dev->devname) { ++ drm_free(dev->devname, strlen(dev->devname) + 1, ++ DRM_MEM_DRIVER); ++ dev->devname = NULL; ++ } ++ drm_free(dev, sizeof(*dev), DRM_MEM_STUB); ++} ++EXPORT_SYMBOL(drm_put_dev); +diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c +index 5aa6780..bc0c684 100644 +--- a/drivers/gpu/drm/drm_sysfs.c ++++ b/drivers/gpu/drm/drm_sysfs.c +@@ -35,7 +35,9 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) + struct drm_minor *drm_minor = to_drm_minor(dev); + struct drm_device *drm_dev = drm_minor->dev; + +- if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->suspend) ++ if (drm_minor->type == DRM_MINOR_LEGACY && ++ !drm_core_check_feature(drm_dev, DRIVER_MODESET) && ++ drm_dev->driver->suspend) + return drm_dev->driver->suspend(drm_dev, state); + + return 0; +@@ -53,7 +55,9 @@ static int drm_sysfs_resume(struct device *dev) + struct drm_minor *drm_minor = to_drm_minor(dev); + struct drm_device *drm_dev = drm_minor->dev; + +- if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->resume) ++ if (drm_minor->type == DRM_MINOR_LEGACY && ++ !drm_core_check_feature(drm_dev, DRIVER_MODESET) && ++ drm_dev->driver->resume) + return drm_dev->driver->resume(drm_dev); + + return 0; +@@ -118,20 +122,6 @@ void drm_sysfs_destroy(void) + class_destroy(drm_class); + } + +-static ssize_t show_dri(struct device *device, struct device_attribute *attr, +- char *buf) +-{ +- struct drm_minor *drm_minor = to_drm_minor(device); +- struct drm_device *drm_dev = drm_minor->dev; +- if (drm_dev->driver->dri_library_name) +- return drm_dev->driver->dri_library_name(drm_dev, buf); +- return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name); +-} +- +-static struct device_attribute device_attrs[] = { +- __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), +-}; +- + /** + * drm_sysfs_device_release - do nothing + * @dev: Linux device +@@ -359,8 +349,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector) + DRM_DEBUG("adding \"%s\" to sysfs\n", + drm_get_connector_name(connector)); + +- snprintf(connector->kdev.bus_id, BUS_ID_SIZE, "card%d-%s", +- dev->primary->index, drm_get_connector_name(connector)); ++ dev_set_name(&connector->kdev, "card%d-%s", ++ dev->primary->index, drm_get_connector_name(connector)); + ret = device_register(&connector->kdev); + + if (ret) { +@@ -461,6 +451,7 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) + + kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp); + } ++EXPORT_SYMBOL(drm_sysfs_hotplug_event); + + /** + * drm_sysfs_device_add - adds a class device to sysfs for a character driver +@@ -474,7 +465,6 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) + int drm_sysfs_device_add(struct drm_minor *minor) + { + int err; +- int i, j; + char *minor_str; + + minor->kdev.parent = &minor->dev->pdev->dev; +@@ -496,18 +486,8 @@ int drm_sysfs_device_add(struct drm_minor *minor) + goto err_out; + } + +- for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { +- err = device_create_file(&minor->kdev, &device_attrs[i]); +- if (err) +- goto err_out_files; +- } +- + return 0; + +-err_out_files: +- if (i > 0) +- for (j = 0; j < i; j++) +- device_remove_file(&minor->kdev, &device_attrs[j]); + device_unregister(&minor->kdev); + err_out: + +@@ -523,9 +503,5 @@ err_out: + */ + void drm_sysfs_device_remove(struct drm_minor *minor) + { +- int i; +- +- for (i = 0; i < ARRAY_SIZE(device_attrs); i++) +- device_remove_file(&minor->kdev, &device_attrs[i]); + device_unregister(&minor->kdev); + } +diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c +index 3ffae02..22f7656 100644 +--- a/drivers/gpu/drm/drm_vm.c ++++ b/drivers/gpu/drm/drm_vm.c +@@ -91,7 +91,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + { + struct drm_file *priv = vma->vm_file->private_data; + struct drm_device *dev = priv->minor->dev; +- struct drm_map *map = NULL; ++ struct drm_local_map *map = NULL; + struct drm_map_list *r_list; + struct drm_hash_item *hash; + +@@ -115,9 +115,9 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + * Using vm_pgoff as a selector forces us to use this unusual + * addressing scheme. + */ +- unsigned long offset = (unsigned long)vmf->virtual_address - +- vma->vm_start; +- unsigned long baddr = map->offset + offset; ++ resource_size_t offset = (unsigned long)vmf->virtual_address - ++ vma->vm_start; ++ resource_size_t baddr = map->offset + offset; + struct drm_agp_mem *agpmem; + struct page *page; + +@@ -149,8 +149,10 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + vmf->page = page; + + DRM_DEBUG +- ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", +- baddr, __va(agpmem->memory->memory[offset]), offset, ++ ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n", ++ (unsigned long long)baddr, ++ __va(agpmem->memory->memory[offset]), ++ (unsigned long long)offset, + page_count(page)); + return 0; + } +@@ -176,7 +178,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + */ + static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + { +- struct drm_map *map = (struct drm_map *) vma->vm_private_data; ++ struct drm_local_map *map = vma->vm_private_data; + unsigned long offset; + unsigned long i; + struct page *page; +@@ -209,7 +211,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) + struct drm_file *priv = vma->vm_file->private_data; + struct drm_device *dev = priv->minor->dev; + struct drm_vma_entry *pt, *temp; +- struct drm_map *map; ++ struct drm_local_map *map; + struct drm_map_list *r_list; + int found_maps = 0; + +@@ -322,7 +324,7 @@ static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + */ + static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + { +- struct drm_map *map = (struct drm_map *) vma->vm_private_data; ++ struct drm_local_map *map = vma->vm_private_data; + struct drm_file *priv = vma->vm_file->private_data; + struct drm_device *dev = priv->minor->dev; + struct drm_sg_mem *entry = dev->sg; +@@ -512,14 +514,14 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) + return 0; + } + +-unsigned long drm_core_get_map_ofs(struct drm_map * map) ++resource_size_t drm_core_get_map_ofs(struct drm_local_map * map) + { + return map->offset; + } + + EXPORT_SYMBOL(drm_core_get_map_ofs); + +-unsigned long drm_core_get_reg_ofs(struct drm_device *dev) ++resource_size_t drm_core_get_reg_ofs(struct drm_device *dev) + { + #ifdef __alpha__ + return dev->hose->dense_mem_base - dev->hose->mem_space->start; +@@ -547,8 +549,8 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) + { + struct drm_file *priv = filp->private_data; + struct drm_device *dev = priv->minor->dev; +- struct drm_map *map = NULL; +- unsigned long offset = 0; ++ struct drm_local_map *map = NULL; ++ resource_size_t offset = 0; + struct drm_hash_item *hash; + + DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", +@@ -623,9 +625,9 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) + vma->vm_page_prot)) + return -EAGAIN; + DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," +- " offset = 0x%lx\n", ++ " offset = 0x%llx\n", + map->type, +- vma->vm_start, vma->vm_end, map->offset + offset); ++ vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset)); + vma->vm_ops = &drm_vm_ops; + break; + case _DRM_CONSISTENT: +diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h +index 0118849..21e2691 100644 +--- a/drivers/gpu/drm/i810/i810_drv.h ++++ b/drivers/gpu/drm/i810/i810_drv.h +@@ -77,8 +77,8 @@ typedef struct _drm_i810_ring_buffer { + } drm_i810_ring_buffer_t; + + typedef struct drm_i810_private { +- struct drm_map *sarea_map; +- struct drm_map *mmio_map; ++ struct drm_local_map *sarea_map; ++ struct drm_local_map *mmio_map; + + drm_i810_sarea_t *sarea_priv; + drm_i810_ring_buffer_t ring; +diff --git a/drivers/gpu/drm/i830/i830_drv.h b/drivers/gpu/drm/i830/i830_drv.h +index b5bf8cc..da82afe 100644 +--- a/drivers/gpu/drm/i830/i830_drv.h ++++ b/drivers/gpu/drm/i830/i830_drv.h +@@ -84,8 +84,8 @@ typedef struct _drm_i830_ring_buffer { + } drm_i830_ring_buffer_t; + + typedef struct drm_i830_private { +- struct drm_map *sarea_map; +- struct drm_map *mmio_map; ++ struct drm_local_map *sarea_map; ++ struct drm_local_map *mmio_map; + + drm_i830_sarea_t *sarea_priv; + drm_i830_ring_buffer_t ring; +diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile +index 793cba3..51c5a05 100644 +--- a/drivers/gpu/drm/i915/Makefile ++++ b/drivers/gpu/drm/i915/Makefile +@@ -7,7 +7,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ + i915_suspend.o \ + i915_gem.o \ + i915_gem_debug.o \ +- i915_gem_proc.o \ ++ i915_gem_debugfs.o \ + i915_gem_tiling.o \ + intel_display.o \ + intel_crt.o \ +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 6d21b9e..c23b3a9 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -41,7 +41,6 @@ + int i915_wait_ring(struct drm_device * dev, int n, const char *caller) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; + drm_i915_ring_buffer_t *ring = &(dev_priv->ring); + u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; + u32 last_acthd = I915_READ(acthd_reg); +@@ -58,8 +57,12 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) + if (ring->space >= n) + return 0; + +- if (master_priv->sarea_priv) +- master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; ++ if (dev->primary->master) { ++ struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; ++ if (master_priv->sarea_priv) ++ master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; ++ } ++ + + if (ring->head != last_head) + i = 0; +@@ -356,7 +359,7 @@ static int validate_cmd(int cmd) + return ret; + } + +-static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords) ++static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) + { + drm_i915_private_t *dev_priv = dev->dev_private; + int i; +@@ -370,8 +373,7 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor + for (i = 0; i < dwords;) { + int cmd, sz; + +- if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) +- return -EINVAL; ++ cmd = buffer[i]; + + if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) + return -EINVAL; +@@ -379,11 +381,7 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor + OUT_RING(cmd); + + while (++i, --sz) { +- if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], +- sizeof(cmd))) { +- return -EINVAL; +- } +- OUT_RING(cmd); ++ OUT_RING(buffer[i]); + } + } + +@@ -397,17 +395,13 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor + + int + i915_emit_box(struct drm_device *dev, +- struct drm_clip_rect __user *boxes, ++ struct drm_clip_rect *boxes, + int i, int DR1, int DR4) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_clip_rect box; ++ struct drm_clip_rect box = boxes[i]; + RING_LOCALS; + +- if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { +- return -EFAULT; +- } +- + if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { + DRM_ERROR("Bad box %d,%d..%d,%d\n", + box.x1, box.y1, box.x2, box.y2); +@@ -460,7 +454,9 @@ static void i915_emit_breadcrumb(struct drm_device *dev) + } + + static int i915_dispatch_cmdbuffer(struct drm_device * dev, +- drm_i915_cmdbuffer_t * cmd) ++ drm_i915_cmdbuffer_t *cmd, ++ struct drm_clip_rect *cliprects, ++ void *cmdbuf) + { + int nbox = cmd->num_cliprects; + int i = 0, count, ret; +@@ -476,13 +472,13 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, + + for (i = 0; i < count; i++) { + if (i < nbox) { +- ret = i915_emit_box(dev, cmd->cliprects, i, ++ ret = i915_emit_box(dev, cliprects, i, + cmd->DR1, cmd->DR4); + if (ret) + return ret; + } + +- ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4); ++ ret = i915_emit_cmds(dev, cmdbuf, cmd->sz / 4); + if (ret) + return ret; + } +@@ -492,10 +488,10 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, + } + + static int i915_dispatch_batchbuffer(struct drm_device * dev, +- drm_i915_batchbuffer_t * batch) ++ drm_i915_batchbuffer_t * batch, ++ struct drm_clip_rect *cliprects) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_clip_rect __user *boxes = batch->cliprects; + int nbox = batch->num_cliprects; + int i = 0, count; + RING_LOCALS; +@@ -511,7 +507,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, + + for (i = 0; i < count; i++) { + if (i < nbox) { +- int ret = i915_emit_box(dev, boxes, i, ++ int ret = i915_emit_box(dev, cliprects, i, + batch->DR1, batch->DR4); + if (ret) + return ret; +@@ -626,6 +622,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, + master_priv->sarea_priv; + drm_i915_batchbuffer_t *batch = data; + int ret; ++ struct drm_clip_rect *cliprects = NULL; + + if (!dev_priv->allow_batchbuffer) { + DRM_ERROR("Batchbuffer ioctl disabled\n"); +@@ -637,17 +634,35 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, + + RING_LOCK_TEST_WITH_RETURN(dev, file_priv); + +- if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, +- batch->num_cliprects * +- sizeof(struct drm_clip_rect))) +- return -EFAULT; ++ if (batch->num_cliprects < 0) ++ return -EINVAL; ++ ++ if (batch->num_cliprects) { ++ cliprects = drm_calloc(batch->num_cliprects, ++ sizeof(struct drm_clip_rect), ++ DRM_MEM_DRIVER); ++ if (cliprects == NULL) ++ return -ENOMEM; ++ ++ ret = copy_from_user(cliprects, batch->cliprects, ++ batch->num_cliprects * ++ sizeof(struct drm_clip_rect)); ++ if (ret != 0) ++ goto fail_free; ++ } + + mutex_lock(&dev->struct_mutex); +- ret = i915_dispatch_batchbuffer(dev, batch); ++ ret = i915_dispatch_batchbuffer(dev, batch, cliprects); + mutex_unlock(&dev->struct_mutex); + + if (sarea_priv) + sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); ++ ++fail_free: ++ drm_free(cliprects, ++ batch->num_cliprects * sizeof(struct drm_clip_rect), ++ DRM_MEM_DRIVER); ++ + return ret; + } + +@@ -659,6 +674,8 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, + drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) + master_priv->sarea_priv; + drm_i915_cmdbuffer_t *cmdbuf = data; ++ struct drm_clip_rect *cliprects = NULL; ++ void *batch_data; + int ret; + + DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", +@@ -666,25 +683,50 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, + + RING_LOCK_TEST_WITH_RETURN(dev, file_priv); + +- if (cmdbuf->num_cliprects && +- DRM_VERIFYAREA_READ(cmdbuf->cliprects, +- cmdbuf->num_cliprects * +- sizeof(struct drm_clip_rect))) { +- DRM_ERROR("Fault accessing cliprects\n"); +- return -EFAULT; ++ if (cmdbuf->num_cliprects < 0) ++ return -EINVAL; ++ ++ batch_data = drm_alloc(cmdbuf->sz, DRM_MEM_DRIVER); ++ if (batch_data == NULL) ++ return -ENOMEM; ++ ++ ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); ++ if (ret != 0) ++ goto fail_batch_free; ++ ++ if (cmdbuf->num_cliprects) { ++ cliprects = drm_calloc(cmdbuf->num_cliprects, ++ sizeof(struct drm_clip_rect), ++ DRM_MEM_DRIVER); ++ if (cliprects == NULL) ++ goto fail_batch_free; ++ ++ ret = copy_from_user(cliprects, cmdbuf->cliprects, ++ cmdbuf->num_cliprects * ++ sizeof(struct drm_clip_rect)); ++ if (ret != 0) ++ goto fail_clip_free; + } + + mutex_lock(&dev->struct_mutex); +- ret = i915_dispatch_cmdbuffer(dev, cmdbuf); ++ ret = i915_dispatch_cmdbuffer(dev, cmdbuf, cliprects, batch_data); + mutex_unlock(&dev->struct_mutex); + if (ret) { + DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); +- return ret; ++ goto fail_batch_free; + } + + if (sarea_priv) + sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); +- return 0; ++ ++fail_batch_free: ++ drm_free(batch_data, cmdbuf->sz, DRM_MEM_DRIVER); ++fail_clip_free: ++ drm_free(cliprects, ++ cmdbuf->num_cliprects * sizeof(struct drm_clip_rect), ++ DRM_MEM_DRIVER); ++ ++ return ret; + } + + static int i915_flip_bufs(struct drm_device *dev, void *data, +@@ -880,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, + * Some of the preallocated space is taken by the GTT + * and popup. GTT is 1K per MB of aperture size, and popup is 4K. + */ +- if (IS_G4X(dev)) ++ if (IS_G4X(dev) || IS_IGD(dev)) + overhead = 4096; + else + overhead = (*aperture_size / 1024) + 4096; +@@ -988,13 +1030,6 @@ static int i915_load_modeset_init(struct drm_device *dev) + if (ret) + goto destroy_ringbuffer; + +- /* FIXME: re-add hotplug support */ +-#if 0 +- ret = drm_hotplug_init(dev); +- if (ret) +- goto destroy_ringbuffer; +-#endif +- + /* Always safe in the mode setting case. */ + /* FIXME: do pre/post-mode set stuff in core KMS code */ + dev->vblank_disable_allowed = 1; +@@ -1007,7 +1042,7 @@ static int i915_load_modeset_init(struct drm_device *dev) + + intel_modeset_init(dev); + +- drm_helper_initial_config(dev, false); ++ drm_helper_initial_config(dev); + + return 0; + +@@ -1057,7 +1092,7 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) + int i915_driver_load(struct drm_device *dev, unsigned long flags) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- unsigned long base, size; ++ resource_size_t base, size; + int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; + + /* i915 has 4 more counters */ +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index b293ef0..2c01676 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -42,6 +42,8 @@ module_param_named(modeset, i915_modeset, int, 0400); + unsigned int i915_fbpercrtc = 0; + module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); + ++static struct drm_driver driver; ++ + static struct pci_device_id pciidlist[] = { + i915_PCI_IDS + }; +@@ -117,6 +119,36 @@ static int i915_resume(struct drm_device *dev) + return ret; + } + ++static int __devinit ++i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ++{ ++ return drm_get_dev(pdev, ent, &driver); ++} ++ ++static void ++i915_pci_remove(struct pci_dev *pdev) ++{ ++ struct drm_device *dev = pci_get_drvdata(pdev); ++ ++ drm_put_dev(dev); ++} ++ ++static int ++i915_pci_suspend(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct drm_device *dev = pci_get_drvdata(pdev); ++ ++ return i915_suspend(dev, state); ++} ++ ++static int ++i915_pci_resume(struct pci_dev *pdev) ++{ ++ struct drm_device *dev = pci_get_drvdata(pdev); ++ ++ return i915_resume(dev); ++} ++ + static struct vm_operations_struct i915_gem_vm_ops = { + .fault = i915_gem_fault, + .open = drm_gem_vm_open, +@@ -150,8 +182,10 @@ static struct drm_driver driver = { + .get_reg_ofs = drm_core_get_reg_ofs, + .master_create = i915_master_create, + .master_destroy = i915_master_destroy, +- .proc_init = i915_gem_proc_init, +- .proc_cleanup = i915_gem_proc_cleanup, ++#if defined(CONFIG_DEBUG_FS) ++ .debugfs_init = i915_gem_debugfs_init, ++ .debugfs_cleanup = i915_gem_debugfs_cleanup, ++#endif + .gem_init_object = i915_gem_init_object, + .gem_free_object = i915_gem_free_object, + .gem_vm_ops = &i915_gem_vm_ops, +@@ -172,6 +206,12 @@ static struct drm_driver driver = { + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, ++ .probe = i915_pci_probe, ++ .remove = i915_pci_remove, ++#ifdef CONFIG_PM ++ .resume = i915_pci_resume, ++ .suspend = i915_pci_suspend, ++#endif + }, + + .name = DRIVER_NAME, +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index d6cc986..317b122 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -159,6 +159,9 @@ typedef struct drm_i915_private { + u32 irq_mask_reg; + u32 pipestat[2]; + ++ u32 hotplug_supported_mask; ++ struct work_struct hotplug_work; ++ + int tex_lru_log_granularity; + int allow_batchbuffer; + struct mem_block *agp_heap; +@@ -297,6 +300,7 @@ typedef struct drm_i915_private { + * + * A reference is held on the buffer while on this list. + */ ++ spinlock_t active_list_lock; + struct list_head active_list; + + /** +@@ -404,7 +408,8 @@ struct drm_i915_gem_object { + /** AGP memory structure for our GTT binding. */ + DRM_AGP_MEM *agp_mem; + +- struct page **page_list; ++ struct page **pages; ++ int pages_refcount; + + /** + * Current offset of the object in GTT space. +@@ -519,7 +524,7 @@ extern int i915_driver_device_is_agp(struct drm_device * dev); + extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); + extern int i915_emit_box(struct drm_device *dev, +- struct drm_clip_rect __user *boxes, ++ struct drm_clip_rect *boxes, + int i, int DR1, int DR4); + + /* i915_irq.c */ +@@ -604,8 +609,6 @@ int i915_gem_get_tiling(struct drm_device *dev, void *data, + int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + void i915_gem_load(struct drm_device *dev); +-int i915_gem_proc_init(struct drm_minor *minor); +-void i915_gem_proc_cleanup(struct drm_minor *minor); + int i915_gem_init_object(struct drm_gem_object *obj); + void i915_gem_free_object(struct drm_gem_object *obj); + int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); +@@ -649,6 +652,10 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len, + const char *where, uint32_t mark); + void i915_dump_lru(struct drm_device *dev, const char *where); + ++/* i915_debugfs.c */ ++int i915_gem_debugfs_init(struct drm_minor *minor); ++void i915_gem_debugfs_cleanup(struct drm_minor *minor); ++ + /* i915_suspend.c */ + extern int i915_save_state(struct drm_device *dev); + extern int i915_restore_state(struct drm_device *dev); +@@ -784,15 +791,21 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + (dev)->pci_device == 0x2E22 || \ + IS_GM45(dev)) + ++#define IS_IGDG(dev) ((dev)->pci_device == 0xa001) ++#define IS_IGDGM(dev) ((dev)->pci_device == 0xa011) ++#define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev)) ++ + #define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ + (dev)->pci_device == 0x29B2 || \ +- (dev)->pci_device == 0x29D2) ++ (dev)->pci_device == 0x29D2 || \ ++ (IS_IGD(dev))) + + #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ + IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) + + #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ +- IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev)) ++ IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \ ++ IS_IGD(dev)) + + #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev)) + /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte +@@ -801,6 +814,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ + IS_I915GM(dev))) + #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev)) ++#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) + + #define PRIMARY_RINGBUFFER_SIZE (128*1024) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 37427e4..1449b45 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -43,8 +43,8 @@ static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, + uint64_t offset, + uint64_t size); + static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj); +-static int i915_gem_object_get_page_list(struct drm_gem_object *obj); +-static void i915_gem_object_free_page_list(struct drm_gem_object *obj); ++static int i915_gem_object_get_pages(struct drm_gem_object *obj); ++static void i915_gem_object_put_pages(struct drm_gem_object *obj); + static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); + static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, + unsigned alignment); +@@ -136,6 +136,224 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, + return 0; + } + ++static inline int ++fast_shmem_read(struct page **pages, ++ loff_t page_base, int page_offset, ++ char __user *data, ++ int length) ++{ ++ char __iomem *vaddr; ++ int ret; ++ ++ vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0); ++ if (vaddr == NULL) ++ return -ENOMEM; ++ ret = __copy_to_user_inatomic(data, vaddr + page_offset, length); ++ kunmap_atomic(vaddr, KM_USER0); ++ ++ return ret; ++} ++ ++static inline int ++slow_shmem_copy(struct page *dst_page, ++ int dst_offset, ++ struct page *src_page, ++ int src_offset, ++ int length) ++{ ++ char *dst_vaddr, *src_vaddr; ++ ++ dst_vaddr = kmap_atomic(dst_page, KM_USER0); ++ if (dst_vaddr == NULL) ++ return -ENOMEM; ++ ++ src_vaddr = kmap_atomic(src_page, KM_USER1); ++ if (src_vaddr == NULL) { ++ kunmap_atomic(dst_vaddr, KM_USER0); ++ return -ENOMEM; ++ } ++ ++ memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); ++ ++ kunmap_atomic(src_vaddr, KM_USER1); ++ kunmap_atomic(dst_vaddr, KM_USER0); ++ ++ return 0; ++} ++ ++/** ++ * This is the fast shmem pread path, which attempts to copy_from_user directly ++ * from the backing pages of the object to the user's address space. On a ++ * fault, it fails so we can fall back to i915_gem_shmem_pwrite_slow(). ++ */ ++static int ++i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, ++ struct drm_i915_gem_pread *args, ++ struct drm_file *file_priv) ++{ ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ ssize_t remain; ++ loff_t offset, page_base; ++ char __user *user_data; ++ int page_offset, page_length; ++ int ret; ++ ++ user_data = (char __user *) (uintptr_t) args->data_ptr; ++ remain = args->size; ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ ret = i915_gem_object_get_pages(obj); ++ if (ret != 0) ++ goto fail_unlock; ++ ++ ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset, ++ args->size); ++ if (ret != 0) ++ goto fail_put_pages; ++ ++ obj_priv = obj->driver_private; ++ offset = args->offset; ++ ++ while (remain > 0) { ++ /* Operation in this page ++ * ++ * page_base = page offset within aperture ++ * page_offset = offset within page ++ * page_length = bytes to copy for this page ++ */ ++ page_base = (offset & ~(PAGE_SIZE-1)); ++ page_offset = offset & (PAGE_SIZE-1); ++ page_length = remain; ++ if ((page_offset + remain) > PAGE_SIZE) ++ page_length = PAGE_SIZE - page_offset; ++ ++ ret = fast_shmem_read(obj_priv->pages, ++ page_base, page_offset, ++ user_data, page_length); ++ if (ret) ++ goto fail_put_pages; ++ ++ remain -= page_length; ++ user_data += page_length; ++ offset += page_length; ++ } ++ ++fail_put_pages: ++ i915_gem_object_put_pages(obj); ++fail_unlock: ++ mutex_unlock(&dev->struct_mutex); ++ ++ return ret; ++} ++ ++/** ++ * This is the fallback shmem pread path, which allocates temporary storage ++ * in kernel space to copy_to_user into outside of the struct_mutex, so we ++ * can copy out of the object's backing pages while holding the struct mutex ++ * and not take page faults. ++ */ ++static int ++i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, ++ struct drm_i915_gem_pread *args, ++ struct drm_file *file_priv) ++{ ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ struct mm_struct *mm = current->mm; ++ struct page **user_pages; ++ ssize_t remain; ++ loff_t offset, pinned_pages, i; ++ loff_t first_data_page, last_data_page, num_pages; ++ int shmem_page_index, shmem_page_offset; ++ int data_page_index, data_page_offset; ++ int page_length; ++ int ret; ++ uint64_t data_ptr = args->data_ptr; ++ ++ remain = args->size; ++ ++ /* Pin the user pages containing the data. We can't fault while ++ * holding the struct mutex, yet we want to hold it while ++ * dereferencing the user data. ++ */ ++ first_data_page = data_ptr / PAGE_SIZE; ++ last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; ++ num_pages = last_data_page - first_data_page + 1; ++ ++ user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL); ++ if (user_pages == NULL) ++ return -ENOMEM; ++ ++ down_read(&mm->mmap_sem); ++ pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, ++ num_pages, 0, 0, user_pages, NULL); ++ up_read(&mm->mmap_sem); ++ if (pinned_pages < num_pages) { ++ ret = -EFAULT; ++ goto fail_put_user_pages; ++ } ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ ret = i915_gem_object_get_pages(obj); ++ if (ret != 0) ++ goto fail_unlock; ++ ++ ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset, ++ args->size); ++ if (ret != 0) ++ goto fail_put_pages; ++ ++ obj_priv = obj->driver_private; ++ offset = args->offset; ++ ++ while (remain > 0) { ++ /* Operation in this page ++ * ++ * shmem_page_index = page number within shmem file ++ * shmem_page_offset = offset within page in shmem file ++ * data_page_index = page number in get_user_pages return ++ * data_page_offset = offset with data_page_index page. ++ * page_length = bytes to copy for this page ++ */ ++ shmem_page_index = offset / PAGE_SIZE; ++ shmem_page_offset = offset & ~PAGE_MASK; ++ data_page_index = data_ptr / PAGE_SIZE - first_data_page; ++ data_page_offset = data_ptr & ~PAGE_MASK; ++ ++ page_length = remain; ++ if ((shmem_page_offset + page_length) > PAGE_SIZE) ++ page_length = PAGE_SIZE - shmem_page_offset; ++ if ((data_page_offset + page_length) > PAGE_SIZE) ++ page_length = PAGE_SIZE - data_page_offset; ++ ++ ret = slow_shmem_copy(user_pages[data_page_index], ++ data_page_offset, ++ obj_priv->pages[shmem_page_index], ++ shmem_page_offset, ++ page_length); ++ if (ret) ++ goto fail_put_pages; ++ ++ remain -= page_length; ++ data_ptr += page_length; ++ offset += page_length; ++ } ++ ++fail_put_pages: ++ i915_gem_object_put_pages(obj); ++fail_unlock: ++ mutex_unlock(&dev->struct_mutex); ++fail_put_user_pages: ++ for (i = 0; i < pinned_pages; i++) { ++ SetPageDirty(user_pages[i]); ++ page_cache_release(user_pages[i]); ++ } ++ kfree(user_pages); ++ ++ return ret; ++} ++ + /** + * Reads data from the object referenced by handle. + * +@@ -148,8 +366,6 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, + struct drm_i915_gem_pread *args = data; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; +- ssize_t read; +- loff_t offset; + int ret; + + obj = drm_gem_object_lookup(dev, file_priv, args->handle); +@@ -167,33 +383,13 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, + return -EINVAL; + } + +- mutex_lock(&dev->struct_mutex); +- +- ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset, +- args->size); +- if (ret != 0) { +- drm_gem_object_unreference(obj); +- mutex_unlock(&dev->struct_mutex); +- return ret; +- } +- +- offset = args->offset; +- +- read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr, +- args->size, &offset); +- if (read != args->size) { +- drm_gem_object_unreference(obj); +- mutex_unlock(&dev->struct_mutex); +- if (read < 0) +- return read; +- else +- return -EINVAL; +- } ++ ret = i915_gem_shmem_pread_fast(dev, obj, args, file_priv); ++ if (ret != 0) ++ ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv); + + drm_gem_object_unreference(obj); +- mutex_unlock(&dev->struct_mutex); + +- return 0; ++ return ret; + } + + /* This is the fast write path which cannot handle +@@ -223,29 +419,54 @@ fast_user_write(struct io_mapping *mapping, + */ + + static inline int +-slow_user_write(struct io_mapping *mapping, +- loff_t page_base, int page_offset, +- char __user *user_data, +- int length) ++slow_kernel_write(struct io_mapping *mapping, ++ loff_t gtt_base, int gtt_offset, ++ struct page *user_page, int user_offset, ++ int length) ++{ ++ char *src_vaddr, *dst_vaddr; ++ unsigned long unwritten; ++ ++ dst_vaddr = io_mapping_map_atomic_wc(mapping, gtt_base); ++ src_vaddr = kmap_atomic(user_page, KM_USER1); ++ unwritten = __copy_from_user_inatomic_nocache(dst_vaddr + gtt_offset, ++ src_vaddr + user_offset, ++ length); ++ kunmap_atomic(src_vaddr, KM_USER1); ++ io_mapping_unmap_atomic(dst_vaddr); ++ if (unwritten) ++ return -EFAULT; ++ return 0; ++} ++ ++static inline int ++fast_shmem_write(struct page **pages, ++ loff_t page_base, int page_offset, ++ char __user *data, ++ int length) + { + char __iomem *vaddr; + unsigned long unwritten; + +- vaddr = io_mapping_map_wc(mapping, page_base); ++ vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0); + if (vaddr == NULL) +- return -EFAULT; +- unwritten = __copy_from_user(vaddr + page_offset, +- user_data, length); +- io_mapping_unmap(vaddr); ++ return -ENOMEM; ++ unwritten = __copy_from_user_inatomic(vaddr + page_offset, data, length); ++ kunmap_atomic(vaddr, KM_USER0); ++ + if (unwritten) + return -EFAULT; + return 0; + } + ++/** ++ * This is the fast pwrite path, where we copy the data directly from the ++ * user into the GTT, uncached. ++ */ + static int +-i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, +- struct drm_i915_gem_pwrite *args, +- struct drm_file *file_priv) ++i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, ++ struct drm_i915_gem_pwrite *args, ++ struct drm_file *file_priv) + { + struct drm_i915_gem_object *obj_priv = obj->driver_private; + drm_i915_private_t *dev_priv = dev->dev_private; +@@ -273,7 +494,6 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, + + obj_priv = obj->driver_private; + offset = obj_priv->gtt_offset + args->offset; +- obj_priv->dirty = 1; + + while (remain > 0) { + /* Operation in this page +@@ -292,16 +512,11 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, + page_offset, user_data, page_length); + + /* If we get a fault while copying data, then (presumably) our +- * source page isn't available. In this case, use the +- * non-atomic function ++ * source page isn't available. Return the error and we'll ++ * retry in the slow path. + */ +- if (ret) { +- ret = slow_user_write (dev_priv->mm.gtt_mapping, +- page_base, page_offset, +- user_data, page_length); +- if (ret) +- goto fail; +- } ++ if (ret) ++ goto fail; + + remain -= page_length; + user_data += page_length; +@@ -315,39 +530,284 @@ fail: + return ret; + } + ++/** ++ * This is the fallback GTT pwrite path, which uses get_user_pages to pin ++ * the memory and maps it using kmap_atomic for copying. ++ * ++ * This code resulted in x11perf -rgb10text consuming about 10% more CPU ++ * than using i915_gem_gtt_pwrite_fast on a G45 (32-bit). ++ */ + static int +-i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj, +- struct drm_i915_gem_pwrite *args, +- struct drm_file *file_priv) ++i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, ++ struct drm_i915_gem_pwrite *args, ++ struct drm_file *file_priv) + { ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ ssize_t remain; ++ loff_t gtt_page_base, offset; ++ loff_t first_data_page, last_data_page, num_pages; ++ loff_t pinned_pages, i; ++ struct page **user_pages; ++ struct mm_struct *mm = current->mm; ++ int gtt_page_offset, data_page_offset, data_page_index, page_length; + int ret; +- loff_t offset; +- ssize_t written; ++ uint64_t data_ptr = args->data_ptr; ++ ++ remain = args->size; ++ ++ /* Pin the user pages containing the data. We can't fault while ++ * holding the struct mutex, and all of the pwrite implementations ++ * want to hold it while dereferencing the user data. ++ */ ++ first_data_page = data_ptr / PAGE_SIZE; ++ last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; ++ num_pages = last_data_page - first_data_page + 1; ++ ++ user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL); ++ if (user_pages == NULL) ++ return -ENOMEM; ++ ++ down_read(&mm->mmap_sem); ++ pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, ++ num_pages, 0, 0, user_pages, NULL); ++ up_read(&mm->mmap_sem); ++ if (pinned_pages < num_pages) { ++ ret = -EFAULT; ++ goto out_unpin_pages; ++ } ++ ++ mutex_lock(&dev->struct_mutex); ++ ret = i915_gem_object_pin(obj, 0); ++ if (ret) ++ goto out_unlock; ++ ++ ret = i915_gem_object_set_to_gtt_domain(obj, 1); ++ if (ret) ++ goto out_unpin_object; ++ ++ obj_priv = obj->driver_private; ++ offset = obj_priv->gtt_offset + args->offset; ++ ++ while (remain > 0) { ++ /* Operation in this page ++ * ++ * gtt_page_base = page offset within aperture ++ * gtt_page_offset = offset within page in aperture ++ * data_page_index = page number in get_user_pages return ++ * data_page_offset = offset with data_page_index page. ++ * page_length = bytes to copy for this page ++ */ ++ gtt_page_base = offset & PAGE_MASK; ++ gtt_page_offset = offset & ~PAGE_MASK; ++ data_page_index = data_ptr / PAGE_SIZE - first_data_page; ++ data_page_offset = data_ptr & ~PAGE_MASK; ++ ++ page_length = remain; ++ if ((gtt_page_offset + page_length) > PAGE_SIZE) ++ page_length = PAGE_SIZE - gtt_page_offset; ++ if ((data_page_offset + page_length) > PAGE_SIZE) ++ page_length = PAGE_SIZE - data_page_offset; ++ ++ ret = slow_kernel_write(dev_priv->mm.gtt_mapping, ++ gtt_page_base, gtt_page_offset, ++ user_pages[data_page_index], ++ data_page_offset, ++ page_length); ++ ++ /* If we get a fault while copying data, then (presumably) our ++ * source page isn't available. Return the error and we'll ++ * retry in the slow path. ++ */ ++ if (ret) ++ goto out_unpin_object; ++ ++ remain -= page_length; ++ offset += page_length; ++ data_ptr += page_length; ++ } ++ ++out_unpin_object: ++ i915_gem_object_unpin(obj); ++out_unlock: ++ mutex_unlock(&dev->struct_mutex); ++out_unpin_pages: ++ for (i = 0; i < pinned_pages; i++) ++ page_cache_release(user_pages[i]); ++ kfree(user_pages); ++ ++ return ret; ++} ++ ++/** ++ * This is the fast shmem pwrite path, which attempts to directly ++ * copy_from_user into the kmapped pages backing the object. ++ */ ++static int ++i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, ++ struct drm_i915_gem_pwrite *args, ++ struct drm_file *file_priv) ++{ ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ ssize_t remain; ++ loff_t offset, page_base; ++ char __user *user_data; ++ int page_offset, page_length; ++ int ret; ++ ++ user_data = (char __user *) (uintptr_t) args->data_ptr; ++ remain = args->size; + + mutex_lock(&dev->struct_mutex); + ++ ret = i915_gem_object_get_pages(obj); ++ if (ret != 0) ++ goto fail_unlock; ++ + ret = i915_gem_object_set_to_cpu_domain(obj, 1); +- if (ret) { +- mutex_unlock(&dev->struct_mutex); +- return ret; ++ if (ret != 0) ++ goto fail_put_pages; ++ ++ obj_priv = obj->driver_private; ++ offset = args->offset; ++ obj_priv->dirty = 1; ++ ++ while (remain > 0) { ++ /* Operation in this page ++ * ++ * page_base = page offset within aperture ++ * page_offset = offset within page ++ * page_length = bytes to copy for this page ++ */ ++ page_base = (offset & ~(PAGE_SIZE-1)); ++ page_offset = offset & (PAGE_SIZE-1); ++ page_length = remain; ++ if ((page_offset + remain) > PAGE_SIZE) ++ page_length = PAGE_SIZE - page_offset; ++ ++ ret = fast_shmem_write(obj_priv->pages, ++ page_base, page_offset, ++ user_data, page_length); ++ if (ret) ++ goto fail_put_pages; ++ ++ remain -= page_length; ++ user_data += page_length; ++ offset += page_length; ++ } ++ ++fail_put_pages: ++ i915_gem_object_put_pages(obj); ++fail_unlock: ++ mutex_unlock(&dev->struct_mutex); ++ ++ return ret; ++} ++ ++/** ++ * This is the fallback shmem pwrite path, which uses get_user_pages to pin ++ * the memory and maps it using kmap_atomic for copying. ++ * ++ * This avoids taking mmap_sem for faulting on the user's address while the ++ * struct_mutex is held. ++ */ ++static int ++i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, ++ struct drm_i915_gem_pwrite *args, ++ struct drm_file *file_priv) ++{ ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ struct mm_struct *mm = current->mm; ++ struct page **user_pages; ++ ssize_t remain; ++ loff_t offset, pinned_pages, i; ++ loff_t first_data_page, last_data_page, num_pages; ++ int shmem_page_index, shmem_page_offset; ++ int data_page_index, data_page_offset; ++ int page_length; ++ int ret; ++ uint64_t data_ptr = args->data_ptr; ++ ++ remain = args->size; ++ ++ /* Pin the user pages containing the data. We can't fault while ++ * holding the struct mutex, and all of the pwrite implementations ++ * want to hold it while dereferencing the user data. ++ */ ++ first_data_page = data_ptr / PAGE_SIZE; ++ last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; ++ num_pages = last_data_page - first_data_page + 1; ++ ++ user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL); ++ if (user_pages == NULL) ++ return -ENOMEM; ++ ++ down_read(&mm->mmap_sem); ++ pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, ++ num_pages, 0, 0, user_pages, NULL); ++ up_read(&mm->mmap_sem); ++ if (pinned_pages < num_pages) { ++ ret = -EFAULT; ++ goto fail_put_user_pages; + } + ++ mutex_lock(&dev->struct_mutex); ++ ++ ret = i915_gem_object_get_pages(obj); ++ if (ret != 0) ++ goto fail_unlock; ++ ++ ret = i915_gem_object_set_to_cpu_domain(obj, 1); ++ if (ret != 0) ++ goto fail_put_pages; ++ ++ obj_priv = obj->driver_private; + offset = args->offset; ++ obj_priv->dirty = 1; + +- written = vfs_write(obj->filp, +- (char __user *)(uintptr_t) args->data_ptr, +- args->size, &offset); +- if (written != args->size) { +- mutex_unlock(&dev->struct_mutex); +- if (written < 0) +- return written; +- else +- return -EINVAL; ++ while (remain > 0) { ++ /* Operation in this page ++ * ++ * shmem_page_index = page number within shmem file ++ * shmem_page_offset = offset within page in shmem file ++ * data_page_index = page number in get_user_pages return ++ * data_page_offset = offset with data_page_index page. ++ * page_length = bytes to copy for this page ++ */ ++ shmem_page_index = offset / PAGE_SIZE; ++ shmem_page_offset = offset & ~PAGE_MASK; ++ data_page_index = data_ptr / PAGE_SIZE - first_data_page; ++ data_page_offset = data_ptr & ~PAGE_MASK; ++ ++ page_length = remain; ++ if ((shmem_page_offset + page_length) > PAGE_SIZE) ++ page_length = PAGE_SIZE - shmem_page_offset; ++ if ((data_page_offset + page_length) > PAGE_SIZE) ++ page_length = PAGE_SIZE - data_page_offset; ++ ++ ret = slow_shmem_copy(obj_priv->pages[shmem_page_index], ++ shmem_page_offset, ++ user_pages[data_page_index], ++ data_page_offset, ++ page_length); ++ if (ret) ++ goto fail_put_pages; ++ ++ remain -= page_length; ++ data_ptr += page_length; ++ offset += page_length; + } + ++fail_put_pages: ++ i915_gem_object_put_pages(obj); ++fail_unlock: + mutex_unlock(&dev->struct_mutex); ++fail_put_user_pages: ++ for (i = 0; i < pinned_pages; i++) ++ page_cache_release(user_pages[i]); ++ kfree(user_pages); + +- return 0; ++ return ret; + } + + /** +@@ -388,10 +848,19 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, + if (obj_priv->phys_obj) + ret = i915_gem_phys_pwrite(dev, obj, args, file_priv); + else if (obj_priv->tiling_mode == I915_TILING_NONE && +- dev->gtt_total != 0) +- ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv); +- else +- ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv); ++ dev->gtt_total != 0) { ++ ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv); ++ if (ret == -EFAULT) { ++ ret = i915_gem_gtt_pwrite_slow(dev, obj, args, ++ file_priv); ++ } ++ } else { ++ ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file_priv); ++ if (ret == -EFAULT) { ++ ret = i915_gem_shmem_pwrite_slow(dev, obj, args, ++ file_priv); ++ } ++ } + + #if WATCH_PWRITE + if (ret) +@@ -603,6 +1072,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + case -EAGAIN: + return VM_FAULT_OOM; + case -EFAULT: ++ case -EINVAL: + return VM_FAULT_SIGBUS; + default: + return VM_FAULT_NOPAGE; +@@ -627,7 +1097,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) + struct drm_gem_mm *mm = dev->mm_private; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_map_list *list; +- struct drm_map *map; ++ struct drm_local_map *map; + int ret = 0; + + /* Set the object up for mmap'ing */ +@@ -816,29 +1286,30 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, + } + + static void +-i915_gem_object_free_page_list(struct drm_gem_object *obj) ++i915_gem_object_put_pages(struct drm_gem_object *obj) + { + struct drm_i915_gem_object *obj_priv = obj->driver_private; + int page_count = obj->size / PAGE_SIZE; + int i; + +- if (obj_priv->page_list == NULL) +- return; ++ BUG_ON(obj_priv->pages_refcount == 0); + ++ if (--obj_priv->pages_refcount != 0) ++ return; + + for (i = 0; i < page_count; i++) +- if (obj_priv->page_list[i] != NULL) { ++ if (obj_priv->pages[i] != NULL) { + if (obj_priv->dirty) +- set_page_dirty(obj_priv->page_list[i]); +- mark_page_accessed(obj_priv->page_list[i]); +- page_cache_release(obj_priv->page_list[i]); ++ set_page_dirty(obj_priv->pages[i]); ++ mark_page_accessed(obj_priv->pages[i]); ++ page_cache_release(obj_priv->pages[i]); + } + obj_priv->dirty = 0; + +- drm_free(obj_priv->page_list, ++ drm_free(obj_priv->pages, + page_count * sizeof(struct page *), + DRM_MEM_DRIVER); +- obj_priv->page_list = NULL; ++ obj_priv->pages = NULL; + } + + static void +@@ -854,8 +1325,10 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) + obj_priv->active = 1; + } + /* Move from whatever list we were on to the tail of execution. */ ++ spin_lock(&dev_priv->mm.active_list_lock); + list_move_tail(&obj_priv->list, + &dev_priv->mm.active_list); ++ spin_unlock(&dev_priv->mm.active_list_lock); + obj_priv->last_rendering_seqno = seqno; + } + +@@ -997,6 +1470,7 @@ i915_gem_retire_request(struct drm_device *dev, + /* Move any buffers on the active list that are no longer referenced + * by the ringbuffer to the flushing/inactive lists as appropriate. + */ ++ spin_lock(&dev_priv->mm.active_list_lock); + while (!list_empty(&dev_priv->mm.active_list)) { + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; +@@ -1011,7 +1485,7 @@ i915_gem_retire_request(struct drm_device *dev, + * this seqno. + */ + if (obj_priv->last_rendering_seqno != request->seqno) +- return; ++ goto out; + + #if WATCH_LRU + DRM_INFO("%s: retire %d moves to inactive list %p\n", +@@ -1023,6 +1497,8 @@ i915_gem_retire_request(struct drm_device *dev, + else + i915_gem_object_move_to_inactive(obj); + } ++out: ++ spin_unlock(&dev_priv->mm.active_list_lock); + } + + /** +@@ -1290,7 +1766,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) + if (obj_priv->fence_reg != I915_FENCE_REG_NONE) + i915_gem_clear_fence_reg(obj); + +- i915_gem_object_free_page_list(obj); ++ i915_gem_object_put_pages(obj); + + if (obj_priv->gtt_space) { + atomic_dec(&dev->gtt_count); +@@ -1409,7 +1885,7 @@ i915_gem_evict_everything(struct drm_device *dev) + } + + static int +-i915_gem_object_get_page_list(struct drm_gem_object *obj) ++i915_gem_object_get_pages(struct drm_gem_object *obj) + { + struct drm_i915_gem_object *obj_priv = obj->driver_private; + int page_count, i; +@@ -1418,18 +1894,19 @@ i915_gem_object_get_page_list(struct drm_gem_object *obj) + struct page *page; + int ret; + +- if (obj_priv->page_list) ++ if (obj_priv->pages_refcount++ != 0) + return 0; + + /* Get the list of pages out of our struct file. They'll be pinned + * at this point until we release them. + */ + page_count = obj->size / PAGE_SIZE; +- BUG_ON(obj_priv->page_list != NULL); +- obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *), +- DRM_MEM_DRIVER); +- if (obj_priv->page_list == NULL) { ++ BUG_ON(obj_priv->pages != NULL); ++ obj_priv->pages = drm_calloc(page_count, sizeof(struct page *), ++ DRM_MEM_DRIVER); ++ if (obj_priv->pages == NULL) { + DRM_ERROR("Faled to allocate page list\n"); ++ obj_priv->pages_refcount--; + return -ENOMEM; + } + +@@ -1440,10 +1917,10 @@ i915_gem_object_get_page_list(struct drm_gem_object *obj) + if (IS_ERR(page)) { + ret = PTR_ERR(page); + DRM_ERROR("read_mapping_page failed: %d\n", ret); +- i915_gem_object_free_page_list(obj); ++ i915_gem_object_put_pages(obj); + return ret; + } +- obj_priv->page_list[i] = page; ++ obj_priv->pages[i] = page; + } + return 0; + } +@@ -1519,20 +1996,23 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) + int regnum = obj_priv->fence_reg; + uint32_t val; + uint32_t pitch_val; ++ uint32_t fence_size_bits; + +- if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || ++ if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) || + (obj_priv->gtt_offset & (obj->size - 1))) { +- WARN(1, "%s: object 0x%08x not 1M or size aligned\n", ++ WARN(1, "%s: object 0x%08x not 512K or size aligned\n", + __func__, obj_priv->gtt_offset); + return; + } + + pitch_val = (obj_priv->stride / 128) - 1; +- ++ WARN_ON(pitch_val & ~0x0000000f); + val = obj_priv->gtt_offset; + if (obj_priv->tiling_mode == I915_TILING_Y) + val |= 1 << I830_FENCE_TILING_Y_SHIFT; +- val |= I830_FENCE_SIZE_BITS(obj->size); ++ fence_size_bits = I830_FENCE_SIZE_BITS(obj->size); ++ WARN_ON(fence_size_bits & ~0x00000f00); ++ val |= fence_size_bits; + val |= pitch_val << I830_FENCE_PITCH_SHIFT; + val |= I830_FENCE_REG_VALID; + +@@ -1723,7 +2203,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) + return -EBUSY; + if (alignment == 0) + alignment = i915_gem_get_gtt_alignment(obj); +- if (alignment & (PAGE_SIZE - 1)) { ++ if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) { + DRM_ERROR("Invalid object alignment requested %u\n", alignment); + return -EINVAL; + } +@@ -1740,15 +2220,20 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) + } + } + if (obj_priv->gtt_space == NULL) { ++ bool lists_empty; ++ + /* If the gtt is empty and we're still having trouble + * fitting our object in, we're out of memory. + */ + #if WATCH_LRU + DRM_INFO("%s: GTT full, evicting something\n", __func__); + #endif +- if (list_empty(&dev_priv->mm.inactive_list) && +- list_empty(&dev_priv->mm.flushing_list) && +- list_empty(&dev_priv->mm.active_list)) { ++ spin_lock(&dev_priv->mm.active_list_lock); ++ lists_empty = (list_empty(&dev_priv->mm.inactive_list) && ++ list_empty(&dev_priv->mm.flushing_list) && ++ list_empty(&dev_priv->mm.active_list)); ++ spin_unlock(&dev_priv->mm.active_list_lock); ++ if (lists_empty) { + DRM_ERROR("GTT full, but LRU list empty\n"); + return -ENOMEM; + } +@@ -1766,7 +2251,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) + DRM_INFO("Binding object of size %d at 0x%08x\n", + obj->size, obj_priv->gtt_offset); + #endif +- ret = i915_gem_object_get_page_list(obj); ++ ret = i915_gem_object_get_pages(obj); + if (ret) { + drm_mm_put_block(obj_priv->gtt_space); + obj_priv->gtt_space = NULL; +@@ -1778,12 +2263,12 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) + * into the GTT. + */ + obj_priv->agp_mem = drm_agp_bind_pages(dev, +- obj_priv->page_list, ++ obj_priv->pages, + page_count, + obj_priv->gtt_offset, + obj_priv->agp_type); + if (obj_priv->agp_mem == NULL) { +- i915_gem_object_free_page_list(obj); ++ i915_gem_object_put_pages(obj); + drm_mm_put_block(obj_priv->gtt_space); + obj_priv->gtt_space = NULL; + return -ENOMEM; +@@ -1810,10 +2295,10 @@ i915_gem_clflush_object(struct drm_gem_object *obj) + * to GPU, and we can ignore the cache flush because it'll happen + * again at bind time. + */ +- if (obj_priv->page_list == NULL) ++ if (obj_priv->pages == NULL) + return; + +- drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE); ++ drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE); + } + + /** Flushes any GPU write domain for the object if it's dirty. */ +@@ -1913,7 +2398,6 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) + static int + i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) + { +- struct drm_device *dev = obj->dev; + int ret; + + i915_gem_object_flush_gpu_write_domain(obj); +@@ -1932,7 +2416,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) + /* Flush the CPU cache if it's still invalid. */ + if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) { + i915_gem_clflush_object(obj); +- drm_agp_chipset_flush(dev); + + obj->read_domains |= I915_GEM_DOMAIN_CPU; + } +@@ -2144,7 +2627,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) + static void + i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) + { +- struct drm_device *dev = obj->dev; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + + if (!obj_priv->page_cpu_valid) +@@ -2158,9 +2640,8 @@ i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) + for (i = 0; i <= (obj->size - 1) / PAGE_SIZE; i++) { + if (obj_priv->page_cpu_valid[i]) + continue; +- drm_clflush_pages(obj_priv->page_list + i, 1); ++ drm_clflush_pages(obj_priv->pages + i, 1); + } +- drm_agp_chipset_flush(dev); + } + + /* Free the page_cpu_valid mappings which are now stale, whether +@@ -2224,7 +2705,7 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, + if (obj_priv->page_cpu_valid[i]) + continue; + +- drm_clflush_pages(obj_priv->page_list + i, 1); ++ drm_clflush_pages(obj_priv->pages + i, 1); + + obj_priv->page_cpu_valid[i] = 1; + } +@@ -2245,12 +2726,11 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, + static int + i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + struct drm_file *file_priv, +- struct drm_i915_gem_exec_object *entry) ++ struct drm_i915_gem_exec_object *entry, ++ struct drm_i915_gem_relocation_entry *relocs) + { + struct drm_device *dev = obj->dev; + drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_i915_gem_relocation_entry reloc; +- struct drm_i915_gem_relocation_entry __user *relocs; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + int i, ret; + void __iomem *reloc_page; +@@ -2262,25 +2742,18 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + + entry->offset = obj_priv->gtt_offset; + +- relocs = (struct drm_i915_gem_relocation_entry __user *) +- (uintptr_t) entry->relocs_ptr; + /* Apply the relocations, using the GTT aperture to avoid cache + * flushing requirements. + */ + for (i = 0; i < entry->relocation_count; i++) { ++ struct drm_i915_gem_relocation_entry *reloc= &relocs[i]; + struct drm_gem_object *target_obj; + struct drm_i915_gem_object *target_obj_priv; + uint32_t reloc_val, reloc_offset; + uint32_t __iomem *reloc_entry; + +- ret = copy_from_user(&reloc, relocs + i, sizeof(reloc)); +- if (ret != 0) { +- i915_gem_object_unpin(obj); +- return ret; +- } +- + target_obj = drm_gem_object_lookup(obj->dev, file_priv, +- reloc.target_handle); ++ reloc->target_handle); + if (target_obj == NULL) { + i915_gem_object_unpin(obj); + return -EBADF; +@@ -2292,53 +2765,53 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + */ + if (target_obj_priv->gtt_space == NULL) { + DRM_ERROR("No GTT space found for object %d\n", +- reloc.target_handle); ++ reloc->target_handle); + drm_gem_object_unreference(target_obj); + i915_gem_object_unpin(obj); + return -EINVAL; + } + +- if (reloc.offset > obj->size - 4) { ++ if (reloc->offset > obj->size - 4) { + DRM_ERROR("Relocation beyond object bounds: " + "obj %p target %d offset %d size %d.\n", +- obj, reloc.target_handle, +- (int) reloc.offset, (int) obj->size); ++ obj, reloc->target_handle, ++ (int) reloc->offset, (int) obj->size); + drm_gem_object_unreference(target_obj); + i915_gem_object_unpin(obj); + return -EINVAL; + } +- if (reloc.offset & 3) { ++ if (reloc->offset & 3) { + DRM_ERROR("Relocation not 4-byte aligned: " + "obj %p target %d offset %d.\n", +- obj, reloc.target_handle, +- (int) reloc.offset); ++ obj, reloc->target_handle, ++ (int) reloc->offset); + drm_gem_object_unreference(target_obj); + i915_gem_object_unpin(obj); + return -EINVAL; + } + +- if (reloc.write_domain & I915_GEM_DOMAIN_CPU || +- reloc.read_domains & I915_GEM_DOMAIN_CPU) { ++ if (reloc->write_domain & I915_GEM_DOMAIN_CPU || ++ reloc->read_domains & I915_GEM_DOMAIN_CPU) { + DRM_ERROR("reloc with read/write CPU domains: " + "obj %p target %d offset %d " + "read %08x write %08x", +- obj, reloc.target_handle, +- (int) reloc.offset, +- reloc.read_domains, +- reloc.write_domain); ++ obj, reloc->target_handle, ++ (int) reloc->offset, ++ reloc->read_domains, ++ reloc->write_domain); + drm_gem_object_unreference(target_obj); + i915_gem_object_unpin(obj); + return -EINVAL; + } + +- if (reloc.write_domain && target_obj->pending_write_domain && +- reloc.write_domain != target_obj->pending_write_domain) { ++ if (reloc->write_domain && target_obj->pending_write_domain && ++ reloc->write_domain != target_obj->pending_write_domain) { + DRM_ERROR("Write domain conflict: " + "obj %p target %d offset %d " + "new %08x old %08x\n", +- obj, reloc.target_handle, +- (int) reloc.offset, +- reloc.write_domain, ++ obj, reloc->target_handle, ++ (int) reloc->offset, ++ reloc->write_domain, + target_obj->pending_write_domain); + drm_gem_object_unreference(target_obj); + i915_gem_object_unpin(obj); +@@ -2351,22 +2824,22 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + "presumed %08x delta %08x\n", + __func__, + obj, +- (int) reloc.offset, +- (int) reloc.target_handle, +- (int) reloc.read_domains, +- (int) reloc.write_domain, ++ (int) reloc->offset, ++ (int) reloc->target_handle, ++ (int) reloc->read_domains, ++ (int) reloc->write_domain, + (int) target_obj_priv->gtt_offset, +- (int) reloc.presumed_offset, +- reloc.delta); ++ (int) reloc->presumed_offset, ++ reloc->delta); + #endif + +- target_obj->pending_read_domains |= reloc.read_domains; +- target_obj->pending_write_domain |= reloc.write_domain; ++ target_obj->pending_read_domains |= reloc->read_domains; ++ target_obj->pending_write_domain |= reloc->write_domain; + + /* If the relocation already has the right value in it, no + * more work needs to be done. + */ +- if (target_obj_priv->gtt_offset == reloc.presumed_offset) { ++ if (target_obj_priv->gtt_offset == reloc->presumed_offset) { + drm_gem_object_unreference(target_obj); + continue; + } +@@ -2381,32 +2854,26 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + /* Map the page containing the relocation we're going to + * perform. + */ +- reloc_offset = obj_priv->gtt_offset + reloc.offset; ++ reloc_offset = obj_priv->gtt_offset + reloc->offset; + reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, + (reloc_offset & + ~(PAGE_SIZE - 1))); + reloc_entry = (uint32_t __iomem *)(reloc_page + + (reloc_offset & (PAGE_SIZE - 1))); +- reloc_val = target_obj_priv->gtt_offset + reloc.delta; ++ reloc_val = target_obj_priv->gtt_offset + reloc->delta; + + #if WATCH_BUF + DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n", +- obj, (unsigned int) reloc.offset, ++ obj, (unsigned int) reloc->offset, + readl(reloc_entry), reloc_val); + #endif + writel(reloc_val, reloc_entry); + io_mapping_unmap_atomic(reloc_page); + +- /* Write the updated presumed offset for this entry back out +- * to the user. ++ /* The updated presumed offset for this entry will be ++ * copied back out to the user. + */ +- reloc.presumed_offset = target_obj_priv->gtt_offset; +- ret = copy_to_user(relocs + i, &reloc, sizeof(reloc)); +- if (ret != 0) { +- drm_gem_object_unreference(target_obj); +- i915_gem_object_unpin(obj); +- return ret; +- } ++ reloc->presumed_offset = target_obj_priv->gtt_offset; + + drm_gem_object_unreference(target_obj); + } +@@ -2423,11 +2890,10 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + static int + i915_dispatch_gem_execbuffer(struct drm_device *dev, + struct drm_i915_gem_execbuffer *exec, ++ struct drm_clip_rect *cliprects, + uint64_t exec_offset) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *) +- (uintptr_t) exec->cliprects_ptr; + int nbox = exec->num_cliprects; + int i = 0, count; + uint32_t exec_start, exec_len; +@@ -2448,7 +2914,7 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev, + + for (i = 0; i < count; i++) { + if (i < nbox) { +- int ret = i915_emit_box(dev, boxes, i, ++ int ret = i915_emit_box(dev, cliprects, i, + exec->DR1, exec->DR4); + if (ret) + return ret; +@@ -2504,6 +2970,75 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) + return ret; + } + ++static int ++i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, ++ uint32_t buffer_count, ++ struct drm_i915_gem_relocation_entry **relocs) ++{ ++ uint32_t reloc_count = 0, reloc_index = 0, i; ++ int ret; ++ ++ *relocs = NULL; ++ for (i = 0; i < buffer_count; i++) { ++ if (reloc_count + exec_list[i].relocation_count < reloc_count) ++ return -EINVAL; ++ reloc_count += exec_list[i].relocation_count; ++ } ++ ++ *relocs = drm_calloc(reloc_count, sizeof(**relocs), DRM_MEM_DRIVER); ++ if (*relocs == NULL) ++ return -ENOMEM; ++ ++ for (i = 0; i < buffer_count; i++) { ++ struct drm_i915_gem_relocation_entry __user *user_relocs; ++ ++ user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr; ++ ++ ret = copy_from_user(&(*relocs)[reloc_index], ++ user_relocs, ++ exec_list[i].relocation_count * ++ sizeof(**relocs)); ++ if (ret != 0) { ++ drm_free(*relocs, reloc_count * sizeof(**relocs), ++ DRM_MEM_DRIVER); ++ *relocs = NULL; ++ return ret; ++ } ++ ++ reloc_index += exec_list[i].relocation_count; ++ } ++ ++ return ret; ++} ++ ++static int ++i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list, ++ uint32_t buffer_count, ++ struct drm_i915_gem_relocation_entry *relocs) ++{ ++ uint32_t reloc_count = 0, i; ++ int ret; ++ ++ for (i = 0; i < buffer_count; i++) { ++ struct drm_i915_gem_relocation_entry __user *user_relocs; ++ ++ user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr; ++ ++ if (ret == 0) { ++ ret = copy_to_user(user_relocs, ++ &relocs[reloc_count], ++ exec_list[i].relocation_count * ++ sizeof(*relocs)); ++ } ++ ++ reloc_count += exec_list[i].relocation_count; ++ } ++ ++ drm_free(relocs, reloc_count * sizeof(*relocs), DRM_MEM_DRIVER); ++ ++ return ret; ++} ++ + int + i915_gem_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv) +@@ -2515,9 +3050,11 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + struct drm_gem_object **object_list = NULL; + struct drm_gem_object *batch_obj; + struct drm_i915_gem_object *obj_priv; +- int ret, i, pinned = 0; ++ struct drm_clip_rect *cliprects = NULL; ++ struct drm_i915_gem_relocation_entry *relocs; ++ int ret, ret2, i, pinned = 0; + uint64_t exec_offset; +- uint32_t seqno, flush_domains; ++ uint32_t seqno, flush_domains, reloc_index; + int pin_tries; + + #if WATCH_EXEC +@@ -2551,6 +3088,28 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + goto pre_mutex_err; + } + ++ if (args->num_cliprects != 0) { ++ cliprects = drm_calloc(args->num_cliprects, sizeof(*cliprects), ++ DRM_MEM_DRIVER); ++ if (cliprects == NULL) ++ goto pre_mutex_err; ++ ++ ret = copy_from_user(cliprects, ++ (struct drm_clip_rect __user *) ++ (uintptr_t) args->cliprects_ptr, ++ sizeof(*cliprects) * args->num_cliprects); ++ if (ret != 0) { ++ DRM_ERROR("copy %d cliprects failed: %d\n", ++ args->num_cliprects, ret); ++ goto pre_mutex_err; ++ } ++ } ++ ++ ret = i915_gem_get_relocs_from_user(exec_list, args->buffer_count, ++ &relocs); ++ if (ret != 0) ++ goto pre_mutex_err; ++ + mutex_lock(&dev->struct_mutex); + + i915_verify_inactive(dev, __FILE__, __LINE__); +@@ -2593,15 +3152,19 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + /* Pin and relocate */ + for (pin_tries = 0; ; pin_tries++) { + ret = 0; ++ reloc_index = 0; ++ + for (i = 0; i < args->buffer_count; i++) { + object_list[i]->pending_read_domains = 0; + object_list[i]->pending_write_domain = 0; + ret = i915_gem_object_pin_and_relocate(object_list[i], + file_priv, +- &exec_list[i]); ++ &exec_list[i], ++ &relocs[reloc_index]); + if (ret) + break; + pinned = i + 1; ++ reloc_index += exec_list[i].relocation_count; + } + /* success */ + if (ret == 0) +@@ -2687,7 +3250,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + #endif + + /* Exec the batchbuffer */ +- ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset); ++ ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset); + if (ret) { + DRM_ERROR("dispatch failed %d\n", ret); + goto err; +@@ -2751,11 +3314,27 @@ err: + args->buffer_count, ret); + } + ++ /* Copy the updated relocations out regardless of current error ++ * state. Failure to update the relocs would mean that the next ++ * time userland calls execbuf, it would do so with presumed offset ++ * state that didn't match the actual object state. ++ */ ++ ret2 = i915_gem_put_relocs_to_user(exec_list, args->buffer_count, ++ relocs); ++ if (ret2 != 0) { ++ DRM_ERROR("Failed to copy relocations back out: %d\n", ret2); ++ ++ if (ret == 0) ++ ret = ret2; ++ } ++ + pre_mutex_err: + drm_free(object_list, sizeof(*object_list) * args->buffer_count, + DRM_MEM_DRIVER); + drm_free(exec_list, sizeof(*exec_list) * args->buffer_count, + DRM_MEM_DRIVER); ++ drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects, ++ DRM_MEM_DRIVER); + + return ret; + } +@@ -3110,6 +3689,7 @@ i915_gem_idle(struct drm_device *dev) + + i915_gem_retire_requests(dev); + ++ spin_lock(&dev_priv->mm.active_list_lock); + if (!dev_priv->mm.wedged) { + /* Active and flushing should now be empty as we've + * waited for a sequence higher than any pending execbuffer +@@ -3136,6 +3716,7 @@ i915_gem_idle(struct drm_device *dev) + obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS; + i915_gem_object_move_to_inactive(obj_priv->obj); + } ++ spin_unlock(&dev_priv->mm.active_list_lock); + + while (!list_empty(&dev_priv->mm.flushing_list)) { + struct drm_i915_gem_object *obj_priv; +@@ -3192,7 +3773,7 @@ i915_gem_init_hws(struct drm_device *dev) + + dev_priv->status_gfx_addr = obj_priv->gtt_offset; + +- dev_priv->hw_status_page = kmap(obj_priv->page_list[0]); ++ dev_priv->hw_status_page = kmap(obj_priv->pages[0]); + if (dev_priv->hw_status_page == NULL) { + DRM_ERROR("Failed to map status page.\n"); + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); +@@ -3222,7 +3803,7 @@ i915_gem_cleanup_hws(struct drm_device *dev) + obj = dev_priv->hws_obj; + obj_priv = obj->driver_private; + +- kunmap(obj_priv->page_list[0]); ++ kunmap(obj_priv->pages[0]); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(obj); + dev_priv->hws_obj = NULL; +@@ -3384,7 +3965,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, + if (ret != 0) + return ret; + ++ spin_lock(&dev_priv->mm.active_list_lock); + BUG_ON(!list_empty(&dev_priv->mm.active_list)); ++ spin_unlock(&dev_priv->mm.active_list_lock); ++ + BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); + BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); + BUG_ON(!list_empty(&dev_priv->mm.request_list)); +@@ -3428,6 +4012,7 @@ i915_gem_load(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; + ++ spin_lock_init(&dev_priv->mm.active_list_lock); + INIT_LIST_HEAD(&dev_priv->mm.active_list); + INIT_LIST_HEAD(&dev_priv->mm.flushing_list); + INIT_LIST_HEAD(&dev_priv->mm.inactive_list); +@@ -3525,20 +4110,20 @@ void i915_gem_detach_phys_object(struct drm_device *dev, + if (!obj_priv->phys_obj) + return; + +- ret = i915_gem_object_get_page_list(obj); ++ ret = i915_gem_object_get_pages(obj); + if (ret) + goto out; + + page_count = obj->size / PAGE_SIZE; + + for (i = 0; i < page_count; i++) { +- char *dst = kmap_atomic(obj_priv->page_list[i], KM_USER0); ++ char *dst = kmap_atomic(obj_priv->pages[i], KM_USER0); + char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); + + memcpy(dst, src, PAGE_SIZE); + kunmap_atomic(dst, KM_USER0); + } +- drm_clflush_pages(obj_priv->page_list, page_count); ++ drm_clflush_pages(obj_priv->pages, page_count); + drm_agp_chipset_flush(dev); + out: + obj_priv->phys_obj->cur_obj = NULL; +@@ -3581,7 +4166,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, + obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1]; + obj_priv->phys_obj->cur_obj = obj; + +- ret = i915_gem_object_get_page_list(obj); ++ ret = i915_gem_object_get_pages(obj); + if (ret) { + DRM_ERROR("failed to get page list\n"); + goto out; +@@ -3590,7 +4175,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, + page_count = obj->size / PAGE_SIZE; + + for (i = 0; i < page_count; i++) { +- char *src = kmap_atomic(obj_priv->page_list[i], KM_USER0); ++ char *src = kmap_atomic(obj_priv->pages[i], KM_USER0); + char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); + + memcpy(dst, src, PAGE_SIZE); +diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c +index 131c088..8d0b943 100644 +--- a/drivers/gpu/drm/i915/i915_gem_debug.c ++++ b/drivers/gpu/drm/i915/i915_gem_debug.c +@@ -105,12 +105,14 @@ i915_dump_lru(struct drm_device *dev, const char *where) + struct drm_i915_gem_object *obj_priv; + + DRM_INFO("active list %s {\n", where); ++ spin_lock(&dev_priv->mm.active_list_lock); + list_for_each_entry(obj_priv, &dev_priv->mm.active_list, + list) + { + DRM_INFO(" %p: %08x\n", obj_priv, + obj_priv->last_rendering_seqno); + } ++ spin_unlock(&dev_priv->mm.active_list_lock); + DRM_INFO("}\n"); + DRM_INFO("flushing list %s {\n", where); + list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, +diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c +new file mode 100644 +index 0000000..a1ac0c5 +--- /dev/null ++++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c +@@ -0,0 +1,263 @@ ++/* ++ * Copyright © 2008 Intel Corporation ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ * ++ * Authors: ++ * Eric Anholt ++ * Keith Packard ++ * ++ */ ++ ++#include ++#include "drmP.h" ++#include "drm.h" ++#include "i915_drm.h" ++#include "i915_drv.h" ++ ++#define DRM_I915_RING_DEBUG 1 ++ ++ ++#if defined(CONFIG_DEBUG_FS) ++ ++#define ACTIVE_LIST 1 ++#define FLUSHING_LIST 2 ++#define INACTIVE_LIST 3 ++ ++static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv) ++{ ++ if (obj_priv->user_pin_count > 0) ++ return "P"; ++ else if (obj_priv->pin_count > 0) ++ return "p"; ++ else ++ return " "; ++} ++ ++static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv) ++{ ++ switch (obj_priv->tiling_mode) { ++ default: ++ case I915_TILING_NONE: return " "; ++ case I915_TILING_X: return "X"; ++ case I915_TILING_Y: return "Y"; ++ } ++} ++ ++static int i915_gem_object_list_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ uintptr_t list = (uintptr_t) node->info_ent->data; ++ struct list_head *head; ++ struct drm_device *dev = node->minor->dev; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_gem_object *obj_priv; ++ spinlock_t *lock = NULL; ++ ++ switch (list) { ++ case ACTIVE_LIST: ++ seq_printf(m, "Active:\n"); ++ lock = &dev_priv->mm.active_list_lock; ++ spin_lock(lock); ++ head = &dev_priv->mm.active_list; ++ break; ++ case INACTIVE_LIST: ++ seq_printf(m, "Inctive:\n"); ++ head = &dev_priv->mm.inactive_list; ++ break; ++ case FLUSHING_LIST: ++ seq_printf(m, "Flushing:\n"); ++ head = &dev_priv->mm.flushing_list; ++ break; ++ default: ++ DRM_INFO("Ooops, unexpected list\n"); ++ return 0; ++ } ++ ++ list_for_each_entry(obj_priv, head, list) ++ { ++ struct drm_gem_object *obj = obj_priv->obj; ++ ++ seq_printf(m, " %p: %s %08x %08x %d", ++ obj, ++ get_pin_flag(obj_priv), ++ obj->read_domains, obj->write_domain, ++ obj_priv->last_rendering_seqno); ++ ++ if (obj->name) ++ seq_printf(m, " (name: %d)", obj->name); ++ if (obj_priv->fence_reg != I915_FENCE_REG_NONE) ++ seq_printf(m, " (fence: %d\n", obj_priv->fence_reg); ++ seq_printf(m, "\n"); ++ } ++ ++ if (lock) ++ spin_unlock(lock); ++ return 0; ++} ++ ++static int i915_gem_request_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_gem_request *gem_request; ++ ++ seq_printf(m, "Request:\n"); ++ list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) { ++ seq_printf(m, " %d @ %d\n", ++ gem_request->seqno, ++ (int) (jiffies - gem_request->emitted_jiffies)); ++ } ++ return 0; ++} ++ ++static int i915_gem_seqno_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ ++ if (dev_priv->hw_status_page != NULL) { ++ seq_printf(m, "Current sequence: %d\n", ++ i915_get_gem_seqno(dev)); ++ } else { ++ seq_printf(m, "Current sequence: hws uninitialized\n"); ++ } ++ seq_printf(m, "Waiter sequence: %d\n", ++ dev_priv->mm.waiting_gem_seqno); ++ seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); ++ return 0; ++} ++ ++ ++static int i915_interrupt_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ ++ seq_printf(m, "Interrupt enable: %08x\n", ++ I915_READ(IER)); ++ seq_printf(m, "Interrupt identity: %08x\n", ++ I915_READ(IIR)); ++ seq_printf(m, "Interrupt mask: %08x\n", ++ I915_READ(IMR)); ++ seq_printf(m, "Pipe A stat: %08x\n", ++ I915_READ(PIPEASTAT)); ++ seq_printf(m, "Pipe B stat: %08x\n", ++ I915_READ(PIPEBSTAT)); ++ seq_printf(m, "Interrupts received: %d\n", ++ atomic_read(&dev_priv->irq_received)); ++ if (dev_priv->hw_status_page != NULL) { ++ seq_printf(m, "Current sequence: %d\n", ++ i915_get_gem_seqno(dev)); ++ } else { ++ seq_printf(m, "Current sequence: hws uninitialized\n"); ++ } ++ seq_printf(m, "Waiter sequence: %d\n", ++ dev_priv->mm.waiting_gem_seqno); ++ seq_printf(m, "IRQ sequence: %d\n", ++ dev_priv->mm.irq_gem_seqno); ++ return 0; ++} ++ ++static int i915_gem_fence_regs_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ int i; ++ ++ seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); ++ seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); ++ for (i = 0; i < dev_priv->num_fence_regs; i++) { ++ struct drm_gem_object *obj = dev_priv->fence_regs[i].obj; ++ ++ if (obj == NULL) { ++ seq_printf(m, "Fenced object[%2d] = unused\n", i); ++ } else { ++ struct drm_i915_gem_object *obj_priv; ++ ++ obj_priv = obj->driver_private; ++ seq_printf(m, "Fenced object[%2d] = %p: %s " ++ "%08x %08zx %08x %s %08x %08x %d", ++ i, obj, get_pin_flag(obj_priv), ++ obj_priv->gtt_offset, ++ obj->size, obj_priv->stride, ++ get_tiling_flag(obj_priv), ++ obj->read_domains, obj->write_domain, ++ obj_priv->last_rendering_seqno); ++ if (obj->name) ++ seq_printf(m, " (name: %d)", obj->name); ++ seq_printf(m, "\n"); ++ } ++ } ++ ++ return 0; ++} ++ ++static int i915_hws_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ int i; ++ volatile u32 *hws; ++ ++ hws = (volatile u32 *)dev_priv->hw_status_page; ++ if (hws == NULL) ++ return 0; ++ ++ for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) { ++ seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", ++ i * 4, ++ hws[i], hws[i + 1], hws[i + 2], hws[i + 3]); ++ } ++ return 0; ++} ++ ++static struct drm_info_list i915_gem_debugfs_list[] = { ++ {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, ++ {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, ++ {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, ++ {"i915_gem_request", i915_gem_request_info, 0}, ++ {"i915_gem_seqno", i915_gem_seqno_info, 0}, ++ {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, ++ {"i915_gem_interrupt", i915_interrupt_info, 0}, ++ {"i915_gem_hws", i915_hws_info, 0}, ++}; ++#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) ++ ++int i915_gem_debugfs_init(struct drm_minor *minor) ++{ ++ return drm_debugfs_create_files(i915_gem_debugfs_list, ++ I915_GEM_DEBUGFS_ENTRIES, ++ minor->debugfs_root, minor); ++} ++ ++void i915_gem_debugfs_cleanup(struct drm_minor *minor) ++{ ++ drm_debugfs_remove_files(i915_gem_debugfs_list, ++ I915_GEM_DEBUGFS_ENTRIES, minor); ++} ++ ++#endif /* CONFIG_DEBUG_FS */ ++ +diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c +deleted file mode 100644 +index 4d1b9de..0000000 +--- a/drivers/gpu/drm/i915/i915_gem_proc.c ++++ /dev/null +@@ -1,334 +0,0 @@ +-/* +- * Copyright © 2008 Intel Corporation +- * +- * Permission is hereby granted, free of charge, to any person obtaining a +- * copy of this software and associated documentation files (the "Software"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sublicense, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice (including the next +- * paragraph) shall be included in all copies or substantial portions of the +- * Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +- * IN THE SOFTWARE. +- * +- * Authors: +- * Eric Anholt +- * Keith Packard +- * +- */ +- +-#include "drmP.h" +-#include "drm.h" +-#include "i915_drm.h" +-#include "i915_drv.h" +- +-static int i915_gem_active_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_i915_gem_object *obj_priv; +- int len = 0; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- DRM_PROC_PRINT("Active:\n"); +- list_for_each_entry(obj_priv, &dev_priv->mm.active_list, +- list) +- { +- struct drm_gem_object *obj = obj_priv->obj; +- if (obj->name) { +- DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", +- obj, obj->name, +- obj->read_domains, obj->write_domain, +- obj_priv->last_rendering_seqno); +- } else { +- DRM_PROC_PRINT(" %p: %08x %08x %d\n", +- obj, +- obj->read_domains, obj->write_domain, +- obj_priv->last_rendering_seqno); +- } +- } +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-static int i915_gem_flushing_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_i915_gem_object *obj_priv; +- int len = 0; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- DRM_PROC_PRINT("Flushing:\n"); +- list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, +- list) +- { +- struct drm_gem_object *obj = obj_priv->obj; +- if (obj->name) { +- DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", +- obj, obj->name, +- obj->read_domains, obj->write_domain, +- obj_priv->last_rendering_seqno); +- } else { +- DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, +- obj->read_domains, obj->write_domain, +- obj_priv->last_rendering_seqno); +- } +- } +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-static int i915_gem_inactive_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_i915_gem_object *obj_priv; +- int len = 0; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- DRM_PROC_PRINT("Inactive:\n"); +- list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, +- list) +- { +- struct drm_gem_object *obj = obj_priv->obj; +- if (obj->name) { +- DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", +- obj, obj->name, +- obj->read_domains, obj->write_domain, +- obj_priv->last_rendering_seqno); +- } else { +- DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, +- obj->read_domains, obj->write_domain, +- obj_priv->last_rendering_seqno); +- } +- } +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-static int i915_gem_request_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_i915_gem_request *gem_request; +- int len = 0; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- DRM_PROC_PRINT("Request:\n"); +- list_for_each_entry(gem_request, &dev_priv->mm.request_list, +- list) +- { +- DRM_PROC_PRINT(" %d @ %d\n", +- gem_request->seqno, +- (int) (jiffies - gem_request->emitted_jiffies)); +- } +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-static int i915_gem_seqno_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; +- int len = 0; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- if (dev_priv->hw_status_page != NULL) { +- DRM_PROC_PRINT("Current sequence: %d\n", +- i915_get_gem_seqno(dev)); +- } else { +- DRM_PROC_PRINT("Current sequence: hws uninitialized\n"); +- } +- DRM_PROC_PRINT("Waiter sequence: %d\n", +- dev_priv->mm.waiting_gem_seqno); +- DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +- +-static int i915_interrupt_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; +- int len = 0; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- DRM_PROC_PRINT("Interrupt enable: %08x\n", +- I915_READ(IER)); +- DRM_PROC_PRINT("Interrupt identity: %08x\n", +- I915_READ(IIR)); +- DRM_PROC_PRINT("Interrupt mask: %08x\n", +- I915_READ(IMR)); +- DRM_PROC_PRINT("Pipe A stat: %08x\n", +- I915_READ(PIPEASTAT)); +- DRM_PROC_PRINT("Pipe B stat: %08x\n", +- I915_READ(PIPEBSTAT)); +- DRM_PROC_PRINT("Interrupts received: %d\n", +- atomic_read(&dev_priv->irq_received)); +- if (dev_priv->hw_status_page != NULL) { +- DRM_PROC_PRINT("Current sequence: %d\n", +- i915_get_gem_seqno(dev)); +- } else { +- DRM_PROC_PRINT("Current sequence: hws uninitialized\n"); +- } +- DRM_PROC_PRINT("Waiter sequence: %d\n", +- dev_priv->mm.waiting_gem_seqno); +- DRM_PROC_PRINT("IRQ sequence: %d\n", +- dev_priv->mm.irq_gem_seqno); +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-static int i915_hws_info(char *buf, char **start, off_t offset, +- int request, int *eof, void *data) +-{ +- struct drm_minor *minor = (struct drm_minor *) data; +- struct drm_device *dev = minor->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; +- int len = 0, i; +- volatile u32 *hws; +- +- if (offset > DRM_PROC_LIMIT) { +- *eof = 1; +- return 0; +- } +- +- hws = (volatile u32 *)dev_priv->hw_status_page; +- if (hws == NULL) { +- *eof = 1; +- return 0; +- } +- +- *start = &buf[offset]; +- *eof = 0; +- for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) { +- DRM_PROC_PRINT("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", +- i * 4, +- hws[i], hws[i + 1], hws[i + 2], hws[i + 3]); +- } +- if (len > request + offset) +- return request; +- *eof = 1; +- return len - offset; +-} +- +-static struct drm_proc_list { +- /** file name */ +- const char *name; +- /** proc callback*/ +- int (*f) (char *, char **, off_t, int, int *, void *); +-} i915_gem_proc_list[] = { +- {"i915_gem_active", i915_gem_active_info}, +- {"i915_gem_flushing", i915_gem_flushing_info}, +- {"i915_gem_inactive", i915_gem_inactive_info}, +- {"i915_gem_request", i915_gem_request_info}, +- {"i915_gem_seqno", i915_gem_seqno_info}, +- {"i915_gem_interrupt", i915_interrupt_info}, +- {"i915_gem_hws", i915_hws_info}, +-}; +- +-#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list) +- +-int i915_gem_proc_init(struct drm_minor *minor) +-{ +- struct proc_dir_entry *ent; +- int i, j; +- +- for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) { +- ent = create_proc_entry(i915_gem_proc_list[i].name, +- S_IFREG | S_IRUGO, minor->dev_root); +- if (!ent) { +- DRM_ERROR("Cannot create /proc/dri/.../%s\n", +- i915_gem_proc_list[i].name); +- for (j = 0; j < i; j++) +- remove_proc_entry(i915_gem_proc_list[i].name, +- minor->dev_root); +- return -1; +- } +- ent->read_proc = i915_gem_proc_list[i].f; +- ent->data = minor; +- } +- return 0; +-} +- +-void i915_gem_proc_cleanup(struct drm_minor *minor) +-{ +- int i; +- +- if (!minor->dev_root) +- return; +- +- for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) +- remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root); +-} +diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c +index 7fb4191..6be3f92 100644 +--- a/drivers/gpu/drm/i915/i915_gem_tiling.c ++++ b/drivers/gpu/drm/i915/i915_gem_tiling.c +@@ -96,16 +96,16 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) + */ + swizzle_x = I915_BIT_6_SWIZZLE_NONE; + swizzle_y = I915_BIT_6_SWIZZLE_NONE; +- } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev) || +- IS_GM45(dev)) { ++ } else if (IS_MOBILE(dev)) { + uint32_t dcc; + +- /* On 915-945 and GM965, channel interleave by the CPU is +- * determined by DCC. The CPU will alternate based on bit 6 +- * in interleaved mode, and the GPU will then also alternate +- * on bit 6, 9, and 10 for X, but the CPU may also optionally +- * alternate based on bit 17 (XOR not disabled and XOR +- * bit == 17). ++ /* On mobile 9xx chipsets, channel interleave by the CPU is ++ * determined by DCC. For single-channel, neither the CPU ++ * nor the GPU do swizzling. For dual channel interleaved, ++ * the GPU's interleave is bit 9 and 10 for X tiled, and bit ++ * 9 for Y tiled. The CPU's interleave is independent, and ++ * can be based on either bit 11 (haven't seen this yet) or ++ * bit 17 (common). + */ + dcc = I915_READ(DCC); + switch (dcc & DCC_ADDRESSING_MODE_MASK) { +@@ -115,19 +115,18 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) + swizzle_y = I915_BIT_6_SWIZZLE_NONE; + break; + case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED: +- if (IS_I915G(dev) || IS_I915GM(dev) || +- dcc & DCC_CHANNEL_XOR_DISABLE) { ++ if (dcc & DCC_CHANNEL_XOR_DISABLE) { ++ /* This is the base swizzling by the GPU for ++ * tiled buffers. ++ */ + swizzle_x = I915_BIT_6_SWIZZLE_9_10; + swizzle_y = I915_BIT_6_SWIZZLE_9; +- } else if ((IS_I965GM(dev) || IS_GM45(dev)) && +- (dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { +- /* GM965/GM45 does either bit 11 or bit 17 +- * swizzling. +- */ ++ } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { ++ /* Bit 11 swizzling by the CPU in addition. */ + swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; + swizzle_y = I915_BIT_6_SWIZZLE_9_11; + } else { +- /* Bit 17 or perhaps other swizzling */ ++ /* Bit 17 swizzling by the CPU in addition. */ + swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; + swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; + } +@@ -217,6 +216,22 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) + else + tile_width = 512; + ++ /* check maximum stride & object size */ ++ if (IS_I965G(dev)) { ++ /* i965 stores the end address of the gtt mapping in the fence ++ * reg, so dont bother to check the size */ ++ if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) ++ return false; ++ } else if (IS_I9XX(dev)) { ++ if (stride / tile_width > I830_FENCE_MAX_PITCH_VAL || ++ size > (I830_FENCE_MAX_SIZE_VAL << 20)) ++ return false; ++ } else { ++ if (stride / 128 > I830_FENCE_MAX_PITCH_VAL || ++ size > (I830_FENCE_MAX_SIZE_VAL << 19)) ++ return false; ++ } ++ + /* 965+ just needs multiples of tile width */ + if (IS_I965G(dev)) { + if (stride & (tile_width - 1)) +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 87b6b60..ee7ce7b 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -48,10 +48,6 @@ + /** Interrupts that we mask and unmask at runtime. */ + #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) + +-/** These are all of the interrupts used by the driver */ +-#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \ +- I915_INTERRUPT_ENABLE_VAR) +- + #define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\ + PIPE_VBLANK_INTERRUPT_STATUS) + +@@ -187,6 +183,19 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) + return I915_READ(reg); + } + ++/* ++ * Handle hotplug events outside the interrupt handler proper. ++ */ ++static void i915_hotplug_work_func(struct work_struct *work) ++{ ++ drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, ++ hotplug_work); ++ struct drm_device *dev = dev_priv->dev; ++ ++ /* Just fire off a uevent and let userspace tell us what to do */ ++ drm_sysfs_hotplug_event(dev); ++} ++ + irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) + { + struct drm_device *dev = (struct drm_device *) arg; +@@ -244,6 +253,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) + + ret = IRQ_HANDLED; + ++ /* Consume port. Then clear IIR or we'll miss events */ ++ if ((I915_HAS_HOTPLUG(dev)) && ++ (iir & I915_DISPLAY_PORT_INTERRUPT)) { ++ u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); ++ ++ DRM_DEBUG("hotplug event received, stat 0x%08x\n", ++ hotplug_status); ++ if (hotplug_status & dev_priv->hotplug_supported_mask) ++ schedule_work(&dev_priv->hotplug_work); ++ ++ I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); ++ I915_READ(PORT_HOTPLUG_STAT); ++ } ++ + I915_WRITE(IIR, iir); + new_iir = I915_READ(IIR); /* Flush posted writes */ + +@@ -528,17 +551,24 @@ void i915_driver_irq_preinstall(struct drm_device * dev) + + atomic_set(&dev_priv->irq_received, 0); + ++ if (I915_HAS_HOTPLUG(dev)) { ++ I915_WRITE(PORT_HOTPLUG_EN, 0); ++ I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); ++ } ++ + I915_WRITE(HWSTAM, 0xeffe); + I915_WRITE(PIPEASTAT, 0); + I915_WRITE(PIPEBSTAT, 0); + I915_WRITE(IMR, 0xffffffff); + I915_WRITE(IER, 0x0); + (void) I915_READ(IER); ++ INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); + } + + int i915_driver_irq_postinstall(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; ++ u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; + + dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; + +@@ -550,13 +580,35 @@ int i915_driver_irq_postinstall(struct drm_device *dev) + dev_priv->pipestat[0] = 0; + dev_priv->pipestat[1] = 0; + ++ if (I915_HAS_HOTPLUG(dev)) { ++ u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); ++ ++ /* Leave other bits alone */ ++ hotplug_en |= HOTPLUG_EN_MASK; ++ I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); ++ ++ dev_priv->hotplug_supported_mask = CRT_HOTPLUG_INT_STATUS | ++ TV_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS | ++ SDVOB_HOTPLUG_INT_STATUS; ++ if (IS_G4X(dev)) { ++ dev_priv->hotplug_supported_mask |= ++ HDMIB_HOTPLUG_INT_STATUS | ++ HDMIC_HOTPLUG_INT_STATUS | ++ HDMID_HOTPLUG_INT_STATUS; ++ } ++ /* Enable in IER... */ ++ enable_mask |= I915_DISPLAY_PORT_INTERRUPT; ++ /* and unmask in IMR */ ++ i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); ++ } ++ + /* Disable pipe interrupt enables, clear pending pipe status */ + I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); + I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); + /* Clear pending interrupt status */ + I915_WRITE(IIR, I915_READ(IIR)); + +- I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); ++ I915_WRITE(IER, enable_mask); + I915_WRITE(IMR, dev_priv->irq_mask_reg); + (void) I915_READ(IER); + +@@ -575,6 +627,11 @@ void i915_driver_irq_uninstall(struct drm_device * dev) + + dev_priv->vblank_pipe = 0; + ++ if (I915_HAS_HOTPLUG(dev)) { ++ I915_WRITE(PORT_HOTPLUG_EN, 0); ++ I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); ++ } ++ + I915_WRITE(HWSTAM, 0xffffffff); + I915_WRITE(PIPEASTAT, 0); + I915_WRITE(PIPEBSTAT, 0); +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 90600d8..e805b59 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -190,6 +190,8 @@ + #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) + #define I830_FENCE_PITCH_SHIFT 4 + #define I830_FENCE_REG_VALID (1<<0) ++#define I830_FENCE_MAX_PITCH_VAL 0x10 ++#define I830_FENCE_MAX_SIZE_VAL (1<<8) + + #define I915_FENCE_START_MASK 0x0ff00000 + #define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8) +@@ -198,6 +200,7 @@ + #define I965_FENCE_PITCH_SHIFT 2 + #define I965_FENCE_TILING_Y_SHIFT 1 + #define I965_FENCE_REG_VALID (1<<0) ++#define I965_FENCE_MAX_PITCH_VAL 0x0400 + + /* + * Instruction and interrupt control regs +@@ -359,6 +362,7 @@ + #define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ + #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ + #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ ++#define DPLL_FPA01_P1_POST_DIV_MASK_IGD 0x00ff8000 /* IGD */ + + #define I915_FIFO_UNDERRUN_STATUS (1UL<<31) + #define I915_CRC_ERROR_ENABLE (1UL<<29) +@@ -435,6 +439,7 @@ + */ + #define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 + #define DPLL_FPA01_P1_POST_DIV_SHIFT 16 ++#define DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15 + /* i830, required in DVO non-gang */ + #define PLL_P2_DIVIDE_BY_4 (1 << 23) + #define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +@@ -501,10 +506,12 @@ + #define FPB0 0x06048 + #define FPB1 0x0604c + #define FP_N_DIV_MASK 0x003f0000 ++#define FP_N_IGD_DIV_MASK 0x00ff0000 + #define FP_N_DIV_SHIFT 16 + #define FP_M1_DIV_MASK 0x00003f00 + #define FP_M1_DIV_SHIFT 8 + #define FP_M2_DIV_MASK 0x0000003f ++#define FP_M2_IGD_DIV_MASK 0x000000ff + #define FP_M2_DIV_SHIFT 0 + #define DPLL_TEST 0x606c + #define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +@@ -629,6 +636,30 @@ + #define TV_HOTPLUG_INT_EN (1 << 18) + #define CRT_HOTPLUG_INT_EN (1 << 9) + #define CRT_HOTPLUG_FORCE_DETECT (1 << 3) ++#define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) ++/* must use period 64 on GM45 according to docs */ ++#define CRT_HOTPLUG_ACTIVATION_PERIOD_64 (1 << 8) ++#define CRT_HOTPLUG_DAC_ON_TIME_2M (0 << 7) ++#define CRT_HOTPLUG_DAC_ON_TIME_4M (1 << 7) ++#define CRT_HOTPLUG_VOLTAGE_COMPARE_40 (0 << 5) ++#define CRT_HOTPLUG_VOLTAGE_COMPARE_50 (1 << 5) ++#define CRT_HOTPLUG_VOLTAGE_COMPARE_60 (2 << 5) ++#define CRT_HOTPLUG_VOLTAGE_COMPARE_70 (3 << 5) ++#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK (3 << 5) ++#define CRT_HOTPLUG_DETECT_DELAY_1G (0 << 4) ++#define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4) ++#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) ++#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) ++#define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ ++#define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f ++#define HOTPLUG_EN_MASK (HDMIB_HOTPLUG_INT_EN | \ ++ HDMIC_HOTPLUG_INT_EN | \ ++ HDMID_HOTPLUG_INT_EN | \ ++ SDVOB_HOTPLUG_INT_EN | \ ++ SDVOC_HOTPLUG_INT_EN | \ ++ TV_HOTPLUG_INT_EN | \ ++ CRT_HOTPLUG_INT_EN) ++ + + #define PORT_HOTPLUG_STAT 0x61114 + #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) +@@ -856,7 +887,7 @@ + */ + # define TV_ENC_C0_FIX (1 << 10) + /** Bits that must be preserved by software */ +-# define TV_CTL_SAVE ((3 << 8) | (3 << 6)) ++# define TV_CTL_SAVE ((1 << 11) | (3 << 9) | (7 << 6) | 0xf) + # define TV_FUSE_STATE_MASK (3 << 4) + /** Read-only state that reports all features enabled */ + # define TV_FUSE_STATE_ENABLED (0 << 4) +diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h +index 5ea715a..de621aa 100644 +--- a/drivers/gpu/drm/i915/intel_bios.h ++++ b/drivers/gpu/drm/i915/intel_bios.h +@@ -162,13 +162,13 @@ struct bdb_lvds_options { + u8 panel_type; + u8 rsvd1; + /* LVDS capabilities, stored in a dword */ +- u8 rsvd2:1; +- u8 lvds_edid:1; +- u8 pixel_dither:1; +- u8 pfit_ratio_auto:1; +- u8 pfit_gfx_mode_enhanced:1; +- u8 pfit_text_mode_enhanced:1; + u8 pfit_mode:2; ++ u8 pfit_text_mode_enhanced:1; ++ u8 pfit_gfx_mode_enhanced:1; ++ u8 pfit_ratio_auto:1; ++ u8 pixel_dither:1; ++ u8 lvds_edid:1; ++ u8 rsvd2:1; + u8 rsvd4; + } __attribute__((packed)); + +diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c +index dcaed34..9bdd959 100644 +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -41,7 +41,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) + + temp = I915_READ(ADPA); + temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); +- temp &= ~ADPA_DAC_ENABLE; ++ temp |= ADPA_DAC_ENABLE; + + switch(mode) { + case DRM_MODE_DPMS_ON: +@@ -64,11 +64,21 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) + static int intel_crt_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) + { ++ struct drm_device *dev = connector->dev; ++ ++ int max_clock = 0; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + +- if (mode->clock > 400000 || mode->clock < 25000) +- return MODE_CLOCK_RANGE; ++ if (mode->clock < 25000) ++ return MODE_CLOCK_LOW; ++ ++ if (!IS_I9XX(dev)) ++ max_clock = 350000; ++ else ++ max_clock = 400000; ++ if (mode->clock > max_clock) ++ return MODE_CLOCK_HIGH; + + return MODE_OK; + } +@@ -113,10 +123,13 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + adpa |= ADPA_VSYNC_ACTIVE_HIGH; + +- if (intel_crtc->pipe == 0) ++ if (intel_crtc->pipe == 0) { + adpa |= ADPA_PIPE_A_SELECT; +- else ++ I915_WRITE(BCLRPAT_A, 0); ++ } else { + adpa |= ADPA_PIPE_B_SELECT; ++ I915_WRITE(BCLRPAT_B, 0); ++ } + + I915_WRITE(ADPA, adpa); + } +@@ -133,20 +146,39 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) + { + struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- u32 temp; +- +- unsigned long timeout = jiffies + msecs_to_jiffies(1000); +- +- temp = I915_READ(PORT_HOTPLUG_EN); +- +- I915_WRITE(PORT_HOTPLUG_EN, +- temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5)); ++ u32 hotplug_en; ++ int i, tries = 0; ++ /* ++ * On 4 series desktop, CRT detect sequence need to be done twice ++ * to get a reliable result. ++ */ + +- do { +- if (!(I915_READ(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT)) +- break; +- msleep(1); +- } while (time_after(timeout, jiffies)); ++ if (IS_G4X(dev) && !IS_GM45(dev)) ++ tries = 2; ++ else ++ tries = 1; ++ hotplug_en = I915_READ(PORT_HOTPLUG_EN); ++ hotplug_en &= CRT_FORCE_HOTPLUG_MASK; ++ hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; ++ ++ if (IS_GM45(dev)) ++ hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; ++ ++ hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; ++ ++ for (i = 0; i < tries ; i++) { ++ unsigned long timeout; ++ /* turn on the FORCE_DETECT */ ++ I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); ++ timeout = jiffies + msecs_to_jiffies(1000); ++ /* wait for FORCE_DETECT to go off */ ++ do { ++ if (!(I915_READ(PORT_HOTPLUG_EN) & ++ CRT_HOTPLUG_FORCE_DETECT)) ++ break; ++ msleep(1); ++ } while (time_after(timeout, jiffies)); ++ } + + if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) == + CRT_HOTPLUG_MONITOR_COLOR) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index a283427..64773ce 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -56,11 +56,13 @@ typedef struct { + } intel_p2_t; + + #define INTEL_P2_NUM 2 +- +-typedef struct { ++typedef struct intel_limit intel_limit_t; ++struct intel_limit { + intel_range_t dot, vco, n, m, m1, m2, p, p1; + intel_p2_t p2; +-} intel_limit_t; ++ bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, ++ int, int, intel_clock_t *); ++}; + + #define I8XX_DOT_MIN 25000 + #define I8XX_DOT_MAX 350000 +@@ -90,18 +92,32 @@ typedef struct { + #define I9XX_DOT_MAX 400000 + #define I9XX_VCO_MIN 1400000 + #define I9XX_VCO_MAX 2800000 ++#define IGD_VCO_MIN 1700000 ++#define IGD_VCO_MAX 3500000 + #define I9XX_N_MIN 1 + #define I9XX_N_MAX 6 ++/* IGD's Ncounter is a ring counter */ ++#define IGD_N_MIN 3 ++#define IGD_N_MAX 6 + #define I9XX_M_MIN 70 + #define I9XX_M_MAX 120 ++#define IGD_M_MIN 2 ++#define IGD_M_MAX 256 + #define I9XX_M1_MIN 10 + #define I9XX_M1_MAX 22 + #define I9XX_M2_MIN 5 + #define I9XX_M2_MAX 9 ++/* IGD M1 is reserved, and must be 0 */ ++#define IGD_M1_MIN 0 ++#define IGD_M1_MAX 0 ++#define IGD_M2_MIN 0 ++#define IGD_M2_MAX 254 + #define I9XX_P_SDVO_DAC_MIN 5 + #define I9XX_P_SDVO_DAC_MAX 80 + #define I9XX_P_LVDS_MIN 7 + #define I9XX_P_LVDS_MAX 98 ++#define IGD_P_LVDS_MIN 7 ++#define IGD_P_LVDS_MAX 112 + #define I9XX_P1_MIN 1 + #define I9XX_P1_MAX 8 + #define I9XX_P2_SDVO_DAC_SLOW 10 +@@ -115,6 +131,97 @@ typedef struct { + #define INTEL_LIMIT_I8XX_LVDS 1 + #define INTEL_LIMIT_I9XX_SDVO_DAC 2 + #define INTEL_LIMIT_I9XX_LVDS 3 ++#define INTEL_LIMIT_G4X_SDVO 4 ++#define INTEL_LIMIT_G4X_HDMI_DAC 5 ++#define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6 ++#define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7 ++#define INTEL_LIMIT_IGD_SDVO_DAC 8 ++#define INTEL_LIMIT_IGD_LVDS 9 ++ ++/*The parameter is for SDVO on G4x platform*/ ++#define G4X_DOT_SDVO_MIN 25000 ++#define G4X_DOT_SDVO_MAX 270000 ++#define G4X_VCO_MIN 1750000 ++#define G4X_VCO_MAX 3500000 ++#define G4X_N_SDVO_MIN 1 ++#define G4X_N_SDVO_MAX 4 ++#define G4X_M_SDVO_MIN 104 ++#define G4X_M_SDVO_MAX 138 ++#define G4X_M1_SDVO_MIN 17 ++#define G4X_M1_SDVO_MAX 23 ++#define G4X_M2_SDVO_MIN 5 ++#define G4X_M2_SDVO_MAX 11 ++#define G4X_P_SDVO_MIN 10 ++#define G4X_P_SDVO_MAX 30 ++#define G4X_P1_SDVO_MIN 1 ++#define G4X_P1_SDVO_MAX 3 ++#define G4X_P2_SDVO_SLOW 10 ++#define G4X_P2_SDVO_FAST 10 ++#define G4X_P2_SDVO_LIMIT 270000 ++ ++/*The parameter is for HDMI_DAC on G4x platform*/ ++#define G4X_DOT_HDMI_DAC_MIN 22000 ++#define G4X_DOT_HDMI_DAC_MAX 400000 ++#define G4X_N_HDMI_DAC_MIN 1 ++#define G4X_N_HDMI_DAC_MAX 4 ++#define G4X_M_HDMI_DAC_MIN 104 ++#define G4X_M_HDMI_DAC_MAX 138 ++#define G4X_M1_HDMI_DAC_MIN 16 ++#define G4X_M1_HDMI_DAC_MAX 23 ++#define G4X_M2_HDMI_DAC_MIN 5 ++#define G4X_M2_HDMI_DAC_MAX 11 ++#define G4X_P_HDMI_DAC_MIN 5 ++#define G4X_P_HDMI_DAC_MAX 80 ++#define G4X_P1_HDMI_DAC_MIN 1 ++#define G4X_P1_HDMI_DAC_MAX 8 ++#define G4X_P2_HDMI_DAC_SLOW 10 ++#define G4X_P2_HDMI_DAC_FAST 5 ++#define G4X_P2_HDMI_DAC_LIMIT 165000 ++ ++/*The parameter is for SINGLE_CHANNEL_LVDS on G4x platform*/ ++#define G4X_DOT_SINGLE_CHANNEL_LVDS_MIN 20000 ++#define G4X_DOT_SINGLE_CHANNEL_LVDS_MAX 115000 ++#define G4X_N_SINGLE_CHANNEL_LVDS_MIN 1 ++#define G4X_N_SINGLE_CHANNEL_LVDS_MAX 3 ++#define G4X_M_SINGLE_CHANNEL_LVDS_MIN 104 ++#define G4X_M_SINGLE_CHANNEL_LVDS_MAX 138 ++#define G4X_M1_SINGLE_CHANNEL_LVDS_MIN 17 ++#define G4X_M1_SINGLE_CHANNEL_LVDS_MAX 23 ++#define G4X_M2_SINGLE_CHANNEL_LVDS_MIN 5 ++#define G4X_M2_SINGLE_CHANNEL_LVDS_MAX 11 ++#define G4X_P_SINGLE_CHANNEL_LVDS_MIN 28 ++#define G4X_P_SINGLE_CHANNEL_LVDS_MAX 112 ++#define G4X_P1_SINGLE_CHANNEL_LVDS_MIN 2 ++#define G4X_P1_SINGLE_CHANNEL_LVDS_MAX 8 ++#define G4X_P2_SINGLE_CHANNEL_LVDS_SLOW 14 ++#define G4X_P2_SINGLE_CHANNEL_LVDS_FAST 14 ++#define G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT 0 ++ ++/*The parameter is for DUAL_CHANNEL_LVDS on G4x platform*/ ++#define G4X_DOT_DUAL_CHANNEL_LVDS_MIN 80000 ++#define G4X_DOT_DUAL_CHANNEL_LVDS_MAX 224000 ++#define G4X_N_DUAL_CHANNEL_LVDS_MIN 1 ++#define G4X_N_DUAL_CHANNEL_LVDS_MAX 3 ++#define G4X_M_DUAL_CHANNEL_LVDS_MIN 104 ++#define G4X_M_DUAL_CHANNEL_LVDS_MAX 138 ++#define G4X_M1_DUAL_CHANNEL_LVDS_MIN 17 ++#define G4X_M1_DUAL_CHANNEL_LVDS_MAX 23 ++#define G4X_M2_DUAL_CHANNEL_LVDS_MIN 5 ++#define G4X_M2_DUAL_CHANNEL_LVDS_MAX 11 ++#define G4X_P_DUAL_CHANNEL_LVDS_MIN 14 ++#define G4X_P_DUAL_CHANNEL_LVDS_MAX 42 ++#define G4X_P1_DUAL_CHANNEL_LVDS_MIN 2 ++#define G4X_P1_DUAL_CHANNEL_LVDS_MAX 6 ++#define G4X_P2_DUAL_CHANNEL_LVDS_SLOW 7 ++#define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 ++#define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 ++ ++static bool ++intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ++ int target, int refclk, intel_clock_t *best_clock); ++static bool ++intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ++ int target, int refclk, intel_clock_t *best_clock); + + static const intel_limit_t intel_limits[] = { + { /* INTEL_LIMIT_I8XX_DVO_DAC */ +@@ -128,6 +235,7 @@ static const intel_limit_t intel_limits[] = { + .p1 = { .min = I8XX_P1_MIN, .max = I8XX_P1_MAX }, + .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, + .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, ++ .find_pll = intel_find_best_PLL, + }, + { /* INTEL_LIMIT_I8XX_LVDS */ + .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, +@@ -140,6 +248,7 @@ static const intel_limit_t intel_limits[] = { + .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX }, + .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, + .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, ++ .find_pll = intel_find_best_PLL, + }, + { /* INTEL_LIMIT_I9XX_SDVO_DAC */ + .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, +@@ -152,6 +261,7 @@ static const intel_limit_t intel_limits[] = { + .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, + .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, + .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, ++ .find_pll = intel_find_best_PLL, + }, + { /* INTEL_LIMIT_I9XX_LVDS */ + .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, +@@ -167,19 +277,157 @@ static const intel_limit_t intel_limits[] = { + */ + .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, + .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, ++ .find_pll = intel_find_best_PLL, ++ }, ++ /* below parameter and function is for G4X Chipset Family*/ ++ { /* INTEL_LIMIT_G4X_SDVO */ ++ .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, ++ .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, ++ .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, ++ .m = { .min = G4X_M_SDVO_MIN, .max = G4X_M_SDVO_MAX }, ++ .m1 = { .min = G4X_M1_SDVO_MIN, .max = G4X_M1_SDVO_MAX }, ++ .m2 = { .min = G4X_M2_SDVO_MIN, .max = G4X_M2_SDVO_MAX }, ++ .p = { .min = G4X_P_SDVO_MIN, .max = G4X_P_SDVO_MAX }, ++ .p1 = { .min = G4X_P1_SDVO_MIN, .max = G4X_P1_SDVO_MAX}, ++ .p2 = { .dot_limit = G4X_P2_SDVO_LIMIT, ++ .p2_slow = G4X_P2_SDVO_SLOW, ++ .p2_fast = G4X_P2_SDVO_FAST ++ }, ++ .find_pll = intel_g4x_find_best_PLL, ++ }, ++ { /* INTEL_LIMIT_G4X_HDMI_DAC */ ++ .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, ++ .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, ++ .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, ++ .m = { .min = G4X_M_HDMI_DAC_MIN, .max = G4X_M_HDMI_DAC_MAX }, ++ .m1 = { .min = G4X_M1_HDMI_DAC_MIN, .max = G4X_M1_HDMI_DAC_MAX }, ++ .m2 = { .min = G4X_M2_HDMI_DAC_MIN, .max = G4X_M2_HDMI_DAC_MAX }, ++ .p = { .min = G4X_P_HDMI_DAC_MIN, .max = G4X_P_HDMI_DAC_MAX }, ++ .p1 = { .min = G4X_P1_HDMI_DAC_MIN, .max = G4X_P1_HDMI_DAC_MAX}, ++ .p2 = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT, ++ .p2_slow = G4X_P2_HDMI_DAC_SLOW, ++ .p2_fast = G4X_P2_HDMI_DAC_FAST ++ }, ++ .find_pll = intel_g4x_find_best_PLL, ++ }, ++ { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */ ++ .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, ++ .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, ++ .vco = { .min = G4X_VCO_MIN, ++ .max = G4X_VCO_MAX }, ++ .n = { .min = G4X_N_SINGLE_CHANNEL_LVDS_MIN, ++ .max = G4X_N_SINGLE_CHANNEL_LVDS_MAX }, ++ .m = { .min = G4X_M_SINGLE_CHANNEL_LVDS_MIN, ++ .max = G4X_M_SINGLE_CHANNEL_LVDS_MAX }, ++ .m1 = { .min = G4X_M1_SINGLE_CHANNEL_LVDS_MIN, ++ .max = G4X_M1_SINGLE_CHANNEL_LVDS_MAX }, ++ .m2 = { .min = G4X_M2_SINGLE_CHANNEL_LVDS_MIN, ++ .max = G4X_M2_SINGLE_CHANNEL_LVDS_MAX }, ++ .p = { .min = G4X_P_SINGLE_CHANNEL_LVDS_MIN, ++ .max = G4X_P_SINGLE_CHANNEL_LVDS_MAX }, ++ .p1 = { .min = G4X_P1_SINGLE_CHANNEL_LVDS_MIN, ++ .max = G4X_P1_SINGLE_CHANNEL_LVDS_MAX }, ++ .p2 = { .dot_limit = G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT, ++ .p2_slow = G4X_P2_SINGLE_CHANNEL_LVDS_SLOW, ++ .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST ++ }, ++ .find_pll = intel_g4x_find_best_PLL, ++ }, ++ { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */ ++ .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, ++ .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, ++ .vco = { .min = G4X_VCO_MIN, ++ .max = G4X_VCO_MAX }, ++ .n = { .min = G4X_N_DUAL_CHANNEL_LVDS_MIN, ++ .max = G4X_N_DUAL_CHANNEL_LVDS_MAX }, ++ .m = { .min = G4X_M_DUAL_CHANNEL_LVDS_MIN, ++ .max = G4X_M_DUAL_CHANNEL_LVDS_MAX }, ++ .m1 = { .min = G4X_M1_DUAL_CHANNEL_LVDS_MIN, ++ .max = G4X_M1_DUAL_CHANNEL_LVDS_MAX }, ++ .m2 = { .min = G4X_M2_DUAL_CHANNEL_LVDS_MIN, ++ .max = G4X_M2_DUAL_CHANNEL_LVDS_MAX }, ++ .p = { .min = G4X_P_DUAL_CHANNEL_LVDS_MIN, ++ .max = G4X_P_DUAL_CHANNEL_LVDS_MAX }, ++ .p1 = { .min = G4X_P1_DUAL_CHANNEL_LVDS_MIN, ++ .max = G4X_P1_DUAL_CHANNEL_LVDS_MAX }, ++ .p2 = { .dot_limit = G4X_P2_DUAL_CHANNEL_LVDS_LIMIT, ++ .p2_slow = G4X_P2_DUAL_CHANNEL_LVDS_SLOW, ++ .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST ++ }, ++ .find_pll = intel_g4x_find_best_PLL, ++ }, ++ { /* INTEL_LIMIT_IGD_SDVO */ ++ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, ++ .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, ++ .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, ++ .m = { .min = IGD_M_MIN, .max = IGD_M_MAX }, ++ .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX }, ++ .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX }, ++ .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX }, ++ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, ++ .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, ++ .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, + }, ++ { /* INTEL_LIMIT_IGD_LVDS */ ++ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, ++ .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, ++ .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, ++ .m = { .min = IGD_M_MIN, .max = IGD_M_MAX }, ++ .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX }, ++ .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX }, ++ .p = { .min = IGD_P_LVDS_MIN, .max = IGD_P_LVDS_MAX }, ++ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, ++ /* IGD only supports single-channel mode. */ ++ .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, ++ .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, ++ }, ++ + }; + ++static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ const intel_limit_t *limit; ++ ++ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { ++ if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == ++ LVDS_CLKB_POWER_UP) ++ /* LVDS with dual channel */ ++ limit = &intel_limits ++ [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS]; ++ else ++ /* LVDS with dual channel */ ++ limit = &intel_limits ++ [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS]; ++ } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || ++ intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { ++ limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC]; ++ } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { ++ limit = &intel_limits[INTEL_LIMIT_G4X_SDVO]; ++ } else /* The option is for other outputs */ ++ limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; ++ ++ return limit; ++} ++ + static const intel_limit_t *intel_limit(struct drm_crtc *crtc) + { + struct drm_device *dev = crtc->dev; + const intel_limit_t *limit; + +- if (IS_I9XX(dev)) { ++ if (IS_G4X(dev)) { ++ limit = intel_g4x_limit(crtc); ++ } else if (IS_I9XX(dev) && !IS_IGD(dev)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; + else + limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; ++ } else if (IS_IGD(dev)) { ++ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) ++ limit = &intel_limits[INTEL_LIMIT_IGD_LVDS]; ++ else ++ limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC]; + } else { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; +@@ -189,8 +437,21 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) + return limit; + } + +-static void intel_clock(int refclk, intel_clock_t *clock) ++/* m1 is reserved as 0 in IGD, n is a ring counter */ ++static void igd_clock(int refclk, intel_clock_t *clock) ++{ ++ clock->m = clock->m2 + 2; ++ clock->p = clock->p1 * clock->p2; ++ clock->vco = refclk * clock->m / clock->n; ++ clock->dot = clock->vco / clock->p; ++} ++ ++static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock) + { ++ if (IS_IGD(dev)) { ++ igd_clock(refclk, clock); ++ return; ++ } + clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); + clock->p = clock->p1 * clock->p2; + clock->vco = refclk * clock->m / (clock->n + 2); +@@ -226,6 +487,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) + static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock) + { + const intel_limit_t *limit = intel_limit (crtc); ++ struct drm_device *dev = crtc->dev; + + if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) + INTELPllInvalid ("p1 out of range\n"); +@@ -235,7 +497,7 @@ static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock) + INTELPllInvalid ("m2 out of range\n"); + if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) + INTELPllInvalid ("m1 out of range\n"); +- if (clock->m1 <= clock->m2) ++ if (clock->m1 <= clock->m2 && !IS_IGD(dev)) + INTELPllInvalid ("m1 <= m2\n"); + if (clock->m < limit->m.min || limit->m.max < clock->m) + INTELPllInvalid ("m out of range\n"); +@@ -252,18 +514,14 @@ static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock) + return true; + } + +-/** +- * Returns a set of divisors for the desired target clock with the given +- * refclk, or FALSE. The returned values represent the clock equation: +- * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. +- */ +-static bool intel_find_best_PLL(struct drm_crtc *crtc, int target, +- int refclk, intel_clock_t *best_clock) ++static bool ++intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ++ int target, int refclk, intel_clock_t *best_clock) ++ + { + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + intel_clock_t clock; +- const intel_limit_t *limit = intel_limit(crtc); + int err = target; + + if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && +@@ -289,15 +547,17 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target, + memset (best_clock, 0, sizeof (*best_clock)); + + for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { +- for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 && +- clock.m2 <= limit->m2.max; clock.m2++) { ++ for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { ++ /* m1 is always 0 in IGD */ ++ if (clock.m2 >= clock.m1 && !IS_IGD(dev)) ++ break; + for (clock.n = limit->n.min; clock.n <= limit->n.max; + clock.n++) { + for (clock.p1 = limit->p1.min; + clock.p1 <= limit->p1.max; clock.p1++) { + int this_err; + +- intel_clock(refclk, &clock); ++ intel_clock(dev, refclk, &clock); + + if (!intel_PLL_is_valid(crtc, &clock)) + continue; +@@ -315,11 +575,68 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target, + return (err != target); + } + ++static bool ++intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ++ int target, int refclk, intel_clock_t *best_clock) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ intel_clock_t clock; ++ int max_n; ++ bool found; ++ /* approximately equals target * 0.00488 */ ++ int err_most = (target >> 8) + (target >> 10); ++ found = false; ++ ++ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { ++ if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == ++ LVDS_CLKB_POWER_UP) ++ clock.p2 = limit->p2.p2_fast; ++ else ++ clock.p2 = limit->p2.p2_slow; ++ } else { ++ if (target < limit->p2.dot_limit) ++ clock.p2 = limit->p2.p2_slow; ++ else ++ clock.p2 = limit->p2.p2_fast; ++ } ++ ++ memset(best_clock, 0, sizeof(*best_clock)); ++ max_n = limit->n.max; ++ /* based on hardware requriment prefer smaller n to precision */ ++ for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { ++ /* based on hardware requirment prefere larger m1,m2, p1 */ ++ for (clock.m1 = limit->m1.max; ++ clock.m1 >= limit->m1.min; clock.m1--) { ++ for (clock.m2 = limit->m2.max; ++ clock.m2 >= limit->m2.min; clock.m2--) { ++ for (clock.p1 = limit->p1.max; ++ clock.p1 >= limit->p1.min; clock.p1--) { ++ int this_err; ++ ++ intel_clock(dev, refclk, &clock); ++ if (!intel_PLL_is_valid(crtc, &clock)) ++ continue; ++ this_err = abs(clock.dot - target) ; ++ if (this_err < err_most) { ++ *best_clock = clock; ++ err_most = this_err; ++ max_n = clock.n; ++ found = true; ++ } ++ } ++ } ++ } ++ } ++ ++ return found; ++} ++ + void + intel_wait_for_vblank(struct drm_device *dev) + { + /* Wait for 20ms, i.e. one cycle at 50hz. */ +- udelay(20000); ++ mdelay(20); + } + + static int +@@ -634,7 +951,7 @@ static int intel_get_core_clock_speed(struct drm_device *dev) + return 400000; + else if (IS_I915G(dev)) + return 333000; +- else if (IS_I945GM(dev) || IS_845G(dev)) ++ else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev)) + return 200000; + else if (IS_I915GM(dev)) { + u16 gcfgc = 0; +@@ -733,6 +1050,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + bool is_crt = false, is_lvds = false, is_tv = false; + struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector *connector; ++ const intel_limit_t *limit; + int ret; + + drm_vblank_pre_modeset(dev, pipe); +@@ -776,13 +1094,42 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + refclk = 48000; + } + +- ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock); ++ /* ++ * Returns a set of divisors for the desired target clock with the given ++ * refclk, or FALSE. The returned values represent the clock equation: ++ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. ++ */ ++ limit = intel_limit(crtc); ++ ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); + if (!ok) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; + } + +- fp = clock.n << 16 | clock.m1 << 8 | clock.m2; ++ /* SDVO TV has fixed PLL values depend on its clock range, ++ this mirrors vbios setting. */ ++ if (is_sdvo && is_tv) { ++ if (adjusted_mode->clock >= 100000 ++ && adjusted_mode->clock < 140500) { ++ clock.p1 = 2; ++ clock.p2 = 10; ++ clock.n = 3; ++ clock.m1 = 16; ++ clock.m2 = 8; ++ } else if (adjusted_mode->clock >= 140500 ++ && adjusted_mode->clock <= 200000) { ++ clock.p1 = 1; ++ clock.p2 = 10; ++ clock.n = 6; ++ clock.m1 = 12; ++ clock.m2 = 8; ++ } ++ } ++ ++ if (IS_IGD(dev)) ++ fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; ++ else ++ fp = clock.n << 16 | clock.m1 << 8 | clock.m2; + + dpll = DPLL_VGA_MODE_DIS; + if (IS_I9XX(dev)) { +@@ -799,7 +1146,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + } + + /* compute bitmask from p1 value */ +- dpll |= (1 << (clock.p1 - 1)) << 16; ++ if (IS_IGD(dev)) ++ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD; ++ else ++ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + switch (clock.p2) { + case 5: + dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; +@@ -1279,10 +1629,20 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + fp = I915_READ((pipe == 0) ? FPA1 : FPB1); + + clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; +- clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; +- clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; ++ if (IS_IGD(dev)) { ++ clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; ++ clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT; ++ } else { ++ clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; ++ clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; ++ } ++ + if (IS_I9XX(dev)) { +- clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> ++ if (IS_IGD(dev)) ++ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >> ++ DPLL_FPA01_P1_POST_DIV_SHIFT_IGD); ++ else ++ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + + switch (dpll & DPLL_MODE_MASK) { +@@ -1301,7 +1661,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + } + + /* XXX: Handle the 100Mhz refclk */ +- intel_clock(96000, &clock); ++ intel_clock(dev, 96000, &clock); + } else { + bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN); + +@@ -1313,9 +1673,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + if ((dpll & PLL_REF_INPUT_MASK) == + PLLB_REF_INPUT_SPREADSPECTRUMIN) { + /* XXX: might not be 66MHz */ +- intel_clock(66000, &clock); ++ intel_clock(dev, 66000, &clock); + } else +- intel_clock(48000, &clock); ++ intel_clock(dev, 48000, &clock); + } else { + if (dpll & PLL_P1_DIVIDE_BY_TWO) + clock.p1 = 2; +@@ -1328,7 +1688,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + else + clock.p2 = 2; + +- intel_clock(48000, &clock); ++ intel_clock(dev, 48000, &clock); + } + } + +@@ -1474,13 +1834,21 @@ static void intel_setup_outputs(struct drm_device *dev) + + if (IS_I9XX(dev)) { + int found; ++ u32 reg; + + if (I915_READ(SDVOB) & SDVO_DETECTED) { + found = intel_sdvo_init(dev, SDVOB); + if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) + intel_hdmi_init(dev, SDVOB); + } +- if (!IS_G4X(dev) || (I915_READ(SDVOB) & SDVO_DETECTED)) { ++ ++ /* Before G4X SDVOC doesn't have its own detect register */ ++ if (IS_G4X(dev)) ++ reg = SDVOC; ++ else ++ reg = SDVOB; ++ ++ if (I915_READ(reg) & SDVO_DETECTED) { + found = intel_sdvo_init(dev, SDVOC); + if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) + intel_hdmi_init(dev, SDVOC); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 0d211af..6619f26 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -265,7 +265,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, + pfit_control = 0; + + if (!IS_I965G(dev)) { +- if (dev_priv->panel_wants_dither) ++ if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + } + else +diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c +index e42019e..07d7ec9 100644 +--- a/drivers/gpu/drm/i915/intel_modes.c ++++ b/drivers/gpu/drm/i915/intel_modes.c +@@ -76,6 +76,7 @@ int intel_ddc_get_modes(struct intel_output *intel_output) + drm_mode_connector_update_edid_property(&intel_output->base, + edid); + ret = drm_add_edid_modes(&intel_output->base, edid); ++ intel_output->base.display_info.raw_edid = NULL; + kfree(edid); + } + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index fbe6f39..7b31f55 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -273,20 +273,20 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + int i; + +- DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd); ++ printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd); + for (i = 0; i < args_len; i++) +- printk("%02X ", ((u8 *)args)[i]); ++ printk(KERN_DEBUG "%02X ", ((u8 *)args)[i]); + for (; i < 8; i++) +- printk(" "); ++ printk(KERN_DEBUG " "); + for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) { + if (cmd == sdvo_cmd_names[i].cmd) { +- printk("(%s)", sdvo_cmd_names[i].name); ++ printk(KERN_DEBUG "(%s)", sdvo_cmd_names[i].name); + break; + } + } + if (i == sizeof(sdvo_cmd_names)/ sizeof(sdvo_cmd_names[0])) +- printk("(%02X)",cmd); +- printk("\n"); ++ printk(KERN_DEBUG "(%02X)", cmd); ++ printk(KERN_DEBUG "\n"); + } + #else + #define intel_sdvo_debug_write(o, c, a, l) +@@ -323,17 +323,18 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output, + u8 status) + { + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; ++ int i; + +- DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv)); ++ printk(KERN_DEBUG "%s: R: ", SDVO_NAME(sdvo_priv)); + for (i = 0; i < response_len; i++) +- printk("%02X ", ((u8 *)response)[i]); ++ printk(KERN_DEBUG "%02X ", ((u8 *)response)[i]); + for (; i < 8; i++) +- printk(" "); ++ printk(KERN_DEBUG " "); + if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) +- printk("(%s)", cmd_status_names[status]); ++ printk(KERN_DEBUG "(%s)", cmd_status_names[status]); + else +- printk("(??? %d)", status); +- printk("\n"); ++ printk(KERN_DEBUG "(??? %d)", status); ++ printk(KERN_DEBUG "\n"); + } + #else + #define intel_sdvo_debug_response(o, r, l, s) +@@ -588,9 +589,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, + struct intel_sdvo_preferred_input_timing_args args; + uint8_t status; + ++ memset(&args, 0, sizeof(args)); + args.clock = clock; + args.width = width; + args.height = height; ++ args.interlace = 0; ++ args.scaled = 0; + intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, + &args, sizeof(args)); + status = intel_sdvo_read_response(output, NULL, 0); +@@ -683,7 +687,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, + dtd->part1.v_high = (((height >> 8) & 0xf) << 4) | + ((v_blank_len >> 8) & 0xf); + +- dtd->part2.h_sync_off = h_sync_offset; ++ dtd->part2.h_sync_off = h_sync_offset & 0xff; + dtd->part2.h_sync_width = h_sync_len & 0xff; + dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | + (v_sync_len & 0xf); +@@ -705,27 +709,10 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, + static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, + struct intel_sdvo_dtd *dtd) + { +- uint16_t width, height; +- uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; +- uint16_t h_sync_offset, v_sync_offset; +- +- width = mode->crtc_hdisplay; +- height = mode->crtc_vdisplay; +- +- /* do some mode translations */ +- h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start; +- h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; +- +- v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start; +- v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; +- +- h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; +- v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; +- + mode->hdisplay = dtd->part1.h_active; + mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; + mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; +- mode->hsync_start += (dtd->part2.sync_off_width_high & 0xa0) << 2; ++ mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; + mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; + mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; + mode->htotal = mode->hdisplay + dtd->part1.h_blank; +@@ -735,7 +722,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, + mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; + mode->vsync_start = mode->vdisplay; + mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; +- mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0a) << 2; ++ mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; + mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; + mode->vsync_end = mode->vsync_start + + (dtd->part2.v_sync_off_width & 0xf); +@@ -745,7 +732,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, + + mode->clock = dtd->part1.clock * 10; + +- mode->flags &= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); ++ mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); + if (dtd->part2.dtd_flags & 0x2) + mode->flags |= DRM_MODE_FLAG_PHSYNC; + if (dtd->part2.dtd_flags & 0x4) +@@ -924,6 +911,27 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output, + SDVO_HBUF_TX_VSYNC); + } + ++static void intel_sdvo_set_tv_format(struct intel_output *output) ++{ ++ struct intel_sdvo_priv *sdvo_priv = output->dev_priv; ++ struct intel_sdvo_tv_format *format, unset; ++ u8 status; ++ ++ format = &sdvo_priv->tv_format; ++ memset(&unset, 0, sizeof(unset)); ++ if (memcmp(format, &unset, sizeof(*format))) { ++ DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n", ++ SDVO_NAME(sdvo_priv)); ++ format->ntsc_m = 1; ++ intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format, ++ sizeof(*format)); ++ status = intel_sdvo_read_response(output, NULL, 0); ++ if (status != SDVO_CMD_STATUS_SUCCESS) ++ DRM_DEBUG("%s: Failed to set TV format\n", ++ SDVO_NAME(sdvo_priv)); ++ } ++} ++ + static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +@@ -968,6 +976,12 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, + &input_dtd); + intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); + ++ drm_mode_set_crtcinfo(adjusted_mode, 0); ++ ++ mode->clock = adjusted_mode->clock; ++ ++ adjusted_mode->clock *= ++ intel_sdvo_get_pixel_multiplier(mode); + } else { + return false; + } +@@ -1012,7 +1026,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, + sdvox |= SDVO_AUDIO_ENABLE; + } + +- intel_sdvo_get_dtd_from_mode(&input_dtd, mode); ++ /* We have tried to get input timing in mode_fixup, and filled into ++ adjusted_mode */ ++ if (sdvo_priv->is_tv) ++ intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); ++ else ++ intel_sdvo_get_dtd_from_mode(&input_dtd, mode); + + /* If it's a TV, we already set the output timing in mode_fixup. + * Otherwise, the output timing is equal to the input timing. +@@ -1027,6 +1046,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, + /* Set the input timing to the screen. Assume always input 0. */ + intel_sdvo_set_target_input(output, true, false); + ++ if (sdvo_priv->is_tv) ++ intel_sdvo_set_tv_format(output); ++ + /* We would like to use intel_sdvo_create_preferred_input_timing() to + * provide the device with a timing it can support, if it supports that + * feature. However, presumably we would need to adjust the CRTC to +@@ -1395,7 +1417,7 @@ static void + intel_sdvo_check_tv_format(struct intel_output *output) + { + struct intel_sdvo_priv *dev_priv = output->dev_priv; +- struct intel_sdvo_tv_format format, unset; ++ struct intel_sdvo_tv_format format; + uint8_t status; + + intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); +@@ -1403,15 +1425,7 @@ intel_sdvo_check_tv_format(struct intel_output *output) + if (status != SDVO_CMD_STATUS_SUCCESS) + return; + +- memset(&unset, 0, sizeof(unset)); +- if (memcmp(&format, &unset, sizeof(format))) { +- DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n", +- SDVO_NAME(dev_priv)); +- +- format.ntsc_m = true; +- intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0); +- status = intel_sdvo_read_response(output, NULL, 0); +- } ++ memcpy(&dev_priv->tv_format, &format, sizeof(format)); + } + + /* +@@ -1420,68 +1434,70 @@ intel_sdvo_check_tv_format(struct intel_output *output) + * XXX: all 60Hz refresh? + */ + struct drm_display_mode sdvo_tv_modes[] = { +- { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815680, 321, 384, 416, +- 200, 0, 232, 201, 233, 4196112, 0, ++ { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384, ++ 416, 0, 200, 201, 232, 233, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814080, 321, 384, 416, +- 240, 0, 272, 241, 273, 4196112, 0, ++ { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384, ++ 416, 0, 240, 241, 272, 273, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910080, 401, 464, 496, +- 300, 0, 332, 301, 333, 4196112, 0, ++ { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464, ++ 496, 0, 300, 301, 332, 333, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913280, 641, 704, 736, +- 350, 0, 382, 351, 383, 4196112, 0, ++ { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704, ++ 736, 0, 350, 351, 382, 383, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736, +- 400, 0, 432, 401, 433, 4196112, 0, ++ { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704, ++ 736, 0, 400, 401, 432, 433, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736, +- 400, 0, 432, 401, 433, 4196112, 0, ++ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704, ++ 736, 0, 480, 481, 512, 513, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624000, 705, 768, 800, +- 480, 0, 512, 481, 513, 4196112, 0, ++ { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768, ++ 800, 0, 480, 481, 512, 513, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232000, 705, 768, 800, +- 576, 0, 608, 577, 609, 4196112, 0, ++ { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768, ++ 800, 0, 576, 577, 608, 609, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751680, 721, 784, 816, +- 350, 0, 382, 351, 383, 4196112, 0, ++ { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784, ++ 816, 0, 350, 351, 382, 383, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199680, 721, 784, 816, +- 400, 0, 432, 401, 433, 4196112, 0, ++ { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784, ++ 816, 0, 400, 401, 432, 433, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116480, 721, 784, 816, +- 480, 0, 512, 481, 513, 4196112, 0, ++ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784, ++ 816, 0, 480, 481, 512, 513, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054080, 721, 784, 816, +- 540, 0, 572, 541, 573, 4196112, 0, ++ { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784, ++ 816, 0, 540, 541, 572, 573, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816640, 721, 784, 816, +- 576, 0, 608, 577, 609, 4196112, 0, ++ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784, ++ 816, 0, 576, 577, 608, 609, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570560, 769, 832, 864, +- 576, 0, 608, 577, 609, 4196112, 0, ++ { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832, ++ 864, 0, 576, 577, 608, 609, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030080, 801, 864, 896, +- 600, 0, 632, 601, 633, 4196112, 0, ++ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864, ++ 896, 0, 600, 601, 632, 633, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581760, 833, 896, 928, +- 624, 0, 656, 625, 657, 4196112, 0, ++ { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896, ++ 928, 0, 624, 625, 656, 657, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707040, 921, 984, 1016, +- 766, 0, 798, 767, 799, 4196112, 0, ++ { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984, ++ 1016, 0, 766, 767, 798, 799, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827200, 1025, 1088, 1120, +- 768, 0, 800, 769, 801, 4196112, 0, ++ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088, ++ 1120, 0, 768, 769, 800, 801, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265920, 1281, 1344, 1376, +- 1024, 0, 1056, 1025, 1057, 4196112, 0, ++ { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344, ++ 1376, 0, 1024, 1025, 1056, 1057, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + }; + + static void intel_sdvo_get_tv_modes(struct drm_connector *connector) + { + struct intel_output *output = to_intel_output(connector); ++ struct intel_sdvo_priv *sdvo_priv = output->dev_priv; ++ struct intel_sdvo_sdtv_resolution_request tv_res; + uint32_t reply = 0; + uint8_t status; + int i = 0; +@@ -1491,15 +1507,22 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) + /* Read the list of supported input resolutions for the selected TV + * format. + */ ++ memset(&tv_res, 0, sizeof(tv_res)); ++ memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res)); + intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, +- NULL, 0); ++ &tv_res, sizeof(tv_res)); + status = intel_sdvo_read_response(output, &reply, 3); + if (status != SDVO_CMD_STATUS_SUCCESS) + return; + + for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) +- if (reply & (1 << i)) +- drm_mode_probed_add(connector, &sdvo_tv_modes[i]); ++ if (reply & (1 << i)) { ++ struct drm_display_mode *nmode; ++ nmode = drm_mode_duplicate(connector->dev, ++ &sdvo_tv_modes[i]); ++ if (nmode) ++ drm_mode_probed_add(connector, nmode); ++ } + } + + static int intel_sdvo_get_modes(struct drm_connector *connector) +diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h +index 1117b9c..193938b 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h ++++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h +@@ -100,6 +100,9 @@ struct intel_sdvo_preferred_input_timing_args { + u16 clock; + u16 width; + u16 height; ++ u8 interlace:1; ++ u8 scaled:1; ++ u8 pad:6; + } __attribute__((packed)); + + /* I2C registers for SDVO */ +diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c +index 56485d6..d2c3298 100644 +--- a/drivers/gpu/drm/i915/intel_tv.c ++++ b/drivers/gpu/drm/i915/intel_tv.c +@@ -217,8 +217,8 @@ static const u32 filter_table[] = { + */ + static const struct color_conversion ntsc_m_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, +- .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00, +- .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00, ++ .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200, ++ .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200, + }; + + static const struct video_levels ntsc_m_levels_composite = { +@@ -226,9 +226,9 @@ static const struct video_levels ntsc_m_levels_composite = { + }; + + static const struct color_conversion ntsc_m_csc_svideo = { +- .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134, +- .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00, +- .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00, ++ .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133, ++ .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200, ++ .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200, + }; + + static const struct video_levels ntsc_m_levels_svideo = { +@@ -237,8 +237,8 @@ static const struct video_levels ntsc_m_levels_svideo = { + + static const struct color_conversion ntsc_j_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119, +- .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0f00, +- .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0f00, ++ .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200, ++ .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200, + }; + + static const struct video_levels ntsc_j_levels_composite = { +@@ -247,8 +247,8 @@ static const struct video_levels ntsc_j_levels_composite = { + + static const struct color_conversion ntsc_j_csc_svideo = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c, +- .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0f00, +- .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0f00, ++ .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200, ++ .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200, + }; + + static const struct video_levels ntsc_j_levels_svideo = { +@@ -257,8 +257,8 @@ static const struct video_levels ntsc_j_levels_svideo = { + + static const struct color_conversion pal_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113, +- .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0f00, +- .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0f00, ++ .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200, ++ .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200, + }; + + static const struct video_levels pal_levels_composite = { +@@ -267,8 +267,8 @@ static const struct video_levels pal_levels_composite = { + + static const struct color_conversion pal_csc_svideo = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145, +- .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0f00, +- .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0f00, ++ .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200, ++ .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200, + }; + + static const struct video_levels pal_levels_svideo = { +@@ -277,8 +277,8 @@ static const struct video_levels pal_levels_svideo = { + + static const struct color_conversion pal_m_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, +- .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00, +- .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00, ++ .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200, ++ .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200, + }; + + static const struct video_levels pal_m_levels_composite = { +@@ -286,9 +286,9 @@ static const struct video_levels pal_m_levels_composite = { + }; + + static const struct color_conversion pal_m_csc_svideo = { +- .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134, +- .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00, +- .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00, ++ .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133, ++ .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200, ++ .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200, + }; + + static const struct video_levels pal_m_levels_svideo = { +@@ -297,8 +297,8 @@ static const struct video_levels pal_m_levels_svideo = { + + static const struct color_conversion pal_n_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, +- .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00, +- .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00, ++ .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200, ++ .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200, + }; + + static const struct video_levels pal_n_levels_composite = { +@@ -306,9 +306,9 @@ static const struct video_levels pal_n_levels_composite = { + }; + + static const struct color_conversion pal_n_csc_svideo = { +- .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134, +- .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00, +- .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00, ++ .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133, ++ .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200, ++ .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200, + }; + + static const struct video_levels pal_n_levels_svideo = { +@@ -319,9 +319,9 @@ static const struct video_levels pal_n_levels_svideo = { + * Component connections + */ + static const struct color_conversion sdtv_csc_yprpb = { +- .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0146, +- .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0f00, +- .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0f00, ++ .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145, ++ .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200, ++ .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200, + }; + + static const struct color_conversion sdtv_csc_rgb = { +@@ -331,9 +331,9 @@ static const struct color_conversion sdtv_csc_rgb = { + }; + + static const struct color_conversion hdtv_csc_yprpb = { +- .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0146, +- .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0f00, +- .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0f00, ++ .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145, ++ .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200, ++ .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200, + }; + + static const struct color_conversion hdtv_csc_rgb = { +@@ -414,7 +414,7 @@ struct tv_mode { + static const struct tv_mode tv_modes[] = { + { + .name = "NTSC-M", +- .clock = 107520, ++ .clock = 108000, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, +@@ -442,8 +442,8 @@ static const struct tv_mode tv_modes[] = { + .vburst_start_f4 = 10, .vburst_end_f4 = 240, + + /* desired 3.5800000 actual 3.5800000 clock 107.52 */ +- .dda1_inc = 136, +- .dda2_inc = 7624, .dda2_size = 20013, ++ .dda1_inc = 135, ++ .dda2_inc = 20800, .dda2_size = 27456, + .dda3_inc = 0, .dda3_size = 0, + .sc_reset = TV_SC_RESET_EVERY_4, + .pal_burst = false, +@@ -457,7 +457,7 @@ static const struct tv_mode tv_modes[] = { + }, + { + .name = "NTSC-443", +- .clock = 107520, ++ .clock = 108000, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, +@@ -485,10 +485,10 @@ static const struct tv_mode tv_modes[] = { + + /* desired 4.4336180 actual 4.4336180 clock 107.52 */ + .dda1_inc = 168, +- .dda2_inc = 18557, .dda2_size = 20625, +- .dda3_inc = 0, .dda3_size = 0, +- .sc_reset = TV_SC_RESET_EVERY_8, +- .pal_burst = true, ++ .dda2_inc = 4093, .dda2_size = 27456, ++ .dda3_inc = 310, .dda3_size = 525, ++ .sc_reset = TV_SC_RESET_NEVER, ++ .pal_burst = false, + + .composite_levels = &ntsc_m_levels_composite, + .composite_color = &ntsc_m_csc_composite, +@@ -499,7 +499,7 @@ static const struct tv_mode tv_modes[] = { + }, + { + .name = "NTSC-J", +- .clock = 107520, ++ .clock = 108000, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, +@@ -527,8 +527,8 @@ static const struct tv_mode tv_modes[] = { + .vburst_start_f4 = 10, .vburst_end_f4 = 240, + + /* desired 3.5800000 actual 3.5800000 clock 107.52 */ +- .dda1_inc = 136, +- .dda2_inc = 7624, .dda2_size = 20013, ++ .dda1_inc = 135, ++ .dda2_inc = 20800, .dda2_size = 27456, + .dda3_inc = 0, .dda3_size = 0, + .sc_reset = TV_SC_RESET_EVERY_4, + .pal_burst = false, +@@ -542,7 +542,7 @@ static const struct tv_mode tv_modes[] = { + }, + { + .name = "PAL-M", +- .clock = 107520, ++ .clock = 108000, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, +@@ -570,11 +570,11 @@ static const struct tv_mode tv_modes[] = { + .vburst_start_f4 = 10, .vburst_end_f4 = 240, + + /* desired 3.5800000 actual 3.5800000 clock 107.52 */ +- .dda1_inc = 136, +- .dda2_inc = 7624, .dda2_size = 20013, ++ .dda1_inc = 135, ++ .dda2_inc = 16704, .dda2_size = 27456, + .dda3_inc = 0, .dda3_size = 0, +- .sc_reset = TV_SC_RESET_EVERY_4, +- .pal_burst = false, ++ .sc_reset = TV_SC_RESET_EVERY_8, ++ .pal_burst = true, + + .composite_levels = &pal_m_levels_composite, + .composite_color = &pal_m_csc_composite, +@@ -586,7 +586,7 @@ static const struct tv_mode tv_modes[] = { + { + /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ + .name = "PAL-N", +- .clock = 107520, ++ .clock = 108000, + .refresh = 25000, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, +@@ -615,9 +615,9 @@ static const struct tv_mode tv_modes[] = { + + + /* desired 4.4336180 actual 4.4336180 clock 107.52 */ +- .dda1_inc = 168, +- .dda2_inc = 18557, .dda2_size = 20625, +- .dda3_inc = 0, .dda3_size = 0, ++ .dda1_inc = 135, ++ .dda2_inc = 23578, .dda2_size = 27648, ++ .dda3_inc = 134, .dda3_size = 625, + .sc_reset = TV_SC_RESET_EVERY_8, + .pal_burst = true, + +@@ -631,12 +631,12 @@ static const struct tv_mode tv_modes[] = { + { + /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ + .name = "PAL", +- .clock = 107520, ++ .clock = 108000, + .refresh = 25000, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, + +- .hsync_end = 64, .hblank_end = 128, ++ .hsync_end = 64, .hblank_end = 142, + .hblank_start = 844, .htotal = 863, + + .progressive = false, .trilevel_sync = false, +@@ -659,8 +659,8 @@ static const struct tv_mode tv_modes[] = { + + /* desired 4.4336180 actual 4.4336180 clock 107.52 */ + .dda1_inc = 168, +- .dda2_inc = 18557, .dda2_size = 20625, +- .dda3_inc = 0, .dda3_size = 0, ++ .dda2_inc = 4122, .dda2_size = 27648, ++ .dda3_inc = 67, .dda3_size = 625, + .sc_reset = TV_SC_RESET_EVERY_8, + .pal_burst = true, + +@@ -689,7 +689,7 @@ static const struct tv_mode tv_modes[] = { + .veq_ena = false, + + .vi_end_f1 = 44, .vi_end_f2 = 44, +- .nbr_end = 496, ++ .nbr_end = 479, + + .burst_ena = false, + +@@ -713,7 +713,7 @@ static const struct tv_mode tv_modes[] = { + .veq_ena = false, + + .vi_end_f1 = 44, .vi_end_f2 = 44, +- .nbr_end = 496, ++ .nbr_end = 479, + + .burst_ena = false, + +@@ -876,7 +876,7 @@ static const struct tv_mode tv_modes[] = { + .component_only = 1, + + .hsync_end = 88, .hblank_end = 235, +- .hblank_start = 2155, .htotal = 2200, ++ .hblank_start = 2155, .htotal = 2201, + + .progressive = false, .trilevel_sync = true, + +@@ -1082,7 +1082,7 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mo + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + + /* Ensure TV refresh is close to desired refresh */ +- if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 1) ++ if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 10) + return MODE_OK; + return MODE_CLOCK_RANGE; + } +@@ -1135,7 +1135,8 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + if (!tv_mode) + return; /* can't happen (mode_prepare prevents this) */ + +- tv_ctl = 0; ++ tv_ctl = I915_READ(TV_CTL); ++ tv_ctl &= TV_CTL_SAVE; + + switch (tv_priv->type) { + default: +@@ -1215,7 +1216,6 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + /* dda1 implies valid video levels */ + if (tv_mode->dda1_inc) { + scctl1 |= TV_SC_DDA1_EN; +- scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; + } + + if (tv_mode->dda2_inc) +@@ -1225,6 +1225,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + scctl1 |= TV_SC_DDA3_EN; + + scctl1 |= tv_mode->sc_reset; ++ scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; + scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; + + scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | +@@ -1266,7 +1267,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + color_conversion->av); + } + +- I915_WRITE(TV_CLR_KNOBS, 0x00606000); ++ if (IS_I965G(dev)) ++ I915_WRITE(TV_CLR_KNOBS, 0x00404000); ++ else ++ I915_WRITE(TV_CLR_KNOBS, 0x00606000); ++ + if (video_levels) + I915_WRITE(TV_CLR_LEVEL, + ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | +@@ -1401,6 +1406,7 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) + tv_dac = I915_READ(TV_DAC); + I915_WRITE(TV_DAC, save_tv_dac); + I915_WRITE(TV_CTL, save_tv_ctl); ++ intel_wait_for_vblank(dev); + } + /* + * A B C +@@ -1451,7 +1457,7 @@ intel_tv_detect(struct drm_connector *connector) + mode = reported_modes[0]; + drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); + +- if (encoder->crtc) { ++ if (encoder->crtc && encoder->crtc->enabled) { + type = intel_tv_detect_type(encoder->crtc, intel_output); + } else { + crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode); +@@ -1462,6 +1468,8 @@ intel_tv_detect(struct drm_connector *connector) + type = -1; + } + ++ tv_priv->type = type; ++ + if (type < 0) + return connector_status_disconnected; + +@@ -1495,7 +1503,8 @@ intel_tv_get_modes(struct drm_connector *connector) + struct drm_display_mode *mode_ptr; + struct intel_output *intel_output = to_intel_output(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); +- int j; ++ int j, count = 0; ++ u64 tmp; + + for (j = 0; j < sizeof(input_res_table) / sizeof(input_res_table[0]); + j++) { +@@ -1510,8 +1519,9 @@ intel_tv_get_modes(struct drm_connector *connector) + && !tv_mode->component_only)) + continue; + +- mode_ptr = drm_calloc(1, sizeof(struct drm_display_mode), +- DRM_MEM_DRIVER); ++ mode_ptr = drm_mode_create(connector->dev); ++ if (!mode_ptr) ++ continue; + strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN); + + mode_ptr->hdisplay = hactive_s; +@@ -1528,15 +1538,17 @@ intel_tv_get_modes(struct drm_connector *connector) + mode_ptr->vsync_end = mode_ptr->vsync_start + 1; + mode_ptr->vtotal = vactive_s + 33; + +- mode_ptr->clock = (int) (tv_mode->refresh * +- mode_ptr->vtotal * +- mode_ptr->htotal / 1000) / 1000; ++ tmp = (u64) tv_mode->refresh * mode_ptr->vtotal; ++ tmp *= mode_ptr->htotal; ++ tmp = div_u64(tmp, 1000000); ++ mode_ptr->clock = (int) tmp; + + mode_ptr->type = DRM_MODE_TYPE_DRIVER; + drm_mode_probed_add(connector, mode_ptr); ++ count++; + } + +- return 0; ++ return count; + } + + static void +@@ -1558,33 +1570,49 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop + struct drm_device *dev = connector->dev; + struct intel_output *intel_output = to_intel_output(connector); + struct intel_tv_priv *tv_priv = intel_output->dev_priv; ++ struct drm_encoder *encoder = &intel_output->enc; ++ struct drm_crtc *crtc = encoder->crtc; + int ret = 0; ++ bool changed = false; + + ret = drm_connector_property_set_value(connector, property, val); + if (ret < 0) + goto out; + +- if (property == dev->mode_config.tv_left_margin_property) ++ if (property == dev->mode_config.tv_left_margin_property && ++ tv_priv->margin[TV_MARGIN_LEFT] != val) { + tv_priv->margin[TV_MARGIN_LEFT] = val; +- else if (property == dev->mode_config.tv_right_margin_property) ++ changed = true; ++ } else if (property == dev->mode_config.tv_right_margin_property && ++ tv_priv->margin[TV_MARGIN_RIGHT] != val) { + tv_priv->margin[TV_MARGIN_RIGHT] = val; +- else if (property == dev->mode_config.tv_top_margin_property) ++ changed = true; ++ } else if (property == dev->mode_config.tv_top_margin_property && ++ tv_priv->margin[TV_MARGIN_TOP] != val) { + tv_priv->margin[TV_MARGIN_TOP] = val; +- else if (property == dev->mode_config.tv_bottom_margin_property) ++ changed = true; ++ } else if (property == dev->mode_config.tv_bottom_margin_property && ++ tv_priv->margin[TV_MARGIN_BOTTOM] != val) { + tv_priv->margin[TV_MARGIN_BOTTOM] = val; +- else if (property == dev->mode_config.tv_mode_property) { ++ changed = true; ++ } else if (property == dev->mode_config.tv_mode_property) { + if (val >= NUM_TV_MODES) { + ret = -EINVAL; + goto out; + } ++ if (!strcmp(tv_priv->tv_format, tv_modes[val].name)) ++ goto out; ++ + tv_priv->tv_format = tv_modes[val].name; +- intel_tv_mode_set(&intel_output->enc, NULL, NULL); ++ changed = true; + } else { + ret = -EINVAL; + goto out; + } + +- intel_tv_mode_set(&intel_output->enc, NULL, NULL); ++ if (changed && crtc) ++ drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, ++ crtc->y, crtc->fb, 0); + out: + return ret; + } +diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c +index b49c5ff..7a6bf9f 100644 +--- a/drivers/gpu/drm/mga/mga_dma.c ++++ b/drivers/gpu/drm/mga/mga_dma.c +@@ -148,8 +148,8 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv) + primary->space = head - tail; + } + +- DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset); +- DRM_DEBUG(" tail = 0x%06lx\n", tail - dev_priv->primary->offset); ++ DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); ++ DRM_DEBUG(" tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset)); + DRM_DEBUG(" space = 0x%06x\n", primary->space); + + mga_flush_write_combine(); +@@ -187,7 +187,7 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) + primary->space = head - dev_priv->primary->offset; + } + +- DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset); ++ DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); + DRM_DEBUG(" tail = 0x%06x\n", primary->tail); + DRM_DEBUG(" wrap = %d\n", primary->last_wrap); + DRM_DEBUG(" space = 0x%06x\n", primary->space); +@@ -239,7 +239,7 @@ static void mga_freelist_print(struct drm_device * dev) + for (entry = dev_priv->head->next; entry; entry = entry->next) { + DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n", + entry, entry->buf->idx, entry->age.head, +- entry->age.head - dev_priv->primary->offset); ++ (unsigned long)(entry->age.head - dev_priv->primary->offset)); + } + DRM_INFO("\n"); + } +@@ -340,10 +340,10 @@ static struct drm_buf *mga_freelist_get(struct drm_device * dev) + + DRM_DEBUG(" tail=0x%06lx %d\n", + tail->age.head ? +- tail->age.head - dev_priv->primary->offset : 0, ++ (unsigned long)(tail->age.head - dev_priv->primary->offset) : 0, + tail->age.wrap); + DRM_DEBUG(" head=0x%06lx %d\n", +- head - dev_priv->primary->offset, wrap); ++ (unsigned long)(head - dev_priv->primary->offset), wrap); + + if (TEST_AGE(&tail->age, head, wrap)) { + prev = dev_priv->tail->prev; +@@ -366,8 +366,9 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf) + drm_mga_freelist_t *head, *entry, *prev; + + DRM_DEBUG("age=0x%06lx wrap=%d\n", +- buf_priv->list_entry->age.head - +- dev_priv->primary->offset, buf_priv->list_entry->age.wrap); ++ (unsigned long)(buf_priv->list_entry->age.head - ++ dev_priv->primary->offset), ++ buf_priv->list_entry->age.wrap); + + entry = buf_priv->list_entry; + head = dev_priv->head; +diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h +index 88257c2..3d264f2 100644 +--- a/drivers/gpu/drm/mga/mga_drv.h ++++ b/drivers/gpu/drm/mga/mga_drv.h +@@ -113,8 +113,8 @@ typedef struct drm_mga_private { + * \sa drm_mga_private_t::mmio + */ + /*@{ */ +- u32 mmio_base; /**< Bus address of base of MMIO. */ +- u32 mmio_size; /**< Size of the MMIO region. */ ++ resource_size_t mmio_base; /**< Bus address of base of MMIO. */ ++ resource_size_t mmio_size; /**< Size of the MMIO region. */ + /*@} */ + + u32 clear_cmd; +@@ -317,8 +317,8 @@ do { \ + DRM_INFO( "\n" ); \ + DRM_INFO( " tail=0x%06x head=0x%06lx\n", \ + dev_priv->prim.tail, \ +- MGA_READ( MGA_PRIMADDRESS ) - \ +- dev_priv->primary->offset ); \ ++ (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \ ++ dev_priv->primary->offset)); \ + } \ + if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) { \ + if ( dev_priv->prim.space < \ +diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c +index c31afbd..32de4ce 100644 +--- a/drivers/gpu/drm/r128/r128_cce.c ++++ b/drivers/gpu/drm/r128/r128_cce.c +@@ -525,11 +525,12 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) + } else + #endif + { +- dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset; ++ dev_priv->cce_ring->handle = ++ (void *)(unsigned long)dev_priv->cce_ring->offset; + dev_priv->ring_rptr->handle = +- (void *)dev_priv->ring_rptr->offset; ++ (void *)(unsigned long)dev_priv->ring_rptr->offset; + dev->agp_buffer_map->handle = +- (void *)dev->agp_buffer_map->offset; ++ (void *)(unsigned long)dev->agp_buffer_map->offset; + } + + #if __OS_HAS_AGP +diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile +index feb521e..52ce439 100644 +--- a/drivers/gpu/drm/radeon/Makefile ++++ b/drivers/gpu/drm/radeon/Makefile +@@ -3,7 +3,7 @@ + # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + + ccflags-y := -Iinclude/drm +-radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o ++radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o r600_cp.o + + radeon-$(CONFIG_COMPAT) += radeon_ioc32.o + +diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c +index cace396..cb2e470 100644 +--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c ++++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c +@@ -37,6 +37,8 @@ + #include "radeon_drv.h" + #include "r300_reg.h" + ++#include ++ + #define R300_SIMULTANEOUS_CLIPRECTS 4 + + /* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects +@@ -205,6 +207,10 @@ void r300_init_reg_flags(struct drm_device *dev) + ADD_RANGE(0x42C0, 2); + ADD_RANGE(R300_RS_CNTL_0, 2); + ++ ADD_RANGE(R300_SU_REG_DEST, 1); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ++ ADD_RANGE(RV530_FG_ZBREG_DEST, 1); ++ + ADD_RANGE(R300_SC_HYPERZ, 2); + ADD_RANGE(0x43E8, 1); + +@@ -230,6 +236,7 @@ void r300_init_reg_flags(struct drm_device *dev) + ADD_RANGE(R300_ZB_DEPTHPITCH, 1); + ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1); + ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13); ++ ADD_RANGE(R300_ZB_ZPASS_DATA, 2); /* ZB_ZPASS_DATA, ZB_ZPASS_ADDR */ + + ADD_RANGE(R300_TX_FILTER_0, 16); + ADD_RANGE(R300_TX_FILTER1_0, 16); +@@ -917,6 +924,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, + { + u32 *ref_age_base; + u32 i, buf_idx, h_pending; ++ u64 ptr_addr; + RING_LOCALS; + + if (cmdbuf->bufsz < +@@ -930,7 +938,8 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, + + dev_priv->scratch_ages[header.scratch.reg]++; + +- ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf); ++ ptr_addr = get_unaligned((u64 *)cmdbuf->buf); ++ ref_age_base = (u32 *)(unsigned long)ptr_addr; + + cmdbuf->buf += sizeof(u64); + cmdbuf->bufsz -= sizeof(u64); +diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h +index ee6f811..bdbc95f 100644 +--- a/drivers/gpu/drm/radeon/r300_reg.h ++++ b/drivers/gpu/drm/radeon/r300_reg.h +@@ -1770,4 +1770,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. + #define R500_RB3D_COLOR_CLEAR_VALUE_AR 0x46c0 + #define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8 + ++#define R300_SU_REG_DEST 0x42c8 ++#define RV530_FG_ZBREG_DEST 0x4be8 ++#define R300_ZB_ZPASS_DATA 0x4f58 ++#define R300_ZB_ZPASS_ADDR 0x4f5c ++ + #endif /* _R300_REG_H */ +diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c +new file mode 100644 +index 0000000..bc9d09d +--- /dev/null ++++ b/drivers/gpu/drm/radeon/r600_cp.c +@@ -0,0 +1,2253 @@ ++/* ++ * Copyright 2008-2009 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * Dave Airlie ++ * Alex Deucher ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++#include "r600_microcode.h" ++ ++# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ ++# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) ++ ++#define R600_PTE_VALID (1 << 0) ++#define R600_PTE_SYSTEM (1 << 1) ++#define R600_PTE_SNOOPED (1 << 2) ++#define R600_PTE_READABLE (1 << 5) ++#define R600_PTE_WRITEABLE (1 << 6) ++ ++/* MAX values used for gfx init */ ++#define R6XX_MAX_SH_GPRS 256 ++#define R6XX_MAX_TEMP_GPRS 16 ++#define R6XX_MAX_SH_THREADS 256 ++#define R6XX_MAX_SH_STACK_ENTRIES 4096 ++#define R6XX_MAX_BACKENDS 8 ++#define R6XX_MAX_BACKENDS_MASK 0xff ++#define R6XX_MAX_SIMDS 8 ++#define R6XX_MAX_SIMDS_MASK 0xff ++#define R6XX_MAX_PIPES 8 ++#define R6XX_MAX_PIPES_MASK 0xff ++ ++#define R7XX_MAX_SH_GPRS 256 ++#define R7XX_MAX_TEMP_GPRS 16 ++#define R7XX_MAX_SH_THREADS 256 ++#define R7XX_MAX_SH_STACK_ENTRIES 4096 ++#define R7XX_MAX_BACKENDS 8 ++#define R7XX_MAX_BACKENDS_MASK 0xff ++#define R7XX_MAX_SIMDS 16 ++#define R7XX_MAX_SIMDS_MASK 0xffff ++#define R7XX_MAX_PIPES 8 ++#define R7XX_MAX_PIPES_MASK 0xff ++ ++static int r600_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries) ++{ ++ int i; ++ ++ dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; ++ ++ for (i = 0; i < dev_priv->usec_timeout; i++) { ++ int slots; ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) ++ slots = (RADEON_READ(R600_GRBM_STATUS) ++ & R700_CMDFIFO_AVAIL_MASK); ++ else ++ slots = (RADEON_READ(R600_GRBM_STATUS) ++ & R600_CMDFIFO_AVAIL_MASK); ++ if (slots >= entries) ++ return 0; ++ DRM_UDELAY(1); ++ } ++ DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n", ++ RADEON_READ(R600_GRBM_STATUS), ++ RADEON_READ(R600_GRBM_STATUS2)); ++ ++ return -EBUSY; ++} ++ ++static int r600_do_wait_for_idle(drm_radeon_private_t *dev_priv) ++{ ++ int i, ret; ++ ++ dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) ++ ret = r600_do_wait_for_fifo(dev_priv, 8); ++ else ++ ret = r600_do_wait_for_fifo(dev_priv, 16); ++ if (ret) ++ return ret; ++ for (i = 0; i < dev_priv->usec_timeout; i++) { ++ if (!(RADEON_READ(R600_GRBM_STATUS) & R600_GUI_ACTIVE)) ++ return 0; ++ DRM_UDELAY(1); ++ } ++ DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n", ++ RADEON_READ(R600_GRBM_STATUS), ++ RADEON_READ(R600_GRBM_STATUS2)); ++ ++ return -EBUSY; ++} ++ ++void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) ++{ ++ struct drm_sg_mem *entry = dev->sg; ++ int max_pages; ++ int pages; ++ int i; ++ ++ if (!entry) ++ return; ++ ++ if (gart_info->bus_addr) { ++ max_pages = (gart_info->table_size / sizeof(u64)); ++ pages = (entry->pages <= max_pages) ++ ? entry->pages : max_pages; ++ ++ for (i = 0; i < pages; i++) { ++ if (!entry->busaddr[i]) ++ break; ++ pci_unmap_page(dev->pdev, entry->busaddr[i], ++ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); ++ } ++ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) ++ gart_info->bus_addr = 0; ++ } ++} ++ ++/* R600 has page table setup */ ++int r600_page_table_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; ++ struct drm_local_map *map = &gart_info->mapping; ++ struct drm_sg_mem *entry = dev->sg; ++ int ret = 0; ++ int i, j; ++ int pages; ++ u64 page_base; ++ dma_addr_t entry_addr; ++ int max_ati_pages, max_real_pages, gart_idx; ++ ++ /* okay page table is available - lets rock */ ++ max_ati_pages = (gart_info->table_size / sizeof(u64)); ++ max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); ++ ++ pages = (entry->pages <= max_real_pages) ? ++ entry->pages : max_real_pages; ++ ++ memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u64)); ++ ++ gart_idx = 0; ++ for (i = 0; i < pages; i++) { ++ entry->busaddr[i] = pci_map_page(dev->pdev, ++ entry->pagelist[i], 0, ++ PAGE_SIZE, ++ PCI_DMA_BIDIRECTIONAL); ++ if (entry->busaddr[i] == 0) { ++ DRM_ERROR("unable to map PCIGART pages!\n"); ++ r600_page_table_cleanup(dev, gart_info); ++ goto done; ++ } ++ entry_addr = entry->busaddr[i]; ++ for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { ++ page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK; ++ page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; ++ page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE; ++ ++ DRM_WRITE64(map, gart_idx * sizeof(u64), page_base); ++ ++ gart_idx++; ++ ++ if ((i % 128) == 0) ++ DRM_DEBUG("page entry %d: 0x%016llx\n", ++ i, (unsigned long long)page_base); ++ entry_addr += ATI_PCIGART_PAGE_SIZE; ++ } ++ } ++ ret = 1; ++done: ++ return ret; ++} ++ ++static void r600_vm_flush_gart_range(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ u32 resp, countdown = 1000; ++ RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR, dev_priv->gart_vm_start >> 12); ++ RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); ++ RADEON_WRITE(R600_VM_CONTEXT0_REQUEST_RESPONSE, 2); ++ ++ do { ++ resp = RADEON_READ(R600_VM_CONTEXT0_REQUEST_RESPONSE); ++ countdown--; ++ DRM_UDELAY(1); ++ } while (((resp & 0xf0) == 0) && countdown); ++} ++ ++static void r600_vm_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ /* initialise the VM to use the page table we constructed up there */ ++ u32 vm_c0, i; ++ u32 mc_rd_a; ++ u32 vm_l2_cntl, vm_l2_cntl3; ++ /* okay set up the PCIE aperture type thingo */ ++ RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); ++ RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); ++ RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); ++ ++ /* setup MC RD a */ ++ mc_rd_a = R600_MCD_L1_TLB | R600_MCD_L1_FRAG_PROC | R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS | ++ R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | R600_MCD_EFFECTIVE_L1_TLB_SIZE(5) | ++ R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(5) | R600_MCD_WAIT_L2_QUERY; ++ ++ RADEON_WRITE(R600_MCD_RD_A_CNTL, mc_rd_a); ++ RADEON_WRITE(R600_MCD_RD_B_CNTL, mc_rd_a); ++ ++ RADEON_WRITE(R600_MCD_WR_A_CNTL, mc_rd_a); ++ RADEON_WRITE(R600_MCD_WR_B_CNTL, mc_rd_a); ++ ++ RADEON_WRITE(R600_MCD_RD_GFX_CNTL, mc_rd_a); ++ RADEON_WRITE(R600_MCD_WR_GFX_CNTL, mc_rd_a); ++ ++ RADEON_WRITE(R600_MCD_RD_SYS_CNTL, mc_rd_a); ++ RADEON_WRITE(R600_MCD_WR_SYS_CNTL, mc_rd_a); ++ ++ RADEON_WRITE(R600_MCD_RD_HDP_CNTL, mc_rd_a | R600_MCD_L1_STRICT_ORDERING); ++ RADEON_WRITE(R600_MCD_WR_HDP_CNTL, mc_rd_a /*| R600_MCD_L1_STRICT_ORDERING*/); ++ ++ RADEON_WRITE(R600_MCD_RD_PDMA_CNTL, mc_rd_a); ++ RADEON_WRITE(R600_MCD_WR_PDMA_CNTL, mc_rd_a); ++ ++ RADEON_WRITE(R600_MCD_RD_SEM_CNTL, mc_rd_a | R600_MCD_SEMAPHORE_MODE); ++ RADEON_WRITE(R600_MCD_WR_SEM_CNTL, mc_rd_a); ++ ++ vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; ++ vm_l2_cntl |= R600_VM_L2_CNTL_QUEUE_SIZE(7); ++ RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); ++ ++ RADEON_WRITE(R600_VM_L2_CNTL2, 0); ++ vm_l2_cntl3 = (R600_VM_L2_CNTL3_BANK_SELECT_0(0) | ++ R600_VM_L2_CNTL3_BANK_SELECT_1(1) | ++ R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(2)); ++ RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); ++ ++ vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; ++ ++ RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); ++ ++ vm_c0 &= ~R600_VM_ENABLE_CONTEXT; ++ ++ /* disable all other contexts */ ++ for (i = 1; i < 8; i++) ++ RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); ++ ++ RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); ++ RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); ++ RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); ++ ++ r600_vm_flush_gart_range(dev); ++} ++ ++/* load r600 microcode */ ++static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) ++{ ++ int i; ++ ++ r600_do_cp_stop(dev_priv); ++ ++ RADEON_WRITE(R600_CP_RB_CNTL, ++ R600_RB_NO_UPDATE | ++ R600_RB_BLKSZ(15) | ++ R600_RB_BUFSZ(3)); ++ ++ RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); ++ RADEON_READ(R600_GRBM_SOFT_RESET); ++ DRM_UDELAY(15000); ++ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); ++ ++ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); ++ ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) { ++ DRM_INFO("Loading R600 CP Microcode\n"); ++ for (i = 0; i < PM4_UCODE_SIZE; i++) { ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ R600_cp_microcode[i][0]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ R600_cp_microcode[i][1]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ R600_cp_microcode[i][2]); ++ } ++ ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading R600 PFP Microcode\n"); ++ for (i = 0; i < PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) { ++ DRM_INFO("Loading RV610 CP Microcode\n"); ++ for (i = 0; i < PM4_UCODE_SIZE; i++) { ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV610_cp_microcode[i][0]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV610_cp_microcode[i][1]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV610_cp_microcode[i][2]); ++ } ++ ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading RV610 PFP Microcode\n"); ++ for (i = 0; i < PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { ++ DRM_INFO("Loading RV630 CP Microcode\n"); ++ for (i = 0; i < PM4_UCODE_SIZE; i++) { ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV630_cp_microcode[i][0]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV630_cp_microcode[i][1]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV630_cp_microcode[i][2]); ++ } ++ ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading RV630 PFP Microcode\n"); ++ for (i = 0; i < PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) { ++ DRM_INFO("Loading RV620 CP Microcode\n"); ++ for (i = 0; i < PM4_UCODE_SIZE; i++) { ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV620_cp_microcode[i][0]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV620_cp_microcode[i][1]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV620_cp_microcode[i][2]); ++ } ++ ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading RV620 PFP Microcode\n"); ++ for (i = 0; i < PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { ++ DRM_INFO("Loading RV635 CP Microcode\n"); ++ for (i = 0; i < PM4_UCODE_SIZE; i++) { ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV635_cp_microcode[i][0]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV635_cp_microcode[i][1]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV635_cp_microcode[i][2]); ++ } ++ ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading RV635 PFP Microcode\n"); ++ for (i = 0; i < PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) { ++ DRM_INFO("Loading RV670 CP Microcode\n"); ++ for (i = 0; i < PM4_UCODE_SIZE; i++) { ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV670_cp_microcode[i][0]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV670_cp_microcode[i][1]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RV670_cp_microcode[i][2]); ++ } ++ ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading RV670 PFP Microcode\n"); ++ for (i = 0; i < PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { ++ DRM_INFO("Loading RS780 CP Microcode\n"); ++ for (i = 0; i < PM4_UCODE_SIZE; i++) { ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RS780_cp_microcode[i][0]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RS780_cp_microcode[i][1]); ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, ++ RS780_cp_microcode[i][2]); ++ } ++ ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading RS780 PFP Microcode\n"); ++ for (i = 0; i < PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RS780_pfp_microcode[i]); ++ } ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); ++ RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); ++ ++} ++ ++static void r700_vm_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ /* initialise the VM to use the page table we constructed up there */ ++ u32 vm_c0, i; ++ u32 mc_vm_md_l1; ++ u32 vm_l2_cntl, vm_l2_cntl3; ++ /* okay set up the PCIE aperture type thingo */ ++ RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); ++ RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); ++ RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); ++ ++ mc_vm_md_l1 = R700_ENABLE_L1_TLB | ++ R700_ENABLE_L1_FRAGMENT_PROCESSING | ++ R700_SYSTEM_ACCESS_MODE_IN_SYS | ++ R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | ++ R700_EFFECTIVE_L1_TLB_SIZE(5) | ++ R700_EFFECTIVE_L1_QUEUE_SIZE(5); ++ ++ RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1); ++ RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1); ++ RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1); ++ RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1); ++ RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1); ++ RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1); ++ RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1); ++ ++ vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; ++ vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7); ++ RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); ++ ++ RADEON_WRITE(R600_VM_L2_CNTL2, 0); ++ vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2); ++ RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); ++ ++ vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; ++ ++ RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); ++ ++ vm_c0 &= ~R600_VM_ENABLE_CONTEXT; ++ ++ /* disable all other contexts */ ++ for (i = 1; i < 8; i++) ++ RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); ++ ++ RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); ++ RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); ++ RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); ++ ++ r600_vm_flush_gart_range(dev); ++} ++ ++/* load r600 microcode */ ++static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) ++{ ++ int i; ++ ++ r600_do_cp_stop(dev_priv); ++ ++ RADEON_WRITE(R600_CP_RB_CNTL, ++ R600_RB_NO_UPDATE | ++ (15 << 8) | ++ (3 << 0)); ++ ++ RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); ++ RADEON_READ(R600_GRBM_SOFT_RESET); ++ DRM_UDELAY(15000); ++ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); ++ ++ ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) { ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading RV770 PFP Microcode\n"); ++ for (i = 0; i < R700_PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]); ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ ++ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); ++ DRM_INFO("Loading RV770 CP Microcode\n"); ++ for (i = 0; i < R700_PM4_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]); ++ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); ++ ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730)) { ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading RV730 PFP Microcode\n"); ++ for (i = 0; i < R700_PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]); ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ ++ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); ++ DRM_INFO("Loading RV730 CP Microcode\n"); ++ for (i = 0; i < R700_PM4_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]); ++ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); ++ ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) { ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ DRM_INFO("Loading RV710 PFP Microcode\n"); ++ for (i = 0; i < R700_PFP_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]); ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ ++ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); ++ DRM_INFO("Loading RV710 CP Microcode\n"); ++ for (i = 0; i < R700_PM4_UCODE_SIZE; i++) ++ RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]); ++ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); ++ ++ } ++ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); ++ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); ++ RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); ++ ++} ++ ++static void r600_test_writeback(drm_radeon_private_t *dev_priv) ++{ ++ u32 tmp; ++ ++ /* Start with assuming that writeback doesn't work */ ++ dev_priv->writeback_works = 0; ++ ++ /* Writeback doesn't seem to work everywhere, test it here and possibly ++ * enable it if it appears to work ++ */ ++ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); ++ ++ RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef); ++ ++ for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { ++ u32 val; ++ ++ val = radeon_read_ring_rptr(dev_priv, R600_SCRATCHOFF(1)); ++ if (val == 0xdeadbeef) ++ break; ++ DRM_UDELAY(1); ++ } ++ ++ if (tmp < dev_priv->usec_timeout) { ++ dev_priv->writeback_works = 1; ++ DRM_INFO("writeback test succeeded in %d usecs\n", tmp); ++ } else { ++ dev_priv->writeback_works = 0; ++ DRM_INFO("writeback test failed\n"); ++ } ++ if (radeon_no_wb == 1) { ++ dev_priv->writeback_works = 0; ++ DRM_INFO("writeback forced off\n"); ++ } ++ ++ if (!dev_priv->writeback_works) { ++ /* Disable writeback to avoid unnecessary bus master transfer */ ++ RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) | ++ RADEON_RB_NO_UPDATE); ++ RADEON_WRITE(R600_SCRATCH_UMSK, 0); ++ } ++} ++ ++int r600_do_engine_reset(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ u32 cp_ptr, cp_me_cntl, cp_rb_cntl; ++ ++ DRM_INFO("Resetting GPU\n"); ++ ++ cp_ptr = RADEON_READ(R600_CP_RB_WPTR); ++ cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL); ++ RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT); ++ ++ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff); ++ RADEON_READ(R600_GRBM_SOFT_RESET); ++ DRM_UDELAY(50); ++ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); ++ RADEON_READ(R600_GRBM_SOFT_RESET); ++ ++ RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); ++ cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); ++ RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA); ++ ++ RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); ++ RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); ++ RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl); ++ RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl); ++ ++ /* Reset the CP ring */ ++ r600_do_cp_reset(dev_priv); ++ ++ /* The CP is no longer running after an engine reset */ ++ dev_priv->cp_running = 0; ++ ++ /* Reset any pending vertex, indirect buffers */ ++ radeon_freelist_reset(dev); ++ ++ return 0; ++ ++} ++ ++static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, ++ u32 num_backends, ++ u32 backend_disable_mask) ++{ ++ u32 backend_map = 0; ++ u32 enabled_backends_mask; ++ u32 enabled_backends_count; ++ u32 cur_pipe; ++ u32 swizzle_pipe[R6XX_MAX_PIPES]; ++ u32 cur_backend; ++ u32 i; ++ ++ if (num_tile_pipes > R6XX_MAX_PIPES) ++ num_tile_pipes = R6XX_MAX_PIPES; ++ if (num_tile_pipes < 1) ++ num_tile_pipes = 1; ++ if (num_backends > R6XX_MAX_BACKENDS) ++ num_backends = R6XX_MAX_BACKENDS; ++ if (num_backends < 1) ++ num_backends = 1; ++ ++ enabled_backends_mask = 0; ++ enabled_backends_count = 0; ++ for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { ++ if (((backend_disable_mask >> i) & 1) == 0) { ++ enabled_backends_mask |= (1 << i); ++ ++enabled_backends_count; ++ } ++ if (enabled_backends_count == num_backends) ++ break; ++ } ++ ++ if (enabled_backends_count == 0) { ++ enabled_backends_mask = 1; ++ enabled_backends_count = 1; ++ } ++ ++ if (enabled_backends_count != num_backends) ++ num_backends = enabled_backends_count; ++ ++ memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); ++ switch (num_tile_pipes) { ++ case 1: ++ swizzle_pipe[0] = 0; ++ break; ++ case 2: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 1; ++ break; ++ case 3: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 1; ++ swizzle_pipe[2] = 2; ++ break; ++ case 4: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 1; ++ swizzle_pipe[2] = 2; ++ swizzle_pipe[3] = 3; ++ break; ++ case 5: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 1; ++ swizzle_pipe[2] = 2; ++ swizzle_pipe[3] = 3; ++ swizzle_pipe[4] = 4; ++ break; ++ case 6: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 2; ++ swizzle_pipe[2] = 4; ++ swizzle_pipe[3] = 5; ++ swizzle_pipe[4] = 1; ++ swizzle_pipe[5] = 3; ++ break; ++ case 7: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 2; ++ swizzle_pipe[2] = 4; ++ swizzle_pipe[3] = 6; ++ swizzle_pipe[4] = 1; ++ swizzle_pipe[5] = 3; ++ swizzle_pipe[6] = 5; ++ break; ++ case 8: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 2; ++ swizzle_pipe[2] = 4; ++ swizzle_pipe[3] = 6; ++ swizzle_pipe[4] = 1; ++ swizzle_pipe[5] = 3; ++ swizzle_pipe[6] = 5; ++ swizzle_pipe[7] = 7; ++ break; ++ } ++ ++ cur_backend = 0; ++ for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { ++ while (((1 << cur_backend) & enabled_backends_mask) == 0) ++ cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; ++ ++ backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); ++ ++ cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; ++ } ++ ++ return backend_map; ++} ++ ++static int r600_count_pipe_bits(uint32_t val) ++{ ++ int i, ret = 0; ++ for (i = 0; i < 32; i++) { ++ ret += val & 1; ++ val >>= 1; ++ } ++ return ret; ++} ++ ++static void r600_gfx_init(struct drm_device *dev, ++ drm_radeon_private_t *dev_priv) ++{ ++ int i, j, num_qd_pipes; ++ u32 sx_debug_1; ++ u32 tc_cntl; ++ u32 arb_pop; ++ u32 num_gs_verts_per_thread; ++ u32 vgt_gs_per_es; ++ u32 gs_prim_buffer_depth = 0; ++ u32 sq_ms_fifo_sizes; ++ u32 sq_config; ++ u32 sq_gpr_resource_mgmt_1 = 0; ++ u32 sq_gpr_resource_mgmt_2 = 0; ++ u32 sq_thread_resource_mgmt = 0; ++ u32 sq_stack_resource_mgmt_1 = 0; ++ u32 sq_stack_resource_mgmt_2 = 0; ++ u32 hdp_host_path_cntl; ++ u32 backend_map; ++ u32 gb_tiling_config = 0; ++ u32 cc_rb_backend_disable = 0; ++ u32 cc_gc_shader_pipe_config = 0; ++ u32 ramcfg; ++ ++ /* setup chip specs */ ++ switch (dev_priv->flags & RADEON_FAMILY_MASK) { ++ case CHIP_R600: ++ dev_priv->r600_max_pipes = 4; ++ dev_priv->r600_max_tile_pipes = 8; ++ dev_priv->r600_max_simds = 4; ++ dev_priv->r600_max_backends = 4; ++ dev_priv->r600_max_gprs = 256; ++ dev_priv->r600_max_threads = 192; ++ dev_priv->r600_max_stack_entries = 256; ++ dev_priv->r600_max_hw_contexts = 8; ++ dev_priv->r600_max_gs_threads = 16; ++ dev_priv->r600_sx_max_export_size = 128; ++ dev_priv->r600_sx_max_export_pos_size = 16; ++ dev_priv->r600_sx_max_export_smx_size = 128; ++ dev_priv->r600_sq_num_cf_insts = 2; ++ break; ++ case CHIP_RV630: ++ case CHIP_RV635: ++ dev_priv->r600_max_pipes = 2; ++ dev_priv->r600_max_tile_pipes = 2; ++ dev_priv->r600_max_simds = 3; ++ dev_priv->r600_max_backends = 1; ++ dev_priv->r600_max_gprs = 128; ++ dev_priv->r600_max_threads = 192; ++ dev_priv->r600_max_stack_entries = 128; ++ dev_priv->r600_max_hw_contexts = 8; ++ dev_priv->r600_max_gs_threads = 4; ++ dev_priv->r600_sx_max_export_size = 128; ++ dev_priv->r600_sx_max_export_pos_size = 16; ++ dev_priv->r600_sx_max_export_smx_size = 128; ++ dev_priv->r600_sq_num_cf_insts = 2; ++ break; ++ case CHIP_RV610: ++ case CHIP_RS780: ++ case CHIP_RV620: ++ dev_priv->r600_max_pipes = 1; ++ dev_priv->r600_max_tile_pipes = 1; ++ dev_priv->r600_max_simds = 2; ++ dev_priv->r600_max_backends = 1; ++ dev_priv->r600_max_gprs = 128; ++ dev_priv->r600_max_threads = 192; ++ dev_priv->r600_max_stack_entries = 128; ++ dev_priv->r600_max_hw_contexts = 4; ++ dev_priv->r600_max_gs_threads = 4; ++ dev_priv->r600_sx_max_export_size = 128; ++ dev_priv->r600_sx_max_export_pos_size = 16; ++ dev_priv->r600_sx_max_export_smx_size = 128; ++ dev_priv->r600_sq_num_cf_insts = 1; ++ break; ++ case CHIP_RV670: ++ dev_priv->r600_max_pipes = 4; ++ dev_priv->r600_max_tile_pipes = 4; ++ dev_priv->r600_max_simds = 4; ++ dev_priv->r600_max_backends = 4; ++ dev_priv->r600_max_gprs = 192; ++ dev_priv->r600_max_threads = 192; ++ dev_priv->r600_max_stack_entries = 256; ++ dev_priv->r600_max_hw_contexts = 8; ++ dev_priv->r600_max_gs_threads = 16; ++ dev_priv->r600_sx_max_export_size = 128; ++ dev_priv->r600_sx_max_export_pos_size = 16; ++ dev_priv->r600_sx_max_export_smx_size = 128; ++ dev_priv->r600_sq_num_cf_insts = 2; ++ break; ++ default: ++ break; ++ } ++ ++ /* Initialize HDP */ ++ j = 0; ++ for (i = 0; i < 32; i++) { ++ RADEON_WRITE((0x2c14 + j), 0x00000000); ++ RADEON_WRITE((0x2c18 + j), 0x00000000); ++ RADEON_WRITE((0x2c1c + j), 0x00000000); ++ RADEON_WRITE((0x2c20 + j), 0x00000000); ++ RADEON_WRITE((0x2c24 + j), 0x00000000); ++ j += 0x18; ++ } ++ ++ RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); ++ ++ /* setup tiling, simd, pipe config */ ++ ramcfg = RADEON_READ(R600_RAMCFG); ++ ++ switch (dev_priv->r600_max_tile_pipes) { ++ case 1: ++ gb_tiling_config |= R600_PIPE_TILING(0); ++ break; ++ case 2: ++ gb_tiling_config |= R600_PIPE_TILING(1); ++ break; ++ case 4: ++ gb_tiling_config |= R600_PIPE_TILING(2); ++ break; ++ case 8: ++ gb_tiling_config |= R600_PIPE_TILING(3); ++ break; ++ default: ++ break; ++ } ++ ++ gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK); ++ ++ gb_tiling_config |= R600_GROUP_SIZE(0); ++ ++ if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) { ++ gb_tiling_config |= R600_ROW_TILING(3); ++ gb_tiling_config |= R600_SAMPLE_SPLIT(3); ++ } else { ++ gb_tiling_config |= ++ R600_ROW_TILING(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); ++ gb_tiling_config |= ++ R600_SAMPLE_SPLIT(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); ++ } ++ ++ gb_tiling_config |= R600_BANK_SWAPS(1); ++ ++ backend_map = r600_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, ++ dev_priv->r600_max_backends, ++ (0xff << dev_priv->r600_max_backends) & 0xff); ++ gb_tiling_config |= R600_BACKEND_MAP(backend_map); ++ ++ cc_gc_shader_pipe_config = ++ R600_INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R6XX_MAX_PIPES_MASK); ++ cc_gc_shader_pipe_config |= ++ R600_INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R6XX_MAX_SIMDS_MASK); ++ ++ cc_rb_backend_disable = ++ R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK); ++ ++ RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); ++ RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); ++ RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); ++ ++ RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); ++ RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); ++ RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); ++ ++ num_qd_pipes = ++ R6XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); ++ RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); ++ RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); ++ ++ /* set HW defaults for 3D engine */ ++ RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | ++ R600_ROQ_IB2_START(0x2b))); ++ ++ RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, (R600_MEQ_END(0x40) | ++ R600_ROQ_END(0x40))); ++ ++ RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | ++ R600_SYNC_GRADIENT | ++ R600_SYNC_WALKER | ++ R600_SYNC_ALIGNER)); ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) ++ RADEON_WRITE(R600_ARB_GDEC_RD_CNTL, 0x00000021); ++ ++ sx_debug_1 = RADEON_READ(R600_SX_DEBUG_1); ++ sx_debug_1 |= R600_SMX_EVENT_RELEASE; ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600)) ++ sx_debug_1 |= R600_ENABLE_NEW_SMX_ADDRESS; ++ RADEON_WRITE(R600_SX_DEBUG_1, sx_debug_1); ++ ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) ++ RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE); ++ else ++ RADEON_WRITE(R600_DB_DEBUG, 0); ++ ++ RADEON_WRITE(R600_DB_WATERMARKS, (R600_DEPTH_FREE(4) | ++ R600_DEPTH_FLUSH(16) | ++ R600_DEPTH_PENDING_FREE(4) | ++ R600_DEPTH_CACHELINE_FREE(16))); ++ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); ++ RADEON_WRITE(R600_VGT_NUM_INSTANCES, 0); ++ ++ RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); ++ RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(0)); ++ ++ sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES); ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { ++ sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) | ++ R600_FETCH_FIFO_HIWATER(0xa) | ++ R600_DONE_FIFO_HIWATER(0xe0) | ++ R600_ALU_UPDATE_FIFO_HIWATER(0x8)); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { ++ sq_ms_fifo_sizes &= ~R600_DONE_FIFO_HIWATER(0xff); ++ sq_ms_fifo_sizes |= R600_DONE_FIFO_HIWATER(0x4); ++ } ++ RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); ++ ++ /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT ++ * should be adjusted as needed by the 2D/3D drivers. This just sets default values ++ */ ++ sq_config = RADEON_READ(R600_SQ_CONFIG); ++ sq_config &= ~(R600_PS_PRIO(3) | ++ R600_VS_PRIO(3) | ++ R600_GS_PRIO(3) | ++ R600_ES_PRIO(3)); ++ sq_config |= (R600_DX9_CONSTS | ++ R600_VC_ENABLE | ++ R600_PS_PRIO(0) | ++ R600_VS_PRIO(1) | ++ R600_GS_PRIO(2) | ++ R600_ES_PRIO(3)); ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) { ++ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(124) | ++ R600_NUM_VS_GPRS(124) | ++ R600_NUM_CLAUSE_TEMP_GPRS(4)); ++ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(0) | ++ R600_NUM_ES_GPRS(0)); ++ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(136) | ++ R600_NUM_VS_THREADS(48) | ++ R600_NUM_GS_THREADS(4) | ++ R600_NUM_ES_THREADS(4)); ++ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(128) | ++ R600_NUM_VS_STACK_ENTRIES(128)); ++ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(0) | ++ R600_NUM_ES_STACK_ENTRIES(0)); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { ++ /* no vertex cache */ ++ sq_config &= ~R600_VC_ENABLE; ++ ++ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | ++ R600_NUM_VS_GPRS(44) | ++ R600_NUM_CLAUSE_TEMP_GPRS(2)); ++ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | ++ R600_NUM_ES_GPRS(17)); ++ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | ++ R600_NUM_VS_THREADS(78) | ++ R600_NUM_GS_THREADS(4) | ++ R600_NUM_ES_THREADS(31)); ++ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | ++ R600_NUM_VS_STACK_ENTRIES(40)); ++ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | ++ R600_NUM_ES_STACK_ENTRIES(16)); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { ++ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | ++ R600_NUM_VS_GPRS(44) | ++ R600_NUM_CLAUSE_TEMP_GPRS(2)); ++ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(18) | ++ R600_NUM_ES_GPRS(18)); ++ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | ++ R600_NUM_VS_THREADS(78) | ++ R600_NUM_GS_THREADS(4) | ++ R600_NUM_ES_THREADS(31)); ++ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | ++ R600_NUM_VS_STACK_ENTRIES(40)); ++ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | ++ R600_NUM_ES_STACK_ENTRIES(16)); ++ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) { ++ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | ++ R600_NUM_VS_GPRS(44) | ++ R600_NUM_CLAUSE_TEMP_GPRS(2)); ++ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | ++ R600_NUM_ES_GPRS(17)); ++ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | ++ R600_NUM_VS_THREADS(78) | ++ R600_NUM_GS_THREADS(4) | ++ R600_NUM_ES_THREADS(31)); ++ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(64) | ++ R600_NUM_VS_STACK_ENTRIES(64)); ++ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(64) | ++ R600_NUM_ES_STACK_ENTRIES(64)); ++ } ++ ++ RADEON_WRITE(R600_SQ_CONFIG, sq_config); ++ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); ++ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); ++ RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); ++ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); ++ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); ++ ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) ++ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY)); ++ else ++ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC)); ++ ++ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_2S, (R600_S0_X(0xc) | ++ R600_S0_Y(0x4) | ++ R600_S1_X(0x4) | ++ R600_S1_Y(0xc))); ++ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_4S, (R600_S0_X(0xe) | ++ R600_S0_Y(0xe) | ++ R600_S1_X(0x2) | ++ R600_S1_Y(0x2) | ++ R600_S2_X(0xa) | ++ R600_S2_Y(0x6) | ++ R600_S3_X(0x6) | ++ R600_S3_Y(0xa))); ++ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0, (R600_S0_X(0xe) | ++ R600_S0_Y(0xb) | ++ R600_S1_X(0x4) | ++ R600_S1_Y(0xc) | ++ R600_S2_X(0x1) | ++ R600_S2_Y(0x6) | ++ R600_S3_X(0xa) | ++ R600_S3_Y(0xe))); ++ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1, (R600_S4_X(0x6) | ++ R600_S4_Y(0x1) | ++ R600_S5_X(0x0) | ++ R600_S5_Y(0x0) | ++ R600_S6_X(0xb) | ++ R600_S6_Y(0x4) | ++ R600_S7_X(0x7) | ++ R600_S7_Y(0x8))); ++ ++ ++ switch (dev_priv->flags & RADEON_FAMILY_MASK) { ++ case CHIP_R600: ++ case CHIP_RV630: ++ case CHIP_RV635: ++ gs_prim_buffer_depth = 0; ++ break; ++ case CHIP_RV610: ++ case CHIP_RS780: ++ case CHIP_RV620: ++ gs_prim_buffer_depth = 32; ++ break; ++ case CHIP_RV670: ++ gs_prim_buffer_depth = 128; ++ break; ++ default: ++ break; ++ } ++ ++ num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; ++ vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; ++ /* Max value for this is 256 */ ++ if (vgt_gs_per_es > 256) ++ vgt_gs_per_es = 256; ++ ++ RADEON_WRITE(R600_VGT_ES_PER_GS, 128); ++ RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); ++ RADEON_WRITE(R600_VGT_GS_PER_VS, 2); ++ RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); ++ ++ /* more default values. 2D/3D driver should adjust as needed */ ++ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); ++ RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); ++ RADEON_WRITE(R600_SX_MISC, 0); ++ RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); ++ RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); ++ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); ++ RADEON_WRITE(R600_SPI_INPUT_Z, 0); ++ RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); ++ RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); ++ ++ /* clear render buffer base addresses */ ++ RADEON_WRITE(R600_CB_COLOR0_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR1_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR2_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR3_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR4_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR5_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR6_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR7_BASE, 0); ++ ++ switch (dev_priv->flags & RADEON_FAMILY_MASK) { ++ case CHIP_RV610: ++ case CHIP_RS780: ++ case CHIP_RV620: ++ tc_cntl = R600_TC_L2_SIZE(8); ++ break; ++ case CHIP_RV630: ++ case CHIP_RV635: ++ tc_cntl = R600_TC_L2_SIZE(4); ++ break; ++ case CHIP_R600: ++ tc_cntl = R600_TC_L2_SIZE(0) | R600_L2_DISABLE_LATE_HIT; ++ break; ++ default: ++ tc_cntl = R600_TC_L2_SIZE(0); ++ break; ++ } ++ ++ RADEON_WRITE(R600_TC_CNTL, tc_cntl); ++ ++ hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); ++ RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); ++ ++ arb_pop = RADEON_READ(R600_ARB_POP); ++ arb_pop |= R600_ENABLE_TC128; ++ RADEON_WRITE(R600_ARB_POP, arb_pop); ++ ++ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); ++ RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | ++ R600_NUM_CLIP_SEQ(3))); ++ RADEON_WRITE(R600_PA_SC_ENHANCE, R600_FORCE_EOV_MAX_CLK_CNT(4095)); ++ ++} ++ ++static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, ++ u32 num_backends, ++ u32 backend_disable_mask) ++{ ++ u32 backend_map = 0; ++ u32 enabled_backends_mask; ++ u32 enabled_backends_count; ++ u32 cur_pipe; ++ u32 swizzle_pipe[R7XX_MAX_PIPES]; ++ u32 cur_backend; ++ u32 i; ++ ++ if (num_tile_pipes > R7XX_MAX_PIPES) ++ num_tile_pipes = R7XX_MAX_PIPES; ++ if (num_tile_pipes < 1) ++ num_tile_pipes = 1; ++ if (num_backends > R7XX_MAX_BACKENDS) ++ num_backends = R7XX_MAX_BACKENDS; ++ if (num_backends < 1) ++ num_backends = 1; ++ ++ enabled_backends_mask = 0; ++ enabled_backends_count = 0; ++ for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { ++ if (((backend_disable_mask >> i) & 1) == 0) { ++ enabled_backends_mask |= (1 << i); ++ ++enabled_backends_count; ++ } ++ if (enabled_backends_count == num_backends) ++ break; ++ } ++ ++ if (enabled_backends_count == 0) { ++ enabled_backends_mask = 1; ++ enabled_backends_count = 1; ++ } ++ ++ if (enabled_backends_count != num_backends) ++ num_backends = enabled_backends_count; ++ ++ memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); ++ switch (num_tile_pipes) { ++ case 1: ++ swizzle_pipe[0] = 0; ++ break; ++ case 2: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 1; ++ break; ++ case 3: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 2; ++ swizzle_pipe[2] = 1; ++ break; ++ case 4: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 2; ++ swizzle_pipe[2] = 3; ++ swizzle_pipe[3] = 1; ++ break; ++ case 5: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 2; ++ swizzle_pipe[2] = 4; ++ swizzle_pipe[3] = 1; ++ swizzle_pipe[4] = 3; ++ break; ++ case 6: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 2; ++ swizzle_pipe[2] = 4; ++ swizzle_pipe[3] = 5; ++ swizzle_pipe[4] = 3; ++ swizzle_pipe[5] = 1; ++ break; ++ case 7: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 2; ++ swizzle_pipe[2] = 4; ++ swizzle_pipe[3] = 6; ++ swizzle_pipe[4] = 3; ++ swizzle_pipe[5] = 1; ++ swizzle_pipe[6] = 5; ++ break; ++ case 8: ++ swizzle_pipe[0] = 0; ++ swizzle_pipe[1] = 2; ++ swizzle_pipe[2] = 4; ++ swizzle_pipe[3] = 6; ++ swizzle_pipe[4] = 3; ++ swizzle_pipe[5] = 1; ++ swizzle_pipe[6] = 7; ++ swizzle_pipe[7] = 5; ++ break; ++ } ++ ++ cur_backend = 0; ++ for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { ++ while (((1 << cur_backend) & enabled_backends_mask) == 0) ++ cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; ++ ++ backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); ++ ++ cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; ++ } ++ ++ return backend_map; ++} ++ ++static void r700_gfx_init(struct drm_device *dev, ++ drm_radeon_private_t *dev_priv) ++{ ++ int i, j, num_qd_pipes; ++ u32 sx_debug_1; ++ u32 smx_dc_ctl0; ++ u32 num_gs_verts_per_thread; ++ u32 vgt_gs_per_es; ++ u32 gs_prim_buffer_depth = 0; ++ u32 sq_ms_fifo_sizes; ++ u32 sq_config; ++ u32 sq_thread_resource_mgmt; ++ u32 hdp_host_path_cntl; ++ u32 sq_dyn_gpr_size_simd_ab_0; ++ u32 backend_map; ++ u32 gb_tiling_config = 0; ++ u32 cc_rb_backend_disable = 0; ++ u32 cc_gc_shader_pipe_config = 0; ++ u32 mc_arb_ramcfg; ++ u32 db_debug4; ++ ++ /* setup chip specs */ ++ switch (dev_priv->flags & RADEON_FAMILY_MASK) { ++ case CHIP_RV770: ++ dev_priv->r600_max_pipes = 4; ++ dev_priv->r600_max_tile_pipes = 8; ++ dev_priv->r600_max_simds = 10; ++ dev_priv->r600_max_backends = 4; ++ dev_priv->r600_max_gprs = 256; ++ dev_priv->r600_max_threads = 248; ++ dev_priv->r600_max_stack_entries = 512; ++ dev_priv->r600_max_hw_contexts = 8; ++ dev_priv->r600_max_gs_threads = 16 * 2; ++ dev_priv->r600_sx_max_export_size = 128; ++ dev_priv->r600_sx_max_export_pos_size = 16; ++ dev_priv->r600_sx_max_export_smx_size = 112; ++ dev_priv->r600_sq_num_cf_insts = 2; ++ ++ dev_priv->r700_sx_num_of_sets = 7; ++ dev_priv->r700_sc_prim_fifo_size = 0xF9; ++ dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; ++ dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; ++ break; ++ case CHIP_RV730: ++ dev_priv->r600_max_pipes = 2; ++ dev_priv->r600_max_tile_pipes = 4; ++ dev_priv->r600_max_simds = 8; ++ dev_priv->r600_max_backends = 2; ++ dev_priv->r600_max_gprs = 128; ++ dev_priv->r600_max_threads = 248; ++ dev_priv->r600_max_stack_entries = 256; ++ dev_priv->r600_max_hw_contexts = 8; ++ dev_priv->r600_max_gs_threads = 16 * 2; ++ dev_priv->r600_sx_max_export_size = 256; ++ dev_priv->r600_sx_max_export_pos_size = 32; ++ dev_priv->r600_sx_max_export_smx_size = 224; ++ dev_priv->r600_sq_num_cf_insts = 2; ++ ++ dev_priv->r700_sx_num_of_sets = 7; ++ dev_priv->r700_sc_prim_fifo_size = 0xf9; ++ dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; ++ dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; ++ break; ++ case CHIP_RV710: ++ dev_priv->r600_max_pipes = 2; ++ dev_priv->r600_max_tile_pipes = 2; ++ dev_priv->r600_max_simds = 2; ++ dev_priv->r600_max_backends = 1; ++ dev_priv->r600_max_gprs = 256; ++ dev_priv->r600_max_threads = 192; ++ dev_priv->r600_max_stack_entries = 256; ++ dev_priv->r600_max_hw_contexts = 4; ++ dev_priv->r600_max_gs_threads = 8 * 2; ++ dev_priv->r600_sx_max_export_size = 128; ++ dev_priv->r600_sx_max_export_pos_size = 16; ++ dev_priv->r600_sx_max_export_smx_size = 112; ++ dev_priv->r600_sq_num_cf_insts = 1; ++ ++ dev_priv->r700_sx_num_of_sets = 7; ++ dev_priv->r700_sc_prim_fifo_size = 0x40; ++ dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; ++ dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; ++ break; ++ default: ++ break; ++ } ++ ++ /* Initialize HDP */ ++ j = 0; ++ for (i = 0; i < 32; i++) { ++ RADEON_WRITE((0x2c14 + j), 0x00000000); ++ RADEON_WRITE((0x2c18 + j), 0x00000000); ++ RADEON_WRITE((0x2c1c + j), 0x00000000); ++ RADEON_WRITE((0x2c20 + j), 0x00000000); ++ RADEON_WRITE((0x2c24 + j), 0x00000000); ++ j += 0x18; ++ } ++ ++ RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); ++ ++ /* setup tiling, simd, pipe config */ ++ mc_arb_ramcfg = RADEON_READ(R700_MC_ARB_RAMCFG); ++ ++ switch (dev_priv->r600_max_tile_pipes) { ++ case 1: ++ gb_tiling_config |= R600_PIPE_TILING(0); ++ break; ++ case 2: ++ gb_tiling_config |= R600_PIPE_TILING(1); ++ break; ++ case 4: ++ gb_tiling_config |= R600_PIPE_TILING(2); ++ break; ++ case 8: ++ gb_tiling_config |= R600_PIPE_TILING(3); ++ break; ++ default: ++ break; ++ } ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) ++ gb_tiling_config |= R600_BANK_TILING(1); ++ else ++ gb_tiling_config |= R600_BANK_TILING((mc_arb_ramcfg >> R700_NOOFBANK_SHIFT) & R700_NOOFBANK_MASK); ++ ++ gb_tiling_config |= R600_GROUP_SIZE(0); ++ ++ if (((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK) > 3) { ++ gb_tiling_config |= R600_ROW_TILING(3); ++ gb_tiling_config |= R600_SAMPLE_SPLIT(3); ++ } else { ++ gb_tiling_config |= ++ R600_ROW_TILING(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); ++ gb_tiling_config |= ++ R600_SAMPLE_SPLIT(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); ++ } ++ ++ gb_tiling_config |= R600_BANK_SWAPS(1); ++ ++ backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, ++ dev_priv->r600_max_backends, ++ (0xff << dev_priv->r600_max_backends) & 0xff); ++ gb_tiling_config |= R600_BACKEND_MAP(backend_map); ++ ++ cc_gc_shader_pipe_config = ++ R600_INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R7XX_MAX_PIPES_MASK); ++ cc_gc_shader_pipe_config |= ++ R600_INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R7XX_MAX_SIMDS_MASK); ++ ++ cc_rb_backend_disable = ++ R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK); ++ ++ RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); ++ RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); ++ RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); ++ ++ RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); ++ RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); ++ RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); ++ ++ RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); ++ RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0); ++ RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0); ++ RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0); ++ RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0); ++ ++ num_qd_pipes = ++ R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); ++ RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); ++ RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); ++ ++ /* set HW defaults for 3D engine */ ++ RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | ++ R600_ROQ_IB2_START(0x2b))); ++ ++ RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, R700_STQ_SPLIT(0x30)); ++ ++ RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | ++ R600_SYNC_GRADIENT | ++ R600_SYNC_WALKER | ++ R600_SYNC_ALIGNER)); ++ ++ sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1); ++ sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS; ++ RADEON_WRITE(R700_SX_DEBUG_1, sx_debug_1); ++ ++ smx_dc_ctl0 = RADEON_READ(R600_SMX_DC_CTL0); ++ smx_dc_ctl0 &= ~R700_CACHE_DEPTH(0x1ff); ++ smx_dc_ctl0 |= R700_CACHE_DEPTH((dev_priv->r700_sx_num_of_sets * 64) - 1); ++ RADEON_WRITE(R600_SMX_DC_CTL0, smx_dc_ctl0); ++ ++ RADEON_WRITE(R700_SMX_EVENT_CTL, (R700_ES_FLUSH_CTL(4) | ++ R700_GS_FLUSH_CTL(4) | ++ R700_ACK_FLUSH_CTL(3) | ++ R700_SYNC_FLUSH_CTL)); ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) ++ RADEON_WRITE(R700_DB_DEBUG3, R700_DB_CLK_OFF_DELAY(0x1f)); ++ else { ++ db_debug4 = RADEON_READ(RV700_DB_DEBUG4); ++ db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER; ++ RADEON_WRITE(RV700_DB_DEBUG4, db_debug4); ++ } ++ ++ RADEON_WRITE(R600_SX_EXPORT_BUFFER_SIZES, (R600_COLOR_BUFFER_SIZE((dev_priv->r600_sx_max_export_size / 4) - 1) | ++ R600_POSITION_BUFFER_SIZE((dev_priv->r600_sx_max_export_pos_size / 4) - 1) | ++ R600_SMX_BUFFER_SIZE((dev_priv->r600_sx_max_export_smx_size / 4) - 1))); ++ ++ RADEON_WRITE(R700_PA_SC_FIFO_SIZE_R7XX, (R700_SC_PRIM_FIFO_SIZE(dev_priv->r700_sc_prim_fifo_size) | ++ R700_SC_HIZ_TILE_FIFO_SIZE(dev_priv->r700_sc_hiz_tile_fifo_size) | ++ R700_SC_EARLYZ_TILE_FIFO_SIZE(dev_priv->r700_sc_earlyz_tile_fifo_fize))); ++ ++ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); ++ ++ RADEON_WRITE(R600_VGT_NUM_INSTANCES, 1); ++ ++ RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); ++ ++ RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(4)); ++ ++ RADEON_WRITE(R600_CP_PERFMON_CNTL, 0); ++ ++ sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(16 * dev_priv->r600_sq_num_cf_insts) | ++ R600_DONE_FIFO_HIWATER(0xe0) | ++ R600_ALU_UPDATE_FIFO_HIWATER(0x8)); ++ switch (dev_priv->flags & RADEON_FAMILY_MASK) { ++ case CHIP_RV770: ++ sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1); ++ break; ++ case CHIP_RV730: ++ case CHIP_RV710: ++ default: ++ sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4); ++ break; ++ } ++ RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); ++ ++ /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT ++ * should be adjusted as needed by the 2D/3D drivers. This just sets default values ++ */ ++ sq_config = RADEON_READ(R600_SQ_CONFIG); ++ sq_config &= ~(R600_PS_PRIO(3) | ++ R600_VS_PRIO(3) | ++ R600_GS_PRIO(3) | ++ R600_ES_PRIO(3)); ++ sq_config |= (R600_DX9_CONSTS | ++ R600_VC_ENABLE | ++ R600_EXPORT_SRC_C | ++ R600_PS_PRIO(0) | ++ R600_VS_PRIO(1) | ++ R600_GS_PRIO(2) | ++ R600_ES_PRIO(3)); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) ++ /* no vertex cache */ ++ sq_config &= ~R600_VC_ENABLE; ++ ++ RADEON_WRITE(R600_SQ_CONFIG, sq_config); ++ ++ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, (R600_NUM_PS_GPRS((dev_priv->r600_max_gprs * 24)/64) | ++ R600_NUM_VS_GPRS((dev_priv->r600_max_gprs * 24)/64) | ++ R600_NUM_CLAUSE_TEMP_GPRS(((dev_priv->r600_max_gprs * 24)/64)/2))); ++ ++ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, (R600_NUM_GS_GPRS((dev_priv->r600_max_gprs * 7)/64) | ++ R600_NUM_ES_GPRS((dev_priv->r600_max_gprs * 7)/64))); ++ ++ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS((dev_priv->r600_max_threads * 4)/8) | ++ R600_NUM_VS_THREADS((dev_priv->r600_max_threads * 2)/8) | ++ R600_NUM_ES_THREADS((dev_priv->r600_max_threads * 1)/8)); ++ if (((dev_priv->r600_max_threads * 1) / 8) > dev_priv->r600_max_gs_threads) ++ sq_thread_resource_mgmt |= R600_NUM_GS_THREADS(dev_priv->r600_max_gs_threads); ++ else ++ sq_thread_resource_mgmt |= R600_NUM_GS_THREADS((dev_priv->r600_max_gs_threads * 1)/8); ++ RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); ++ ++ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, (R600_NUM_PS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | ++ R600_NUM_VS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); ++ ++ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, (R600_NUM_GS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | ++ R600_NUM_ES_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); ++ ++ sq_dyn_gpr_size_simd_ab_0 = (R700_SIMDA_RING0((dev_priv->r600_max_gprs * 38)/64) | ++ R700_SIMDA_RING1((dev_priv->r600_max_gprs * 38)/64) | ++ R700_SIMDB_RING0((dev_priv->r600_max_gprs * 38)/64) | ++ R700_SIMDB_RING1((dev_priv->r600_max_gprs * 38)/64)); ++ ++ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0); ++ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0); ++ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0); ++ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0); ++ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0); ++ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0); ++ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0); ++ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0); ++ ++ RADEON_WRITE(R700_PA_SC_FORCE_EOV_MAX_CNTS, (R700_FORCE_EOV_MAX_CLK_CNT(4095) | ++ R700_FORCE_EOV_MAX_REZ_CNT(255))); ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) ++ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_TC_ONLY) | ++ R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); ++ else ++ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_VC_AND_TC) | ++ R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); ++ ++ switch (dev_priv->flags & RADEON_FAMILY_MASK) { ++ case CHIP_RV770: ++ case CHIP_RV730: ++ gs_prim_buffer_depth = 384; ++ break; ++ case CHIP_RV710: ++ gs_prim_buffer_depth = 128; ++ break; ++ default: ++ break; ++ } ++ ++ num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; ++ vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; ++ /* Max value for this is 256 */ ++ if (vgt_gs_per_es > 256) ++ vgt_gs_per_es = 256; ++ ++ RADEON_WRITE(R600_VGT_ES_PER_GS, 128); ++ RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); ++ RADEON_WRITE(R600_VGT_GS_PER_VS, 2); ++ ++ /* more default values. 2D/3D driver should adjust as needed */ ++ RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); ++ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); ++ RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); ++ RADEON_WRITE(R600_SX_MISC, 0); ++ RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); ++ RADEON_WRITE(R700_PA_SC_EDGERULE, 0xaaaaaaaa); ++ RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); ++ RADEON_WRITE(R600_PA_SC_CLIPRECT_RULE, 0xffff); ++ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); ++ RADEON_WRITE(R600_SPI_INPUT_Z, 0); ++ RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); ++ RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); ++ ++ /* clear render buffer base addresses */ ++ RADEON_WRITE(R600_CB_COLOR0_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR1_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR2_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR3_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR4_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR5_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR6_BASE, 0); ++ RADEON_WRITE(R600_CB_COLOR7_BASE, 0); ++ ++ RADEON_WRITE(R700_TCP_CNTL, 0); ++ ++ hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); ++ RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); ++ ++ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); ++ ++ RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | ++ R600_NUM_CLIP_SEQ(3))); ++ ++} ++ ++static void r600_cp_init_ring_buffer(struct drm_device *dev, ++ drm_radeon_private_t *dev_priv, ++ struct drm_file *file_priv) ++{ ++ struct drm_radeon_master_private *master_priv; ++ u32 ring_start; ++ u64 rptr_addr; ++ ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) ++ r700_gfx_init(dev, dev_priv); ++ else ++ r600_gfx_init(dev, dev_priv); ++ ++ RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); ++ RADEON_READ(R600_GRBM_SOFT_RESET); ++ DRM_UDELAY(15000); ++ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); ++ ++ ++ /* Set ring buffer size */ ++#ifdef __BIG_ENDIAN ++ RADEON_WRITE(R600_CP_RB_CNTL, ++ RADEON_BUF_SWAP_32BIT | ++ RADEON_RB_NO_UPDATE | ++ (dev_priv->ring.rptr_update_l2qw << 8) | ++ dev_priv->ring.size_l2qw); ++#else ++ RADEON_WRITE(R600_CP_RB_CNTL, ++ RADEON_RB_NO_UPDATE | ++ (dev_priv->ring.rptr_update_l2qw << 8) | ++ dev_priv->ring.size_l2qw); ++#endif ++ ++ RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x4); ++ ++ /* Set the write pointer delay */ ++ RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); ++ ++#ifdef __BIG_ENDIAN ++ RADEON_WRITE(R600_CP_RB_CNTL, ++ RADEON_BUF_SWAP_32BIT | ++ RADEON_RB_NO_UPDATE | ++ RADEON_RB_RPTR_WR_ENA | ++ (dev_priv->ring.rptr_update_l2qw << 8) | ++ dev_priv->ring.size_l2qw); ++#else ++ RADEON_WRITE(R600_CP_RB_CNTL, ++ RADEON_RB_NO_UPDATE | ++ RADEON_RB_RPTR_WR_ENA | ++ (dev_priv->ring.rptr_update_l2qw << 8) | ++ dev_priv->ring.size_l2qw); ++#endif ++ ++ /* Initialize the ring buffer's read and write pointers */ ++ RADEON_WRITE(R600_CP_RB_RPTR_WR, 0); ++ RADEON_WRITE(R600_CP_RB_WPTR, 0); ++ SET_RING_HEAD(dev_priv, 0); ++ dev_priv->ring.tail = 0; ++ ++#if __OS_HAS_AGP ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ rptr_addr = dev_priv->ring_rptr->offset ++ - dev->agp->base + ++ dev_priv->gart_vm_start; ++ } else ++#endif ++ { ++ rptr_addr = dev_priv->ring_rptr->offset ++ - ((unsigned long) dev->sg->virtual) ++ + dev_priv->gart_vm_start; ++ } ++ RADEON_WRITE(R600_CP_RB_RPTR_ADDR, ++ rptr_addr & 0xffffffff); ++ RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, ++ upper_32_bits(rptr_addr)); ++ ++#ifdef __BIG_ENDIAN ++ RADEON_WRITE(R600_CP_RB_CNTL, ++ RADEON_BUF_SWAP_32BIT | ++ (dev_priv->ring.rptr_update_l2qw << 8) | ++ dev_priv->ring.size_l2qw); ++#else ++ RADEON_WRITE(R600_CP_RB_CNTL, ++ (dev_priv->ring.rptr_update_l2qw << 8) | ++ dev_priv->ring.size_l2qw); ++#endif ++ ++#if __OS_HAS_AGP ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ /* XXX */ ++ radeon_write_agp_base(dev_priv, dev->agp->base); ++ ++ /* XXX */ ++ radeon_write_agp_location(dev_priv, ++ (((dev_priv->gart_vm_start - 1 + ++ dev_priv->gart_size) & 0xffff0000) | ++ (dev_priv->gart_vm_start >> 16))); ++ ++ ring_start = (dev_priv->cp_ring->offset ++ - dev->agp->base ++ + dev_priv->gart_vm_start); ++ } else ++#endif ++ ring_start = (dev_priv->cp_ring->offset ++ - (unsigned long)dev->sg->virtual ++ + dev_priv->gart_vm_start); ++ ++ RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8); ++ ++ RADEON_WRITE(R600_CP_ME_CNTL, 0xff); ++ ++ RADEON_WRITE(R600_CP_DEBUG, (1 << 27) | (1 << 28)); ++ ++ /* Initialize the scratch register pointer. This will cause ++ * the scratch register values to be written out to memory ++ * whenever they are updated. ++ * ++ * We simply put this behind the ring read pointer, this works ++ * with PCI GART as well as (whatever kind of) AGP GART ++ */ ++ { ++ u64 scratch_addr; ++ ++ scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR); ++ scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; ++ scratch_addr += R600_SCRATCH_REG_OFFSET; ++ scratch_addr >>= 8; ++ scratch_addr &= 0xffffffff; ++ ++ RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr); ++ } ++ ++ RADEON_WRITE(R600_SCRATCH_UMSK, 0x7); ++ ++ /* Turn on bus mastering */ ++ radeon_enable_bm(dev_priv); ++ ++ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0); ++ RADEON_WRITE(R600_LAST_FRAME_REG, 0); ++ ++ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); ++ RADEON_WRITE(R600_LAST_DISPATCH_REG, 0); ++ ++ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0); ++ RADEON_WRITE(R600_LAST_CLEAR_REG, 0); ++ ++ /* reset sarea copies of these */ ++ master_priv = file_priv->master->driver_priv; ++ if (master_priv->sarea_priv) { ++ master_priv->sarea_priv->last_frame = 0; ++ master_priv->sarea_priv->last_dispatch = 0; ++ master_priv->sarea_priv->last_clear = 0; ++ } ++ ++ r600_do_wait_for_idle(dev_priv); ++ ++} ++ ++int r600_do_cleanup_cp(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ DRM_DEBUG("\n"); ++ ++ /* Make sure interrupts are disabled here because the uninstall ioctl ++ * may not have been called from userspace and after dev_private ++ * is freed, it's too late. ++ */ ++ if (dev->irq_enabled) ++ drm_irq_uninstall(dev); ++ ++#if __OS_HAS_AGP ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ if (dev_priv->cp_ring != NULL) { ++ drm_core_ioremapfree(dev_priv->cp_ring, dev); ++ dev_priv->cp_ring = NULL; ++ } ++ if (dev_priv->ring_rptr != NULL) { ++ drm_core_ioremapfree(dev_priv->ring_rptr, dev); ++ dev_priv->ring_rptr = NULL; ++ } ++ if (dev->agp_buffer_map != NULL) { ++ drm_core_ioremapfree(dev->agp_buffer_map, dev); ++ dev->agp_buffer_map = NULL; ++ } ++ } else ++#endif ++ { ++ ++ if (dev_priv->gart_info.bus_addr) ++ r600_page_table_cleanup(dev, &dev_priv->gart_info); ++ ++ if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { ++ drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); ++ dev_priv->gart_info.addr = NULL; ++ } ++ } ++ /* only clear to the start of flags */ ++ memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); ++ ++ return 0; ++} ++ ++int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, ++ struct drm_file *file_priv) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; ++ ++ DRM_DEBUG("\n"); ++ ++ /* if we require new memory map but we don't have it fail */ ++ if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { ++ DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ ++ if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { ++ DRM_DEBUG("Forcing AGP card to PCI mode\n"); ++ dev_priv->flags &= ~RADEON_IS_AGP; ++ /* The writeback test succeeds, but when writeback is enabled, ++ * the ring buffer read ptr update fails after first 128 bytes. ++ */ ++ radeon_no_wb = 1; ++ } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) ++ && !init->is_pci) { ++ DRM_DEBUG("Restoring AGP flag\n"); ++ dev_priv->flags |= RADEON_IS_AGP; ++ } ++ ++ dev_priv->usec_timeout = init->usec_timeout; ++ if (dev_priv->usec_timeout < 1 || ++ dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { ++ DRM_DEBUG("TIMEOUT problem!\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ ++ /* Enable vblank on CRTC1 for older X servers ++ */ ++ dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; ++ ++ dev_priv->cp_mode = init->cp_mode; ++ ++ /* We don't support anything other than bus-mastering ring mode, ++ * but the ring can be in either AGP or PCI space for the ring ++ * read pointer. ++ */ ++ if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && ++ (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { ++ DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ ++ switch (init->fb_bpp) { ++ case 16: ++ dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; ++ break; ++ case 32: ++ default: ++ dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; ++ break; ++ } ++ dev_priv->front_offset = init->front_offset; ++ dev_priv->front_pitch = init->front_pitch; ++ dev_priv->back_offset = init->back_offset; ++ dev_priv->back_pitch = init->back_pitch; ++ ++ dev_priv->ring_offset = init->ring_offset; ++ dev_priv->ring_rptr_offset = init->ring_rptr_offset; ++ dev_priv->buffers_offset = init->buffers_offset; ++ dev_priv->gart_textures_offset = init->gart_textures_offset; ++ ++ master_priv->sarea = drm_getsarea(dev); ++ if (!master_priv->sarea) { ++ DRM_ERROR("could not find sarea!\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ ++ dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); ++ if (!dev_priv->cp_ring) { ++ DRM_ERROR("could not find cp ring region!\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); ++ if (!dev_priv->ring_rptr) { ++ DRM_ERROR("could not find ring read pointer!\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ dev->agp_buffer_token = init->buffers_offset; ++ dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); ++ if (!dev->agp_buffer_map) { ++ DRM_ERROR("could not find dma buffer region!\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ ++ if (init->gart_textures_offset) { ++ dev_priv->gart_textures = ++ drm_core_findmap(dev, init->gart_textures_offset); ++ if (!dev_priv->gart_textures) { ++ DRM_ERROR("could not find GART texture region!\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ } ++ ++#if __OS_HAS_AGP ++ /* XXX */ ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ drm_core_ioremap_wc(dev_priv->cp_ring, dev); ++ drm_core_ioremap_wc(dev_priv->ring_rptr, dev); ++ drm_core_ioremap_wc(dev->agp_buffer_map, dev); ++ if (!dev_priv->cp_ring->handle || ++ !dev_priv->ring_rptr->handle || ++ !dev->agp_buffer_map->handle) { ++ DRM_ERROR("could not find ioremap agp regions!\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ } else ++#endif ++ { ++ dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; ++ dev_priv->ring_rptr->handle = ++ (void *)dev_priv->ring_rptr->offset; ++ dev->agp_buffer_map->handle = ++ (void *)dev->agp_buffer_map->offset; ++ ++ DRM_DEBUG("dev_priv->cp_ring->handle %p\n", ++ dev_priv->cp_ring->handle); ++ DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", ++ dev_priv->ring_rptr->handle); ++ DRM_DEBUG("dev->agp_buffer_map->handle %p\n", ++ dev->agp_buffer_map->handle); ++ } ++ ++ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24; ++ dev_priv->fb_size = ++ (((radeon_read_fb_location(dev_priv) & 0xffff0000u) << 8) + 0x1000000) ++ - dev_priv->fb_location; ++ ++ dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | ++ ((dev_priv->front_offset ++ + dev_priv->fb_location) >> 10)); ++ ++ dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | ++ ((dev_priv->back_offset ++ + dev_priv->fb_location) >> 10)); ++ ++ dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | ++ ((dev_priv->depth_offset ++ + dev_priv->fb_location) >> 10)); ++ ++ dev_priv->gart_size = init->gart_size; ++ ++ /* New let's set the memory map ... */ ++ if (dev_priv->new_memmap) { ++ u32 base = 0; ++ ++ DRM_INFO("Setting GART location based on new memory map\n"); ++ ++ /* If using AGP, try to locate the AGP aperture at the same ++ * location in the card and on the bus, though we have to ++ * align it down. ++ */ ++#if __OS_HAS_AGP ++ /* XXX */ ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ base = dev->agp->base; ++ /* Check if valid */ ++ if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && ++ base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { ++ DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", ++ dev->agp->base); ++ base = 0; ++ } ++ } ++#endif ++ /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ ++ if (base == 0) { ++ base = dev_priv->fb_location + dev_priv->fb_size; ++ if (base < dev_priv->fb_location || ++ ((base + dev_priv->gart_size) & 0xfffffffful) < base) ++ base = dev_priv->fb_location ++ - dev_priv->gart_size; ++ } ++ dev_priv->gart_vm_start = base & 0xffc00000u; ++ if (dev_priv->gart_vm_start != base) ++ DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", ++ base, dev_priv->gart_vm_start); ++ } ++ ++#if __OS_HAS_AGP ++ /* XXX */ ++ if (dev_priv->flags & RADEON_IS_AGP) ++ dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset ++ - dev->agp->base ++ + dev_priv->gart_vm_start); ++ else ++#endif ++ dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset ++ - (unsigned long)dev->sg->virtual ++ + dev_priv->gart_vm_start); ++ ++ DRM_DEBUG("fb 0x%08x size %d\n", ++ (unsigned int) dev_priv->fb_location, ++ (unsigned int) dev_priv->fb_size); ++ DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); ++ DRM_DEBUG("dev_priv->gart_vm_start 0x%08x\n", ++ (unsigned int) dev_priv->gart_vm_start); ++ DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n", ++ dev_priv->gart_buffers_offset); ++ ++ dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; ++ dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle ++ + init->ring_size / sizeof(u32)); ++ dev_priv->ring.size = init->ring_size; ++ dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); ++ ++ dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; ++ dev_priv->ring.rptr_update_l2qw = drm_order(/* init->rptr_update */ 4096 / 8); ++ ++ dev_priv->ring.fetch_size = /* init->fetch_size */ 32; ++ dev_priv->ring.fetch_size_l2ow = drm_order(/* init->fetch_size */ 32 / 16); ++ ++ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; ++ ++ dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; ++ ++#if __OS_HAS_AGP ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ /* XXX turn off pcie gart */ ++ } else ++#endif ++ { ++ dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); ++ /* if we have an offset set from userspace */ ++ if (!dev_priv->pcigart_offset_set) { ++ DRM_ERROR("Need gart offset from userspace\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ ++ DRM_DEBUG("Using gart offset 0x%08lx\n", dev_priv->pcigart_offset); ++ ++ dev_priv->gart_info.bus_addr = ++ dev_priv->pcigart_offset + dev_priv->fb_location; ++ dev_priv->gart_info.mapping.offset = ++ dev_priv->pcigart_offset + dev_priv->fb_aper_offset; ++ dev_priv->gart_info.mapping.size = ++ dev_priv->gart_info.table_size; ++ ++ drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); ++ if (!dev_priv->gart_info.mapping.handle) { ++ DRM_ERROR("ioremap failed.\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ ++ dev_priv->gart_info.addr = ++ dev_priv->gart_info.mapping.handle; ++ ++ DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", ++ dev_priv->gart_info.addr, ++ dev_priv->pcigart_offset); ++ ++ if (!r600_page_table_init(dev)) { ++ DRM_ERROR("Failed to init GART table\n"); ++ r600_do_cleanup_cp(dev); ++ return -EINVAL; ++ } ++ ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) ++ r700_vm_init(dev); ++ else ++ r600_vm_init(dev); ++ } ++ ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) ++ r700_cp_load_microcode(dev_priv); ++ else ++ r600_cp_load_microcode(dev_priv); ++ ++ r600_cp_init_ring_buffer(dev, dev_priv, file_priv); ++ ++ dev_priv->last_buf = 0; ++ ++ r600_do_engine_reset(dev); ++ r600_test_writeback(dev_priv); ++ ++ return 0; ++} ++ ++int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ DRM_DEBUG("\n"); ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) { ++ r700_vm_init(dev); ++ r700_cp_load_microcode(dev_priv); ++ } else { ++ r600_vm_init(dev); ++ r600_cp_load_microcode(dev_priv); ++ } ++ r600_cp_init_ring_buffer(dev, dev_priv, file_priv); ++ r600_do_engine_reset(dev); ++ ++ return 0; ++} ++ ++/* Wait for the CP to go idle. ++ */ ++int r600_do_cp_idle(drm_radeon_private_t *dev_priv) ++{ ++ RING_LOCALS; ++ DRM_DEBUG("\n"); ++ ++ BEGIN_RING(5); ++ OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); ++ OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); ++ /* wait for 3D idle clean */ ++ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); ++ OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); ++ OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); ++ ++ ADVANCE_RING(); ++ COMMIT_RING(); ++ ++ return r600_do_wait_for_idle(dev_priv); ++} ++ ++/* Start the Command Processor. ++ */ ++void r600_do_cp_start(drm_radeon_private_t *dev_priv) ++{ ++ u32 cp_me; ++ RING_LOCALS; ++ DRM_DEBUG("\n"); ++ ++ BEGIN_RING(7); ++ OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5)); ++ OUT_RING(0x00000001); ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) ++ OUT_RING(0x00000003); ++ else ++ OUT_RING(0x00000000); ++ OUT_RING((dev_priv->r600_max_hw_contexts - 1)); ++ OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1)); ++ OUT_RING(0x00000000); ++ OUT_RING(0x00000000); ++ ADVANCE_RING(); ++ COMMIT_RING(); ++ ++ /* set the mux and reset the halt bit */ ++ cp_me = 0xff; ++ RADEON_WRITE(R600_CP_ME_CNTL, cp_me); ++ ++ dev_priv->cp_running = 1; ++ ++} ++ ++void r600_do_cp_reset(drm_radeon_private_t *dev_priv) ++{ ++ u32 cur_read_ptr; ++ DRM_DEBUG("\n"); ++ ++ cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR); ++ RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr); ++ SET_RING_HEAD(dev_priv, cur_read_ptr); ++ dev_priv->ring.tail = cur_read_ptr; ++} ++ ++void r600_do_cp_stop(drm_radeon_private_t *dev_priv) ++{ ++ uint32_t cp_me; ++ ++ DRM_DEBUG("\n"); ++ ++ cp_me = 0xff | R600_CP_ME_HALT; ++ ++ RADEON_WRITE(R600_CP_ME_CNTL, cp_me); ++ ++ dev_priv->cp_running = 0; ++} ++ ++int r600_cp_dispatch_indirect(struct drm_device *dev, ++ struct drm_buf *buf, int start, int end) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ RING_LOCALS; ++ ++ if (start != end) { ++ unsigned long offset = (dev_priv->gart_buffers_offset ++ + buf->offset + start); ++ int dwords = (end - start + 3) / sizeof(u32); ++ ++ DRM_DEBUG("dwords:%d\n", dwords); ++ DRM_DEBUG("offset 0x%lx\n", offset); ++ ++ ++ /* Indirect buffer data must be a multiple of 16 dwords. ++ * pad the data with a Type-2 CP packet. ++ */ ++ while (dwords & 0xf) { ++ u32 *data = (u32 *) ++ ((char *)dev->agp_buffer_map->handle ++ + buf->offset + start); ++ data[dwords++] = RADEON_CP_PACKET2; ++ } ++ ++ /* Fire off the indirect buffer */ ++ BEGIN_RING(4); ++ OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2)); ++ OUT_RING((offset & 0xfffffffc)); ++ OUT_RING((upper_32_bits(offset) & 0xff)); ++ OUT_RING(dwords); ++ ADVANCE_RING(); ++ } ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/radeon/r600_microcode.h b/drivers/gpu/drm/radeon/r600_microcode.h +new file mode 100644 +index 0000000..778c8b4 +--- /dev/null ++++ b/drivers/gpu/drm/radeon/r600_microcode.h +@@ -0,0 +1,23297 @@ ++/* ++ * Copyright 2008-2009 Advanced Micro Devices, Inc. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef R600_MICROCODE_H ++#define R600_MICROCODE_H ++ ++static const int ME_JUMP_TABLE_START = 1764; ++static const int ME_JUMP_TABLE_END = 1792; ++ ++#define PFP_UCODE_SIZE 576 ++#define PM4_UCODE_SIZE 1792 ++#define R700_PFP_UCODE_SIZE 848 ++#define R700_PM4_UCODE_SIZE 1360 ++ ++static const u32 R600_cp_microcode[][3] = { ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0000ffff, 0x00284621, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x000 }, ++ { 0x00010000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x614 }, ++ { 0x00000000, 0x00600000, 0x5b2 }, ++ { 0x00000000, 0x00600000, 0x5c5 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000f00, 0x00281622, 0x000 }, ++ { 0x00000008, 0x00211625, 0x000 }, ++ { 0x00000020, 0x00203625, 0x000 }, ++ { 0x8d000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x002f0225, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x018 }, ++ { 0x00412000, 0x00404811, 0x019 }, ++ { 0x00422000, 0x00204811, 0x000 }, ++ { 0x8e000000, 0x00204411, 0x000 }, ++ { 0x00000031, 0x00204a2d, 0x000 }, ++ { 0x90000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x0000000c, 0x00211622, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000019, 0x00211a22, 0x000 }, ++ { 0x00000004, 0x00281a26, 0x000 }, ++ { 0x00000000, 0x002914c5, 0x000 }, ++ { 0x00000021, 0x00203625, 0x000 }, ++ { 0x00000000, 0x003a1402, 0x000 }, ++ { 0x00000016, 0x00211625, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x0000001d, 0x00200e2d, 0x000 }, ++ { 0xfffffffc, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002914a3, 0x000 }, ++ { 0x0000001d, 0x00203625, 0x000 }, ++ { 0x00008000, 0x00280e22, 0x000 }, ++ { 0x00000007, 0x00220e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x20000000, 0x00280e22, 0x000 }, ++ { 0x00000006, 0x00210e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x00000000, 0x00220222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x038 }, ++ { 0x00000000, 0x2ee00000, 0x035 }, ++ { 0x00000000, 0x2ce00000, 0x037 }, ++ { 0x00000000, 0x00400e2d, 0x039 }, ++ { 0x00000008, 0x00200e2d, 0x000 }, ++ { 0x00000009, 0x0040122d, 0x046 }, ++ { 0x00000001, 0x00400e2d, 0x039 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x03e }, ++ { 0x00000008, 0x00401c11, 0x041 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x0000000f, 0x00281e27, 0x000 }, ++ { 0x00000003, 0x00221e27, 0x000 }, ++ { 0x7fc00000, 0x00281a23, 0x000 }, ++ { 0x00000014, 0x00211a26, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000008, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x00290cc7, 0x000 }, ++ { 0x00000030, 0x00203624, 0x000 }, ++ { 0x00007f00, 0x00281221, 0x000 }, ++ { 0x00001400, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x04b }, ++ { 0x00000001, 0x00290e23, 0x000 }, ++ { 0x00000010, 0x00203623, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfff80000, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x003a2c02, 0x000 }, ++ { 0x00000002, 0x00220e2b, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x00000011, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00294a23, 0x000 }, ++ { 0x00000030, 0x00204a2d, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000032, 0x00200e2d, 0x000 }, ++ { 0x060a0200, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x061 }, ++ { 0x00000000, 0x2ee00000, 0x05f }, ++ { 0x00000000, 0x2ce00000, 0x05e }, ++ { 0x00000000, 0x00400e2d, 0x062 }, ++ { 0x00000001, 0x00400e2d, 0x062 }, ++ { 0x0000000a, 0x00200e2d, 0x000 }, ++ { 0x0000000b, 0x0040122d, 0x06a }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x7fc00000, 0x00281623, 0x000 }, ++ { 0x00000014, 0x00211625, 0x000 }, ++ { 0x00000001, 0x00331625, 0x000 }, ++ { 0x80000000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00290ca3, 0x000 }, ++ { 0x3ffffc00, 0x00290e23, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x06d }, ++ { 0x00000100, 0x00401c11, 0x070 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x000000f0, 0x00281e27, 0x000 }, ++ { 0x00000004, 0x00221e27, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0xfffff0ff, 0x00281a30, 0x000 }, ++ { 0x0000a028, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948e6, 0x000 }, ++ { 0x0000a018, 0x00204411, 0x000 }, ++ { 0x3fffffff, 0x00284a23, 0x000 }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x0000002d, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a3, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x080 }, ++ { 0x0000002e, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a4, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x081 }, ++ { 0x00000000, 0x00400000, 0x087 }, ++ { 0x0000002d, 0x00203623, 0x000 }, ++ { 0x0000002e, 0x00203624, 0x000 }, ++ { 0x0000001d, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x087 }, ++ { 0x00000000, 0x00600000, 0x5ed }, ++ { 0x00000000, 0x00600000, 0x5e1 }, ++ { 0x00000002, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x08a }, ++ { 0x00000018, 0xc0403620, 0x090 }, ++ { 0x00000000, 0x2ee00000, 0x08e }, ++ { 0x00000000, 0x2ce00000, 0x08d }, ++ { 0x00000002, 0x00400e2d, 0x08f }, ++ { 0x00000003, 0x00400e2d, 0x08f }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000018, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x095 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x09d }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x2ee00000, 0x09b }, ++ { 0x00000000, 0x2ce00000, 0x09a }, ++ { 0x00000002, 0x00400e2d, 0x09c }, ++ { 0x00000003, 0x00400e2d, 0x09c }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x003f0000, 0x00280e23, 0x000 }, ++ { 0x00000010, 0x00210e23, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x0000001e, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0a4 }, ++ { 0x0000001c, 0xc0203620, 0x000 }, ++ { 0x0000001f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0a7 }, ++ { 0x0000001b, 0xc0203620, 0x000 }, ++ { 0x00000008, 0x00210e2b, 0x000 }, ++ { 0x0000007f, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0db }, ++ { 0x00000000, 0x27000000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x28c }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000000c, 0x00221e30, 0x000 }, ++ { 0x99800000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x0020122d, 0x000 }, ++ { 0x00000008, 0x00221224, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00291ce4, 0x000 }, ++ { 0x00000000, 0x00604807, 0x128 }, ++ { 0x9b000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x9c000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x0033146f, 0x000 }, ++ { 0x00000001, 0x00333e23, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0x00203c05, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e007, 0x00204411, 0x000 }, ++ { 0x0000000f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0c5 }, ++ { 0x00f8ff08, 0x00204811, 0x000 }, ++ { 0x98000000, 0x00404811, 0x0d6 }, ++ { 0x000000f0, 0x00280e22, 0x000 }, ++ { 0x000000a0, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x0d4 }, ++ { 0x00000013, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0cf }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0ce }, ++ { 0x00003f00, 0x00400c11, 0x0d0 }, ++ { 0x00001f00, 0x00400c11, 0x0d0 }, ++ { 0x00000f00, 0x00200c11, 0x000 }, ++ { 0x00380009, 0x00294a23, 0x000 }, ++ { 0x3f000000, 0x00280e2b, 0x000 }, ++ { 0x00000002, 0x00220e23, 0x000 }, ++ { 0x00000007, 0x00494a23, 0x0d6 }, ++ { 0x00380f09, 0x00204811, 0x000 }, ++ { 0x68000007, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000a202, 0x00204411, 0x000 }, ++ { 0x00ff0000, 0x00284a22, 0x000 }, ++ { 0x00000030, 0x00200e2d, 0x000 }, ++ { 0x0000002e, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x002f0083, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0e3 }, ++ { 0x00000000, 0x00600000, 0x5e7 }, ++ { 0x00000000, 0x00400000, 0x0e4 }, ++ { 0x00000000, 0x00600000, 0x5ea }, ++ { 0x00000007, 0x0020222d, 0x000 }, ++ { 0x00000005, 0x00220e22, 0x000 }, ++ { 0x00100000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x000000ef, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x0000001d, 0x00200e2d, 0x000 }, ++ { 0x00000003, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x0f1 }, ++ { 0x0000000b, 0x00210228, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0f1 }, ++ { 0x00000400, 0x00292228, 0x000 }, ++ { 0x0000001a, 0x00203628, 0x000 }, ++ { 0x0000001c, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0f6 }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000001e, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x104 }, ++ { 0x0000a30f, 0x00204411, 0x000 }, ++ { 0x00000013, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x0fd }, ++ { 0xffffffff, 0x00404811, 0x104 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x100 }, ++ { 0x0000ffff, 0x00404811, 0x104 }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x103 }, ++ { 0x000000ff, 0x00404811, 0x104 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0002c400, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x10b }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000019, 0x00203623, 0x000 }, ++ { 0x00000018, 0x40224a20, 0x000 }, ++ { 0x00000010, 0xc0424a20, 0x10d }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000019, 0x00203623, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000000a, 0x00201011, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x114 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00531224, 0x110 }, ++ { 0xffbfffff, 0x00283a2e, 0x000 }, ++ { 0x0000001b, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x127 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0x00000018, 0x00220e30, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e00e, 0x00204411, 0x000 }, ++ { 0x07f8ff08, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00294a23, 0x000 }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00800000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204806, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x614 }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x613 }, ++ { 0x00000004, 0x00404c11, 0x12e }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x2fe }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x19f }, ++ { 0x00000000, 0x00600000, 0x151 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40280620, 0x000 }, ++ { 0x00000010, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x00341461, 0x000 }, ++ { 0x00000000, 0x00741882, 0x2a4 }, ++ { 0x0001a1fd, 0x00604411, 0x2c9 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x138 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x2fe }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x19f }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x151 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0681a20, 0x2a4 }, ++ { 0x0001a1fd, 0x00604411, 0x2c9 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x149 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00300a2f, 0x000 }, ++ { 0x00000001, 0x00210a22, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600000, 0x17c }, ++ { 0x00000000, 0x00600000, 0x18d }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00202c08, 0x000 }, ++ { 0x00000000, 0x00202411, 0x000 }, ++ { 0x00000000, 0x00202811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00221e29, 0x000 }, ++ { 0x00000000, 0x007048eb, 0x189 }, ++ { 0x00000000, 0x00600000, 0x2a4 }, ++ { 0x00000001, 0x40330620, 0x000 }, ++ { 0x00000000, 0xc0302409, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x28c }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x173 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000001, 0x00530621, 0x16f }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x184 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000013, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x0078042a, 0x2e4 }, ++ { 0x00000000, 0x00202809, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x165 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000210, 0x00600411, 0x2fe }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x181 }, ++ { 0x0000001b, 0xc0203620, 0x000 }, ++ { 0x0000001c, 0xc0203620, 0x000 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x46000000, 0x00600811, 0x19f }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x188 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00804811, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40281620, 0x000 }, ++ { 0x00000010, 0xc0811a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00221e30, 0x000 }, ++ { 0x00000032, 0x00201a2d, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfffbff09, 0x00204811, 0x000 }, ++ { 0x00000011, 0x0020222d, 0x000 }, ++ { 0x00001fff, 0x00294a28, 0x000 }, ++ { 0x00000006, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000100, 0x00201811, 0x000 }, ++ { 0x00000008, 0x00621e28, 0x128 }, ++ { 0x00000008, 0x00822228, 0x000 }, ++ { 0x0002c000, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00600e2d, 0x1aa }, ++ { 0x0000001c, 0x00600e2d, 0x1aa }, ++ { 0x0000c008, 0x00204411, 0x000 }, ++ { 0x0000001d, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x1a6 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x39000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00804802, 0x000 }, ++ { 0x00000020, 0x00202e2d, 0x000 }, ++ { 0x00000000, 0x003b0d63, 0x000 }, ++ { 0x00000008, 0x00224a23, 0x000 }, ++ { 0x00000010, 0x00224a23, 0x000 }, ++ { 0x00000018, 0x00224a23, 0x000 }, ++ { 0x00000000, 0x00804803, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x2fe }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x19f }, ++ { 0x00000007, 0x0021062f, 0x000 }, ++ { 0x00000019, 0x00200a2d, 0x000 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000ffff, 0x40282220, 0x000 }, ++ { 0x0000000f, 0x00262228, 0x000 }, ++ { 0x00000010, 0x40212620, 0x000 }, ++ { 0x0000000f, 0x00262629, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1cd }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000081, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000080, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1c9 }, ++ { 0x00000000, 0x00600000, 0x1d6 }, ++ { 0x00000001, 0x00531e27, 0x1c5 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000001f, 0x00280a22, 0x000 }, ++ { 0x0000001f, 0x00282a2a, 0x000 }, ++ { 0x00000001, 0x00530621, 0x1be }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00304a2f, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00301e2f, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x1d6 }, ++ { 0x00000001, 0x00531e27, 0x1d2 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x0000000f, 0x00260e23, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000000f, 0x00261224, 0x000 }, ++ { 0x00000000, 0x00201411, 0x000 }, ++ { 0x00000000, 0x00601811, 0x2a4 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022b, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1e5 }, ++ { 0x00000010, 0x00221628, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a29, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x0020480a, 0x000 }, ++ { 0x00000000, 0x00202c11, 0x000 }, ++ { 0x00000010, 0x00221623, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a24, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x00731503, 0x1f2 }, ++ { 0x00000000, 0x00201805, 0x000 }, ++ { 0x00000000, 0x00731524, 0x1f2 }, ++ { 0x00000000, 0x002d14c5, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00000000, 0x00202003, 0x000 }, ++ { 0x00000000, 0x00802404, 0x000 }, ++ { 0x0000000f, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x613 }, ++ { 0x00000000, 0x002b1405, 0x000 }, ++ { 0x00000001, 0x00901625, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x2fe }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x19f }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00294a22, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a21, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0x40281220, 0x000 }, ++ { 0x00000010, 0xc0211a20, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211620, 0x000 }, ++ { 0x00000000, 0x00741465, 0x2a4 }, ++ { 0x0001a1fd, 0x00604411, 0x2c9 }, ++ { 0x00000001, 0x00330621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x206 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x1ff }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x5c5 }, ++ { 0x00000000, 0x0040040f, 0x200 }, ++ { 0x00000000, 0x00600000, 0x5b2 }, ++ { 0x00000000, 0x00600000, 0x5c5 }, ++ { 0x00000210, 0x00600411, 0x2fe }, ++ { 0x00000000, 0x00600000, 0x18d }, ++ { 0x00000000, 0x00600000, 0x189 }, ++ { 0x00000000, 0x00600000, 0x2a4 }, ++ { 0x00000000, 0x00600000, 0x28c }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x21f }, ++ { 0x00000000, 0xc0404800, 0x21c }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00600411, 0x2e4 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x5b2 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000018, 0x40210a20, 0x000 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x235 }, ++ { 0x0000001a, 0x0020222d, 0x000 }, ++ { 0x00080101, 0x00292228, 0x000 }, ++ { 0x0000001a, 0x00203628, 0x000 }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x23a }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000010, 0x00600411, 0x2fe }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x19f }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x265 }, ++ { 0x0000001d, 0x00201e2d, 0x000 }, ++ { 0x00000001, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x253 }, ++ { 0x00000018, 0x00201e2d, 0x000 }, ++ { 0x0000ffff, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00341c27, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x248 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e5, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x24b }, ++ { 0x00000000, 0x00201407, 0x000 }, ++ { 0x00000018, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x00341c47, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x250 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x253 }, ++ { 0x00000000, 0x00201807, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2aa }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00342023, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x25b }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x25a }, ++ { 0x00000016, 0x00404811, 0x25f }, ++ { 0x00000018, 0x00404811, 0x25f }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x25e }, ++ { 0x00000017, 0x00404811, 0x25f }, ++ { 0x00000019, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00604411, 0x2d2 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x23f }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000010, 0x40210620, 0x000 }, ++ { 0x0000ffff, 0xc0280a20, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0881a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x614 }, ++ { 0x00000000, 0x00600000, 0x5b2 }, ++ { 0x00000000, 0xc0600000, 0x28c }, ++ { 0x00000005, 0x00200a2d, 0x000 }, ++ { 0x00000008, 0x00220a22, 0x000 }, ++ { 0x00000034, 0x00201a2d, 0x000 }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00007000, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00311ce6, 0x000 }, ++ { 0x00000033, 0x00201a2d, 0x000 }, ++ { 0x0000000c, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x27b }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000034, 0x00203623, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00691ce2, 0x128 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x286 }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000024, 0x00403627, 0x000 }, ++ { 0x0000000c, 0xc0220a20, 0x000 }, ++ { 0x00000032, 0x00203622, 0x000 }, ++ { 0x00000031, 0xc0403620, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000009, 0x00204811, 0x000 }, ++ { 0xa1000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000029, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce3, 0x000 }, ++ { 0x00000029, 0x00203627, 0x000 }, ++ { 0x0000002a, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce4, 0x000 }, ++ { 0x0000002a, 0x00203627, 0x000 }, ++ { 0x0000002b, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a3, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x0000002b, 0x00203627, 0x000 }, ++ { 0x0000002c, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x0000002c, 0x00803627, 0x000 }, ++ { 0x00000029, 0x00203623, 0x000 }, ++ { 0x0000002a, 0x00203624, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x0000002b, 0x00203627, 0x000 }, ++ { 0x00000000, 0x00311cc4, 0x000 }, ++ { 0x0000002c, 0x00803627, 0x000 }, ++ { 0x00000022, 0x00203627, 0x000 }, ++ { 0x00000023, 0x00203628, 0x000 }, ++ { 0x0000001d, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x2c5 }, ++ { 0x00000000, 0x00400000, 0x2c2 }, ++ { 0x00000022, 0x00203627, 0x000 }, ++ { 0x00000023, 0x00203628, 0x000 }, ++ { 0x0000001d, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2c2 }, ++ { 0x00000003, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2c5 }, ++ { 0x0000002b, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e1, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2c5 }, ++ { 0x00000029, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a1, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2c5 }, ++ { 0x0000002c, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e2, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2c5 }, ++ { 0x0000002a, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2c5 }, ++ { 0x00000000, 0x00600000, 0x5ed }, ++ { 0x00000000, 0x00600000, 0x29e }, ++ { 0x00000000, 0x00400000, 0x2c7 }, ++ { 0x00000000, 0x00600000, 0x29e }, ++ { 0x00000000, 0x00600000, 0x5e4 }, ++ { 0x00000000, 0x00400000, 0x2c7 }, ++ { 0x00000000, 0x00600000, 0x290 }, ++ { 0x00000000, 0x00400000, 0x2c7 }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000023, 0x0080222d, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca1, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x003808c5, 0x000 }, ++ { 0x00000000, 0x00300841, 0x000 }, ++ { 0x00000001, 0x00220a22, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x0000001d, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x301 }, ++ { 0xffffffef, 0x00280621, 0x000 }, ++ { 0x0000001a, 0x0020222d, 0x000 }, ++ { 0x0000f8e0, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00294901, 0x000 }, ++ { 0x00000000, 0x00894901, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x97000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00002257, 0x00204411, 0x000 }, ++ { 0x00000003, 0xc0484a20, 0x000 }, ++ { 0x0000225d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x5c5 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x00000001, 0x40304a20, 0x000 }, ++ { 0x00000002, 0xc0304a20, 0x000 }, ++ { 0x00000001, 0x00530a22, 0x334 }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x614 }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x33d }, ++ { 0x00000014, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x351 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000016, 0x00604811, 0x35e }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x355 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00404811, 0x349 }, ++ { 0x00000028, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x349 }, ++ { 0x00002104, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x00000035, 0x00203626, 0x000 }, ++ { 0x00000049, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000000, 0x002f0226, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x360 }, ++ { 0x00000035, 0x00801a2d, 0x000 }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x00000015, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x376 }, ++ { 0x0000001e, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x380 }, ++ { 0x00000020, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x38c }, ++ { 0x0000000f, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x398 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x398 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x39a }, ++ { 0x00000016, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x39f }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x08000000, 0x00290a22, 0x000 }, ++ { 0x00000003, 0x40210e20, 0x000 }, ++ { 0x0000000c, 0xc0211220, 0x000 }, ++ { 0x00080000, 0x00281224, 0x000 }, ++ { 0x00000014, 0xc0221620, 0x000 }, ++ { 0x00000000, 0x002914a4, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948a2, 0x000 }, ++ { 0x0000a1fe, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000015, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x614 }, ++ { 0x00000015, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x382 }, ++ { 0x0000210e, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x614 }, ++ { 0x00000003, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x38e }, ++ { 0x00002108, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00404811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000006, 0x00404811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000016, 0x00604811, 0x35e }, ++ { 0x00000016, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x0000001d, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3b9 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x614 }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3ab }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0xbabecafe, 0x00204811, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00404811, 0x000 }, ++ { 0x00002170, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000a, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3be }, ++ { 0x8c000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00003fff, 0x40280a20, 0x000 }, ++ { 0x80000000, 0x40280e20, 0x000 }, ++ { 0x40000000, 0xc0281220, 0x000 }, ++ { 0x00040000, 0x00694622, 0x614 }, ++ { 0x00000000, 0x00201410, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3cc }, ++ { 0x00000000, 0xc0401800, 0x3cf }, ++ { 0x00003fff, 0xc0281a20, 0x000 }, ++ { 0x00040000, 0x00694626, 0x614 }, ++ { 0x00000000, 0x00201810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3d2 }, ++ { 0x00000000, 0xc0401c00, 0x3d5 }, ++ { 0x00003fff, 0xc0281e20, 0x000 }, ++ { 0x00040000, 0x00694627, 0x614 }, ++ { 0x00000000, 0x00201c10, 0x000 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0x002820c5, 0x000 }, ++ { 0x00000000, 0x004948e8, 0x000 }, ++ { 0xa5800000, 0x00200811, 0x000 }, ++ { 0x00002000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x3fd }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x0000001f, 0xc0210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3e2 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0xc0481220, 0x3ea }, ++ { 0xa7800000, 0x00200811, 0x000 }, ++ { 0x0000a000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x3fd }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00304883, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x83000000, 0x00604411, 0x3fd }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xa9800000, 0x00200811, 0x000 }, ++ { 0x0000c000, 0x00400c11, 0x3e5 }, ++ { 0xab800000, 0x00200811, 0x000 }, ++ { 0x0000f8e0, 0x00400c11, 0x3e5 }, ++ { 0xad800000, 0x00200811, 0x000 }, ++ { 0x0000f880, 0x00400c11, 0x3e5 }, ++ { 0xb3800000, 0x00200811, 0x000 }, ++ { 0x0000f3fc, 0x00400c11, 0x3e5 }, ++ { 0xaf800000, 0x00200811, 0x000 }, ++ { 0x0000e000, 0x00400c11, 0x3e5 }, ++ { 0xb1800000, 0x00200811, 0x000 }, ++ { 0x0000f000, 0x00400c11, 0x3e5 }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00002148, 0x00204811, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00182000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0018a000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0018c000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0018f8e0, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0018f880, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0018e000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0018f000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0018f3fc, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x86000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x85000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x614 }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00404c02, 0x42e }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x00000000, 0xc0201400, 0x000 }, ++ { 0x00000000, 0xc0201800, 0x000 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x43c }, ++ { 0x00000000, 0xc0202000, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x00000010, 0x00280a23, 0x000 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x444 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0x00694624, 0x614 }, ++ { 0x00000000, 0x00400000, 0x44d }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x449 }, ++ { 0x9e000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x44c }, ++ { 0x00000000, 0x002824f0, 0x000 }, ++ { 0x00000007, 0x00280a23, 0x000 }, ++ { 0x00000001, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x454 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x04e00000, 0x46d }, ++ { 0x00000000, 0x00400000, 0x47a }, ++ { 0x00000002, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x459 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x02e00000, 0x46d }, ++ { 0x00000000, 0x00400000, 0x47a }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x45e }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x46d }, ++ { 0x00000000, 0x00400000, 0x47a }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x463 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46d }, ++ { 0x00000000, 0x00400000, 0x47a }, ++ { 0x00000005, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x468 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x46d }, ++ { 0x00000000, 0x00400000, 0x47a }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46d }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x08e00000, 0x46d }, ++ { 0x00000000, 0x00400000, 0x47a }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x000 }, ++ { 0x00000008, 0x00210a23, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x477 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x480 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x00404c08, 0x43c }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000011, 0x40211220, 0x000 }, ++ { 0x00000012, 0x40211620, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x48a }, ++ { 0x00040000, 0xc0494a20, 0x48b }, ++ { 0xfffbffff, 0xc0284a20, 0x000 }, ++ { 0x00000000, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x497 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000c, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x493 }, ++ { 0xa0000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00204811, 0x000 }, ++ { 0x0000216b, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000216c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x491 }, ++ { 0x00000000, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4ae }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x4a9 }, ++ { 0x9e000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x4ac }, ++ { 0x00000000, 0x00400000, 0x4b2 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x614 }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4b9 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0404810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x614 }, ++ { 0x00000000, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4bb }, ++ { 0x00002180, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000003, 0x00333e2f, 0x000 }, ++ { 0x00000001, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4eb }, ++ { 0x00000035, 0x00200a2d, 0x000 }, ++ { 0x00040000, 0x18e00c11, 0x4da }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xd8c04800, 0x4ce }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000036, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x00290c83, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000011, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x491 }, ++ { 0x00000035, 0xc0203620, 0x000 }, ++ { 0x00000036, 0xc0403620, 0x000 }, ++ { 0x0000304a, 0x00204411, 0x000 }, ++ { 0xe0000000, 0xc0484a20, 0x000 }, ++ { 0x0000000f, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4f2 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0xd9000000, 0x000 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00204811, 0x000 }, ++ { 0x000000ff, 0x00280e30, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x4f6 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x50b }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000024, 0x00203623, 0x000 }, ++ { 0x00000034, 0x00203623, 0x000 }, ++ { 0x00000032, 0x00203623, 0x000 }, ++ { 0x00000031, 0x00203623, 0x000 }, ++ { 0x0000001d, 0x00203623, 0x000 }, ++ { 0x0000002d, 0x00203623, 0x000 }, ++ { 0x0000002e, 0x00203623, 0x000 }, ++ { 0x0000001b, 0x00203623, 0x000 }, ++ { 0x0000001c, 0x00203623, 0x000 }, ++ { 0xffffe000, 0x00200c11, 0x000 }, ++ { 0x00000029, 0x00203623, 0x000 }, ++ { 0x0000002a, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00200c11, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x0000002c, 0x00203623, 0x000 }, ++ { 0xf1ffffff, 0x00283a2e, 0x000 }, ++ { 0x0000001a, 0xc0220e20, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000033, 0x40203620, 0x000 }, ++ { 0x87000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x9d000000, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x40214a20, 0x000 }, ++ { 0x96000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x0000001f, 0x00211624, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00281e23, 0x000 }, ++ { 0x00000008, 0x00222223, 0x000 }, ++ { 0xfffff000, 0x00282228, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x00000027, 0x00203628, 0x000 }, ++ { 0x00000018, 0x00211e23, 0x000 }, ++ { 0x00000028, 0x00203627, 0x000 }, ++ { 0x00000002, 0x00221624, 0x000 }, ++ { 0x00000000, 0x003014a8, 0x000 }, ++ { 0x00000026, 0x00203625, 0x000 }, ++ { 0x00000003, 0x00211a24, 0x000 }, ++ { 0x10000000, 0x00281a26, 0x000 }, ++ { 0xefffffff, 0x00283a2e, 0x000 }, ++ { 0x00000000, 0x004938ce, 0x602 }, ++ { 0x00000001, 0x40280a20, 0x000 }, ++ { 0x00000006, 0x40280e20, 0x000 }, ++ { 0x00000300, 0xc0281220, 0x000 }, ++ { 0x00000008, 0x00211224, 0x000 }, ++ { 0x00000000, 0xc0201620, 0x000 }, ++ { 0x00000000, 0xc0201a20, 0x000 }, ++ { 0x00000000, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x541 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x614 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00020000, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x549 }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x55b }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x549 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x614 }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x55b }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x54d }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x55b }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x559 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x554 }, ++ { 0x9e000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x557 }, ++ { 0x00000000, 0x00401c10, 0x55b }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x55d }, ++ { 0x00000000, 0x00600000, 0x5a4 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56d }, ++ { 0x0000a2b7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x614 }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x0000a2c4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x56b }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000001, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x57d }, ++ { 0x0000a2bb, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x614 }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x0000a2c5, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x57b }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000002, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x58d }, ++ { 0x0000a2bf, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x614 }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x0000a2c6, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x58b }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x0000a2c3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x614 }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x0000a2c7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x599 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x85000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x0000304a, 0x00204411, 0x000 }, ++ { 0x01000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00400000, 0x59f }, ++ { 0xa4000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x5a4 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x88000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0xff000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000002, 0x00804811, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x5b7 }, ++ { 0x00001000, 0x00200811, 0x000 }, ++ { 0x00000034, 0x00203622, 0x000 }, ++ { 0x00000000, 0x00600000, 0x5bb }, ++ { 0x00000000, 0x00600000, 0x5a4 }, ++ { 0x98000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x5bb }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000022, 0x00204811, 0x000 }, ++ { 0x89000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0xff000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000002, 0x00804811, 0x000 }, ++ { 0x0000217a, 0xc0204411, 0x000 }, ++ { 0x00000000, 0x00404811, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0xff000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000002, 0x00804811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x5e1 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0xc0204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000016, 0x00604811, 0x35e }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x09800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x614 }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000004, 0x00404c11, 0x5dc }, ++ { 0x0000001d, 0x00201e2d, 0x000 }, ++ { 0x00000004, 0x00291e27, 0x000 }, ++ { 0x0000001d, 0x00803627, 0x000 }, ++ { 0x0000001d, 0x00201e2d, 0x000 }, ++ { 0xfffffffb, 0x00281e27, 0x000 }, ++ { 0x0000001d, 0x00803627, 0x000 }, ++ { 0x0000001d, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00291e27, 0x000 }, ++ { 0x0000001d, 0x00803627, 0x000 }, ++ { 0x0000001d, 0x00201e2d, 0x000 }, ++ { 0xfffffff7, 0x00281e27, 0x000 }, ++ { 0x0000001d, 0x00803627, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000016, 0x00604811, 0x35e }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x01800000, 0x00204811, 0x000 }, ++ { 0x00ffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x614 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x613 }, ++ { 0x00000010, 0x00404c11, 0x5f9 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x38c00000, 0x000 }, ++ { 0x00000025, 0x00200a2d, 0x000 }, ++ { 0x00000026, 0x00200e2d, 0x000 }, ++ { 0x00000027, 0x0020122d, 0x000 }, ++ { 0x00000028, 0x0020162d, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000004, 0x00301224, 0x000 }, ++ { 0x00000000, 0x002f0064, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x612 }, ++ { 0x00000003, 0x00281a22, 0x000 }, ++ { 0x00000008, 0x00221222, 0x000 }, ++ { 0xfffff000, 0x00281224, 0x000 }, ++ { 0x00000000, 0x002910c4, 0x000 }, ++ { 0x00000027, 0x00403624, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x614 }, ++ { 0x9f000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x617 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x2fe }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x19f }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0xc0204411, 0x000 }, ++ { 0x00000029, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x0000002c, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000002a, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000002b, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00404811, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x013304ef, 0x059b0239, 0x000 }, ++ { 0x01b00159, 0x0425059b, 0x000 }, ++ { 0x021201f6, 0x02390142, 0x000 }, ++ { 0x0210022e, 0x0289022a, 0x000 }, ++ { 0x03c2059b, 0x059b059b, 0x000 }, ++ { 0x05cd05ce, 0x0308059b, 0x000 }, ++ { 0x059b05a0, 0x03090329, 0x000 }, ++ { 0x0313026b, 0x032b031d, 0x000 }, ++ { 0x059b059b, 0x059b059b, 0x000 }, ++ { 0x059b052c, 0x059b059b, 0x000 }, ++ { 0x03a5059b, 0x04a2032d, 0x000 }, ++ { 0x04810433, 0x0423059b, 0x000 }, ++ { 0x04bb04ed, 0x042704c8, 0x000 }, ++ { 0x043304f4, 0x033a0365, 0x000 }, ++ { 0x059b059b, 0x059b059b, 0x000 }, ++ { 0x059b059b, 0x059b059b, 0x000 }, ++ { 0x059b059b, 0x05b905a2, 0x000 }, ++ { 0x059b059b, 0x0007059b, 0x000 }, ++ { 0x059b059b, 0x059b059b, 0x000 }, ++ { 0x059b059b, 0x059b059b, 0x000 }, ++ { 0x03e303d8, 0x03f303f1, 0x000 }, ++ { 0x03f903f5, 0x03f703fb, 0x000 }, ++ { 0x04070403, 0x040f040b, 0x000 }, ++ { 0x04170413, 0x041f041b, 0x000 }, ++ { 0x059b059b, 0x059b059b, 0x000 }, ++ { 0x059b059b, 0x059b059b, 0x000 }, ++ { 0x059b059b, 0x059b059b, 0x000 }, ++ { 0x00020600, 0x06190006, 0x000 }, ++}; ++ ++static const u32 R600_pfp_microcode[] = { ++0xd40071, ++0xd40072, ++0xca0400, ++0xa00000, ++0x7e828b, ++0x800003, ++0xca0400, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xc41838, ++0xca2400, ++0xca2800, ++0x9581a8, ++0xc41c3a, ++0xc3c000, ++0xca0800, ++0xca0c00, ++0x7c744b, ++0xc20005, ++0x99c000, ++0xc41c3a, ++0x7c744c, ++0xc0fff0, ++0x042c04, ++0x309002, ++0x7d2500, ++0x351402, ++0x7d350b, ++0x255403, ++0x7cd580, ++0x259c03, ++0x95c004, ++0xd5001b, ++0x7eddc1, ++0x7d9d80, ++0xd6801b, ++0xd5801b, ++0xd4401e, ++0xd5401e, ++0xd6401e, ++0xd6801e, ++0xd4801e, ++0xd4c01e, ++0x9783d4, ++0xd5c01e, ++0xca0800, ++0x80001b, ++0xca0c00, ++0xe4011e, ++0xd4001e, ++0x80000d, ++0xc41838, ++0xe4013e, ++0xd4001e, ++0x80000d, ++0xc41838, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca1800, ++0xd4401e, ++0xd5801e, ++0x800054, ++0xd40073, ++0xd4401e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd48019, ++0xd4c018, ++0xd50017, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xe2001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0xd48060, ++0xd4401e, ++0x800002, ++0xd4801e, ++0xca0800, ++0xd48061, ++0xd4401e, ++0x800002, ++0xd4801e, ++0xca0800, ++0xca0c00, ++0xd4401e, ++0xd48016, ++0xd4c016, ++0xd4801e, ++0x8001b9, ++0xd4c01e, ++0xc6083e, ++0xca0c00, ++0xca1000, ++0x948004, ++0xca1400, ++0xe420f3, ++0xd42013, ++0xd56065, ++0xd4e01c, ++0xd5201c, ++0xd5601c, ++0x800002, ++0x062001, ++0xc6083e, ++0xca0c00, ++0xca1000, ++0x9483f7, ++0xca1400, ++0xe420f3, ++0x80007a, ++0xd42013, ++0xc6083e, ++0xca0c00, ++0xca1000, ++0x9883ef, ++0xca1400, ++0xd40064, ++0x80008e, ++0x000000, ++0xc41432, ++0xc6183e, ++0xc4082f, ++0x954005, ++0xc40c30, ++0xd4401e, ++0x800002, ++0xee001e, ++0x9583f5, ++0xc41031, ++0xd44033, ++0xd52065, ++0xd4a01c, ++0xd4e01c, ++0xd5201c, ++0xd40073, ++0xe4015e, ++0xd4001e, ++0x8001b9, ++0x062001, ++0x0a2001, ++0xd60074, ++0xc40836, ++0xc61040, ++0x988007, ++0xcc3835, ++0x95010f, ++0xd4001f, ++0xd46062, ++0x800002, ++0xd42062, ++0xcc1433, ++0x8401bc, ++0xd40070, ++0xd5401e, ++0x800002, ++0xee001e, ++0xca0c00, ++0xca1000, ++0xd4c01a, ++0x8401bc, ++0xd5001a, ++0xcc0443, ++0x35101f, ++0x2c9401, ++0x7d098b, ++0x984005, ++0x7d15cb, ++0xd4001a, ++0x8001b9, ++0xd4006d, ++0x344401, ++0xcc0c44, ++0x98403a, ++0xcc2c46, ++0x958004, ++0xcc0445, ++0x8001b9, ++0xd4001a, ++0xd4c01a, ++0x282801, ++0x8400f3, ++0xcc1003, ++0x98801b, ++0x04380c, ++0x8400f3, ++0xcc1003, ++0x988017, ++0x043808, ++0x8400f3, ++0xcc1003, ++0x988013, ++0x043804, ++0x8400f3, ++0xcc1003, ++0x988014, ++0xcc1047, ++0x9a8009, ++0xcc1448, ++0x9840da, ++0xd4006d, ++0xcc1844, ++0xd5001a, ++0xd5401a, ++0x8000cc, ++0xd5801a, ++0x96c0d3, ++0xd4006d, ++0x8001b9, ++0xd4006e, ++0x9ac003, ++0xd4006d, ++0xd4006e, ++0x800002, ++0xec007f, ++0x9ac0ca, ++0xd4006d, ++0x8001b9, ++0xd4006e, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0x7d9103, ++0x7dd583, ++0x7d190c, ++0x35cc1f, ++0x35701f, ++0x7cf0cb, ++0x7cd08b, ++0x880000, ++0x7e8e8b, ++0x95c004, ++0xd4006e, ++0x8001b9, ++0xd4001a, ++0xd4c01a, ++0xcc0803, ++0xcc0c03, ++0xcc1003, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0xcc2403, ++0xcc2803, ++0x35c41f, ++0x36b01f, ++0x7c704b, ++0x34f01f, ++0x7c704b, ++0x35701f, ++0x7c704b, ++0x7d8881, ++0x7dccc1, ++0x7e5101, ++0x7e9541, ++0x7c9082, ++0x7cd4c2, ++0x7c848b, ++0x9ac003, ++0x7c8c8b, ++0x2c8801, ++0x98809c, ++0xd4006d, ++0x98409a, ++0xd4006e, ++0xcc0847, ++0xcc0c48, ++0xcc1044, ++0xd4801a, ++0xd4c01a, ++0x800104, ++0xd5001a, ++0xcc0832, ++0xd40032, ++0x9482d8, ++0xca0c00, ++0xd4401e, ++0x800002, ++0xd4001e, ++0xe4011e, ++0xd4001e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd4401e, ++0xca1400, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xd5401e, ++0xd54034, ++0x800002, ++0xee001e, ++0x280404, ++0xe2001a, ++0xe2001a, ++0xd4401a, ++0xca3800, ++0xcc0803, ++0xcc0c03, ++0xcc0c03, ++0xcc0c03, ++0x9882bc, ++0x000000, ++0x8401bc, ++0xd7806f, ++0x800002, ++0xee001f, ++0xca0400, ++0xc2ff00, ++0xcc0834, ++0xc13fff, ++0x7c74cb, ++0x7cc90b, ++0x7d010f, ++0x9902af, ++0x7c738b, ++0x8401bc, ++0xd7806f, ++0x800002, ++0xee001f, ++0xca0800, ++0x281900, ++0x7d898b, ++0x958014, ++0x281404, ++0xca0c00, ++0xca1000, ++0xca1c00, ++0xca2400, ++0xe2001f, ++0xd4c01a, ++0xd5001a, ++0xd5401a, ++0xcc1803, ++0xcc2c03, ++0xcc2c03, ++0xcc2c03, ++0x7da58b, ++0x7d9c47, ++0x984296, ++0x000000, ++0x800164, ++0xd4c01a, ++0xd4401e, ++0xd4801e, ++0x800002, ++0xee001e, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0x248c06, ++0x0ccc06, ++0x98c006, ++0xcc1049, ++0x990004, ++0xd40071, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xd4801e, ++0x800002, ++0xee001e, ++0xca0800, ++0xca0c00, ++0x34d018, ++0x251001, ++0x95001f, ++0xc17fff, ++0xca1000, ++0xca1400, ++0xca1800, ++0xd4801d, ++0xd4c01d, ++0x7db18b, ++0xc14202, ++0xc2c001, ++0xd5801d, ++0x34dc0e, ++0x7d5d4c, ++0x7f734c, ++0xd7401e, ++0xd5001e, ++0xd5401e, ++0xc14200, ++0xc2c000, ++0x099c01, ++0x31dc10, ++0x7f5f4c, ++0x7f734c, ++0x7d8380, ++0xd5806f, ++0xd58066, ++0xd7401e, ++0xec005e, ++0xc82402, ++0x8001b9, ++0xd60074, ++0xd4401e, ++0xd4801e, ++0xd4c01e, ++0x800002, ++0xee001e, ++0x800002, ++0xee001f, ++0xd4001f, ++0x800002, ++0xd4001f, ++0xd4001f, ++0x880000, ++0xd4001f, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x010174, ++0x02017b, ++0x030090, ++0x040080, ++0x050005, ++0x060040, ++0x070033, ++0x08012f, ++0x090047, ++0x0a0037, ++0x1001b7, ++0x1700a4, ++0x22013d, ++0x23014c, ++0x2000b5, ++0x240128, ++0x27004e, ++0x28006b, ++0x2a0061, ++0x2b0053, ++0x2f0066, ++0x320088, ++0x340182, ++0x3c0159, ++0x3f0073, ++0x41018f, ++0x440131, ++0x550176, ++0x56017d, ++0x60000c, ++0x610035, ++0x620039, ++0x630039, ++0x640039, ++0x650039, ++0x660039, ++0x670039, ++0x68003b, ++0x690042, ++0x6a0049, ++0x6b0049, ++0x6c0049, ++0x6d0049, ++0x6e0049, ++0x6f0049, ++0x7301b7, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++0x000007, ++}; ++ ++static const u32 RV610_cp_microcode[][3] = { ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0000ffff, 0x00284621, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x000 }, ++ { 0x00010000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x00000000, 0x00600000, 0x631 }, ++ { 0x00000000, 0x00600000, 0x645 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000f00, 0x00281622, 0x000 }, ++ { 0x00000008, 0x00211625, 0x000 }, ++ { 0x00000018, 0x00203625, 0x000 }, ++ { 0x8d000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x002f0225, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x018 }, ++ { 0x00412000, 0x00404811, 0x019 }, ++ { 0x00422000, 0x00204811, 0x000 }, ++ { 0x8e000000, 0x00204411, 0x000 }, ++ { 0x00000028, 0x00204a2d, 0x000 }, ++ { 0x90000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x0000000c, 0x00211622, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000019, 0x00211a22, 0x000 }, ++ { 0x00000004, 0x00281a26, 0x000 }, ++ { 0x00000000, 0x002914c5, 0x000 }, ++ { 0x00000019, 0x00203625, 0x000 }, ++ { 0x00000000, 0x003a1402, 0x000 }, ++ { 0x00000016, 0x00211625, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0xfffffffc, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002914a3, 0x000 }, ++ { 0x00000017, 0x00203625, 0x000 }, ++ { 0x00008000, 0x00280e22, 0x000 }, ++ { 0x00000007, 0x00220e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x20000000, 0x00280e22, 0x000 }, ++ { 0x00000006, 0x00210e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x00000000, 0x00220222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x038 }, ++ { 0x00000000, 0x2ee00000, 0x035 }, ++ { 0x00000000, 0x2ce00000, 0x037 }, ++ { 0x00000000, 0x00400e2d, 0x039 }, ++ { 0x00000008, 0x00200e2d, 0x000 }, ++ { 0x00000009, 0x0040122d, 0x046 }, ++ { 0x00000001, 0x00400e2d, 0x039 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x03e }, ++ { 0x00000008, 0x00401c11, 0x041 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x0000000f, 0x00281e27, 0x000 }, ++ { 0x00000003, 0x00221e27, 0x000 }, ++ { 0x7fc00000, 0x00281a23, 0x000 }, ++ { 0x00000014, 0x00211a26, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000008, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x00290cc7, 0x000 }, ++ { 0x00000027, 0x00203624, 0x000 }, ++ { 0x00007f00, 0x00281221, 0x000 }, ++ { 0x00001400, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x04b }, ++ { 0x00000001, 0x00290e23, 0x000 }, ++ { 0x0000000e, 0x00203623, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfff80000, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x003a2c02, 0x000 }, ++ { 0x00000002, 0x00220e2b, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x0000000f, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00204a2d, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000029, 0x00200e2d, 0x000 }, ++ { 0x060a0200, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x061 }, ++ { 0x00000000, 0x2ee00000, 0x05f }, ++ { 0x00000000, 0x2ce00000, 0x05e }, ++ { 0x00000000, 0x00400e2d, 0x062 }, ++ { 0x00000001, 0x00400e2d, 0x062 }, ++ { 0x0000000a, 0x00200e2d, 0x000 }, ++ { 0x0000000b, 0x0040122d, 0x06a }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x7fc00000, 0x00281623, 0x000 }, ++ { 0x00000014, 0x00211625, 0x000 }, ++ { 0x00000001, 0x00331625, 0x000 }, ++ { 0x80000000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00290ca3, 0x000 }, ++ { 0x3ffffc00, 0x00290e23, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x06d }, ++ { 0x00000100, 0x00401c11, 0x070 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x000000f0, 0x00281e27, 0x000 }, ++ { 0x00000004, 0x00221e27, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0xfffff0ff, 0x00281a30, 0x000 }, ++ { 0x0000a028, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948e6, 0x000 }, ++ { 0x0000a018, 0x00204411, 0x000 }, ++ { 0x3fffffff, 0x00284a23, 0x000 }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000030, 0x0020162d, 0x000 }, ++ { 0x00000002, 0x00291625, 0x000 }, ++ { 0x00000030, 0x00203625, 0x000 }, ++ { 0x00000025, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a3, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x083 }, ++ { 0x00000026, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a4, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x084 }, ++ { 0x00000000, 0x00400000, 0x08a }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203624, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x08a }, ++ { 0x00000000, 0x00600000, 0x668 }, ++ { 0x00000000, 0x00600000, 0x65c }, ++ { 0x00000002, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x08d }, ++ { 0x00000012, 0xc0403620, 0x093 }, ++ { 0x00000000, 0x2ee00000, 0x091 }, ++ { 0x00000000, 0x2ce00000, 0x090 }, ++ { 0x00000002, 0x00400e2d, 0x092 }, ++ { 0x00000003, 0x00400e2d, 0x092 }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000012, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x098 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x0a0 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x2ee00000, 0x09e }, ++ { 0x00000000, 0x2ce00000, 0x09d }, ++ { 0x00000002, 0x00400e2d, 0x09f }, ++ { 0x00000003, 0x00400e2d, 0x09f }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x003f0000, 0x00280e23, 0x000 }, ++ { 0x00000010, 0x00210e23, 0x000 }, ++ { 0x00000011, 0x00203623, 0x000 }, ++ { 0x0000001e, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0a7 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x0000001f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0aa }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000008, 0x00210e2b, 0x000 }, ++ { 0x0000007f, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0e1 }, ++ { 0x00000000, 0x27000000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x0b3 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000000c, 0x00221e30, 0x000 }, ++ { 0x99800000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x0020122d, 0x000 }, ++ { 0x00000008, 0x00221224, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00291ce4, 0x000 }, ++ { 0x00000000, 0x00604807, 0x12f }, ++ { 0x9b000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x9c000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x0033146f, 0x000 }, ++ { 0x00000001, 0x00333e23, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0x00203c05, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e007, 0x00204411, 0x000 }, ++ { 0x0000000f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0cb }, ++ { 0x00f8ff08, 0x00204811, 0x000 }, ++ { 0x98000000, 0x00404811, 0x0dc }, ++ { 0x000000f0, 0x00280e22, 0x000 }, ++ { 0x000000a0, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x0da }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d5 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d4 }, ++ { 0x00003f00, 0x00400c11, 0x0d6 }, ++ { 0x00001f00, 0x00400c11, 0x0d6 }, ++ { 0x00000f00, 0x00200c11, 0x000 }, ++ { 0x00380009, 0x00294a23, 0x000 }, ++ { 0x3f000000, 0x00280e2b, 0x000 }, ++ { 0x00000002, 0x00220e23, 0x000 }, ++ { 0x00000007, 0x00494a23, 0x0dc }, ++ { 0x00380f09, 0x00204811, 0x000 }, ++ { 0x68000007, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000a202, 0x00204411, 0x000 }, ++ { 0x00ff0000, 0x00280e22, 0x000 }, ++ { 0x00000080, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00200e2d, 0x000 }, ++ { 0x00000026, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x002f0083, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0ea }, ++ { 0x00000000, 0x00600000, 0x662 }, ++ { 0x00000000, 0x00400000, 0x0eb }, ++ { 0x00000000, 0x00600000, 0x665 }, ++ { 0x00000007, 0x0020222d, 0x000 }, ++ { 0x00000005, 0x00220e22, 0x000 }, ++ { 0x00100000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x000000ef, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000003, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x0f8 }, ++ { 0x0000000b, 0x00210228, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0f8 }, ++ { 0x00000400, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000001c, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0fd }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000001e, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x10b }, ++ { 0x0000a30f, 0x00204411, 0x000 }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x104 }, ++ { 0xffffffff, 0x00404811, 0x10b }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x107 }, ++ { 0x0000ffff, 0x00404811, 0x10b }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x10a }, ++ { 0x000000ff, 0x00404811, 0x10b }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0002c400, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x112 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000018, 0x40224a20, 0x000 }, ++ { 0x00000010, 0xc0424a20, 0x114 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000000a, 0x00201011, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x11b }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00531224, 0x117 }, ++ { 0xffbfffff, 0x00283a2e, 0x000 }, ++ { 0x0000001b, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x12e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0x00000018, 0x00220e30, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e00e, 0x00204411, 0x000 }, ++ { 0x07f8ff08, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00294a23, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00800000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204806, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68d }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x68c }, ++ { 0x00000004, 0x00404c11, 0x135 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000001c, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x13c }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40280620, 0x000 }, ++ { 0x00000010, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x00341461, 0x000 }, ++ { 0x00000000, 0x00741882, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x147 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0681a20, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x158 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00300a2f, 0x000 }, ++ { 0x00000001, 0x00210a22, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600000, 0x18f }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00202c08, 0x000 }, ++ { 0x00000000, 0x00202411, 0x000 }, ++ { 0x00000000, 0x00202811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00221e29, 0x000 }, ++ { 0x00000000, 0x007048eb, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000001, 0x40330620, 0x000 }, ++ { 0x00000000, 0xc0302409, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x181 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x186 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x186 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000001, 0x00530621, 0x182 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x197 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000011, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x0078042a, 0x2fb }, ++ { 0x00000000, 0x00202809, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x174 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x194 }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x46000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x19b }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00804811, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40281620, 0x000 }, ++ { 0x00000010, 0xc0811a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00221e30, 0x000 }, ++ { 0x00000029, 0x00201a2d, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfffbff09, 0x00204811, 0x000 }, ++ { 0x0000000f, 0x0020222d, 0x000 }, ++ { 0x00001fff, 0x00294a28, 0x000 }, ++ { 0x00000006, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000100, 0x00201811, 0x000 }, ++ { 0x00000008, 0x00621e28, 0x12f }, ++ { 0x00000008, 0x00822228, 0x000 }, ++ { 0x0002c000, 0x00204411, 0x000 }, ++ { 0x00000015, 0x00600e2d, 0x1bd }, ++ { 0x00000016, 0x00600e2d, 0x1bd }, ++ { 0x0000c008, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x1b9 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x39000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00804802, 0x000 }, ++ { 0x00000018, 0x00202e2d, 0x000 }, ++ { 0x00000000, 0x003b0d63, 0x000 }, ++ { 0x00000008, 0x00224a23, 0x000 }, ++ { 0x00000010, 0x00224a23, 0x000 }, ++ { 0x00000018, 0x00224a23, 0x000 }, ++ { 0x00000000, 0x00804803, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000007, 0x0021062f, 0x000 }, ++ { 0x00000013, 0x00200a2d, 0x000 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000ffff, 0x40282220, 0x000 }, ++ { 0x0000000f, 0x00262228, 0x000 }, ++ { 0x00000010, 0x40212620, 0x000 }, ++ { 0x0000000f, 0x00262629, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1e0 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000081, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000080, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1dc }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1d8 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000001f, 0x00280a22, 0x000 }, ++ { 0x0000001f, 0x00282a2a, 0x000 }, ++ { 0x00000001, 0x00530621, 0x1d1 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00304a2f, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00301e2f, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1e5 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x0000000f, 0x00260e23, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000000f, 0x00261224, 0x000 }, ++ { 0x00000000, 0x00201411, 0x000 }, ++ { 0x00000000, 0x00601811, 0x2bb }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022b, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1f8 }, ++ { 0x00000010, 0x00221628, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a29, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x0020480a, 0x000 }, ++ { 0x00000000, 0x00202c11, 0x000 }, ++ { 0x00000010, 0x00221623, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a24, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x00731503, 0x205 }, ++ { 0x00000000, 0x00201805, 0x000 }, ++ { 0x00000000, 0x00731524, 0x205 }, ++ { 0x00000000, 0x002d14c5, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00000000, 0x00202003, 0x000 }, ++ { 0x00000000, 0x00802404, 0x000 }, ++ { 0x0000000f, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x68c }, ++ { 0x00000000, 0x002b1405, 0x000 }, ++ { 0x00000001, 0x00901625, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00294a22, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a21, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0x40281220, 0x000 }, ++ { 0x00000010, 0xc0211a20, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211620, 0x000 }, ++ { 0x00000000, 0x00741465, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00000001, 0x00330621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x219 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x212 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x645 }, ++ { 0x00000000, 0x0040040f, 0x213 }, ++ { 0x00000000, 0x00600000, 0x631 }, ++ { 0x00000000, 0x00600000, 0x645 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00000000, 0x00600000, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x232 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x236 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x236 }, ++ { 0x00000000, 0xc0404800, 0x233 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00600411, 0x2fb }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x631 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000018, 0x40210a20, 0x000 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x24c }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x00080101, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x251 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000010, 0x00600411, 0x315 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x27c }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000001, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x26a }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x0000ffff, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00341c27, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x25f }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e5, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x262 }, ++ { 0x00000000, 0x00201407, 0x000 }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x00341c47, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x267 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x26a }, ++ { 0x00000000, 0x00201807, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2c1 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00342023, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x272 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x271 }, ++ { 0x00000016, 0x00404811, 0x276 }, ++ { 0x00000018, 0x00404811, 0x276 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x275 }, ++ { 0x00000017, 0x00404811, 0x276 }, ++ { 0x00000019, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00604411, 0x2e9 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x256 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000010, 0x40210620, 0x000 }, ++ { 0x0000ffff, 0xc0280a20, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0881a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x00000000, 0x00600000, 0x631 }, ++ { 0x00000000, 0xc0600000, 0x2a3 }, ++ { 0x00000005, 0x00200a2d, 0x000 }, ++ { 0x00000008, 0x00220a22, 0x000 }, ++ { 0x0000002b, 0x00201a2d, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00007000, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00311ce6, 0x000 }, ++ { 0x0000002a, 0x00201a2d, 0x000 }, ++ { 0x0000000c, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x292 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00691ce2, 0x12f }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x29d }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000001c, 0x00403627, 0x000 }, ++ { 0x0000000c, 0xc0220a20, 0x000 }, ++ { 0x00000029, 0x00203622, 0x000 }, ++ { 0x00000028, 0xc0403620, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000009, 0x00204811, 0x000 }, ++ { 0xa1000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce3, 0x000 }, ++ { 0x00000021, 0x00203627, 0x000 }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce4, 0x000 }, ++ { 0x00000022, 0x00203627, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a3, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203624, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000000, 0x00311cc4, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x2dc }, ++ { 0x00000000, 0x00400000, 0x2d9 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2d9 }, ++ { 0x00000003, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2dc }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e1, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a1, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e2, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000000, 0x00600000, 0x668 }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00600000, 0x65f }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2a7 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x0000001a, 0x00201e2d, 0x000 }, ++ { 0x0000001b, 0x0080222d, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca1, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x003808c5, 0x000 }, ++ { 0x00000000, 0x00300841, 0x000 }, ++ { 0x00000001, 0x00220a22, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000017, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x318 }, ++ { 0xffffffef, 0x00280621, 0x000 }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x0000f8e0, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00294901, 0x000 }, ++ { 0x00000000, 0x00894901, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x97000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00002257, 0x00204411, 0x000 }, ++ { 0x00000003, 0xc0484a20, 0x000 }, ++ { 0x0000225d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x645 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x00000001, 0x40304a20, 0x000 }, ++ { 0x00000002, 0xc0304a20, 0x000 }, ++ { 0x00000001, 0x00530a22, 0x34b }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x354 }, ++ { 0x00000014, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x364 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00604802, 0x36e }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x36a }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35f }, ++ { 0x00000028, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5c0 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35f }, ++ { 0x0000002c, 0x00203626, 0x000 }, ++ { 0x00000049, 0x00201811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000000, 0x002f0226, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x370 }, ++ { 0x0000002c, 0x00801a2d, 0x000 }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x00000015, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x386 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b1 }, ++ { 0x00000016, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b5 }, ++ { 0x00000020, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x39c }, ++ { 0x0000000f, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a8 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a8 }, ++ { 0x0000001e, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x390 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x08000000, 0x00290a22, 0x000 }, ++ { 0x00000003, 0x40210e20, 0x000 }, ++ { 0x0000000c, 0xc0211220, 0x000 }, ++ { 0x00080000, 0x00281224, 0x000 }, ++ { 0x00000014, 0xc0221620, 0x000 }, ++ { 0x00000000, 0x002914a4, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948a2, 0x000 }, ++ { 0x0000a1fe, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000015, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x392 }, ++ { 0x0000210e, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000003, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x39e }, ++ { 0x00002108, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x80000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000010, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3ae }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00404811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x0000001d, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3ce }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3c0 }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0xbabecafe, 0x00204811, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00404811, 0x000 }, ++ { 0x00002170, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000a, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3d3 }, ++ { 0x8c000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00003fff, 0x40280a20, 0x000 }, ++ { 0x80000000, 0x40280e20, 0x000 }, ++ { 0x40000000, 0xc0281220, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68d }, ++ { 0x00000000, 0x00201410, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e1 }, ++ { 0x00000000, 0xc0401800, 0x3e4 }, ++ { 0x00003fff, 0xc0281a20, 0x000 }, ++ { 0x00040000, 0x00694626, 0x68d }, ++ { 0x00000000, 0x00201810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e7 }, ++ { 0x00000000, 0xc0401c00, 0x3ea }, ++ { 0x00003fff, 0xc0281e20, 0x000 }, ++ { 0x00040000, 0x00694627, 0x68d }, ++ { 0x00000000, 0x00201c10, 0x000 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0x002820c5, 0x000 }, ++ { 0x00000000, 0x004948e8, 0x000 }, ++ { 0xa5800000, 0x00200811, 0x000 }, ++ { 0x00002000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x0000001f, 0xc0210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3f7 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0xc0481220, 0x3ff }, ++ { 0xa7800000, 0x00200811, 0x000 }, ++ { 0x0000a000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00304883, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xa9800000, 0x00200811, 0x000 }, ++ { 0x0000c000, 0x00400c11, 0x3fa }, ++ { 0xab800000, 0x00200811, 0x000 }, ++ { 0x0000f8e0, 0x00400c11, 0x3fa }, ++ { 0xad800000, 0x00200811, 0x000 }, ++ { 0x0000f880, 0x00400c11, 0x3fa }, ++ { 0xb3800000, 0x00200811, 0x000 }, ++ { 0x0000f3fc, 0x00400c11, 0x3fa }, ++ { 0xaf800000, 0x00200811, 0x000 }, ++ { 0x0000e000, 0x00400c11, 0x3fa }, ++ { 0xb1800000, 0x00200811, 0x000 }, ++ { 0x0000f000, 0x00400c11, 0x3fa }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00002148, 0x00204811, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x01182000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0218a000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0318c000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0418f8e0, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0518f880, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0618e000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0718f000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0818f3fc, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000030, 0x00200a2d, 0x000 }, ++ { 0x00000000, 0xc0290c40, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x86000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x85000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00000018, 0x40210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x445 }, ++ { 0x00800000, 0xc0494a20, 0x446 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68d }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00404c02, 0x44b }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x00000000, 0xc0201400, 0x000 }, ++ { 0x00000000, 0xc0201800, 0x000 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x459 }, ++ { 0x00000000, 0xc0202000, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x00000010, 0x00280a23, 0x000 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x461 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0x00694624, 0x68d }, ++ { 0x00000000, 0x00400000, 0x466 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00604805, 0x692 }, ++ { 0x00000000, 0x002824f0, 0x000 }, ++ { 0x00000007, 0x00280a23, 0x000 }, ++ { 0x00000001, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46d }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x04e00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000002, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x472 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x02e00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x477 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x47c }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000005, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x481 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x486 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x08e00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x000 }, ++ { 0x00000008, 0x00210a23, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x490 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x499 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x00404c08, 0x459 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000011, 0x40211220, 0x000 }, ++ { 0x00000012, 0x40211620, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4a3 }, ++ { 0x00040000, 0xc0494a20, 0x4a4 }, ++ { 0xfffbffff, 0xc0284a20, 0x000 }, ++ { 0x00000000, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4b0 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000c, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4ac }, ++ { 0xa0000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00204811, 0x000 }, ++ { 0x0000216b, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000216c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4aa }, ++ { 0x00000000, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4c3 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x692 }, ++ { 0x00000000, 0x00400000, 0x4c7 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x68d }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4ce }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0404810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000000, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4d0 }, ++ { 0x00002180, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000003, 0x00333e2f, 0x000 }, ++ { 0x00000001, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x500 }, ++ { 0x0000002c, 0x00200a2d, 0x000 }, ++ { 0x00040000, 0x18e00c11, 0x4ef }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xd8c04800, 0x4e3 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000002d, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x00290c83, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000011, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4aa }, ++ { 0x0000002c, 0xc0203620, 0x000 }, ++ { 0x0000002d, 0xc0403620, 0x000 }, ++ { 0x0000000f, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x505 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0xd9000000, 0x000 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xb5000000, 0x00204411, 0x000 }, ++ { 0x00002000, 0x00204811, 0x000 }, ++ { 0xb6000000, 0x00204411, 0x000 }, ++ { 0x0000a000, 0x00204811, 0x000 }, ++ { 0xb7000000, 0x00204411, 0x000 }, ++ { 0x0000c000, 0x00204811, 0x000 }, ++ { 0xb8000000, 0x00204411, 0x000 }, ++ { 0x0000f8e0, 0x00204811, 0x000 }, ++ { 0xb9000000, 0x00204411, 0x000 }, ++ { 0x0000f880, 0x00204811, 0x000 }, ++ { 0xba000000, 0x00204411, 0x000 }, ++ { 0x0000e000, 0x00204811, 0x000 }, ++ { 0xbb000000, 0x00204411, 0x000 }, ++ { 0x0000f000, 0x00204811, 0x000 }, ++ { 0xbc000000, 0x00204411, 0x000 }, ++ { 0x0000f3fc, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00204811, 0x000 }, ++ { 0x000000ff, 0x00280e30, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x519 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x52e }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000001c, 0x00203623, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000029, 0x00203623, 0x000 }, ++ { 0x00000028, 0x00203623, 0x000 }, ++ { 0x00000017, 0x00203623, 0x000 }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203623, 0x000 }, ++ { 0x00000015, 0x00203623, 0x000 }, ++ { 0x00000016, 0x00203623, 0x000 }, ++ { 0xffffe000, 0x00200c11, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00200c11, 0x000 }, ++ { 0x00000023, 0x00203623, 0x000 }, ++ { 0x00000024, 0x00203623, 0x000 }, ++ { 0xf1ffffff, 0x00283a2e, 0x000 }, ++ { 0x0000001a, 0xc0220e20, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000002a, 0x40203620, 0x000 }, ++ { 0x87000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x9d000000, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x40214a20, 0x000 }, ++ { 0x96000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x0000001f, 0x00211624, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x0000001d, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00281e23, 0x000 }, ++ { 0x00000008, 0x00222223, 0x000 }, ++ { 0xfffff000, 0x00282228, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x0000001f, 0x00203628, 0x000 }, ++ { 0x00000018, 0x00211e23, 0x000 }, ++ { 0x00000020, 0x00203627, 0x000 }, ++ { 0x00000002, 0x00221624, 0x000 }, ++ { 0x00000000, 0x003014a8, 0x000 }, ++ { 0x0000001e, 0x00203625, 0x000 }, ++ { 0x00000003, 0x00211a24, 0x000 }, ++ { 0x10000000, 0x00281a26, 0x000 }, ++ { 0xefffffff, 0x00283a2e, 0x000 }, ++ { 0x00000000, 0x004938ce, 0x67b }, ++ { 0x00000001, 0x40280a20, 0x000 }, ++ { 0x00000006, 0x40280e20, 0x000 }, ++ { 0x00000300, 0xc0281220, 0x000 }, ++ { 0x00000008, 0x00211224, 0x000 }, ++ { 0x00000000, 0xc0201620, 0x000 }, ++ { 0x00000000, 0xc0201a20, 0x000 }, ++ { 0x00000000, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x566 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68d }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00020000, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56e }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x57c }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68d }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x57c }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x572 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x57c }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x57a }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x692 }, ++ { 0x00000000, 0x00401c10, 0x57c }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x57e }, ++ { 0x00000000, 0x00600000, 0x5c9 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x58f }, ++ { 0x0000a2b7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x68d }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000a2c4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x58d }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000001, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5a0 }, ++ { 0x0000a2bb, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x68d }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000a2c5, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x59e }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000002, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5b1 }, ++ { 0x0000a2bf, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x68d }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000a2c6, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5af }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x0000a2c3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x68d }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000a2c7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5be }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x85000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x0000304a, 0x00204411, 0x000 }, ++ { 0x01000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00400000, 0x5c4 }, ++ { 0xa4000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x5c9 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000002c, 0x00203621, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5d0 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000030, 0x00403621, 0x5e3 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x5e3 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a092, 0x00604411, 0x68d }, ++ { 0x00000031, 0x00203630, 0x000 }, ++ { 0x0004a093, 0x00604411, 0x68d }, ++ { 0x00000032, 0x00203630, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x68d }, ++ { 0x00000033, 0x00203630, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x68d }, ++ { 0x00000034, 0x00203630, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x68d }, ++ { 0x00000035, 0x00203630, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x68d }, ++ { 0x00000036, 0x00203630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x88000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000001, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x62c }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x62c }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x605 }, ++ { 0x0000a092, 0x00204411, 0x000 }, ++ { 0x00000031, 0x00204a2d, 0x000 }, ++ { 0x0000a093, 0x00204411, 0x000 }, ++ { 0x00000032, 0x00204a2d, 0x000 }, ++ { 0x0000a2b6, 0x00204411, 0x000 }, ++ { 0x00000033, 0x00204a2d, 0x000 }, ++ { 0x0000a2ba, 0x00204411, 0x000 }, ++ { 0x00000034, 0x00204a2d, 0x000 }, ++ { 0x0000a2be, 0x00204411, 0x000 }, ++ { 0x00000035, 0x00204a2d, 0x000 }, ++ { 0x0000a2c2, 0x00204411, 0x000 }, ++ { 0x00000036, 0x00204a2d, 0x000 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x000001ff, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x62b }, ++ { 0x00000000, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x60e }, ++ { 0x0004a003, 0x00604411, 0x68d }, ++ { 0x0000a003, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x613 }, ++ { 0x0004a010, 0x00604411, 0x68d }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x62b }, ++ { 0x0004a011, 0x00604411, 0x68d }, ++ { 0x0000a011, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a012, 0x00604411, 0x68d }, ++ { 0x0000a012, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a013, 0x00604411, 0x68d }, ++ { 0x0000a013, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a014, 0x00604411, 0x68d }, ++ { 0x0000a014, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a015, 0x00604411, 0x68d }, ++ { 0x0000a015, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a016, 0x00604411, 0x68d }, ++ { 0x0000a016, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a017, 0x00604411, 0x68d }, ++ { 0x0000a017, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000002c, 0x0080062d, 0x000 }, ++ { 0xff000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000002, 0x00804811, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x63d }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000002, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x63b }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x00001000, 0x00200811, 0x000 }, ++ { 0x0000002b, 0x00203622, 0x000 }, ++ { 0x00000000, 0x00600000, 0x641 }, ++ { 0x00000000, 0x00600000, 0x5c9 }, ++ { 0x98000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x641 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000022, 0x00204811, 0x000 }, ++ { 0x89000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00404811, 0x62d }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404811, 0x62d }, ++ { 0x00000000, 0x00600000, 0x65c }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0xc0204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x09800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68d }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000004, 0x00404c11, 0x656 }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000004, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffffb, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffff7, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x01800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68d }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x68c }, ++ { 0x00000010, 0x00404c11, 0x672 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x38c00000, 0x000 }, ++ { 0x0000001d, 0x00200a2d, 0x000 }, ++ { 0x0000001e, 0x00200e2d, 0x000 }, ++ { 0x0000001f, 0x0020122d, 0x000 }, ++ { 0x00000020, 0x0020162d, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000004, 0x00301224, 0x000 }, ++ { 0x00000000, 0x002f0064, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x68b }, ++ { 0x00000003, 0x00281a22, 0x000 }, ++ { 0x00000008, 0x00221222, 0x000 }, ++ { 0xfffff000, 0x00281224, 0x000 }, ++ { 0x00000000, 0x002910c4, 0x000 }, ++ { 0x0000001f, 0x00403624, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x68d }, ++ { 0x9f000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x690 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x692 }, ++ { 0x9e000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x695 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0xc0204411, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000024, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000022, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00404811, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x01420502, 0x05c00250, 0x000 }, ++ { 0x01c30168, 0x043f05c0, 0x000 }, ++ { 0x02250209, 0x02500151, 0x000 }, ++ { 0x02230245, 0x02a00241, 0x000 }, ++ { 0x03d705c0, 0x05c005c0, 0x000 }, ++ { 0x0649064a, 0x031f05c0, 0x000 }, ++ { 0x05c005c5, 0x03200340, 0x000 }, ++ { 0x032a0282, 0x03420334, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c00551, 0x05c005c0, 0x000 }, ++ { 0x03ba05c0, 0x04bb0344, 0x000 }, ++ { 0x049a0450, 0x043d05c0, 0x000 }, ++ { 0x04d005c0, 0x044104dd, 0x000 }, ++ { 0x04500507, 0x03510375, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c005c0, 0x063f05c7, 0x000 }, ++ { 0x05c005c0, 0x000705c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x03f803ed, 0x04080406, 0x000 }, ++ { 0x040e040a, 0x040c0410, 0x000 }, ++ { 0x041c0418, 0x04240420, 0x000 }, ++ { 0x042c0428, 0x04340430, 0x000 }, ++ { 0x05c005c0, 0x043805c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x00020679, 0x06970006, 0x000 }, ++}; ++ ++static const u32 RV610_pfp_microcode[] = { ++0xca0400, ++0xa00000, ++0x7e828b, ++0x7c038b, ++0x8001b8, ++0x7c038b, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xc41838, ++0xca2400, ++0xca2800, ++0x9581a8, ++0xc41c3a, ++0xc3c000, ++0xca0800, ++0xca0c00, ++0x7c744b, ++0xc20005, ++0x99c000, ++0xc41c3a, ++0x7c744c, ++0xc0fff0, ++0x042c04, ++0x309002, ++0x7d2500, ++0x351402, ++0x7d350b, ++0x255403, ++0x7cd580, ++0x259c03, ++0x95c004, ++0xd5001b, ++0x7eddc1, ++0x7d9d80, ++0xd6801b, ++0xd5801b, ++0xd4401e, ++0xd5401e, ++0xd6401e, ++0xd6801e, ++0xd4801e, ++0xd4c01e, ++0x9783d3, ++0xd5c01e, ++0xca0800, ++0x80001a, ++0xca0c00, ++0xe4011e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xe4013e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca1800, ++0xd4401e, ++0xd5801e, ++0x800053, ++0xd40075, ++0xd4401e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd48019, ++0xd4c018, ++0xd50017, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xe2001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0xd48060, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xd48061, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xca0c00, ++0xd4401e, ++0xd48016, ++0xd4c016, ++0xd4801e, ++0x8001b8, ++0xd4c01e, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x948004, ++0xca1400, ++0xe420f3, ++0xd42013, ++0xd56065, ++0xd4e01c, ++0xd5201c, ++0xd5601c, ++0x800000, ++0x062001, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9483f7, ++0xca1400, ++0xe420f3, ++0x800079, ++0xd42013, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9883ef, ++0xca1400, ++0xd40064, ++0x80008d, ++0x000000, ++0xc41432, ++0xc61843, ++0xc4082f, ++0x954005, ++0xc40c30, ++0xd4401e, ++0x800000, ++0xee001e, ++0x9583f5, ++0xc41031, ++0xd44033, ++0xd52065, ++0xd4a01c, ++0xd4e01c, ++0xd5201c, ++0xe4015e, ++0xd4001e, ++0x800000, ++0x062001, ++0xca1800, ++0x0a2001, ++0xd60076, ++0xc40836, ++0x988007, ++0xc61045, ++0x950110, ++0xd4001f, ++0xd46062, ++0x800000, ++0xd42062, ++0xcc3835, ++0xcc1433, ++0x8401bb, ++0xd40072, ++0xd5401e, ++0x800000, ++0xee001e, ++0xe2001a, ++0x8401bb, ++0xe2001a, ++0xcc104b, ++0xcc0447, ++0x2c9401, ++0x7d098b, ++0x984005, ++0x7d15cb, ++0xd4001a, ++0x8001b8, ++0xd4006d, ++0x344401, ++0xcc0c48, ++0x98403a, ++0xcc2c4a, ++0x958004, ++0xcc0449, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0x282801, ++0x8400f0, ++0xcc1003, ++0x98801b, ++0x04380c, ++0x8400f0, ++0xcc1003, ++0x988017, ++0x043808, ++0x8400f0, ++0xcc1003, ++0x988013, ++0x043804, ++0x8400f0, ++0xcc1003, ++0x988014, ++0xcc104c, ++0x9a8009, ++0xcc144d, ++0x9840dc, ++0xd4006d, ++0xcc1848, ++0xd5001a, ++0xd5401a, ++0x8000c9, ++0xd5801a, ++0x96c0d5, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0x9ac003, ++0xd4006d, ++0xd4006e, ++0x800000, ++0xec007f, ++0x9ac0cc, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0x7d9103, ++0x7dd583, ++0x7d190c, ++0x35cc1f, ++0x35701f, ++0x7cf0cb, ++0x7cd08b, ++0x880000, ++0x7e8e8b, ++0x95c004, ++0xd4006e, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0xcc0803, ++0xcc0c03, ++0xcc1003, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0xcc2403, ++0xcc2803, ++0x35c41f, ++0x36b01f, ++0x7c704b, ++0x34f01f, ++0x7c704b, ++0x35701f, ++0x7c704b, ++0x7d8881, ++0x7dccc1, ++0x7e5101, ++0x7e9541, ++0x7c9082, ++0x7cd4c2, ++0x7c848b, ++0x9ac003, ++0x7c8c8b, ++0x2c8801, ++0x98809e, ++0xd4006d, ++0x98409c, ++0xd4006e, ++0xcc084c, ++0xcc0c4d, ++0xcc1048, ++0xd4801a, ++0xd4c01a, ++0x800101, ++0xd5001a, ++0xcc0832, ++0xd40032, ++0x9482d9, ++0xca0c00, ++0xd4401e, ++0x800000, ++0xd4001e, ++0xe4011e, ++0xd4001e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd4401e, ++0xca1400, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xd5401e, ++0xd54034, ++0x800000, ++0xee001e, ++0x280404, ++0xe2001a, ++0xe2001a, ++0xd4401a, ++0xca3800, ++0xcc0803, ++0xcc0c03, ++0xcc0c03, ++0xcc0c03, ++0x9882bd, ++0x000000, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0400, ++0xc2ff00, ++0xcc0834, ++0xc13fff, ++0x7c74cb, ++0x7cc90b, ++0x7d010f, ++0x9902b0, ++0x7c738b, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0800, ++0x281900, ++0x7d898b, ++0x958014, ++0x281404, ++0xca0c00, ++0xca1000, ++0xca1c00, ++0xca2400, ++0xe2001f, ++0xd4c01a, ++0xd5001a, ++0xd5401a, ++0xcc1803, ++0xcc2c03, ++0xcc2c03, ++0xcc2c03, ++0x7da58b, ++0x7d9c47, ++0x984297, ++0x000000, ++0x800161, ++0xd4c01a, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0x248c06, ++0x0ccc06, ++0x98c006, ++0xcc104e, ++0x990004, ++0xd40073, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xca0800, ++0xca0c00, ++0x34d018, ++0x251001, ++0x950021, ++0xc17fff, ++0xca1000, ++0xca1400, ++0xca1800, ++0xd4801d, ++0xd4c01d, ++0x7db18b, ++0xc14202, ++0xc2c001, ++0xd5801d, ++0x34dc0e, ++0x7d5d4c, ++0x7f734c, ++0xd7401e, ++0xd5001e, ++0xd5401e, ++0xc14200, ++0xc2c000, ++0x099c01, ++0x31dc10, ++0x7f5f4c, ++0x7f734c, ++0x042802, ++0x7d8380, ++0xd5a86f, ++0xd58066, ++0xd7401e, ++0xec005e, ++0xc82402, ++0xc82402, ++0x8001b8, ++0xd60076, ++0xd4401e, ++0xd4801e, ++0xd4c01e, ++0x800000, ++0xee001e, ++0x800000, ++0xee001f, ++0xd4001f, ++0x800000, ++0xd4001f, ++0xd4001f, ++0x880000, ++0xd4001f, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x010171, ++0x020178, ++0x03008f, ++0x04007f, ++0x050003, ++0x06003f, ++0x070032, ++0x08012c, ++0x090046, ++0x0a0036, ++0x1001b6, ++0x1700a2, ++0x22013a, ++0x230149, ++0x2000b4, ++0x240125, ++0x27004d, ++0x28006a, ++0x2a0060, ++0x2b0052, ++0x2f0065, ++0x320087, ++0x34017f, ++0x3c0156, ++0x3f0072, ++0x41018c, ++0x44012e, ++0x550173, ++0x56017a, ++0x60000b, ++0x610034, ++0x620038, ++0x630038, ++0x640038, ++0x650038, ++0x660038, ++0x670038, ++0x68003a, ++0x690041, ++0x6a0048, ++0x6b0048, ++0x6c0048, ++0x6d0048, ++0x6e0048, ++0x6f0048, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++}; ++ ++static const u32 RV620_cp_microcode[][3] = { ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0000ffff, 0x00284621, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x000 }, ++ { 0x00010000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x00000000, 0x00600000, 0x631 }, ++ { 0x00000000, 0x00600000, 0x645 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000f00, 0x00281622, 0x000 }, ++ { 0x00000008, 0x00211625, 0x000 }, ++ { 0x00000018, 0x00203625, 0x000 }, ++ { 0x8d000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x002f0225, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x018 }, ++ { 0x00412000, 0x00404811, 0x019 }, ++ { 0x00422000, 0x00204811, 0x000 }, ++ { 0x8e000000, 0x00204411, 0x000 }, ++ { 0x00000028, 0x00204a2d, 0x000 }, ++ { 0x90000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x0000000c, 0x00211622, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000019, 0x00211a22, 0x000 }, ++ { 0x00000004, 0x00281a26, 0x000 }, ++ { 0x00000000, 0x002914c5, 0x000 }, ++ { 0x00000019, 0x00203625, 0x000 }, ++ { 0x00000000, 0x003a1402, 0x000 }, ++ { 0x00000016, 0x00211625, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0xfffffffc, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002914a3, 0x000 }, ++ { 0x00000017, 0x00203625, 0x000 }, ++ { 0x00008000, 0x00280e22, 0x000 }, ++ { 0x00000007, 0x00220e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x20000000, 0x00280e22, 0x000 }, ++ { 0x00000006, 0x00210e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x00000000, 0x00220222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x038 }, ++ { 0x00000000, 0x2ee00000, 0x035 }, ++ { 0x00000000, 0x2ce00000, 0x037 }, ++ { 0x00000000, 0x00400e2d, 0x039 }, ++ { 0x00000008, 0x00200e2d, 0x000 }, ++ { 0x00000009, 0x0040122d, 0x046 }, ++ { 0x00000001, 0x00400e2d, 0x039 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x03e }, ++ { 0x00000008, 0x00401c11, 0x041 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x0000000f, 0x00281e27, 0x000 }, ++ { 0x00000003, 0x00221e27, 0x000 }, ++ { 0x7fc00000, 0x00281a23, 0x000 }, ++ { 0x00000014, 0x00211a26, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000008, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x00290cc7, 0x000 }, ++ { 0x00000027, 0x00203624, 0x000 }, ++ { 0x00007f00, 0x00281221, 0x000 }, ++ { 0x00001400, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x04b }, ++ { 0x00000001, 0x00290e23, 0x000 }, ++ { 0x0000000e, 0x00203623, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfff80000, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x003a2c02, 0x000 }, ++ { 0x00000002, 0x00220e2b, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x0000000f, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00204a2d, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000029, 0x00200e2d, 0x000 }, ++ { 0x060a0200, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x061 }, ++ { 0x00000000, 0x2ee00000, 0x05f }, ++ { 0x00000000, 0x2ce00000, 0x05e }, ++ { 0x00000000, 0x00400e2d, 0x062 }, ++ { 0x00000001, 0x00400e2d, 0x062 }, ++ { 0x0000000a, 0x00200e2d, 0x000 }, ++ { 0x0000000b, 0x0040122d, 0x06a }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x7fc00000, 0x00281623, 0x000 }, ++ { 0x00000014, 0x00211625, 0x000 }, ++ { 0x00000001, 0x00331625, 0x000 }, ++ { 0x80000000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00290ca3, 0x000 }, ++ { 0x3ffffc00, 0x00290e23, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x06d }, ++ { 0x00000100, 0x00401c11, 0x070 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x000000f0, 0x00281e27, 0x000 }, ++ { 0x00000004, 0x00221e27, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0xfffff0ff, 0x00281a30, 0x000 }, ++ { 0x0000a028, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948e6, 0x000 }, ++ { 0x0000a018, 0x00204411, 0x000 }, ++ { 0x3fffffff, 0x00284a23, 0x000 }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000030, 0x0020162d, 0x000 }, ++ { 0x00000002, 0x00291625, 0x000 }, ++ { 0x00000030, 0x00203625, 0x000 }, ++ { 0x00000025, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a3, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x083 }, ++ { 0x00000026, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a4, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x084 }, ++ { 0x00000000, 0x00400000, 0x08a }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203624, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x08a }, ++ { 0x00000000, 0x00600000, 0x668 }, ++ { 0x00000000, 0x00600000, 0x65c }, ++ { 0x00000002, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x08d }, ++ { 0x00000012, 0xc0403620, 0x093 }, ++ { 0x00000000, 0x2ee00000, 0x091 }, ++ { 0x00000000, 0x2ce00000, 0x090 }, ++ { 0x00000002, 0x00400e2d, 0x092 }, ++ { 0x00000003, 0x00400e2d, 0x092 }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000012, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x098 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x0a0 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x2ee00000, 0x09e }, ++ { 0x00000000, 0x2ce00000, 0x09d }, ++ { 0x00000002, 0x00400e2d, 0x09f }, ++ { 0x00000003, 0x00400e2d, 0x09f }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x003f0000, 0x00280e23, 0x000 }, ++ { 0x00000010, 0x00210e23, 0x000 }, ++ { 0x00000011, 0x00203623, 0x000 }, ++ { 0x0000001e, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0a7 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x0000001f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0aa }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000008, 0x00210e2b, 0x000 }, ++ { 0x0000007f, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0e1 }, ++ { 0x00000000, 0x27000000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x0b3 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000000c, 0x00221e30, 0x000 }, ++ { 0x99800000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x0020122d, 0x000 }, ++ { 0x00000008, 0x00221224, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00291ce4, 0x000 }, ++ { 0x00000000, 0x00604807, 0x12f }, ++ { 0x9b000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x9c000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x0033146f, 0x000 }, ++ { 0x00000001, 0x00333e23, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0x00203c05, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e007, 0x00204411, 0x000 }, ++ { 0x0000000f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0cb }, ++ { 0x00f8ff08, 0x00204811, 0x000 }, ++ { 0x98000000, 0x00404811, 0x0dc }, ++ { 0x000000f0, 0x00280e22, 0x000 }, ++ { 0x000000a0, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x0da }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d5 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d4 }, ++ { 0x00003f00, 0x00400c11, 0x0d6 }, ++ { 0x00001f00, 0x00400c11, 0x0d6 }, ++ { 0x00000f00, 0x00200c11, 0x000 }, ++ { 0x00380009, 0x00294a23, 0x000 }, ++ { 0x3f000000, 0x00280e2b, 0x000 }, ++ { 0x00000002, 0x00220e23, 0x000 }, ++ { 0x00000007, 0x00494a23, 0x0dc }, ++ { 0x00380f09, 0x00204811, 0x000 }, ++ { 0x68000007, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000a202, 0x00204411, 0x000 }, ++ { 0x00ff0000, 0x00280e22, 0x000 }, ++ { 0x00000080, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00200e2d, 0x000 }, ++ { 0x00000026, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x002f0083, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0ea }, ++ { 0x00000000, 0x00600000, 0x662 }, ++ { 0x00000000, 0x00400000, 0x0eb }, ++ { 0x00000000, 0x00600000, 0x665 }, ++ { 0x00000007, 0x0020222d, 0x000 }, ++ { 0x00000005, 0x00220e22, 0x000 }, ++ { 0x00100000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x000000ef, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000003, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x0f8 }, ++ { 0x0000000b, 0x00210228, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0f8 }, ++ { 0x00000400, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000001c, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0fd }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000001e, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x10b }, ++ { 0x0000a30f, 0x00204411, 0x000 }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x104 }, ++ { 0xffffffff, 0x00404811, 0x10b }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x107 }, ++ { 0x0000ffff, 0x00404811, 0x10b }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x10a }, ++ { 0x000000ff, 0x00404811, 0x10b }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0002c400, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x112 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000018, 0x40224a20, 0x000 }, ++ { 0x00000010, 0xc0424a20, 0x114 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000000a, 0x00201011, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x11b }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00531224, 0x117 }, ++ { 0xffbfffff, 0x00283a2e, 0x000 }, ++ { 0x0000001b, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x12e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0x00000018, 0x00220e30, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e00e, 0x00204411, 0x000 }, ++ { 0x07f8ff08, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00294a23, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00800000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204806, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68d }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x68c }, ++ { 0x00000004, 0x00404c11, 0x135 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000001c, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x13c }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40280620, 0x000 }, ++ { 0x00000010, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x00341461, 0x000 }, ++ { 0x00000000, 0x00741882, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x147 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0681a20, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x158 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00300a2f, 0x000 }, ++ { 0x00000001, 0x00210a22, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600000, 0x18f }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00202c08, 0x000 }, ++ { 0x00000000, 0x00202411, 0x000 }, ++ { 0x00000000, 0x00202811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00221e29, 0x000 }, ++ { 0x00000000, 0x007048eb, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000001, 0x40330620, 0x000 }, ++ { 0x00000000, 0xc0302409, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x181 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x186 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x186 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000001, 0x00530621, 0x182 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x197 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000011, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x0078042a, 0x2fb }, ++ { 0x00000000, 0x00202809, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x174 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x194 }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x46000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x19b }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00804811, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40281620, 0x000 }, ++ { 0x00000010, 0xc0811a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00221e30, 0x000 }, ++ { 0x00000029, 0x00201a2d, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfffbff09, 0x00204811, 0x000 }, ++ { 0x0000000f, 0x0020222d, 0x000 }, ++ { 0x00001fff, 0x00294a28, 0x000 }, ++ { 0x00000006, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000100, 0x00201811, 0x000 }, ++ { 0x00000008, 0x00621e28, 0x12f }, ++ { 0x00000008, 0x00822228, 0x000 }, ++ { 0x0002c000, 0x00204411, 0x000 }, ++ { 0x00000015, 0x00600e2d, 0x1bd }, ++ { 0x00000016, 0x00600e2d, 0x1bd }, ++ { 0x0000c008, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x1b9 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x39000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00804802, 0x000 }, ++ { 0x00000018, 0x00202e2d, 0x000 }, ++ { 0x00000000, 0x003b0d63, 0x000 }, ++ { 0x00000008, 0x00224a23, 0x000 }, ++ { 0x00000010, 0x00224a23, 0x000 }, ++ { 0x00000018, 0x00224a23, 0x000 }, ++ { 0x00000000, 0x00804803, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000007, 0x0021062f, 0x000 }, ++ { 0x00000013, 0x00200a2d, 0x000 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000ffff, 0x40282220, 0x000 }, ++ { 0x0000000f, 0x00262228, 0x000 }, ++ { 0x00000010, 0x40212620, 0x000 }, ++ { 0x0000000f, 0x00262629, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1e0 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000081, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000080, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1dc }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1d8 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000001f, 0x00280a22, 0x000 }, ++ { 0x0000001f, 0x00282a2a, 0x000 }, ++ { 0x00000001, 0x00530621, 0x1d1 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00304a2f, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00301e2f, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1e5 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x0000000f, 0x00260e23, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000000f, 0x00261224, 0x000 }, ++ { 0x00000000, 0x00201411, 0x000 }, ++ { 0x00000000, 0x00601811, 0x2bb }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022b, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1f8 }, ++ { 0x00000010, 0x00221628, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a29, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x0020480a, 0x000 }, ++ { 0x00000000, 0x00202c11, 0x000 }, ++ { 0x00000010, 0x00221623, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a24, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x00731503, 0x205 }, ++ { 0x00000000, 0x00201805, 0x000 }, ++ { 0x00000000, 0x00731524, 0x205 }, ++ { 0x00000000, 0x002d14c5, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00000000, 0x00202003, 0x000 }, ++ { 0x00000000, 0x00802404, 0x000 }, ++ { 0x0000000f, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x68c }, ++ { 0x00000000, 0x002b1405, 0x000 }, ++ { 0x00000001, 0x00901625, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00294a22, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a21, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0x40281220, 0x000 }, ++ { 0x00000010, 0xc0211a20, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211620, 0x000 }, ++ { 0x00000000, 0x00741465, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00000001, 0x00330621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x219 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x212 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x645 }, ++ { 0x00000000, 0x0040040f, 0x213 }, ++ { 0x00000000, 0x00600000, 0x631 }, ++ { 0x00000000, 0x00600000, 0x645 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00000000, 0x00600000, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x232 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x236 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x236 }, ++ { 0x00000000, 0xc0404800, 0x233 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00600411, 0x2fb }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x631 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000018, 0x40210a20, 0x000 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x24c }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x00080101, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x251 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000010, 0x00600411, 0x315 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x27c }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000001, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x26a }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x0000ffff, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00341c27, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x25f }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e5, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x262 }, ++ { 0x00000000, 0x00201407, 0x000 }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x00341c47, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x267 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x26a }, ++ { 0x00000000, 0x00201807, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2c1 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00342023, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x272 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x271 }, ++ { 0x00000016, 0x00404811, 0x276 }, ++ { 0x00000018, 0x00404811, 0x276 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x275 }, ++ { 0x00000017, 0x00404811, 0x276 }, ++ { 0x00000019, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00604411, 0x2e9 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x256 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000010, 0x40210620, 0x000 }, ++ { 0x0000ffff, 0xc0280a20, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0881a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x00000000, 0x00600000, 0x631 }, ++ { 0x00000000, 0xc0600000, 0x2a3 }, ++ { 0x00000005, 0x00200a2d, 0x000 }, ++ { 0x00000008, 0x00220a22, 0x000 }, ++ { 0x0000002b, 0x00201a2d, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00007000, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00311ce6, 0x000 }, ++ { 0x0000002a, 0x00201a2d, 0x000 }, ++ { 0x0000000c, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x292 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00691ce2, 0x12f }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x29d }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000001c, 0x00403627, 0x000 }, ++ { 0x0000000c, 0xc0220a20, 0x000 }, ++ { 0x00000029, 0x00203622, 0x000 }, ++ { 0x00000028, 0xc0403620, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000009, 0x00204811, 0x000 }, ++ { 0xa1000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce3, 0x000 }, ++ { 0x00000021, 0x00203627, 0x000 }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce4, 0x000 }, ++ { 0x00000022, 0x00203627, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a3, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203624, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000000, 0x00311cc4, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x2dc }, ++ { 0x00000000, 0x00400000, 0x2d9 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2d9 }, ++ { 0x00000003, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2dc }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e1, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a1, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e2, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000000, 0x00600000, 0x668 }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00600000, 0x65f }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2a7 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x0000001a, 0x00201e2d, 0x000 }, ++ { 0x0000001b, 0x0080222d, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca1, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x003808c5, 0x000 }, ++ { 0x00000000, 0x00300841, 0x000 }, ++ { 0x00000001, 0x00220a22, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000017, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x318 }, ++ { 0xffffffef, 0x00280621, 0x000 }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x0000f8e0, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00294901, 0x000 }, ++ { 0x00000000, 0x00894901, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x97000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00002257, 0x00204411, 0x000 }, ++ { 0x00000003, 0xc0484a20, 0x000 }, ++ { 0x0000225d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x645 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x00000001, 0x40304a20, 0x000 }, ++ { 0x00000002, 0xc0304a20, 0x000 }, ++ { 0x00000001, 0x00530a22, 0x34b }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x354 }, ++ { 0x00000014, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x364 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00604802, 0x36e }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x36a }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35f }, ++ { 0x00000028, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5c0 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35f }, ++ { 0x0000002c, 0x00203626, 0x000 }, ++ { 0x00000049, 0x00201811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000000, 0x002f0226, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x370 }, ++ { 0x0000002c, 0x00801a2d, 0x000 }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x00000015, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x386 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b1 }, ++ { 0x00000016, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b5 }, ++ { 0x00000020, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x39c }, ++ { 0x0000000f, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a8 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a8 }, ++ { 0x0000001e, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x390 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x08000000, 0x00290a22, 0x000 }, ++ { 0x00000003, 0x40210e20, 0x000 }, ++ { 0x0000000c, 0xc0211220, 0x000 }, ++ { 0x00080000, 0x00281224, 0x000 }, ++ { 0x00000014, 0xc0221620, 0x000 }, ++ { 0x00000000, 0x002914a4, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948a2, 0x000 }, ++ { 0x0000a1fe, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000015, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x392 }, ++ { 0x0000210e, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000003, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x39e }, ++ { 0x00002108, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x80000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000010, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3ae }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00404811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x0000001d, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3ce }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3c0 }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0xbabecafe, 0x00204811, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00404811, 0x000 }, ++ { 0x00002170, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000a, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3d3 }, ++ { 0x8c000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00003fff, 0x40280a20, 0x000 }, ++ { 0x80000000, 0x40280e20, 0x000 }, ++ { 0x40000000, 0xc0281220, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68d }, ++ { 0x00000000, 0x00201410, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e1 }, ++ { 0x00000000, 0xc0401800, 0x3e4 }, ++ { 0x00003fff, 0xc0281a20, 0x000 }, ++ { 0x00040000, 0x00694626, 0x68d }, ++ { 0x00000000, 0x00201810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e7 }, ++ { 0x00000000, 0xc0401c00, 0x3ea }, ++ { 0x00003fff, 0xc0281e20, 0x000 }, ++ { 0x00040000, 0x00694627, 0x68d }, ++ { 0x00000000, 0x00201c10, 0x000 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0x002820c5, 0x000 }, ++ { 0x00000000, 0x004948e8, 0x000 }, ++ { 0xa5800000, 0x00200811, 0x000 }, ++ { 0x00002000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x0000001f, 0xc0210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3f7 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0xc0481220, 0x3ff }, ++ { 0xa7800000, 0x00200811, 0x000 }, ++ { 0x0000a000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00304883, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xa9800000, 0x00200811, 0x000 }, ++ { 0x0000c000, 0x00400c11, 0x3fa }, ++ { 0xab800000, 0x00200811, 0x000 }, ++ { 0x0000f8e0, 0x00400c11, 0x3fa }, ++ { 0xad800000, 0x00200811, 0x000 }, ++ { 0x0000f880, 0x00400c11, 0x3fa }, ++ { 0xb3800000, 0x00200811, 0x000 }, ++ { 0x0000f3fc, 0x00400c11, 0x3fa }, ++ { 0xaf800000, 0x00200811, 0x000 }, ++ { 0x0000e000, 0x00400c11, 0x3fa }, ++ { 0xb1800000, 0x00200811, 0x000 }, ++ { 0x0000f000, 0x00400c11, 0x3fa }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00002148, 0x00204811, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x01182000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0218a000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0318c000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0418f8e0, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0518f880, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0618e000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0718f000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0818f3fc, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000030, 0x00200a2d, 0x000 }, ++ { 0x00000000, 0xc0290c40, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x86000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x85000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00000018, 0x40210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x445 }, ++ { 0x00800000, 0xc0494a20, 0x446 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68d }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00404c02, 0x44b }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x00000000, 0xc0201400, 0x000 }, ++ { 0x00000000, 0xc0201800, 0x000 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x459 }, ++ { 0x00000000, 0xc0202000, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x00000010, 0x00280a23, 0x000 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x461 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0x00694624, 0x68d }, ++ { 0x00000000, 0x00400000, 0x466 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00604805, 0x692 }, ++ { 0x00000000, 0x002824f0, 0x000 }, ++ { 0x00000007, 0x00280a23, 0x000 }, ++ { 0x00000001, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46d }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x04e00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000002, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x472 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x02e00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x477 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x47c }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000005, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x481 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x486 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x08e00000, 0x486 }, ++ { 0x00000000, 0x00400000, 0x493 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x000 }, ++ { 0x00000008, 0x00210a23, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x490 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x499 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x00404c08, 0x459 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000011, 0x40211220, 0x000 }, ++ { 0x00000012, 0x40211620, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4a3 }, ++ { 0x00040000, 0xc0494a20, 0x4a4 }, ++ { 0xfffbffff, 0xc0284a20, 0x000 }, ++ { 0x00000000, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4b0 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000c, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4ac }, ++ { 0xa0000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00204811, 0x000 }, ++ { 0x0000216b, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000216c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4aa }, ++ { 0x00000000, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4c3 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x692 }, ++ { 0x00000000, 0x00400000, 0x4c7 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x68d }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4ce }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0404810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68d }, ++ { 0x00000000, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4d0 }, ++ { 0x00002180, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000003, 0x00333e2f, 0x000 }, ++ { 0x00000001, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x500 }, ++ { 0x0000002c, 0x00200a2d, 0x000 }, ++ { 0x00040000, 0x18e00c11, 0x4ef }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xd8c04800, 0x4e3 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000002d, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x00290c83, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000011, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4aa }, ++ { 0x0000002c, 0xc0203620, 0x000 }, ++ { 0x0000002d, 0xc0403620, 0x000 }, ++ { 0x0000000f, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x505 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0xd9000000, 0x000 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xb5000000, 0x00204411, 0x000 }, ++ { 0x00002000, 0x00204811, 0x000 }, ++ { 0xb6000000, 0x00204411, 0x000 }, ++ { 0x0000a000, 0x00204811, 0x000 }, ++ { 0xb7000000, 0x00204411, 0x000 }, ++ { 0x0000c000, 0x00204811, 0x000 }, ++ { 0xb8000000, 0x00204411, 0x000 }, ++ { 0x0000f8e0, 0x00204811, 0x000 }, ++ { 0xb9000000, 0x00204411, 0x000 }, ++ { 0x0000f880, 0x00204811, 0x000 }, ++ { 0xba000000, 0x00204411, 0x000 }, ++ { 0x0000e000, 0x00204811, 0x000 }, ++ { 0xbb000000, 0x00204411, 0x000 }, ++ { 0x0000f000, 0x00204811, 0x000 }, ++ { 0xbc000000, 0x00204411, 0x000 }, ++ { 0x0000f3fc, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00204811, 0x000 }, ++ { 0x000000ff, 0x00280e30, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x519 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x52e }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000001c, 0x00203623, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000029, 0x00203623, 0x000 }, ++ { 0x00000028, 0x00203623, 0x000 }, ++ { 0x00000017, 0x00203623, 0x000 }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203623, 0x000 }, ++ { 0x00000015, 0x00203623, 0x000 }, ++ { 0x00000016, 0x00203623, 0x000 }, ++ { 0xffffe000, 0x00200c11, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00200c11, 0x000 }, ++ { 0x00000023, 0x00203623, 0x000 }, ++ { 0x00000024, 0x00203623, 0x000 }, ++ { 0xf1ffffff, 0x00283a2e, 0x000 }, ++ { 0x0000001a, 0xc0220e20, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000002a, 0x40203620, 0x000 }, ++ { 0x87000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x9d000000, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x40214a20, 0x000 }, ++ { 0x96000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x0000001f, 0x00211624, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x0000001d, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00281e23, 0x000 }, ++ { 0x00000008, 0x00222223, 0x000 }, ++ { 0xfffff000, 0x00282228, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x0000001f, 0x00203628, 0x000 }, ++ { 0x00000018, 0x00211e23, 0x000 }, ++ { 0x00000020, 0x00203627, 0x000 }, ++ { 0x00000002, 0x00221624, 0x000 }, ++ { 0x00000000, 0x003014a8, 0x000 }, ++ { 0x0000001e, 0x00203625, 0x000 }, ++ { 0x00000003, 0x00211a24, 0x000 }, ++ { 0x10000000, 0x00281a26, 0x000 }, ++ { 0xefffffff, 0x00283a2e, 0x000 }, ++ { 0x00000000, 0x004938ce, 0x67b }, ++ { 0x00000001, 0x40280a20, 0x000 }, ++ { 0x00000006, 0x40280e20, 0x000 }, ++ { 0x00000300, 0xc0281220, 0x000 }, ++ { 0x00000008, 0x00211224, 0x000 }, ++ { 0x00000000, 0xc0201620, 0x000 }, ++ { 0x00000000, 0xc0201a20, 0x000 }, ++ { 0x00000000, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x566 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68d }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00020000, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56e }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x57c }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68d }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x57c }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x572 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x57c }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x57a }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x692 }, ++ { 0x00000000, 0x00401c10, 0x57c }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x57e }, ++ { 0x00000000, 0x00600000, 0x5c9 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x58f }, ++ { 0x0000a2b7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x68d }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000a2c4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x58d }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000001, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5a0 }, ++ { 0x0000a2bb, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x68d }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000a2c5, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x59e }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000002, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5b1 }, ++ { 0x0000a2bf, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x68d }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000a2c6, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5af }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x0000a2c3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x68d }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000a2c7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5be }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x85000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x0000304a, 0x00204411, 0x000 }, ++ { 0x01000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00400000, 0x5c4 }, ++ { 0xa4000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x5c9 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000002c, 0x00203621, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5d0 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000030, 0x00403621, 0x5e3 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x5e3 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a092, 0x00604411, 0x68d }, ++ { 0x00000031, 0x00203630, 0x000 }, ++ { 0x0004a093, 0x00604411, 0x68d }, ++ { 0x00000032, 0x00203630, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x68d }, ++ { 0x00000033, 0x00203630, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x68d }, ++ { 0x00000034, 0x00203630, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x68d }, ++ { 0x00000035, 0x00203630, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x68d }, ++ { 0x00000036, 0x00203630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x88000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000001, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x62c }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x62c }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x605 }, ++ { 0x0000a092, 0x00204411, 0x000 }, ++ { 0x00000031, 0x00204a2d, 0x000 }, ++ { 0x0000a093, 0x00204411, 0x000 }, ++ { 0x00000032, 0x00204a2d, 0x000 }, ++ { 0x0000a2b6, 0x00204411, 0x000 }, ++ { 0x00000033, 0x00204a2d, 0x000 }, ++ { 0x0000a2ba, 0x00204411, 0x000 }, ++ { 0x00000034, 0x00204a2d, 0x000 }, ++ { 0x0000a2be, 0x00204411, 0x000 }, ++ { 0x00000035, 0x00204a2d, 0x000 }, ++ { 0x0000a2c2, 0x00204411, 0x000 }, ++ { 0x00000036, 0x00204a2d, 0x000 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x000001ff, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x62b }, ++ { 0x00000000, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x60e }, ++ { 0x0004a003, 0x00604411, 0x68d }, ++ { 0x0000a003, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x613 }, ++ { 0x0004a010, 0x00604411, 0x68d }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x62b }, ++ { 0x0004a011, 0x00604411, 0x68d }, ++ { 0x0000a011, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a012, 0x00604411, 0x68d }, ++ { 0x0000a012, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a013, 0x00604411, 0x68d }, ++ { 0x0000a013, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a014, 0x00604411, 0x68d }, ++ { 0x0000a014, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a015, 0x00604411, 0x68d }, ++ { 0x0000a015, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a016, 0x00604411, 0x68d }, ++ { 0x0000a016, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a017, 0x00604411, 0x68d }, ++ { 0x0000a017, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x0000002c, 0x0080062d, 0x000 }, ++ { 0xff000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000002, 0x00804811, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x63d }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000002, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x63b }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68d }, ++ { 0x00001000, 0x00200811, 0x000 }, ++ { 0x0000002b, 0x00203622, 0x000 }, ++ { 0x00000000, 0x00600000, 0x641 }, ++ { 0x00000000, 0x00600000, 0x5c9 }, ++ { 0x98000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x641 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000022, 0x00204811, 0x000 }, ++ { 0x89000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00404811, 0x62d }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404811, 0x62d }, ++ { 0x00000000, 0x00600000, 0x65c }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0xc0204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x09800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68d }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000004, 0x00404c11, 0x656 }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000004, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffffb, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffff7, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x01800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68d }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x68c }, ++ { 0x00000010, 0x00404c11, 0x672 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x38c00000, 0x000 }, ++ { 0x0000001d, 0x00200a2d, 0x000 }, ++ { 0x0000001e, 0x00200e2d, 0x000 }, ++ { 0x0000001f, 0x0020122d, 0x000 }, ++ { 0x00000020, 0x0020162d, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000004, 0x00301224, 0x000 }, ++ { 0x00000000, 0x002f0064, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x68b }, ++ { 0x00000003, 0x00281a22, 0x000 }, ++ { 0x00000008, 0x00221222, 0x000 }, ++ { 0xfffff000, 0x00281224, 0x000 }, ++ { 0x00000000, 0x002910c4, 0x000 }, ++ { 0x0000001f, 0x00403624, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x68d }, ++ { 0x9f000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x690 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x692 }, ++ { 0x9e000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x695 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0xc0204411, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000024, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000022, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00404811, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x01420502, 0x05c00250, 0x000 }, ++ { 0x01c30168, 0x043f05c0, 0x000 }, ++ { 0x02250209, 0x02500151, 0x000 }, ++ { 0x02230245, 0x02a00241, 0x000 }, ++ { 0x03d705c0, 0x05c005c0, 0x000 }, ++ { 0x0649064a, 0x031f05c0, 0x000 }, ++ { 0x05c005c5, 0x03200340, 0x000 }, ++ { 0x032a0282, 0x03420334, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c00551, 0x05c005c0, 0x000 }, ++ { 0x03ba05c0, 0x04bb0344, 0x000 }, ++ { 0x049a0450, 0x043d05c0, 0x000 }, ++ { 0x04d005c0, 0x044104dd, 0x000 }, ++ { 0x04500507, 0x03510375, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c005c0, 0x063f05c7, 0x000 }, ++ { 0x05c005c0, 0x000705c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x03f803ed, 0x04080406, 0x000 }, ++ { 0x040e040a, 0x040c0410, 0x000 }, ++ { 0x041c0418, 0x04240420, 0x000 }, ++ { 0x042c0428, 0x04340430, 0x000 }, ++ { 0x05c005c0, 0x043805c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x05c005c0, 0x05c005c0, 0x000 }, ++ { 0x00020679, 0x06970006, 0x000 }, ++}; ++ ++static const u32 RV620_pfp_microcode[] = { ++0xca0400, ++0xa00000, ++0x7e828b, ++0x7c038b, ++0x8001b8, ++0x7c038b, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xc41838, ++0xca2400, ++0xca2800, ++0x9581a8, ++0xc41c3a, ++0xc3c000, ++0xca0800, ++0xca0c00, ++0x7c744b, ++0xc20005, ++0x99c000, ++0xc41c3a, ++0x7c744c, ++0xc0fff0, ++0x042c04, ++0x309002, ++0x7d2500, ++0x351402, ++0x7d350b, ++0x255403, ++0x7cd580, ++0x259c03, ++0x95c004, ++0xd5001b, ++0x7eddc1, ++0x7d9d80, ++0xd6801b, ++0xd5801b, ++0xd4401e, ++0xd5401e, ++0xd6401e, ++0xd6801e, ++0xd4801e, ++0xd4c01e, ++0x9783d3, ++0xd5c01e, ++0xca0800, ++0x80001a, ++0xca0c00, ++0xe4011e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xe4013e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca1800, ++0xd4401e, ++0xd5801e, ++0x800053, ++0xd40075, ++0xd4401e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd48019, ++0xd4c018, ++0xd50017, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xe2001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0xd48060, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xd48061, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xca0c00, ++0xd4401e, ++0xd48016, ++0xd4c016, ++0xd4801e, ++0x8001b8, ++0xd4c01e, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x948004, ++0xca1400, ++0xe420f3, ++0xd42013, ++0xd56065, ++0xd4e01c, ++0xd5201c, ++0xd5601c, ++0x800000, ++0x062001, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9483f7, ++0xca1400, ++0xe420f3, ++0x800079, ++0xd42013, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9883ef, ++0xca1400, ++0xd40064, ++0x80008d, ++0x000000, ++0xc41432, ++0xc61843, ++0xc4082f, ++0x954005, ++0xc40c30, ++0xd4401e, ++0x800000, ++0xee001e, ++0x9583f5, ++0xc41031, ++0xd44033, ++0xd52065, ++0xd4a01c, ++0xd4e01c, ++0xd5201c, ++0xe4015e, ++0xd4001e, ++0x800000, ++0x062001, ++0xca1800, ++0x0a2001, ++0xd60076, ++0xc40836, ++0x988007, ++0xc61045, ++0x950110, ++0xd4001f, ++0xd46062, ++0x800000, ++0xd42062, ++0xcc3835, ++0xcc1433, ++0x8401bb, ++0xd40072, ++0xd5401e, ++0x800000, ++0xee001e, ++0xe2001a, ++0x8401bb, ++0xe2001a, ++0xcc104b, ++0xcc0447, ++0x2c9401, ++0x7d098b, ++0x984005, ++0x7d15cb, ++0xd4001a, ++0x8001b8, ++0xd4006d, ++0x344401, ++0xcc0c48, ++0x98403a, ++0xcc2c4a, ++0x958004, ++0xcc0449, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0x282801, ++0x8400f0, ++0xcc1003, ++0x98801b, ++0x04380c, ++0x8400f0, ++0xcc1003, ++0x988017, ++0x043808, ++0x8400f0, ++0xcc1003, ++0x988013, ++0x043804, ++0x8400f0, ++0xcc1003, ++0x988014, ++0xcc104c, ++0x9a8009, ++0xcc144d, ++0x9840dc, ++0xd4006d, ++0xcc1848, ++0xd5001a, ++0xd5401a, ++0x8000c9, ++0xd5801a, ++0x96c0d5, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0x9ac003, ++0xd4006d, ++0xd4006e, ++0x800000, ++0xec007f, ++0x9ac0cc, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0x7d9103, ++0x7dd583, ++0x7d190c, ++0x35cc1f, ++0x35701f, ++0x7cf0cb, ++0x7cd08b, ++0x880000, ++0x7e8e8b, ++0x95c004, ++0xd4006e, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0xcc0803, ++0xcc0c03, ++0xcc1003, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0xcc2403, ++0xcc2803, ++0x35c41f, ++0x36b01f, ++0x7c704b, ++0x34f01f, ++0x7c704b, ++0x35701f, ++0x7c704b, ++0x7d8881, ++0x7dccc1, ++0x7e5101, ++0x7e9541, ++0x7c9082, ++0x7cd4c2, ++0x7c848b, ++0x9ac003, ++0x7c8c8b, ++0x2c8801, ++0x98809e, ++0xd4006d, ++0x98409c, ++0xd4006e, ++0xcc084c, ++0xcc0c4d, ++0xcc1048, ++0xd4801a, ++0xd4c01a, ++0x800101, ++0xd5001a, ++0xcc0832, ++0xd40032, ++0x9482d9, ++0xca0c00, ++0xd4401e, ++0x800000, ++0xd4001e, ++0xe4011e, ++0xd4001e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd4401e, ++0xca1400, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xd5401e, ++0xd54034, ++0x800000, ++0xee001e, ++0x280404, ++0xe2001a, ++0xe2001a, ++0xd4401a, ++0xca3800, ++0xcc0803, ++0xcc0c03, ++0xcc0c03, ++0xcc0c03, ++0x9882bd, ++0x000000, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0400, ++0xc2ff00, ++0xcc0834, ++0xc13fff, ++0x7c74cb, ++0x7cc90b, ++0x7d010f, ++0x9902b0, ++0x7c738b, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0800, ++0x281900, ++0x7d898b, ++0x958014, ++0x281404, ++0xca0c00, ++0xca1000, ++0xca1c00, ++0xca2400, ++0xe2001f, ++0xd4c01a, ++0xd5001a, ++0xd5401a, ++0xcc1803, ++0xcc2c03, ++0xcc2c03, ++0xcc2c03, ++0x7da58b, ++0x7d9c47, ++0x984297, ++0x000000, ++0x800161, ++0xd4c01a, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0x248c06, ++0x0ccc06, ++0x98c006, ++0xcc104e, ++0x990004, ++0xd40073, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xca0800, ++0xca0c00, ++0x34d018, ++0x251001, ++0x950021, ++0xc17fff, ++0xca1000, ++0xca1400, ++0xca1800, ++0xd4801d, ++0xd4c01d, ++0x7db18b, ++0xc14202, ++0xc2c001, ++0xd5801d, ++0x34dc0e, ++0x7d5d4c, ++0x7f734c, ++0xd7401e, ++0xd5001e, ++0xd5401e, ++0xc14200, ++0xc2c000, ++0x099c01, ++0x31dc10, ++0x7f5f4c, ++0x7f734c, ++0x042802, ++0x7d8380, ++0xd5a86f, ++0xd58066, ++0xd7401e, ++0xec005e, ++0xc82402, ++0xc82402, ++0x8001b8, ++0xd60076, ++0xd4401e, ++0xd4801e, ++0xd4c01e, ++0x800000, ++0xee001e, ++0x800000, ++0xee001f, ++0xd4001f, ++0x800000, ++0xd4001f, ++0xd4001f, ++0x880000, ++0xd4001f, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x010171, ++0x020178, ++0x03008f, ++0x04007f, ++0x050003, ++0x06003f, ++0x070032, ++0x08012c, ++0x090046, ++0x0a0036, ++0x1001b6, ++0x1700a2, ++0x22013a, ++0x230149, ++0x2000b4, ++0x240125, ++0x27004d, ++0x28006a, ++0x2a0060, ++0x2b0052, ++0x2f0065, ++0x320087, ++0x34017f, ++0x3c0156, ++0x3f0072, ++0x41018c, ++0x44012e, ++0x550173, ++0x56017a, ++0x60000b, ++0x610034, ++0x620038, ++0x630038, ++0x640038, ++0x650038, ++0x660038, ++0x670038, ++0x68003a, ++0x690041, ++0x6a0048, ++0x6b0048, ++0x6c0048, ++0x6d0048, ++0x6e0048, ++0x6f0048, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++}; ++ ++static const u32 RV630_cp_microcode[][3] = { ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0000ffff, 0x00284621, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x000 }, ++ { 0x00010000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x00000000, 0x00600000, 0x62e }, ++ { 0x00000000, 0x00600000, 0x642 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000f00, 0x00281622, 0x000 }, ++ { 0x00000008, 0x00211625, 0x000 }, ++ { 0x00000018, 0x00203625, 0x000 }, ++ { 0x8d000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x002f0225, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x018 }, ++ { 0x00412000, 0x00404811, 0x019 }, ++ { 0x00422000, 0x00204811, 0x000 }, ++ { 0x8e000000, 0x00204411, 0x000 }, ++ { 0x00000028, 0x00204a2d, 0x000 }, ++ { 0x90000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x0000000c, 0x00211622, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000019, 0x00211a22, 0x000 }, ++ { 0x00000004, 0x00281a26, 0x000 }, ++ { 0x00000000, 0x002914c5, 0x000 }, ++ { 0x00000019, 0x00203625, 0x000 }, ++ { 0x00000000, 0x003a1402, 0x000 }, ++ { 0x00000016, 0x00211625, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0xfffffffc, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002914a3, 0x000 }, ++ { 0x00000017, 0x00203625, 0x000 }, ++ { 0x00008000, 0x00280e22, 0x000 }, ++ { 0x00000007, 0x00220e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x20000000, 0x00280e22, 0x000 }, ++ { 0x00000006, 0x00210e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x00000000, 0x00220222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x038 }, ++ { 0x00000000, 0x2ee00000, 0x035 }, ++ { 0x00000000, 0x2ce00000, 0x037 }, ++ { 0x00000000, 0x00400e2d, 0x039 }, ++ { 0x00000008, 0x00200e2d, 0x000 }, ++ { 0x00000009, 0x0040122d, 0x046 }, ++ { 0x00000001, 0x00400e2d, 0x039 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x03e }, ++ { 0x00000008, 0x00401c11, 0x041 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x0000000f, 0x00281e27, 0x000 }, ++ { 0x00000003, 0x00221e27, 0x000 }, ++ { 0x7fc00000, 0x00281a23, 0x000 }, ++ { 0x00000014, 0x00211a26, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000008, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x00290cc7, 0x000 }, ++ { 0x00000027, 0x00203624, 0x000 }, ++ { 0x00007f00, 0x00281221, 0x000 }, ++ { 0x00001400, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x04b }, ++ { 0x00000001, 0x00290e23, 0x000 }, ++ { 0x0000000e, 0x00203623, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfff80000, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x003a2c02, 0x000 }, ++ { 0x00000002, 0x00220e2b, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x0000000f, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00204a2d, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000029, 0x00200e2d, 0x000 }, ++ { 0x060a0200, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x061 }, ++ { 0x00000000, 0x2ee00000, 0x05f }, ++ { 0x00000000, 0x2ce00000, 0x05e }, ++ { 0x00000000, 0x00400e2d, 0x062 }, ++ { 0x00000001, 0x00400e2d, 0x062 }, ++ { 0x0000000a, 0x00200e2d, 0x000 }, ++ { 0x0000000b, 0x0040122d, 0x06a }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x7fc00000, 0x00281623, 0x000 }, ++ { 0x00000014, 0x00211625, 0x000 }, ++ { 0x00000001, 0x00331625, 0x000 }, ++ { 0x80000000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00290ca3, 0x000 }, ++ { 0x3ffffc00, 0x00290e23, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x06d }, ++ { 0x00000100, 0x00401c11, 0x070 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x000000f0, 0x00281e27, 0x000 }, ++ { 0x00000004, 0x00221e27, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0xfffff0ff, 0x00281a30, 0x000 }, ++ { 0x0000a028, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948e6, 0x000 }, ++ { 0x0000a018, 0x00204411, 0x000 }, ++ { 0x3fffffff, 0x00284a23, 0x000 }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000030, 0x0020162d, 0x000 }, ++ { 0x00000002, 0x00291625, 0x000 }, ++ { 0x00000030, 0x00203625, 0x000 }, ++ { 0x00000025, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a3, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x083 }, ++ { 0x00000026, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a4, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x084 }, ++ { 0x00000000, 0x00400000, 0x08a }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203624, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x08a }, ++ { 0x00000000, 0x00600000, 0x665 }, ++ { 0x00000000, 0x00600000, 0x659 }, ++ { 0x00000002, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x08d }, ++ { 0x00000012, 0xc0403620, 0x093 }, ++ { 0x00000000, 0x2ee00000, 0x091 }, ++ { 0x00000000, 0x2ce00000, 0x090 }, ++ { 0x00000002, 0x00400e2d, 0x092 }, ++ { 0x00000003, 0x00400e2d, 0x092 }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000012, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x098 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x0a0 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x2ee00000, 0x09e }, ++ { 0x00000000, 0x2ce00000, 0x09d }, ++ { 0x00000002, 0x00400e2d, 0x09f }, ++ { 0x00000003, 0x00400e2d, 0x09f }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x003f0000, 0x00280e23, 0x000 }, ++ { 0x00000010, 0x00210e23, 0x000 }, ++ { 0x00000011, 0x00203623, 0x000 }, ++ { 0x0000001e, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0a7 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x0000001f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0aa }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000008, 0x00210e2b, 0x000 }, ++ { 0x0000007f, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0e1 }, ++ { 0x00000000, 0x27000000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x0b3 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000000c, 0x00221e30, 0x000 }, ++ { 0x99800000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x0020122d, 0x000 }, ++ { 0x00000008, 0x00221224, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00291ce4, 0x000 }, ++ { 0x00000000, 0x00604807, 0x12f }, ++ { 0x9b000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x9c000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x0033146f, 0x000 }, ++ { 0x00000001, 0x00333e23, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0x00203c05, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e007, 0x00204411, 0x000 }, ++ { 0x0000000f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0cb }, ++ { 0x00f8ff08, 0x00204811, 0x000 }, ++ { 0x98000000, 0x00404811, 0x0dc }, ++ { 0x000000f0, 0x00280e22, 0x000 }, ++ { 0x000000a0, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x0da }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d5 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d4 }, ++ { 0x00003f00, 0x00400c11, 0x0d6 }, ++ { 0x00001f00, 0x00400c11, 0x0d6 }, ++ { 0x00000f00, 0x00200c11, 0x000 }, ++ { 0x00380009, 0x00294a23, 0x000 }, ++ { 0x3f000000, 0x00280e2b, 0x000 }, ++ { 0x00000002, 0x00220e23, 0x000 }, ++ { 0x00000007, 0x00494a23, 0x0dc }, ++ { 0x00380f09, 0x00204811, 0x000 }, ++ { 0x68000007, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000a202, 0x00204411, 0x000 }, ++ { 0x00ff0000, 0x00280e22, 0x000 }, ++ { 0x00000080, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00200e2d, 0x000 }, ++ { 0x00000026, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x002f0083, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0ea }, ++ { 0x00000000, 0x00600000, 0x65f }, ++ { 0x00000000, 0x00400000, 0x0eb }, ++ { 0x00000000, 0x00600000, 0x662 }, ++ { 0x00000007, 0x0020222d, 0x000 }, ++ { 0x00000005, 0x00220e22, 0x000 }, ++ { 0x00100000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x000000ef, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000003, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x0f8 }, ++ { 0x0000000b, 0x00210228, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0f8 }, ++ { 0x00000400, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000001c, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0fd }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000001e, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x10b }, ++ { 0x0000a30f, 0x00204411, 0x000 }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x104 }, ++ { 0xffffffff, 0x00404811, 0x10b }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x107 }, ++ { 0x0000ffff, 0x00404811, 0x10b }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x10a }, ++ { 0x000000ff, 0x00404811, 0x10b }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0002c400, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x112 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000018, 0x40224a20, 0x000 }, ++ { 0x00000010, 0xc0424a20, 0x114 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000000a, 0x00201011, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x11b }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00531224, 0x117 }, ++ { 0xffbfffff, 0x00283a2e, 0x000 }, ++ { 0x0000001b, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x12e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0x00000018, 0x00220e30, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e00e, 0x00204411, 0x000 }, ++ { 0x07f8ff08, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00294a23, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00800000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204806, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68a }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x689 }, ++ { 0x00000004, 0x00404c11, 0x135 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000001c, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x13c }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40280620, 0x000 }, ++ { 0x00000010, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x00341461, 0x000 }, ++ { 0x00000000, 0x00741882, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x147 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0681a20, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x158 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00300a2f, 0x000 }, ++ { 0x00000001, 0x00210a22, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600000, 0x18f }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00202c08, 0x000 }, ++ { 0x00000000, 0x00202411, 0x000 }, ++ { 0x00000000, 0x00202811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00221e29, 0x000 }, ++ { 0x00000000, 0x007048eb, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000001, 0x40330620, 0x000 }, ++ { 0x00000000, 0xc0302409, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x181 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x186 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x186 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000001, 0x00530621, 0x182 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x197 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000011, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x0078042a, 0x2fb }, ++ { 0x00000000, 0x00202809, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x174 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x194 }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x46000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x19b }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00804811, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40281620, 0x000 }, ++ { 0x00000010, 0xc0811a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00221e30, 0x000 }, ++ { 0x00000029, 0x00201a2d, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfffbff09, 0x00204811, 0x000 }, ++ { 0x0000000f, 0x0020222d, 0x000 }, ++ { 0x00001fff, 0x00294a28, 0x000 }, ++ { 0x00000006, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000100, 0x00201811, 0x000 }, ++ { 0x00000008, 0x00621e28, 0x12f }, ++ { 0x00000008, 0x00822228, 0x000 }, ++ { 0x0002c000, 0x00204411, 0x000 }, ++ { 0x00000015, 0x00600e2d, 0x1bd }, ++ { 0x00000016, 0x00600e2d, 0x1bd }, ++ { 0x0000c008, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x1b9 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x39000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00804802, 0x000 }, ++ { 0x00000018, 0x00202e2d, 0x000 }, ++ { 0x00000000, 0x003b0d63, 0x000 }, ++ { 0x00000008, 0x00224a23, 0x000 }, ++ { 0x00000010, 0x00224a23, 0x000 }, ++ { 0x00000018, 0x00224a23, 0x000 }, ++ { 0x00000000, 0x00804803, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000007, 0x0021062f, 0x000 }, ++ { 0x00000013, 0x00200a2d, 0x000 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000ffff, 0x40282220, 0x000 }, ++ { 0x0000000f, 0x00262228, 0x000 }, ++ { 0x00000010, 0x40212620, 0x000 }, ++ { 0x0000000f, 0x00262629, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1e0 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000081, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000080, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1dc }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1d8 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000001f, 0x00280a22, 0x000 }, ++ { 0x0000001f, 0x00282a2a, 0x000 }, ++ { 0x00000001, 0x00530621, 0x1d1 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00304a2f, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00301e2f, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1e5 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x0000000f, 0x00260e23, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000000f, 0x00261224, 0x000 }, ++ { 0x00000000, 0x00201411, 0x000 }, ++ { 0x00000000, 0x00601811, 0x2bb }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022b, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1f8 }, ++ { 0x00000010, 0x00221628, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a29, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x0020480a, 0x000 }, ++ { 0x00000000, 0x00202c11, 0x000 }, ++ { 0x00000010, 0x00221623, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a24, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x00731503, 0x205 }, ++ { 0x00000000, 0x00201805, 0x000 }, ++ { 0x00000000, 0x00731524, 0x205 }, ++ { 0x00000000, 0x002d14c5, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00000000, 0x00202003, 0x000 }, ++ { 0x00000000, 0x00802404, 0x000 }, ++ { 0x0000000f, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x689 }, ++ { 0x00000000, 0x002b1405, 0x000 }, ++ { 0x00000001, 0x00901625, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00294a22, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a21, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0x40281220, 0x000 }, ++ { 0x00000010, 0xc0211a20, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211620, 0x000 }, ++ { 0x00000000, 0x00741465, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00000001, 0x00330621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x219 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x212 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x642 }, ++ { 0x00000000, 0x0040040f, 0x213 }, ++ { 0x00000000, 0x00600000, 0x62e }, ++ { 0x00000000, 0x00600000, 0x642 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00000000, 0x00600000, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x232 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x236 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x236 }, ++ { 0x00000000, 0xc0404800, 0x233 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00600411, 0x2fb }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x62e }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000018, 0x40210a20, 0x000 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x24c }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x00080101, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x251 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000010, 0x00600411, 0x315 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x27c }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000001, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x26a }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x0000ffff, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00341c27, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x25f }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e5, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x262 }, ++ { 0x00000000, 0x00201407, 0x000 }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x00341c47, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x267 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x26a }, ++ { 0x00000000, 0x00201807, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2c1 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00342023, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x272 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x271 }, ++ { 0x00000016, 0x00404811, 0x276 }, ++ { 0x00000018, 0x00404811, 0x276 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x275 }, ++ { 0x00000017, 0x00404811, 0x276 }, ++ { 0x00000019, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00604411, 0x2e9 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x256 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000010, 0x40210620, 0x000 }, ++ { 0x0000ffff, 0xc0280a20, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0881a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x00000000, 0x00600000, 0x62e }, ++ { 0x00000000, 0xc0600000, 0x2a3 }, ++ { 0x00000005, 0x00200a2d, 0x000 }, ++ { 0x00000008, 0x00220a22, 0x000 }, ++ { 0x0000002b, 0x00201a2d, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00007000, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00311ce6, 0x000 }, ++ { 0x0000002a, 0x00201a2d, 0x000 }, ++ { 0x0000000c, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x292 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00691ce2, 0x12f }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x29d }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000001c, 0x00403627, 0x000 }, ++ { 0x0000000c, 0xc0220a20, 0x000 }, ++ { 0x00000029, 0x00203622, 0x000 }, ++ { 0x00000028, 0xc0403620, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000009, 0x00204811, 0x000 }, ++ { 0xa1000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce3, 0x000 }, ++ { 0x00000021, 0x00203627, 0x000 }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce4, 0x000 }, ++ { 0x00000022, 0x00203627, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a3, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203624, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000000, 0x00311cc4, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x2dc }, ++ { 0x00000000, 0x00400000, 0x2d9 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2d9 }, ++ { 0x00000003, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2dc }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e1, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a1, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e2, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000000, 0x00600000, 0x665 }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00600000, 0x65c }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2a7 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x0000001a, 0x00201e2d, 0x000 }, ++ { 0x0000001b, 0x0080222d, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca1, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x003808c5, 0x000 }, ++ { 0x00000000, 0x00300841, 0x000 }, ++ { 0x00000001, 0x00220a22, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000017, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x318 }, ++ { 0xffffffef, 0x00280621, 0x000 }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x0000f8e0, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00294901, 0x000 }, ++ { 0x00000000, 0x00894901, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x97000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00002257, 0x00204411, 0x000 }, ++ { 0x00000003, 0xc0484a20, 0x000 }, ++ { 0x0000225d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x642 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x00000001, 0x40304a20, 0x000 }, ++ { 0x00000002, 0xc0304a20, 0x000 }, ++ { 0x00000001, 0x00530a22, 0x34b }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x354 }, ++ { 0x00000014, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x364 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00604802, 0x36e }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x36a }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35f }, ++ { 0x00000028, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5bd }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35f }, ++ { 0x0000002c, 0x00203626, 0x000 }, ++ { 0x00000049, 0x00201811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000000, 0x002f0226, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x370 }, ++ { 0x0000002c, 0x00801a2d, 0x000 }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x00000015, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x386 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b1 }, ++ { 0x00000016, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b5 }, ++ { 0x00000020, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x39c }, ++ { 0x0000000f, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a8 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a8 }, ++ { 0x0000001e, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x390 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x08000000, 0x00290a22, 0x000 }, ++ { 0x00000003, 0x40210e20, 0x000 }, ++ { 0x0000000c, 0xc0211220, 0x000 }, ++ { 0x00080000, 0x00281224, 0x000 }, ++ { 0x00000014, 0xc0221620, 0x000 }, ++ { 0x00000000, 0x002914a4, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948a2, 0x000 }, ++ { 0x0000a1fe, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000015, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x392 }, ++ { 0x0000210e, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000003, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x39e }, ++ { 0x00002108, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x80000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000010, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3ae }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00404811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x0000001d, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3ce }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3c0 }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0xbabecafe, 0x00204811, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00404811, 0x000 }, ++ { 0x00002170, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000a, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3d3 }, ++ { 0x8c000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00003fff, 0x40280a20, 0x000 }, ++ { 0x80000000, 0x40280e20, 0x000 }, ++ { 0x40000000, 0xc0281220, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68a }, ++ { 0x00000000, 0x00201410, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e1 }, ++ { 0x00000000, 0xc0401800, 0x3e4 }, ++ { 0x00003fff, 0xc0281a20, 0x000 }, ++ { 0x00040000, 0x00694626, 0x68a }, ++ { 0x00000000, 0x00201810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e7 }, ++ { 0x00000000, 0xc0401c00, 0x3ea }, ++ { 0x00003fff, 0xc0281e20, 0x000 }, ++ { 0x00040000, 0x00694627, 0x68a }, ++ { 0x00000000, 0x00201c10, 0x000 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0x002820c5, 0x000 }, ++ { 0x00000000, 0x004948e8, 0x000 }, ++ { 0xa5800000, 0x00200811, 0x000 }, ++ { 0x00002000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x0000001f, 0xc0210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3f7 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0xc0481220, 0x3ff }, ++ { 0xa7800000, 0x00200811, 0x000 }, ++ { 0x0000a000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00304883, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xa9800000, 0x00200811, 0x000 }, ++ { 0x0000c000, 0x00400c11, 0x3fa }, ++ { 0xab800000, 0x00200811, 0x000 }, ++ { 0x0000f8e0, 0x00400c11, 0x3fa }, ++ { 0xad800000, 0x00200811, 0x000 }, ++ { 0x0000f880, 0x00400c11, 0x3fa }, ++ { 0xb3800000, 0x00200811, 0x000 }, ++ { 0x0000f3fc, 0x00400c11, 0x3fa }, ++ { 0xaf800000, 0x00200811, 0x000 }, ++ { 0x0000e000, 0x00400c11, 0x3fa }, ++ { 0xb1800000, 0x00200811, 0x000 }, ++ { 0x0000f000, 0x00400c11, 0x3fa }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00002148, 0x00204811, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x01182000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0218a000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0318c000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0418f8e0, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0518f880, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0618e000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0718f000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0818f3fc, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000030, 0x00200a2d, 0x000 }, ++ { 0x00000000, 0xc0290c40, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x86000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x85000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68a }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00404c02, 0x448 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x00000000, 0xc0201400, 0x000 }, ++ { 0x00000000, 0xc0201800, 0x000 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x456 }, ++ { 0x00000000, 0xc0202000, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x00000010, 0x00280a23, 0x000 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x45e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0x00694624, 0x68a }, ++ { 0x00000000, 0x00400000, 0x463 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00604805, 0x68f }, ++ { 0x00000000, 0x002824f0, 0x000 }, ++ { 0x00000007, 0x00280a23, 0x000 }, ++ { 0x00000001, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46a }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x04e00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000002, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46f }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x02e00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x474 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x479 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000005, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x47e }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x483 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x08e00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x000 }, ++ { 0x00000008, 0x00210a23, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x48d }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x496 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x00404c08, 0x456 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000011, 0x40211220, 0x000 }, ++ { 0x00000012, 0x40211620, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4a0 }, ++ { 0x00040000, 0xc0494a20, 0x4a1 }, ++ { 0xfffbffff, 0xc0284a20, 0x000 }, ++ { 0x00000000, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4ad }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000c, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4a9 }, ++ { 0xa0000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00204811, 0x000 }, ++ { 0x0000216b, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000216c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4a7 }, ++ { 0x00000000, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4c0 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x68f }, ++ { 0x00000000, 0x00400000, 0x4c4 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x68a }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4cb }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0404810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000000, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4cd }, ++ { 0x00002180, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000003, 0x00333e2f, 0x000 }, ++ { 0x00000001, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4fd }, ++ { 0x0000002c, 0x00200a2d, 0x000 }, ++ { 0x00040000, 0x18e00c11, 0x4ec }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xd8c04800, 0x4e0 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000002d, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x00290c83, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000011, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4a7 }, ++ { 0x0000002c, 0xc0203620, 0x000 }, ++ { 0x0000002d, 0xc0403620, 0x000 }, ++ { 0x0000000f, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x502 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0xd9000000, 0x000 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xb5000000, 0x00204411, 0x000 }, ++ { 0x00002000, 0x00204811, 0x000 }, ++ { 0xb6000000, 0x00204411, 0x000 }, ++ { 0x0000a000, 0x00204811, 0x000 }, ++ { 0xb7000000, 0x00204411, 0x000 }, ++ { 0x0000c000, 0x00204811, 0x000 }, ++ { 0xb8000000, 0x00204411, 0x000 }, ++ { 0x0000f8e0, 0x00204811, 0x000 }, ++ { 0xb9000000, 0x00204411, 0x000 }, ++ { 0x0000f880, 0x00204811, 0x000 }, ++ { 0xba000000, 0x00204411, 0x000 }, ++ { 0x0000e000, 0x00204811, 0x000 }, ++ { 0xbb000000, 0x00204411, 0x000 }, ++ { 0x0000f000, 0x00204811, 0x000 }, ++ { 0xbc000000, 0x00204411, 0x000 }, ++ { 0x0000f3fc, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00204811, 0x000 }, ++ { 0x000000ff, 0x00280e30, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x516 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x52b }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000001c, 0x00203623, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000029, 0x00203623, 0x000 }, ++ { 0x00000028, 0x00203623, 0x000 }, ++ { 0x00000017, 0x00203623, 0x000 }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203623, 0x000 }, ++ { 0x00000015, 0x00203623, 0x000 }, ++ { 0x00000016, 0x00203623, 0x000 }, ++ { 0xffffe000, 0x00200c11, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00200c11, 0x000 }, ++ { 0x00000023, 0x00203623, 0x000 }, ++ { 0x00000024, 0x00203623, 0x000 }, ++ { 0xf1ffffff, 0x00283a2e, 0x000 }, ++ { 0x0000001a, 0xc0220e20, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000002a, 0x40203620, 0x000 }, ++ { 0x87000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x9d000000, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x40214a20, 0x000 }, ++ { 0x96000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x0000001f, 0x00211624, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x0000001d, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00281e23, 0x000 }, ++ { 0x00000008, 0x00222223, 0x000 }, ++ { 0xfffff000, 0x00282228, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x0000001f, 0x00203628, 0x000 }, ++ { 0x00000018, 0x00211e23, 0x000 }, ++ { 0x00000020, 0x00203627, 0x000 }, ++ { 0x00000002, 0x00221624, 0x000 }, ++ { 0x00000000, 0x003014a8, 0x000 }, ++ { 0x0000001e, 0x00203625, 0x000 }, ++ { 0x00000003, 0x00211a24, 0x000 }, ++ { 0x10000000, 0x00281a26, 0x000 }, ++ { 0xefffffff, 0x00283a2e, 0x000 }, ++ { 0x00000000, 0x004938ce, 0x678 }, ++ { 0x00000001, 0x40280a20, 0x000 }, ++ { 0x00000006, 0x40280e20, 0x000 }, ++ { 0x00000300, 0xc0281220, 0x000 }, ++ { 0x00000008, 0x00211224, 0x000 }, ++ { 0x00000000, 0xc0201620, 0x000 }, ++ { 0x00000000, 0xc0201a20, 0x000 }, ++ { 0x00000000, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x563 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68a }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00020000, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56b }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x579 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56b }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68a }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x579 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56f }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x579 }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x577 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x68f }, ++ { 0x00000000, 0x00401c10, 0x579 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x57b }, ++ { 0x00000000, 0x00600000, 0x5c6 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x58c }, ++ { 0x0000a2b7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x68a }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000a2c4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x58a }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000001, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x59d }, ++ { 0x0000a2bb, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x68a }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000a2c5, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x59b }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000002, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5ae }, ++ { 0x0000a2bf, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x68a }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000a2c6, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5ac }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x0000a2c3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x68a }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000a2c7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5bb }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x85000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x0000304a, 0x00204411, 0x000 }, ++ { 0x01000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00400000, 0x5c1 }, ++ { 0xa4000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x5c6 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000002c, 0x00203621, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5cd }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000030, 0x00403621, 0x5e0 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x5e0 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a092, 0x00604411, 0x68a }, ++ { 0x00000031, 0x00203630, 0x000 }, ++ { 0x0004a093, 0x00604411, 0x68a }, ++ { 0x00000032, 0x00203630, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x68a }, ++ { 0x00000033, 0x00203630, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x68a }, ++ { 0x00000034, 0x00203630, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x68a }, ++ { 0x00000035, 0x00203630, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x68a }, ++ { 0x00000036, 0x00203630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x88000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000001, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x629 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x629 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x602 }, ++ { 0x0000a092, 0x00204411, 0x000 }, ++ { 0x00000031, 0x00204a2d, 0x000 }, ++ { 0x0000a093, 0x00204411, 0x000 }, ++ { 0x00000032, 0x00204a2d, 0x000 }, ++ { 0x0000a2b6, 0x00204411, 0x000 }, ++ { 0x00000033, 0x00204a2d, 0x000 }, ++ { 0x0000a2ba, 0x00204411, 0x000 }, ++ { 0x00000034, 0x00204a2d, 0x000 }, ++ { 0x0000a2be, 0x00204411, 0x000 }, ++ { 0x00000035, 0x00204a2d, 0x000 }, ++ { 0x0000a2c2, 0x00204411, 0x000 }, ++ { 0x00000036, 0x00204a2d, 0x000 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x000001ff, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x628 }, ++ { 0x00000000, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x60b }, ++ { 0x0004a003, 0x00604411, 0x68a }, ++ { 0x0000a003, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x610 }, ++ { 0x0004a010, 0x00604411, 0x68a }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x628 }, ++ { 0x0004a011, 0x00604411, 0x68a }, ++ { 0x0000a011, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a012, 0x00604411, 0x68a }, ++ { 0x0000a012, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a013, 0x00604411, 0x68a }, ++ { 0x0000a013, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a014, 0x00604411, 0x68a }, ++ { 0x0000a014, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a015, 0x00604411, 0x68a }, ++ { 0x0000a015, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a016, 0x00604411, 0x68a }, ++ { 0x0000a016, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a017, 0x00604411, 0x68a }, ++ { 0x0000a017, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000002c, 0x0080062d, 0x000 }, ++ { 0xff000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000002, 0x00804811, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x63a }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000002, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x638 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x00001000, 0x00200811, 0x000 }, ++ { 0x0000002b, 0x00203622, 0x000 }, ++ { 0x00000000, 0x00600000, 0x63e }, ++ { 0x00000000, 0x00600000, 0x5c6 }, ++ { 0x98000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x63e }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000022, 0x00204811, 0x000 }, ++ { 0x89000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00404811, 0x62a }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404811, 0x62a }, ++ { 0x00000000, 0x00600000, 0x659 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0xc0204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x09800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68a }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000004, 0x00404c11, 0x653 }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000004, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffffb, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffff7, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x01800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68a }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x689 }, ++ { 0x00000010, 0x00404c11, 0x66f }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x38c00000, 0x000 }, ++ { 0x0000001d, 0x00200a2d, 0x000 }, ++ { 0x0000001e, 0x00200e2d, 0x000 }, ++ { 0x0000001f, 0x0020122d, 0x000 }, ++ { 0x00000020, 0x0020162d, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000004, 0x00301224, 0x000 }, ++ { 0x00000000, 0x002f0064, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x688 }, ++ { 0x00000003, 0x00281a22, 0x000 }, ++ { 0x00000008, 0x00221222, 0x000 }, ++ { 0xfffff000, 0x00281224, 0x000 }, ++ { 0x00000000, 0x002910c4, 0x000 }, ++ { 0x0000001f, 0x00403624, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x68a }, ++ { 0x9f000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x68d }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x68f }, ++ { 0x9e000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x692 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0xc0204411, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000024, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000022, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00404811, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x014204ff, 0x05bd0250, 0x000 }, ++ { 0x01c30168, 0x043f05bd, 0x000 }, ++ { 0x02250209, 0x02500151, 0x000 }, ++ { 0x02230245, 0x02a00241, 0x000 }, ++ { 0x03d705bd, 0x05bd05bd, 0x000 }, ++ { 0x06460647, 0x031f05bd, 0x000 }, ++ { 0x05bd05c2, 0x03200340, 0x000 }, ++ { 0x032a0282, 0x03420334, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd054e, 0x05bd05bd, 0x000 }, ++ { 0x03ba05bd, 0x04b80344, 0x000 }, ++ { 0x0497044d, 0x043d05bd, 0x000 }, ++ { 0x04cd05bd, 0x044104da, 0x000 }, ++ { 0x044d0504, 0x03510375, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd05bd, 0x063c05c4, 0x000 }, ++ { 0x05bd05bd, 0x000705bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x03f803ed, 0x04080406, 0x000 }, ++ { 0x040e040a, 0x040c0410, 0x000 }, ++ { 0x041c0418, 0x04240420, 0x000 }, ++ { 0x042c0428, 0x04340430, 0x000 }, ++ { 0x05bd05bd, 0x043805bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x00020676, 0x06940006, 0x000 }, ++}; ++ ++static const u32 RV630_pfp_microcode[] = { ++0xca0400, ++0xa00000, ++0x7e828b, ++0x7c038b, ++0x8001b8, ++0x7c038b, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xc41838, ++0xca2400, ++0xca2800, ++0x9581a8, ++0xc41c3a, ++0xc3c000, ++0xca0800, ++0xca0c00, ++0x7c744b, ++0xc20005, ++0x99c000, ++0xc41c3a, ++0x7c744c, ++0xc0fff0, ++0x042c04, ++0x309002, ++0x7d2500, ++0x351402, ++0x7d350b, ++0x255403, ++0x7cd580, ++0x259c03, ++0x95c004, ++0xd5001b, ++0x7eddc1, ++0x7d9d80, ++0xd6801b, ++0xd5801b, ++0xd4401e, ++0xd5401e, ++0xd6401e, ++0xd6801e, ++0xd4801e, ++0xd4c01e, ++0x9783d3, ++0xd5c01e, ++0xca0800, ++0x80001a, ++0xca0c00, ++0xe4011e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xe4013e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca1800, ++0xd4401e, ++0xd5801e, ++0x800053, ++0xd40075, ++0xd4401e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd48019, ++0xd4c018, ++0xd50017, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xe2001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0xd48060, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xd48061, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xca0c00, ++0xd4401e, ++0xd48016, ++0xd4c016, ++0xd4801e, ++0x8001b8, ++0xd4c01e, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x948004, ++0xca1400, ++0xe420f3, ++0xd42013, ++0xd56065, ++0xd4e01c, ++0xd5201c, ++0xd5601c, ++0x800000, ++0x062001, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9483f7, ++0xca1400, ++0xe420f3, ++0x800079, ++0xd42013, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9883ef, ++0xca1400, ++0xd40064, ++0x80008d, ++0x000000, ++0xc41432, ++0xc61843, ++0xc4082f, ++0x954005, ++0xc40c30, ++0xd4401e, ++0x800000, ++0xee001e, ++0x9583f5, ++0xc41031, ++0xd44033, ++0xd52065, ++0xd4a01c, ++0xd4e01c, ++0xd5201c, ++0xe4015e, ++0xd4001e, ++0x800000, ++0x062001, ++0xca1800, ++0x0a2001, ++0xd60076, ++0xc40836, ++0x988007, ++0xc61045, ++0x950110, ++0xd4001f, ++0xd46062, ++0x800000, ++0xd42062, ++0xcc3835, ++0xcc1433, ++0x8401bb, ++0xd40072, ++0xd5401e, ++0x800000, ++0xee001e, ++0xe2001a, ++0x8401bb, ++0xe2001a, ++0xcc104b, ++0xcc0447, ++0x2c9401, ++0x7d098b, ++0x984005, ++0x7d15cb, ++0xd4001a, ++0x8001b8, ++0xd4006d, ++0x344401, ++0xcc0c48, ++0x98403a, ++0xcc2c4a, ++0x958004, ++0xcc0449, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0x282801, ++0x8400f0, ++0xcc1003, ++0x98801b, ++0x04380c, ++0x8400f0, ++0xcc1003, ++0x988017, ++0x043808, ++0x8400f0, ++0xcc1003, ++0x988013, ++0x043804, ++0x8400f0, ++0xcc1003, ++0x988014, ++0xcc104c, ++0x9a8009, ++0xcc144d, ++0x9840dc, ++0xd4006d, ++0xcc1848, ++0xd5001a, ++0xd5401a, ++0x8000c9, ++0xd5801a, ++0x96c0d5, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0x9ac003, ++0xd4006d, ++0xd4006e, ++0x800000, ++0xec007f, ++0x9ac0cc, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0x7d9103, ++0x7dd583, ++0x7d190c, ++0x35cc1f, ++0x35701f, ++0x7cf0cb, ++0x7cd08b, ++0x880000, ++0x7e8e8b, ++0x95c004, ++0xd4006e, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0xcc0803, ++0xcc0c03, ++0xcc1003, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0xcc2403, ++0xcc2803, ++0x35c41f, ++0x36b01f, ++0x7c704b, ++0x34f01f, ++0x7c704b, ++0x35701f, ++0x7c704b, ++0x7d8881, ++0x7dccc1, ++0x7e5101, ++0x7e9541, ++0x7c9082, ++0x7cd4c2, ++0x7c848b, ++0x9ac003, ++0x7c8c8b, ++0x2c8801, ++0x98809e, ++0xd4006d, ++0x98409c, ++0xd4006e, ++0xcc084c, ++0xcc0c4d, ++0xcc1048, ++0xd4801a, ++0xd4c01a, ++0x800101, ++0xd5001a, ++0xcc0832, ++0xd40032, ++0x9482d9, ++0xca0c00, ++0xd4401e, ++0x800000, ++0xd4001e, ++0xe4011e, ++0xd4001e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd4401e, ++0xca1400, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xd5401e, ++0xd54034, ++0x800000, ++0xee001e, ++0x280404, ++0xe2001a, ++0xe2001a, ++0xd4401a, ++0xca3800, ++0xcc0803, ++0xcc0c03, ++0xcc0c03, ++0xcc0c03, ++0x9882bd, ++0x000000, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0400, ++0xc2ff00, ++0xcc0834, ++0xc13fff, ++0x7c74cb, ++0x7cc90b, ++0x7d010f, ++0x9902b0, ++0x7c738b, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0800, ++0x281900, ++0x7d898b, ++0x958014, ++0x281404, ++0xca0c00, ++0xca1000, ++0xca1c00, ++0xca2400, ++0xe2001f, ++0xd4c01a, ++0xd5001a, ++0xd5401a, ++0xcc1803, ++0xcc2c03, ++0xcc2c03, ++0xcc2c03, ++0x7da58b, ++0x7d9c47, ++0x984297, ++0x000000, ++0x800161, ++0xd4c01a, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0x248c06, ++0x0ccc06, ++0x98c006, ++0xcc104e, ++0x990004, ++0xd40073, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xca0800, ++0xca0c00, ++0x34d018, ++0x251001, ++0x950021, ++0xc17fff, ++0xca1000, ++0xca1400, ++0xca1800, ++0xd4801d, ++0xd4c01d, ++0x7db18b, ++0xc14202, ++0xc2c001, ++0xd5801d, ++0x34dc0e, ++0x7d5d4c, ++0x7f734c, ++0xd7401e, ++0xd5001e, ++0xd5401e, ++0xc14200, ++0xc2c000, ++0x099c01, ++0x31dc10, ++0x7f5f4c, ++0x7f734c, ++0x042802, ++0x7d8380, ++0xd5a86f, ++0xd58066, ++0xd7401e, ++0xec005e, ++0xc82402, ++0xc82402, ++0x8001b8, ++0xd60076, ++0xd4401e, ++0xd4801e, ++0xd4c01e, ++0x800000, ++0xee001e, ++0x800000, ++0xee001f, ++0xd4001f, ++0x800000, ++0xd4001f, ++0xd4001f, ++0x880000, ++0xd4001f, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x010171, ++0x020178, ++0x03008f, ++0x04007f, ++0x050003, ++0x06003f, ++0x070032, ++0x08012c, ++0x090046, ++0x0a0036, ++0x1001b6, ++0x1700a2, ++0x22013a, ++0x230149, ++0x2000b4, ++0x240125, ++0x27004d, ++0x28006a, ++0x2a0060, ++0x2b0052, ++0x2f0065, ++0x320087, ++0x34017f, ++0x3c0156, ++0x3f0072, ++0x41018c, ++0x44012e, ++0x550173, ++0x56017a, ++0x60000b, ++0x610034, ++0x620038, ++0x630038, ++0x640038, ++0x650038, ++0x660038, ++0x670038, ++0x68003a, ++0x690041, ++0x6a0048, ++0x6b0048, ++0x6c0048, ++0x6d0048, ++0x6e0048, ++0x6f0048, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++}; ++ ++static const u32 RV635_cp_microcode[][3] = { ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0000ffff, 0x00284621, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x000 }, ++ { 0x00010000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x00000000, 0x00600000, 0x62e }, ++ { 0x00000000, 0x00600000, 0x642 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000f00, 0x00281622, 0x000 }, ++ { 0x00000008, 0x00211625, 0x000 }, ++ { 0x00000018, 0x00203625, 0x000 }, ++ { 0x8d000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x002f0225, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x018 }, ++ { 0x00412000, 0x00404811, 0x019 }, ++ { 0x00422000, 0x00204811, 0x000 }, ++ { 0x8e000000, 0x00204411, 0x000 }, ++ { 0x00000028, 0x00204a2d, 0x000 }, ++ { 0x90000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x0000000c, 0x00211622, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000019, 0x00211a22, 0x000 }, ++ { 0x00000004, 0x00281a26, 0x000 }, ++ { 0x00000000, 0x002914c5, 0x000 }, ++ { 0x00000019, 0x00203625, 0x000 }, ++ { 0x00000000, 0x003a1402, 0x000 }, ++ { 0x00000016, 0x00211625, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0xfffffffc, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002914a3, 0x000 }, ++ { 0x00000017, 0x00203625, 0x000 }, ++ { 0x00008000, 0x00280e22, 0x000 }, ++ { 0x00000007, 0x00220e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x20000000, 0x00280e22, 0x000 }, ++ { 0x00000006, 0x00210e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x00000000, 0x00220222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x038 }, ++ { 0x00000000, 0x2ee00000, 0x035 }, ++ { 0x00000000, 0x2ce00000, 0x037 }, ++ { 0x00000000, 0x00400e2d, 0x039 }, ++ { 0x00000008, 0x00200e2d, 0x000 }, ++ { 0x00000009, 0x0040122d, 0x046 }, ++ { 0x00000001, 0x00400e2d, 0x039 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x03e }, ++ { 0x00000008, 0x00401c11, 0x041 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x0000000f, 0x00281e27, 0x000 }, ++ { 0x00000003, 0x00221e27, 0x000 }, ++ { 0x7fc00000, 0x00281a23, 0x000 }, ++ { 0x00000014, 0x00211a26, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000008, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x00290cc7, 0x000 }, ++ { 0x00000027, 0x00203624, 0x000 }, ++ { 0x00007f00, 0x00281221, 0x000 }, ++ { 0x00001400, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x04b }, ++ { 0x00000001, 0x00290e23, 0x000 }, ++ { 0x0000000e, 0x00203623, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfff80000, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x003a2c02, 0x000 }, ++ { 0x00000002, 0x00220e2b, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x0000000f, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00204a2d, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000029, 0x00200e2d, 0x000 }, ++ { 0x060a0200, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x061 }, ++ { 0x00000000, 0x2ee00000, 0x05f }, ++ { 0x00000000, 0x2ce00000, 0x05e }, ++ { 0x00000000, 0x00400e2d, 0x062 }, ++ { 0x00000001, 0x00400e2d, 0x062 }, ++ { 0x0000000a, 0x00200e2d, 0x000 }, ++ { 0x0000000b, 0x0040122d, 0x06a }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x7fc00000, 0x00281623, 0x000 }, ++ { 0x00000014, 0x00211625, 0x000 }, ++ { 0x00000001, 0x00331625, 0x000 }, ++ { 0x80000000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00290ca3, 0x000 }, ++ { 0x3ffffc00, 0x00290e23, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x06d }, ++ { 0x00000100, 0x00401c11, 0x070 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x000000f0, 0x00281e27, 0x000 }, ++ { 0x00000004, 0x00221e27, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0xfffff0ff, 0x00281a30, 0x000 }, ++ { 0x0000a028, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948e6, 0x000 }, ++ { 0x0000a018, 0x00204411, 0x000 }, ++ { 0x3fffffff, 0x00284a23, 0x000 }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000030, 0x0020162d, 0x000 }, ++ { 0x00000002, 0x00291625, 0x000 }, ++ { 0x00000030, 0x00203625, 0x000 }, ++ { 0x00000025, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a3, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x083 }, ++ { 0x00000026, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a4, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x084 }, ++ { 0x00000000, 0x00400000, 0x08a }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203624, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x08a }, ++ { 0x00000000, 0x00600000, 0x665 }, ++ { 0x00000000, 0x00600000, 0x659 }, ++ { 0x00000002, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x08d }, ++ { 0x00000012, 0xc0403620, 0x093 }, ++ { 0x00000000, 0x2ee00000, 0x091 }, ++ { 0x00000000, 0x2ce00000, 0x090 }, ++ { 0x00000002, 0x00400e2d, 0x092 }, ++ { 0x00000003, 0x00400e2d, 0x092 }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000012, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x098 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x0a0 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x2ee00000, 0x09e }, ++ { 0x00000000, 0x2ce00000, 0x09d }, ++ { 0x00000002, 0x00400e2d, 0x09f }, ++ { 0x00000003, 0x00400e2d, 0x09f }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x003f0000, 0x00280e23, 0x000 }, ++ { 0x00000010, 0x00210e23, 0x000 }, ++ { 0x00000011, 0x00203623, 0x000 }, ++ { 0x0000001e, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0a7 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x0000001f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0aa }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000008, 0x00210e2b, 0x000 }, ++ { 0x0000007f, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0e1 }, ++ { 0x00000000, 0x27000000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x0b3 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000000c, 0x00221e30, 0x000 }, ++ { 0x99800000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x0020122d, 0x000 }, ++ { 0x00000008, 0x00221224, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00291ce4, 0x000 }, ++ { 0x00000000, 0x00604807, 0x12f }, ++ { 0x9b000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x9c000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x0033146f, 0x000 }, ++ { 0x00000001, 0x00333e23, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0x00203c05, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e007, 0x00204411, 0x000 }, ++ { 0x0000000f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0cb }, ++ { 0x00f8ff08, 0x00204811, 0x000 }, ++ { 0x98000000, 0x00404811, 0x0dc }, ++ { 0x000000f0, 0x00280e22, 0x000 }, ++ { 0x000000a0, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x0da }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d5 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d4 }, ++ { 0x00003f00, 0x00400c11, 0x0d6 }, ++ { 0x00001f00, 0x00400c11, 0x0d6 }, ++ { 0x00000f00, 0x00200c11, 0x000 }, ++ { 0x00380009, 0x00294a23, 0x000 }, ++ { 0x3f000000, 0x00280e2b, 0x000 }, ++ { 0x00000002, 0x00220e23, 0x000 }, ++ { 0x00000007, 0x00494a23, 0x0dc }, ++ { 0x00380f09, 0x00204811, 0x000 }, ++ { 0x68000007, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000a202, 0x00204411, 0x000 }, ++ { 0x00ff0000, 0x00280e22, 0x000 }, ++ { 0x00000080, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00200e2d, 0x000 }, ++ { 0x00000026, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x002f0083, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0ea }, ++ { 0x00000000, 0x00600000, 0x65f }, ++ { 0x00000000, 0x00400000, 0x0eb }, ++ { 0x00000000, 0x00600000, 0x662 }, ++ { 0x00000007, 0x0020222d, 0x000 }, ++ { 0x00000005, 0x00220e22, 0x000 }, ++ { 0x00100000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x000000ef, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000003, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x0f8 }, ++ { 0x0000000b, 0x00210228, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0f8 }, ++ { 0x00000400, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000001c, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0fd }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000001e, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x10b }, ++ { 0x0000a30f, 0x00204411, 0x000 }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x104 }, ++ { 0xffffffff, 0x00404811, 0x10b }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x107 }, ++ { 0x0000ffff, 0x00404811, 0x10b }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x10a }, ++ { 0x000000ff, 0x00404811, 0x10b }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0002c400, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x112 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000018, 0x40224a20, 0x000 }, ++ { 0x00000010, 0xc0424a20, 0x114 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000000a, 0x00201011, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x11b }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00531224, 0x117 }, ++ { 0xffbfffff, 0x00283a2e, 0x000 }, ++ { 0x0000001b, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x12e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0x00000018, 0x00220e30, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e00e, 0x00204411, 0x000 }, ++ { 0x07f8ff08, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00294a23, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00800000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204806, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68a }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x689 }, ++ { 0x00000004, 0x00404c11, 0x135 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000001c, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x13c }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40280620, 0x000 }, ++ { 0x00000010, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x00341461, 0x000 }, ++ { 0x00000000, 0x00741882, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x147 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0681a20, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x158 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00300a2f, 0x000 }, ++ { 0x00000001, 0x00210a22, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600000, 0x18f }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00202c08, 0x000 }, ++ { 0x00000000, 0x00202411, 0x000 }, ++ { 0x00000000, 0x00202811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00221e29, 0x000 }, ++ { 0x00000000, 0x007048eb, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000001, 0x40330620, 0x000 }, ++ { 0x00000000, 0xc0302409, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x181 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x186 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x186 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000001, 0x00530621, 0x182 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x197 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000011, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x0078042a, 0x2fb }, ++ { 0x00000000, 0x00202809, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x174 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x194 }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x46000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x19b }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00804811, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40281620, 0x000 }, ++ { 0x00000010, 0xc0811a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00221e30, 0x000 }, ++ { 0x00000029, 0x00201a2d, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfffbff09, 0x00204811, 0x000 }, ++ { 0x0000000f, 0x0020222d, 0x000 }, ++ { 0x00001fff, 0x00294a28, 0x000 }, ++ { 0x00000006, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000100, 0x00201811, 0x000 }, ++ { 0x00000008, 0x00621e28, 0x12f }, ++ { 0x00000008, 0x00822228, 0x000 }, ++ { 0x0002c000, 0x00204411, 0x000 }, ++ { 0x00000015, 0x00600e2d, 0x1bd }, ++ { 0x00000016, 0x00600e2d, 0x1bd }, ++ { 0x0000c008, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x1b9 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x39000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00804802, 0x000 }, ++ { 0x00000018, 0x00202e2d, 0x000 }, ++ { 0x00000000, 0x003b0d63, 0x000 }, ++ { 0x00000008, 0x00224a23, 0x000 }, ++ { 0x00000010, 0x00224a23, 0x000 }, ++ { 0x00000018, 0x00224a23, 0x000 }, ++ { 0x00000000, 0x00804803, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000007, 0x0021062f, 0x000 }, ++ { 0x00000013, 0x00200a2d, 0x000 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000ffff, 0x40282220, 0x000 }, ++ { 0x0000000f, 0x00262228, 0x000 }, ++ { 0x00000010, 0x40212620, 0x000 }, ++ { 0x0000000f, 0x00262629, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1e0 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000081, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000080, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1dc }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1d8 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000001f, 0x00280a22, 0x000 }, ++ { 0x0000001f, 0x00282a2a, 0x000 }, ++ { 0x00000001, 0x00530621, 0x1d1 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00304a2f, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00301e2f, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1e5 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x0000000f, 0x00260e23, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000000f, 0x00261224, 0x000 }, ++ { 0x00000000, 0x00201411, 0x000 }, ++ { 0x00000000, 0x00601811, 0x2bb }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022b, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1f8 }, ++ { 0x00000010, 0x00221628, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a29, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x0020480a, 0x000 }, ++ { 0x00000000, 0x00202c11, 0x000 }, ++ { 0x00000010, 0x00221623, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a24, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x00731503, 0x205 }, ++ { 0x00000000, 0x00201805, 0x000 }, ++ { 0x00000000, 0x00731524, 0x205 }, ++ { 0x00000000, 0x002d14c5, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00000000, 0x00202003, 0x000 }, ++ { 0x00000000, 0x00802404, 0x000 }, ++ { 0x0000000f, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x689 }, ++ { 0x00000000, 0x002b1405, 0x000 }, ++ { 0x00000001, 0x00901625, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00294a22, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a21, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0x40281220, 0x000 }, ++ { 0x00000010, 0xc0211a20, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211620, 0x000 }, ++ { 0x00000000, 0x00741465, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00000001, 0x00330621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x219 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x212 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x642 }, ++ { 0x00000000, 0x0040040f, 0x213 }, ++ { 0x00000000, 0x00600000, 0x62e }, ++ { 0x00000000, 0x00600000, 0x642 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00000000, 0x00600000, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x232 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x236 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x236 }, ++ { 0x00000000, 0xc0404800, 0x233 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00600411, 0x2fb }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x62e }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000018, 0x40210a20, 0x000 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x24c }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x00080101, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x251 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000010, 0x00600411, 0x315 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x27c }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000001, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x26a }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x0000ffff, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00341c27, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x25f }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e5, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x262 }, ++ { 0x00000000, 0x00201407, 0x000 }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x00341c47, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x267 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x26a }, ++ { 0x00000000, 0x00201807, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2c1 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00342023, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x272 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x271 }, ++ { 0x00000016, 0x00404811, 0x276 }, ++ { 0x00000018, 0x00404811, 0x276 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x275 }, ++ { 0x00000017, 0x00404811, 0x276 }, ++ { 0x00000019, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00604411, 0x2e9 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x256 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000010, 0x40210620, 0x000 }, ++ { 0x0000ffff, 0xc0280a20, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0881a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x00000000, 0x00600000, 0x62e }, ++ { 0x00000000, 0xc0600000, 0x2a3 }, ++ { 0x00000005, 0x00200a2d, 0x000 }, ++ { 0x00000008, 0x00220a22, 0x000 }, ++ { 0x0000002b, 0x00201a2d, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00007000, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00311ce6, 0x000 }, ++ { 0x0000002a, 0x00201a2d, 0x000 }, ++ { 0x0000000c, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x292 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00691ce2, 0x12f }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x29d }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000001c, 0x00403627, 0x000 }, ++ { 0x0000000c, 0xc0220a20, 0x000 }, ++ { 0x00000029, 0x00203622, 0x000 }, ++ { 0x00000028, 0xc0403620, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000009, 0x00204811, 0x000 }, ++ { 0xa1000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce3, 0x000 }, ++ { 0x00000021, 0x00203627, 0x000 }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce4, 0x000 }, ++ { 0x00000022, 0x00203627, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a3, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203624, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000000, 0x00311cc4, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x2dc }, ++ { 0x00000000, 0x00400000, 0x2d9 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2d9 }, ++ { 0x00000003, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2dc }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e1, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a1, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e2, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000000, 0x00600000, 0x665 }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00600000, 0x65c }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2a7 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x0000001a, 0x00201e2d, 0x000 }, ++ { 0x0000001b, 0x0080222d, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca1, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x003808c5, 0x000 }, ++ { 0x00000000, 0x00300841, 0x000 }, ++ { 0x00000001, 0x00220a22, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000017, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x318 }, ++ { 0xffffffef, 0x00280621, 0x000 }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x0000f8e0, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00294901, 0x000 }, ++ { 0x00000000, 0x00894901, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x97000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00002257, 0x00204411, 0x000 }, ++ { 0x00000003, 0xc0484a20, 0x000 }, ++ { 0x0000225d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x642 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x00000001, 0x40304a20, 0x000 }, ++ { 0x00000002, 0xc0304a20, 0x000 }, ++ { 0x00000001, 0x00530a22, 0x34b }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x354 }, ++ { 0x00000014, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x364 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00604802, 0x36e }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x36a }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35f }, ++ { 0x00000028, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5bd }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35f }, ++ { 0x0000002c, 0x00203626, 0x000 }, ++ { 0x00000049, 0x00201811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000000, 0x002f0226, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x370 }, ++ { 0x0000002c, 0x00801a2d, 0x000 }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x00000015, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x386 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b1 }, ++ { 0x00000016, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b5 }, ++ { 0x00000020, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x39c }, ++ { 0x0000000f, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a8 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a8 }, ++ { 0x0000001e, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x390 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x08000000, 0x00290a22, 0x000 }, ++ { 0x00000003, 0x40210e20, 0x000 }, ++ { 0x0000000c, 0xc0211220, 0x000 }, ++ { 0x00080000, 0x00281224, 0x000 }, ++ { 0x00000014, 0xc0221620, 0x000 }, ++ { 0x00000000, 0x002914a4, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948a2, 0x000 }, ++ { 0x0000a1fe, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000015, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x392 }, ++ { 0x0000210e, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000003, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x39e }, ++ { 0x00002108, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x80000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000010, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3ae }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00404811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x0000001d, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3ce }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3c0 }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0xbabecafe, 0x00204811, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00404811, 0x000 }, ++ { 0x00002170, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000a, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3d3 }, ++ { 0x8c000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00003fff, 0x40280a20, 0x000 }, ++ { 0x80000000, 0x40280e20, 0x000 }, ++ { 0x40000000, 0xc0281220, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68a }, ++ { 0x00000000, 0x00201410, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e1 }, ++ { 0x00000000, 0xc0401800, 0x3e4 }, ++ { 0x00003fff, 0xc0281a20, 0x000 }, ++ { 0x00040000, 0x00694626, 0x68a }, ++ { 0x00000000, 0x00201810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e7 }, ++ { 0x00000000, 0xc0401c00, 0x3ea }, ++ { 0x00003fff, 0xc0281e20, 0x000 }, ++ { 0x00040000, 0x00694627, 0x68a }, ++ { 0x00000000, 0x00201c10, 0x000 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0x002820c5, 0x000 }, ++ { 0x00000000, 0x004948e8, 0x000 }, ++ { 0xa5800000, 0x00200811, 0x000 }, ++ { 0x00002000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x0000001f, 0xc0210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3f7 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0xc0481220, 0x3ff }, ++ { 0xa7800000, 0x00200811, 0x000 }, ++ { 0x0000a000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00304883, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xa9800000, 0x00200811, 0x000 }, ++ { 0x0000c000, 0x00400c11, 0x3fa }, ++ { 0xab800000, 0x00200811, 0x000 }, ++ { 0x0000f8e0, 0x00400c11, 0x3fa }, ++ { 0xad800000, 0x00200811, 0x000 }, ++ { 0x0000f880, 0x00400c11, 0x3fa }, ++ { 0xb3800000, 0x00200811, 0x000 }, ++ { 0x0000f3fc, 0x00400c11, 0x3fa }, ++ { 0xaf800000, 0x00200811, 0x000 }, ++ { 0x0000e000, 0x00400c11, 0x3fa }, ++ { 0xb1800000, 0x00200811, 0x000 }, ++ { 0x0000f000, 0x00400c11, 0x3fa }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00002148, 0x00204811, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x01182000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0218a000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0318c000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0418f8e0, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0518f880, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0618e000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0718f000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0818f3fc, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000030, 0x00200a2d, 0x000 }, ++ { 0x00000000, 0xc0290c40, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x86000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x85000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68a }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00404c02, 0x448 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x00000000, 0xc0201400, 0x000 }, ++ { 0x00000000, 0xc0201800, 0x000 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x456 }, ++ { 0x00000000, 0xc0202000, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x00000010, 0x00280a23, 0x000 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x45e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0x00694624, 0x68a }, ++ { 0x00000000, 0x00400000, 0x463 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00604805, 0x68f }, ++ { 0x00000000, 0x002824f0, 0x000 }, ++ { 0x00000007, 0x00280a23, 0x000 }, ++ { 0x00000001, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46a }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x04e00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000002, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46f }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x02e00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x474 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x479 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000005, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x47e }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x483 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x08e00000, 0x483 }, ++ { 0x00000000, 0x00400000, 0x490 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x000 }, ++ { 0x00000008, 0x00210a23, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x48d }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x496 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x00404c08, 0x456 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000011, 0x40211220, 0x000 }, ++ { 0x00000012, 0x40211620, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4a0 }, ++ { 0x00040000, 0xc0494a20, 0x4a1 }, ++ { 0xfffbffff, 0xc0284a20, 0x000 }, ++ { 0x00000000, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4ad }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000c, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4a9 }, ++ { 0xa0000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00204811, 0x000 }, ++ { 0x0000216b, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000216c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4a7 }, ++ { 0x00000000, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4c0 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x68f }, ++ { 0x00000000, 0x00400000, 0x4c4 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x68a }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4cb }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0404810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x68a }, ++ { 0x00000000, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4cd }, ++ { 0x00002180, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000003, 0x00333e2f, 0x000 }, ++ { 0x00000001, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4fd }, ++ { 0x0000002c, 0x00200a2d, 0x000 }, ++ { 0x00040000, 0x18e00c11, 0x4ec }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xd8c04800, 0x4e0 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000002d, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x00290c83, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000011, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4a7 }, ++ { 0x0000002c, 0xc0203620, 0x000 }, ++ { 0x0000002d, 0xc0403620, 0x000 }, ++ { 0x0000000f, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x502 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0xd9000000, 0x000 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xb5000000, 0x00204411, 0x000 }, ++ { 0x00002000, 0x00204811, 0x000 }, ++ { 0xb6000000, 0x00204411, 0x000 }, ++ { 0x0000a000, 0x00204811, 0x000 }, ++ { 0xb7000000, 0x00204411, 0x000 }, ++ { 0x0000c000, 0x00204811, 0x000 }, ++ { 0xb8000000, 0x00204411, 0x000 }, ++ { 0x0000f8e0, 0x00204811, 0x000 }, ++ { 0xb9000000, 0x00204411, 0x000 }, ++ { 0x0000f880, 0x00204811, 0x000 }, ++ { 0xba000000, 0x00204411, 0x000 }, ++ { 0x0000e000, 0x00204811, 0x000 }, ++ { 0xbb000000, 0x00204411, 0x000 }, ++ { 0x0000f000, 0x00204811, 0x000 }, ++ { 0xbc000000, 0x00204411, 0x000 }, ++ { 0x0000f3fc, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00204811, 0x000 }, ++ { 0x000000ff, 0x00280e30, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x516 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x52b }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000001c, 0x00203623, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000029, 0x00203623, 0x000 }, ++ { 0x00000028, 0x00203623, 0x000 }, ++ { 0x00000017, 0x00203623, 0x000 }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203623, 0x000 }, ++ { 0x00000015, 0x00203623, 0x000 }, ++ { 0x00000016, 0x00203623, 0x000 }, ++ { 0xffffe000, 0x00200c11, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00200c11, 0x000 }, ++ { 0x00000023, 0x00203623, 0x000 }, ++ { 0x00000024, 0x00203623, 0x000 }, ++ { 0xf1ffffff, 0x00283a2e, 0x000 }, ++ { 0x0000001a, 0xc0220e20, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000002a, 0x40203620, 0x000 }, ++ { 0x87000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x9d000000, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x40214a20, 0x000 }, ++ { 0x96000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x0000001f, 0x00211624, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x0000001d, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00281e23, 0x000 }, ++ { 0x00000008, 0x00222223, 0x000 }, ++ { 0xfffff000, 0x00282228, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x0000001f, 0x00203628, 0x000 }, ++ { 0x00000018, 0x00211e23, 0x000 }, ++ { 0x00000020, 0x00203627, 0x000 }, ++ { 0x00000002, 0x00221624, 0x000 }, ++ { 0x00000000, 0x003014a8, 0x000 }, ++ { 0x0000001e, 0x00203625, 0x000 }, ++ { 0x00000003, 0x00211a24, 0x000 }, ++ { 0x10000000, 0x00281a26, 0x000 }, ++ { 0xefffffff, 0x00283a2e, 0x000 }, ++ { 0x00000000, 0x004938ce, 0x678 }, ++ { 0x00000001, 0x40280a20, 0x000 }, ++ { 0x00000006, 0x40280e20, 0x000 }, ++ { 0x00000300, 0xc0281220, 0x000 }, ++ { 0x00000008, 0x00211224, 0x000 }, ++ { 0x00000000, 0xc0201620, 0x000 }, ++ { 0x00000000, 0xc0201a20, 0x000 }, ++ { 0x00000000, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x563 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68a }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00020000, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56b }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x579 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56b }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x68a }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x579 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56f }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x579 }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x577 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x68f }, ++ { 0x00000000, 0x00401c10, 0x579 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x57b }, ++ { 0x00000000, 0x00600000, 0x5c6 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x58c }, ++ { 0x0000a2b7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x68a }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000a2c4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x58a }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000001, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x59d }, ++ { 0x0000a2bb, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x68a }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000a2c5, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x59b }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000002, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5ae }, ++ { 0x0000a2bf, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x68a }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000a2c6, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5ac }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x0000a2c3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x68a }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000a2c7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5bb }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x85000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x0000304a, 0x00204411, 0x000 }, ++ { 0x01000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00400000, 0x5c1 }, ++ { 0xa4000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x5c6 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000002c, 0x00203621, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5cd }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000030, 0x00403621, 0x5e0 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x5e0 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a092, 0x00604411, 0x68a }, ++ { 0x00000031, 0x00203630, 0x000 }, ++ { 0x0004a093, 0x00604411, 0x68a }, ++ { 0x00000032, 0x00203630, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x68a }, ++ { 0x00000033, 0x00203630, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x68a }, ++ { 0x00000034, 0x00203630, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x68a }, ++ { 0x00000035, 0x00203630, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x68a }, ++ { 0x00000036, 0x00203630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x88000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000001, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x629 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x629 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x602 }, ++ { 0x0000a092, 0x00204411, 0x000 }, ++ { 0x00000031, 0x00204a2d, 0x000 }, ++ { 0x0000a093, 0x00204411, 0x000 }, ++ { 0x00000032, 0x00204a2d, 0x000 }, ++ { 0x0000a2b6, 0x00204411, 0x000 }, ++ { 0x00000033, 0x00204a2d, 0x000 }, ++ { 0x0000a2ba, 0x00204411, 0x000 }, ++ { 0x00000034, 0x00204a2d, 0x000 }, ++ { 0x0000a2be, 0x00204411, 0x000 }, ++ { 0x00000035, 0x00204a2d, 0x000 }, ++ { 0x0000a2c2, 0x00204411, 0x000 }, ++ { 0x00000036, 0x00204a2d, 0x000 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x000001ff, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x628 }, ++ { 0x00000000, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x60b }, ++ { 0x0004a003, 0x00604411, 0x68a }, ++ { 0x0000a003, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x610 }, ++ { 0x0004a010, 0x00604411, 0x68a }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x628 }, ++ { 0x0004a011, 0x00604411, 0x68a }, ++ { 0x0000a011, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a012, 0x00604411, 0x68a }, ++ { 0x0000a012, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a013, 0x00604411, 0x68a }, ++ { 0x0000a013, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a014, 0x00604411, 0x68a }, ++ { 0x0000a014, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a015, 0x00604411, 0x68a }, ++ { 0x0000a015, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a016, 0x00604411, 0x68a }, ++ { 0x0000a016, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a017, 0x00604411, 0x68a }, ++ { 0x0000a017, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x0000002c, 0x0080062d, 0x000 }, ++ { 0xff000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000002, 0x00804811, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x63a }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000002, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x638 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x68a }, ++ { 0x00001000, 0x00200811, 0x000 }, ++ { 0x0000002b, 0x00203622, 0x000 }, ++ { 0x00000000, 0x00600000, 0x63e }, ++ { 0x00000000, 0x00600000, 0x5c6 }, ++ { 0x98000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x63e }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000022, 0x00204811, 0x000 }, ++ { 0x89000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00404811, 0x62a }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404811, 0x62a }, ++ { 0x00000000, 0x00600000, 0x659 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0xc0204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x09800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68a }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000004, 0x00404c11, 0x653 }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000004, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffffb, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffff7, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36e }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x01800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x68a }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x689 }, ++ { 0x00000010, 0x00404c11, 0x66f }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x38c00000, 0x000 }, ++ { 0x0000001d, 0x00200a2d, 0x000 }, ++ { 0x0000001e, 0x00200e2d, 0x000 }, ++ { 0x0000001f, 0x0020122d, 0x000 }, ++ { 0x00000020, 0x0020162d, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000004, 0x00301224, 0x000 }, ++ { 0x00000000, 0x002f0064, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x688 }, ++ { 0x00000003, 0x00281a22, 0x000 }, ++ { 0x00000008, 0x00221222, 0x000 }, ++ { 0xfffff000, 0x00281224, 0x000 }, ++ { 0x00000000, 0x002910c4, 0x000 }, ++ { 0x0000001f, 0x00403624, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x68a }, ++ { 0x9f000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x68d }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x68f }, ++ { 0x9e000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x692 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0xc0204411, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000024, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000022, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00404811, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x014204ff, 0x05bd0250, 0x000 }, ++ { 0x01c30168, 0x043f05bd, 0x000 }, ++ { 0x02250209, 0x02500151, 0x000 }, ++ { 0x02230245, 0x02a00241, 0x000 }, ++ { 0x03d705bd, 0x05bd05bd, 0x000 }, ++ { 0x06460647, 0x031f05bd, 0x000 }, ++ { 0x05bd05c2, 0x03200340, 0x000 }, ++ { 0x032a0282, 0x03420334, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd054e, 0x05bd05bd, 0x000 }, ++ { 0x03ba05bd, 0x04b80344, 0x000 }, ++ { 0x0497044d, 0x043d05bd, 0x000 }, ++ { 0x04cd05bd, 0x044104da, 0x000 }, ++ { 0x044d0504, 0x03510375, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd05bd, 0x063c05c4, 0x000 }, ++ { 0x05bd05bd, 0x000705bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x03f803ed, 0x04080406, 0x000 }, ++ { 0x040e040a, 0x040c0410, 0x000 }, ++ { 0x041c0418, 0x04240420, 0x000 }, ++ { 0x042c0428, 0x04340430, 0x000 }, ++ { 0x05bd05bd, 0x043805bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x05bd05bd, 0x05bd05bd, 0x000 }, ++ { 0x00020676, 0x06940006, 0x000 }, ++}; ++ ++static const u32 RV635_pfp_microcode[] = { ++0xca0400, ++0xa00000, ++0x7e828b, ++0x7c038b, ++0x8001b8, ++0x7c038b, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xc41838, ++0xca2400, ++0xca2800, ++0x9581a8, ++0xc41c3a, ++0xc3c000, ++0xca0800, ++0xca0c00, ++0x7c744b, ++0xc20005, ++0x99c000, ++0xc41c3a, ++0x7c744c, ++0xc0fff0, ++0x042c04, ++0x309002, ++0x7d2500, ++0x351402, ++0x7d350b, ++0x255403, ++0x7cd580, ++0x259c03, ++0x95c004, ++0xd5001b, ++0x7eddc1, ++0x7d9d80, ++0xd6801b, ++0xd5801b, ++0xd4401e, ++0xd5401e, ++0xd6401e, ++0xd6801e, ++0xd4801e, ++0xd4c01e, ++0x9783d3, ++0xd5c01e, ++0xca0800, ++0x80001a, ++0xca0c00, ++0xe4011e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xe4013e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca1800, ++0xd4401e, ++0xd5801e, ++0x800053, ++0xd40075, ++0xd4401e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd48019, ++0xd4c018, ++0xd50017, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xe2001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0xd48060, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xd48061, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xca0c00, ++0xd4401e, ++0xd48016, ++0xd4c016, ++0xd4801e, ++0x8001b8, ++0xd4c01e, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x948004, ++0xca1400, ++0xe420f3, ++0xd42013, ++0xd56065, ++0xd4e01c, ++0xd5201c, ++0xd5601c, ++0x800000, ++0x062001, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9483f7, ++0xca1400, ++0xe420f3, ++0x800079, ++0xd42013, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9883ef, ++0xca1400, ++0xd40064, ++0x80008d, ++0x000000, ++0xc41432, ++0xc61843, ++0xc4082f, ++0x954005, ++0xc40c30, ++0xd4401e, ++0x800000, ++0xee001e, ++0x9583f5, ++0xc41031, ++0xd44033, ++0xd52065, ++0xd4a01c, ++0xd4e01c, ++0xd5201c, ++0xe4015e, ++0xd4001e, ++0x800000, ++0x062001, ++0xca1800, ++0x0a2001, ++0xd60076, ++0xc40836, ++0x988007, ++0xc61045, ++0x950110, ++0xd4001f, ++0xd46062, ++0x800000, ++0xd42062, ++0xcc3835, ++0xcc1433, ++0x8401bb, ++0xd40072, ++0xd5401e, ++0x800000, ++0xee001e, ++0xe2001a, ++0x8401bb, ++0xe2001a, ++0xcc104b, ++0xcc0447, ++0x2c9401, ++0x7d098b, ++0x984005, ++0x7d15cb, ++0xd4001a, ++0x8001b8, ++0xd4006d, ++0x344401, ++0xcc0c48, ++0x98403a, ++0xcc2c4a, ++0x958004, ++0xcc0449, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0x282801, ++0x8400f0, ++0xcc1003, ++0x98801b, ++0x04380c, ++0x8400f0, ++0xcc1003, ++0x988017, ++0x043808, ++0x8400f0, ++0xcc1003, ++0x988013, ++0x043804, ++0x8400f0, ++0xcc1003, ++0x988014, ++0xcc104c, ++0x9a8009, ++0xcc144d, ++0x9840dc, ++0xd4006d, ++0xcc1848, ++0xd5001a, ++0xd5401a, ++0x8000c9, ++0xd5801a, ++0x96c0d5, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0x9ac003, ++0xd4006d, ++0xd4006e, ++0x800000, ++0xec007f, ++0x9ac0cc, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0x7d9103, ++0x7dd583, ++0x7d190c, ++0x35cc1f, ++0x35701f, ++0x7cf0cb, ++0x7cd08b, ++0x880000, ++0x7e8e8b, ++0x95c004, ++0xd4006e, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0xcc0803, ++0xcc0c03, ++0xcc1003, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0xcc2403, ++0xcc2803, ++0x35c41f, ++0x36b01f, ++0x7c704b, ++0x34f01f, ++0x7c704b, ++0x35701f, ++0x7c704b, ++0x7d8881, ++0x7dccc1, ++0x7e5101, ++0x7e9541, ++0x7c9082, ++0x7cd4c2, ++0x7c848b, ++0x9ac003, ++0x7c8c8b, ++0x2c8801, ++0x98809e, ++0xd4006d, ++0x98409c, ++0xd4006e, ++0xcc084c, ++0xcc0c4d, ++0xcc1048, ++0xd4801a, ++0xd4c01a, ++0x800101, ++0xd5001a, ++0xcc0832, ++0xd40032, ++0x9482d9, ++0xca0c00, ++0xd4401e, ++0x800000, ++0xd4001e, ++0xe4011e, ++0xd4001e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd4401e, ++0xca1400, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xd5401e, ++0xd54034, ++0x800000, ++0xee001e, ++0x280404, ++0xe2001a, ++0xe2001a, ++0xd4401a, ++0xca3800, ++0xcc0803, ++0xcc0c03, ++0xcc0c03, ++0xcc0c03, ++0x9882bd, ++0x000000, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0400, ++0xc2ff00, ++0xcc0834, ++0xc13fff, ++0x7c74cb, ++0x7cc90b, ++0x7d010f, ++0x9902b0, ++0x7c738b, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0800, ++0x281900, ++0x7d898b, ++0x958014, ++0x281404, ++0xca0c00, ++0xca1000, ++0xca1c00, ++0xca2400, ++0xe2001f, ++0xd4c01a, ++0xd5001a, ++0xd5401a, ++0xcc1803, ++0xcc2c03, ++0xcc2c03, ++0xcc2c03, ++0x7da58b, ++0x7d9c47, ++0x984297, ++0x000000, ++0x800161, ++0xd4c01a, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0x248c06, ++0x0ccc06, ++0x98c006, ++0xcc104e, ++0x990004, ++0xd40073, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xca0800, ++0xca0c00, ++0x34d018, ++0x251001, ++0x950021, ++0xc17fff, ++0xca1000, ++0xca1400, ++0xca1800, ++0xd4801d, ++0xd4c01d, ++0x7db18b, ++0xc14202, ++0xc2c001, ++0xd5801d, ++0x34dc0e, ++0x7d5d4c, ++0x7f734c, ++0xd7401e, ++0xd5001e, ++0xd5401e, ++0xc14200, ++0xc2c000, ++0x099c01, ++0x31dc10, ++0x7f5f4c, ++0x7f734c, ++0x042802, ++0x7d8380, ++0xd5a86f, ++0xd58066, ++0xd7401e, ++0xec005e, ++0xc82402, ++0xc82402, ++0x8001b8, ++0xd60076, ++0xd4401e, ++0xd4801e, ++0xd4c01e, ++0x800000, ++0xee001e, ++0x800000, ++0xee001f, ++0xd4001f, ++0x800000, ++0xd4001f, ++0xd4001f, ++0x880000, ++0xd4001f, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x010171, ++0x020178, ++0x03008f, ++0x04007f, ++0x050003, ++0x06003f, ++0x070032, ++0x08012c, ++0x090046, ++0x0a0036, ++0x1001b6, ++0x1700a2, ++0x22013a, ++0x230149, ++0x2000b4, ++0x240125, ++0x27004d, ++0x28006a, ++0x2a0060, ++0x2b0052, ++0x2f0065, ++0x320087, ++0x34017f, ++0x3c0156, ++0x3f0072, ++0x41018c, ++0x44012e, ++0x550173, ++0x56017a, ++0x60000b, ++0x610034, ++0x620038, ++0x630038, ++0x640038, ++0x650038, ++0x660038, ++0x670038, ++0x68003a, ++0x690041, ++0x6a0048, ++0x6b0048, ++0x6c0048, ++0x6d0048, ++0x6e0048, ++0x6f0048, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++}; ++ ++static const u32 RV670_cp_microcode[][3] = { ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0000ffff, 0x00284621, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x000 }, ++ { 0x00010000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x67c }, ++ { 0x00000000, 0x00600000, 0x624 }, ++ { 0x00000000, 0x00600000, 0x638 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000f00, 0x00281622, 0x000 }, ++ { 0x00000008, 0x00211625, 0x000 }, ++ { 0x00000018, 0x00203625, 0x000 }, ++ { 0x8d000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x002f0225, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x018 }, ++ { 0x00412000, 0x00404811, 0x019 }, ++ { 0x00422000, 0x00204811, 0x000 }, ++ { 0x8e000000, 0x00204411, 0x000 }, ++ { 0x00000028, 0x00204a2d, 0x000 }, ++ { 0x90000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x0000000c, 0x00211622, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000019, 0x00211a22, 0x000 }, ++ { 0x00000004, 0x00281a26, 0x000 }, ++ { 0x00000000, 0x002914c5, 0x000 }, ++ { 0x00000019, 0x00203625, 0x000 }, ++ { 0x00000000, 0x003a1402, 0x000 }, ++ { 0x00000016, 0x00211625, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0xfffffffc, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002914a3, 0x000 }, ++ { 0x00000017, 0x00203625, 0x000 }, ++ { 0x00008000, 0x00280e22, 0x000 }, ++ { 0x00000007, 0x00220e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x20000000, 0x00280e22, 0x000 }, ++ { 0x00000006, 0x00210e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x00000000, 0x00220222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x038 }, ++ { 0x00000000, 0x2ee00000, 0x035 }, ++ { 0x00000000, 0x2ce00000, 0x037 }, ++ { 0x00000000, 0x00400e2d, 0x039 }, ++ { 0x00000008, 0x00200e2d, 0x000 }, ++ { 0x00000009, 0x0040122d, 0x046 }, ++ { 0x00000001, 0x00400e2d, 0x039 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x03e }, ++ { 0x00000008, 0x00401c11, 0x041 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x0000000f, 0x00281e27, 0x000 }, ++ { 0x00000003, 0x00221e27, 0x000 }, ++ { 0x7fc00000, 0x00281a23, 0x000 }, ++ { 0x00000014, 0x00211a26, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000008, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x00290cc7, 0x000 }, ++ { 0x00000027, 0x00203624, 0x000 }, ++ { 0x00007f00, 0x00281221, 0x000 }, ++ { 0x00001400, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x04b }, ++ { 0x00000001, 0x00290e23, 0x000 }, ++ { 0x0000000e, 0x00203623, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfff80000, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x003a2c02, 0x000 }, ++ { 0x00000002, 0x00220e2b, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x0000000f, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00204a2d, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000029, 0x00200e2d, 0x000 }, ++ { 0x060a0200, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x061 }, ++ { 0x00000000, 0x2ee00000, 0x05f }, ++ { 0x00000000, 0x2ce00000, 0x05e }, ++ { 0x00000000, 0x00400e2d, 0x062 }, ++ { 0x00000001, 0x00400e2d, 0x062 }, ++ { 0x0000000a, 0x00200e2d, 0x000 }, ++ { 0x0000000b, 0x0040122d, 0x06a }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x7fc00000, 0x00281623, 0x000 }, ++ { 0x00000014, 0x00211625, 0x000 }, ++ { 0x00000001, 0x00331625, 0x000 }, ++ { 0x80000000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00290ca3, 0x000 }, ++ { 0x3ffffc00, 0x00290e23, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x06d }, ++ { 0x00000100, 0x00401c11, 0x070 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x000000f0, 0x00281e27, 0x000 }, ++ { 0x00000004, 0x00221e27, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0xfffff0ff, 0x00281a30, 0x000 }, ++ { 0x0000a028, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948e6, 0x000 }, ++ { 0x0000a018, 0x00204411, 0x000 }, ++ { 0x3fffffff, 0x00284a23, 0x000 }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000030, 0x0020162d, 0x000 }, ++ { 0x00000002, 0x00291625, 0x000 }, ++ { 0x00000030, 0x00203625, 0x000 }, ++ { 0x00000025, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a3, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x083 }, ++ { 0x00000026, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a4, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x084 }, ++ { 0x00000000, 0x00400000, 0x08a }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203624, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x08a }, ++ { 0x00000000, 0x00600000, 0x659 }, ++ { 0x00000000, 0x00600000, 0x64d }, ++ { 0x00000002, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x08d }, ++ { 0x00000012, 0xc0403620, 0x093 }, ++ { 0x00000000, 0x2ee00000, 0x091 }, ++ { 0x00000000, 0x2ce00000, 0x090 }, ++ { 0x00000002, 0x00400e2d, 0x092 }, ++ { 0x00000003, 0x00400e2d, 0x092 }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000012, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x098 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x0a0 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x2ee00000, 0x09e }, ++ { 0x00000000, 0x2ce00000, 0x09d }, ++ { 0x00000002, 0x00400e2d, 0x09f }, ++ { 0x00000003, 0x00400e2d, 0x09f }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x003f0000, 0x00280e23, 0x000 }, ++ { 0x00000010, 0x00210e23, 0x000 }, ++ { 0x00000011, 0x00203623, 0x000 }, ++ { 0x0000001e, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0a7 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x0000001f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0aa }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000008, 0x00210e2b, 0x000 }, ++ { 0x0000007f, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0e1 }, ++ { 0x00000000, 0x27000000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x0b3 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000000c, 0x00221e30, 0x000 }, ++ { 0x99800000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x0020122d, 0x000 }, ++ { 0x00000008, 0x00221224, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00291ce4, 0x000 }, ++ { 0x00000000, 0x00604807, 0x12f }, ++ { 0x9b000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x9c000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x0033146f, 0x000 }, ++ { 0x00000001, 0x00333e23, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0x00203c05, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e007, 0x00204411, 0x000 }, ++ { 0x0000000f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0cb }, ++ { 0x00f8ff08, 0x00204811, 0x000 }, ++ { 0x98000000, 0x00404811, 0x0dc }, ++ { 0x000000f0, 0x00280e22, 0x000 }, ++ { 0x000000a0, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x0da }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d5 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d4 }, ++ { 0x00003f00, 0x00400c11, 0x0d6 }, ++ { 0x00001f00, 0x00400c11, 0x0d6 }, ++ { 0x00000f00, 0x00200c11, 0x000 }, ++ { 0x00380009, 0x00294a23, 0x000 }, ++ { 0x3f000000, 0x00280e2b, 0x000 }, ++ { 0x00000002, 0x00220e23, 0x000 }, ++ { 0x00000007, 0x00494a23, 0x0dc }, ++ { 0x00380f09, 0x00204811, 0x000 }, ++ { 0x68000007, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000a202, 0x00204411, 0x000 }, ++ { 0x00ff0000, 0x00280e22, 0x000 }, ++ { 0x00000080, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00200e2d, 0x000 }, ++ { 0x00000026, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x002f0083, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0ea }, ++ { 0x00000000, 0x00600000, 0x653 }, ++ { 0x00000000, 0x00400000, 0x0eb }, ++ { 0x00000000, 0x00600000, 0x656 }, ++ { 0x00000007, 0x0020222d, 0x000 }, ++ { 0x00000005, 0x00220e22, 0x000 }, ++ { 0x00100000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x000000ef, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000003, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x0f8 }, ++ { 0x0000000b, 0x00210228, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0f8 }, ++ { 0x00000400, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000001c, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0fd }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000001e, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x10b }, ++ { 0x0000a30f, 0x00204411, 0x000 }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x104 }, ++ { 0xffffffff, 0x00404811, 0x10b }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x107 }, ++ { 0x0000ffff, 0x00404811, 0x10b }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x10a }, ++ { 0x000000ff, 0x00404811, 0x10b }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0002c400, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x112 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000018, 0x40224a20, 0x000 }, ++ { 0x00000010, 0xc0424a20, 0x114 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000000a, 0x00201011, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x11b }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00531224, 0x117 }, ++ { 0xffbfffff, 0x00283a2e, 0x000 }, ++ { 0x0000001b, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x12e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0x00000018, 0x00220e30, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e00e, 0x00204411, 0x000 }, ++ { 0x07f8ff08, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00294a23, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00800000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204806, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x67c }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x67b }, ++ { 0x00000004, 0x00404c11, 0x135 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000001c, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x67c }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x13c }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40280620, 0x000 }, ++ { 0x00000010, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x00341461, 0x000 }, ++ { 0x00000000, 0x00741882, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x147 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0681a20, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x158 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00300a2f, 0x000 }, ++ { 0x00000001, 0x00210a22, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600000, 0x18f }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00202c08, 0x000 }, ++ { 0x00000000, 0x00202411, 0x000 }, ++ { 0x00000000, 0x00202811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00221e29, 0x000 }, ++ { 0x00000000, 0x007048eb, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000001, 0x40330620, 0x000 }, ++ { 0x00000000, 0xc0302409, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x181 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x186 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x186 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000001, 0x00530621, 0x182 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x197 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000011, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x0078042a, 0x2fb }, ++ { 0x00000000, 0x00202809, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x174 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x194 }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x46000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x19b }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00804811, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40281620, 0x000 }, ++ { 0x00000010, 0xc0811a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00221e30, 0x000 }, ++ { 0x00000029, 0x00201a2d, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfffbff09, 0x00204811, 0x000 }, ++ { 0x0000000f, 0x0020222d, 0x000 }, ++ { 0x00001fff, 0x00294a28, 0x000 }, ++ { 0x00000006, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000100, 0x00201811, 0x000 }, ++ { 0x00000008, 0x00621e28, 0x12f }, ++ { 0x00000008, 0x00822228, 0x000 }, ++ { 0x0002c000, 0x00204411, 0x000 }, ++ { 0x00000015, 0x00600e2d, 0x1bd }, ++ { 0x00000016, 0x00600e2d, 0x1bd }, ++ { 0x0000c008, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x1b9 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x39000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00804802, 0x000 }, ++ { 0x00000018, 0x00202e2d, 0x000 }, ++ { 0x00000000, 0x003b0d63, 0x000 }, ++ { 0x00000008, 0x00224a23, 0x000 }, ++ { 0x00000010, 0x00224a23, 0x000 }, ++ { 0x00000018, 0x00224a23, 0x000 }, ++ { 0x00000000, 0x00804803, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000007, 0x0021062f, 0x000 }, ++ { 0x00000013, 0x00200a2d, 0x000 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000ffff, 0x40282220, 0x000 }, ++ { 0x0000000f, 0x00262228, 0x000 }, ++ { 0x00000010, 0x40212620, 0x000 }, ++ { 0x0000000f, 0x00262629, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1e0 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000081, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000080, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1dc }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1d8 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000001f, 0x00280a22, 0x000 }, ++ { 0x0000001f, 0x00282a2a, 0x000 }, ++ { 0x00000001, 0x00530621, 0x1d1 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00304a2f, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00301e2f, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1e5 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x0000000f, 0x00260e23, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000000f, 0x00261224, 0x000 }, ++ { 0x00000000, 0x00201411, 0x000 }, ++ { 0x00000000, 0x00601811, 0x2bb }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022b, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1f8 }, ++ { 0x00000010, 0x00221628, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a29, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x0020480a, 0x000 }, ++ { 0x00000000, 0x00202c11, 0x000 }, ++ { 0x00000010, 0x00221623, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a24, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x00731503, 0x205 }, ++ { 0x00000000, 0x00201805, 0x000 }, ++ { 0x00000000, 0x00731524, 0x205 }, ++ { 0x00000000, 0x002d14c5, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00000000, 0x00202003, 0x000 }, ++ { 0x00000000, 0x00802404, 0x000 }, ++ { 0x0000000f, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x67b }, ++ { 0x00000000, 0x002b1405, 0x000 }, ++ { 0x00000001, 0x00901625, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00294a22, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a21, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0x40281220, 0x000 }, ++ { 0x00000010, 0xc0211a20, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211620, 0x000 }, ++ { 0x00000000, 0x00741465, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00000001, 0x00330621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x219 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x212 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x638 }, ++ { 0x00000000, 0x0040040f, 0x213 }, ++ { 0x00000000, 0x00600000, 0x624 }, ++ { 0x00000000, 0x00600000, 0x638 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00000000, 0x00600000, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x232 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x236 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x236 }, ++ { 0x00000000, 0xc0404800, 0x233 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00600411, 0x2fb }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x624 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000018, 0x40210a20, 0x000 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x24c }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x00080101, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x251 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000010, 0x00600411, 0x315 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x27c }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000001, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x26a }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x0000ffff, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00341c27, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x25f }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e5, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x262 }, ++ { 0x00000000, 0x00201407, 0x000 }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x00341c47, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x267 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x26a }, ++ { 0x00000000, 0x00201807, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2c1 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00342023, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x272 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x271 }, ++ { 0x00000016, 0x00404811, 0x276 }, ++ { 0x00000018, 0x00404811, 0x276 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x275 }, ++ { 0x00000017, 0x00404811, 0x276 }, ++ { 0x00000019, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00604411, 0x2e9 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x256 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000010, 0x40210620, 0x000 }, ++ { 0x0000ffff, 0xc0280a20, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0881a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x67c }, ++ { 0x00000000, 0x00600000, 0x624 }, ++ { 0x00000000, 0xc0600000, 0x2a3 }, ++ { 0x00000005, 0x00200a2d, 0x000 }, ++ { 0x00000008, 0x00220a22, 0x000 }, ++ { 0x0000002b, 0x00201a2d, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00007000, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00311ce6, 0x000 }, ++ { 0x0000002a, 0x00201a2d, 0x000 }, ++ { 0x0000000c, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x292 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00691ce2, 0x12f }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x29d }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000001c, 0x00403627, 0x000 }, ++ { 0x0000000c, 0xc0220a20, 0x000 }, ++ { 0x00000029, 0x00203622, 0x000 }, ++ { 0x00000028, 0xc0403620, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000009, 0x00204811, 0x000 }, ++ { 0xa1000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce3, 0x000 }, ++ { 0x00000021, 0x00203627, 0x000 }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce4, 0x000 }, ++ { 0x00000022, 0x00203627, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a3, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203624, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000000, 0x00311cc4, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x2dc }, ++ { 0x00000000, 0x00400000, 0x2d9 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2d9 }, ++ { 0x00000003, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2dc }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e1, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a1, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e2, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000000, 0x00600000, 0x659 }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00600000, 0x650 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2a7 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x0000001a, 0x00201e2d, 0x000 }, ++ { 0x0000001b, 0x0080222d, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca1, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x003808c5, 0x000 }, ++ { 0x00000000, 0x00300841, 0x000 }, ++ { 0x00000001, 0x00220a22, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000017, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x318 }, ++ { 0xffffffef, 0x00280621, 0x000 }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x0000f8e0, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00294901, 0x000 }, ++ { 0x00000000, 0x00894901, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x97000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00002257, 0x00204411, 0x000 }, ++ { 0x00000003, 0xc0484a20, 0x000 }, ++ { 0x0000225d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x638 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x00000001, 0x40304a20, 0x000 }, ++ { 0x00000002, 0xc0304a20, 0x000 }, ++ { 0x00000001, 0x00530a22, 0x34b }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x67c }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x354 }, ++ { 0x00000014, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x362 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00604802, 0x36a }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x366 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35d }, ++ { 0x00000028, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5b3 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x35d }, ++ { 0x0000002c, 0x00203626, 0x000 }, ++ { 0x00000049, 0x00201811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000000, 0x002f0226, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x36c }, ++ { 0x0000002c, 0x00801a2d, 0x000 }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x00000015, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x382 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3ad }, ++ { 0x00000016, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3af }, ++ { 0x00000020, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x398 }, ++ { 0x0000000f, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a4 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a4 }, ++ { 0x0000001e, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x38c }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x08000000, 0x00290a22, 0x000 }, ++ { 0x00000003, 0x40210e20, 0x000 }, ++ { 0x0000000c, 0xc0211220, 0x000 }, ++ { 0x00080000, 0x00281224, 0x000 }, ++ { 0x00000014, 0xc0221620, 0x000 }, ++ { 0x00000000, 0x002914a4, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948a2, 0x000 }, ++ { 0x0000a1fe, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x67c }, ++ { 0x00000015, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x38e }, ++ { 0x0000210e, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x67c }, ++ { 0x00000003, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x39a }, ++ { 0x00002108, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x80000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000010, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3aa }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00404811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36a }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x0000001d, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3c4 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x67c }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3b8 }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0xbabecafe, 0x00204811, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00404811, 0x000 }, ++ { 0x00002170, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000a, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3c9 }, ++ { 0x8c000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00003fff, 0x40280a20, 0x000 }, ++ { 0x80000000, 0x40280e20, 0x000 }, ++ { 0x40000000, 0xc0281220, 0x000 }, ++ { 0x00040000, 0x00694622, 0x67c }, ++ { 0x00000000, 0x00201410, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3d7 }, ++ { 0x00000000, 0xc0401800, 0x3da }, ++ { 0x00003fff, 0xc0281a20, 0x000 }, ++ { 0x00040000, 0x00694626, 0x67c }, ++ { 0x00000000, 0x00201810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3dd }, ++ { 0x00000000, 0xc0401c00, 0x3e0 }, ++ { 0x00003fff, 0xc0281e20, 0x000 }, ++ { 0x00040000, 0x00694627, 0x67c }, ++ { 0x00000000, 0x00201c10, 0x000 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0x002820c5, 0x000 }, ++ { 0x00000000, 0x004948e8, 0x000 }, ++ { 0xa5800000, 0x00200811, 0x000 }, ++ { 0x00002000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x408 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x0000001f, 0xc0210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3ed }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0xc0481220, 0x3f5 }, ++ { 0xa7800000, 0x00200811, 0x000 }, ++ { 0x0000a000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x408 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00304883, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x83000000, 0x00604411, 0x408 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xa9800000, 0x00200811, 0x000 }, ++ { 0x0000c000, 0x00400c11, 0x3f0 }, ++ { 0xab800000, 0x00200811, 0x000 }, ++ { 0x0000f8e0, 0x00400c11, 0x3f0 }, ++ { 0xad800000, 0x00200811, 0x000 }, ++ { 0x0000f880, 0x00400c11, 0x3f0 }, ++ { 0xb3800000, 0x00200811, 0x000 }, ++ { 0x0000f3fc, 0x00400c11, 0x3f0 }, ++ { 0xaf800000, 0x00200811, 0x000 }, ++ { 0x0000e000, 0x00400c11, 0x3f0 }, ++ { 0xb1800000, 0x00200811, 0x000 }, ++ { 0x0000f000, 0x00400c11, 0x3f0 }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00002148, 0x00204811, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x01182000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0218a000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0318c000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0418f8e0, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0518f880, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0618e000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0718f000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0818f3fc, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000030, 0x00200a2d, 0x000 }, ++ { 0x00000000, 0xc0290c40, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x86000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x85000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x67c }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00404c02, 0x43e }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x00000000, 0xc0201400, 0x000 }, ++ { 0x00000000, 0xc0201800, 0x000 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x44c }, ++ { 0x00000000, 0xc0202000, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x00000010, 0x00280a23, 0x000 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x454 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0x00694624, 0x67c }, ++ { 0x00000000, 0x00400000, 0x459 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00604805, 0x681 }, ++ { 0x00000000, 0x002824f0, 0x000 }, ++ { 0x00000007, 0x00280a23, 0x000 }, ++ { 0x00000001, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x460 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x04e00000, 0x479 }, ++ { 0x00000000, 0x00400000, 0x486 }, ++ { 0x00000002, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x465 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x02e00000, 0x479 }, ++ { 0x00000000, 0x00400000, 0x486 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46a }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x479 }, ++ { 0x00000000, 0x00400000, 0x486 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x46f }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x479 }, ++ { 0x00000000, 0x00400000, 0x486 }, ++ { 0x00000005, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x474 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x479 }, ++ { 0x00000000, 0x00400000, 0x486 }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x479 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x08e00000, 0x479 }, ++ { 0x00000000, 0x00400000, 0x486 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x000 }, ++ { 0x00000008, 0x00210a23, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x483 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x48c }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x00404c08, 0x44c }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000011, 0x40211220, 0x000 }, ++ { 0x00000012, 0x40211620, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x496 }, ++ { 0x00040000, 0xc0494a20, 0x497 }, ++ { 0xfffbffff, 0xc0284a20, 0x000 }, ++ { 0x00000000, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4a3 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000c, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x49f }, ++ { 0xa0000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00204811, 0x000 }, ++ { 0x0000216b, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000216c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x49d }, ++ { 0x00000000, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4b6 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x681 }, ++ { 0x00000000, 0x00400000, 0x4ba }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x67c }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4c1 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0404810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x67c }, ++ { 0x00000000, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4c3 }, ++ { 0x00002180, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000003, 0x00333e2f, 0x000 }, ++ { 0x00000001, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4f3 }, ++ { 0x0000002c, 0x00200a2d, 0x000 }, ++ { 0x00040000, 0x18e00c11, 0x4e2 }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xd8c04800, 0x4d6 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000002d, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x00290c83, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000011, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x49d }, ++ { 0x0000002c, 0xc0203620, 0x000 }, ++ { 0x0000002d, 0xc0403620, 0x000 }, ++ { 0x0000000f, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4f8 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0xd9000000, 0x000 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xb5000000, 0x00204411, 0x000 }, ++ { 0x00002000, 0x00204811, 0x000 }, ++ { 0xb6000000, 0x00204411, 0x000 }, ++ { 0x0000a000, 0x00204811, 0x000 }, ++ { 0xb7000000, 0x00204411, 0x000 }, ++ { 0x0000c000, 0x00204811, 0x000 }, ++ { 0xb8000000, 0x00204411, 0x000 }, ++ { 0x0000f8e0, 0x00204811, 0x000 }, ++ { 0xb9000000, 0x00204411, 0x000 }, ++ { 0x0000f880, 0x00204811, 0x000 }, ++ { 0xba000000, 0x00204411, 0x000 }, ++ { 0x0000e000, 0x00204811, 0x000 }, ++ { 0xbb000000, 0x00204411, 0x000 }, ++ { 0x0000f000, 0x00204811, 0x000 }, ++ { 0xbc000000, 0x00204411, 0x000 }, ++ { 0x0000f3fc, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00204811, 0x000 }, ++ { 0x000000ff, 0x00280e30, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x50c }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x521 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000001c, 0x00203623, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000029, 0x00203623, 0x000 }, ++ { 0x00000028, 0x00203623, 0x000 }, ++ { 0x00000017, 0x00203623, 0x000 }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203623, 0x000 }, ++ { 0x00000015, 0x00203623, 0x000 }, ++ { 0x00000016, 0x00203623, 0x000 }, ++ { 0xffffe000, 0x00200c11, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00200c11, 0x000 }, ++ { 0x00000023, 0x00203623, 0x000 }, ++ { 0x00000024, 0x00203623, 0x000 }, ++ { 0xf1ffffff, 0x00283a2e, 0x000 }, ++ { 0x0000001a, 0xc0220e20, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000002a, 0x40203620, 0x000 }, ++ { 0x87000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x9d000000, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x40214a20, 0x000 }, ++ { 0x96000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x0000001f, 0x00211624, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x0000001d, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00281e23, 0x000 }, ++ { 0x00000008, 0x00222223, 0x000 }, ++ { 0xfffff000, 0x00282228, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x0000001f, 0x00203628, 0x000 }, ++ { 0x00000018, 0x00211e23, 0x000 }, ++ { 0x00000020, 0x00203627, 0x000 }, ++ { 0x00000002, 0x00221624, 0x000 }, ++ { 0x00000000, 0x003014a8, 0x000 }, ++ { 0x0000001e, 0x00203625, 0x000 }, ++ { 0x00000003, 0x00211a24, 0x000 }, ++ { 0x10000000, 0x00281a26, 0x000 }, ++ { 0xefffffff, 0x00283a2e, 0x000 }, ++ { 0x00000000, 0x004938ce, 0x66a }, ++ { 0x00000001, 0x40280a20, 0x000 }, ++ { 0x00000006, 0x40280e20, 0x000 }, ++ { 0x00000300, 0xc0281220, 0x000 }, ++ { 0x00000008, 0x00211224, 0x000 }, ++ { 0x00000000, 0xc0201620, 0x000 }, ++ { 0x00000000, 0xc0201a20, 0x000 }, ++ { 0x00000000, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x559 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x67c }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00020000, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x561 }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x56f }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x561 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x67c }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x56f }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x565 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x56f }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x56d }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x681 }, ++ { 0x00000000, 0x00401c10, 0x56f }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x571 }, ++ { 0x00000000, 0x00600000, 0x5bc }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x582 }, ++ { 0x0000a2b7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x67c }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x67c }, ++ { 0x0000a2c4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x580 }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000001, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x593 }, ++ { 0x0000a2bb, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x67c }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x67c }, ++ { 0x0000a2c5, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x591 }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000002, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5a4 }, ++ { 0x0000a2bf, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x67c }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x67c }, ++ { 0x0000a2c6, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5a2 }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x0000a2c3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x67c }, ++ { 0x0000001a, 0x00212230, 0x000 }, ++ { 0x00000006, 0x00222630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x67c }, ++ { 0x0000a2c7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5b1 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x85000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x0000304a, 0x00204411, 0x000 }, ++ { 0x01000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00400000, 0x5b7 }, ++ { 0xa4000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x5bc }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000002c, 0x00203621, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5c3 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000030, 0x00403621, 0x5d6 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x5d6 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004a092, 0x00604411, 0x67c }, ++ { 0x00000031, 0x00203630, 0x000 }, ++ { 0x0004a093, 0x00604411, 0x67c }, ++ { 0x00000032, 0x00203630, 0x000 }, ++ { 0x0004a2b6, 0x00604411, 0x67c }, ++ { 0x00000033, 0x00203630, 0x000 }, ++ { 0x0004a2ba, 0x00604411, 0x67c }, ++ { 0x00000034, 0x00203630, 0x000 }, ++ { 0x0004a2be, 0x00604411, 0x67c }, ++ { 0x00000035, 0x00203630, 0x000 }, ++ { 0x0004a2c2, 0x00604411, 0x67c }, ++ { 0x00000036, 0x00203630, 0x000 }, ++ { 0x00042004, 0x00604411, 0x67c }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x88000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000001, 0x002f0230, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x61f }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x61f }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00007e00, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x5f8 }, ++ { 0x0000a092, 0x00204411, 0x000 }, ++ { 0x00000031, 0x00204a2d, 0x000 }, ++ { 0x0000a093, 0x00204411, 0x000 }, ++ { 0x00000032, 0x00204a2d, 0x000 }, ++ { 0x0000a2b6, 0x00204411, 0x000 }, ++ { 0x00000033, 0x00204a2d, 0x000 }, ++ { 0x0000a2ba, 0x00204411, 0x000 }, ++ { 0x00000034, 0x00204a2d, 0x000 }, ++ { 0x0000a2be, 0x00204411, 0x000 }, ++ { 0x00000035, 0x00204a2d, 0x000 }, ++ { 0x0000a2c2, 0x00204411, 0x000 }, ++ { 0x00000036, 0x00204a2d, 0x000 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x000001ff, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x61e }, ++ { 0x00000000, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x601 }, ++ { 0x0004a003, 0x00604411, 0x67c }, ++ { 0x0000a003, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x606 }, ++ { 0x0004a010, 0x00604411, 0x67c }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00000001, 0x00210621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x61e }, ++ { 0x0004a011, 0x00604411, 0x67c }, ++ { 0x0000a011, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a012, 0x00604411, 0x67c }, ++ { 0x0000a012, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a013, 0x00604411, 0x67c }, ++ { 0x0000a013, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a014, 0x00604411, 0x67c }, ++ { 0x0000a014, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a015, 0x00604411, 0x67c }, ++ { 0x0000a015, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a016, 0x00604411, 0x67c }, ++ { 0x0000a016, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x0004a017, 0x00604411, 0x67c }, ++ { 0x0000a017, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x00042004, 0x00604411, 0x67c }, ++ { 0x0000002c, 0x0080062d, 0x000 }, ++ { 0xff000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000002, 0x00804811, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x630 }, ++ { 0x00000030, 0x0020062d, 0x000 }, ++ { 0x00000002, 0x00280621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x62e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x67c }, ++ { 0x00001000, 0x00200811, 0x000 }, ++ { 0x0000002b, 0x00203622, 0x000 }, ++ { 0x00000000, 0x00600000, 0x634 }, ++ { 0x00000000, 0x00600000, 0x5bc }, ++ { 0x98000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x634 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000022, 0x00204811, 0x000 }, ++ { 0x89000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00404811, 0x620 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404811, 0x620 }, ++ { 0x00000000, 0x00600000, 0x64d }, ++ { 0x0001a2a4, 0xc0204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36a }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x09800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x67c }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000004, 0x00404c11, 0x647 }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000004, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffffb, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffff7, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x36a }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x01800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x67c }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x67b }, ++ { 0x00000010, 0x00404c11, 0x661 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x38c00000, 0x000 }, ++ { 0x0000001d, 0x00200a2d, 0x000 }, ++ { 0x0000001e, 0x00200e2d, 0x000 }, ++ { 0x0000001f, 0x0020122d, 0x000 }, ++ { 0x00000020, 0x0020162d, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000004, 0x00301224, 0x000 }, ++ { 0x00000000, 0x002f0064, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x67a }, ++ { 0x00000003, 0x00281a22, 0x000 }, ++ { 0x00000008, 0x00221222, 0x000 }, ++ { 0xfffff000, 0x00281224, 0x000 }, ++ { 0x00000000, 0x002910c4, 0x000 }, ++ { 0x0000001f, 0x00403624, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x67c }, ++ { 0x9f000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x67f }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x681 }, ++ { 0x9e000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x684 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0xc0204411, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000024, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000022, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00404811, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x014204f5, 0x05b30250, 0x000 }, ++ { 0x01c30168, 0x043505b3, 0x000 }, ++ { 0x02250209, 0x02500151, 0x000 }, ++ { 0x02230245, 0x02a00241, 0x000 }, ++ { 0x03cd05b3, 0x05b305b3, 0x000 }, ++ { 0x063c063d, 0x031f05b3, 0x000 }, ++ { 0x05b305b8, 0x03200340, 0x000 }, ++ { 0x032a0282, 0x03420334, 0x000 }, ++ { 0x05b305b3, 0x05b305b3, 0x000 }, ++ { 0x05b30544, 0x05b305b3, 0x000 }, ++ { 0x03b205b3, 0x04ae0344, 0x000 }, ++ { 0x048d0443, 0x043305b3, 0x000 }, ++ { 0x04c305b3, 0x043704d0, 0x000 }, ++ { 0x044304fa, 0x03510371, 0x000 }, ++ { 0x05b305b3, 0x05b305b3, 0x000 }, ++ { 0x05b305b3, 0x05b305b3, 0x000 }, ++ { 0x05b305b3, 0x063205ba, 0x000 }, ++ { 0x05b305b3, 0x000705b3, 0x000 }, ++ { 0x05b305b3, 0x05b305b3, 0x000 }, ++ { 0x05b305b3, 0x05b305b3, 0x000 }, ++ { 0x03ee03e3, 0x03fe03fc, 0x000 }, ++ { 0x04040400, 0x04020406, 0x000 }, ++ { 0x0412040e, 0x041a0416, 0x000 }, ++ { 0x0422041e, 0x042a0426, 0x000 }, ++ { 0x05b305b3, 0x042e05b3, 0x000 }, ++ { 0x05b305b3, 0x05b305b3, 0x000 }, ++ { 0x05b305b3, 0x05b305b3, 0x000 }, ++ { 0x00020668, 0x06860006, 0x000 }, ++}; ++ ++static const u32 RV670_pfp_microcode[] = { ++0xca0400, ++0xa00000, ++0x7e828b, ++0x7c038b, ++0x8001b8, ++0x7c038b, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xc41838, ++0xca2400, ++0xca2800, ++0x9581a8, ++0xc41c3a, ++0xc3c000, ++0xca0800, ++0xca0c00, ++0x7c744b, ++0xc20005, ++0x99c000, ++0xc41c3a, ++0x7c744c, ++0xc0fff0, ++0x042c04, ++0x309002, ++0x7d2500, ++0x351402, ++0x7d350b, ++0x255403, ++0x7cd580, ++0x259c03, ++0x95c004, ++0xd5001b, ++0x7eddc1, ++0x7d9d80, ++0xd6801b, ++0xd5801b, ++0xd4401e, ++0xd5401e, ++0xd6401e, ++0xd6801e, ++0xd4801e, ++0xd4c01e, ++0x9783d3, ++0xd5c01e, ++0xca0800, ++0x80001a, ++0xca0c00, ++0xe4011e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xe4013e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca1800, ++0xd4401e, ++0xd5801e, ++0x800053, ++0xd40075, ++0xd4401e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd48019, ++0xd4c018, ++0xd50017, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xe2001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0xd48060, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xd48061, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xca0c00, ++0xd4401e, ++0xd48016, ++0xd4c016, ++0xd4801e, ++0x8001b8, ++0xd4c01e, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x948004, ++0xca1400, ++0xe420f3, ++0xd42013, ++0xd56065, ++0xd4e01c, ++0xd5201c, ++0xd5601c, ++0x800000, ++0x062001, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9483f7, ++0xca1400, ++0xe420f3, ++0x800079, ++0xd42013, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9883ef, ++0xca1400, ++0xd40064, ++0x80008d, ++0x000000, ++0xc41432, ++0xc61843, ++0xc4082f, ++0x954005, ++0xc40c30, ++0xd4401e, ++0x800000, ++0xee001e, ++0x9583f5, ++0xc41031, ++0xd44033, ++0xd52065, ++0xd4a01c, ++0xd4e01c, ++0xd5201c, ++0xe4015e, ++0xd4001e, ++0x800000, ++0x062001, ++0xca1800, ++0x0a2001, ++0xd60076, ++0xc40836, ++0x988007, ++0xc61045, ++0x950110, ++0xd4001f, ++0xd46062, ++0x800000, ++0xd42062, ++0xcc3835, ++0xcc1433, ++0x8401bb, ++0xd40072, ++0xd5401e, ++0x800000, ++0xee001e, ++0xe2001a, ++0x8401bb, ++0xe2001a, ++0xcc104b, ++0xcc0447, ++0x2c9401, ++0x7d098b, ++0x984005, ++0x7d15cb, ++0xd4001a, ++0x8001b8, ++0xd4006d, ++0x344401, ++0xcc0c48, ++0x98403a, ++0xcc2c4a, ++0x958004, ++0xcc0449, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0x282801, ++0x8400f0, ++0xcc1003, ++0x98801b, ++0x04380c, ++0x8400f0, ++0xcc1003, ++0x988017, ++0x043808, ++0x8400f0, ++0xcc1003, ++0x988013, ++0x043804, ++0x8400f0, ++0xcc1003, ++0x988014, ++0xcc104c, ++0x9a8009, ++0xcc144d, ++0x9840dc, ++0xd4006d, ++0xcc1848, ++0xd5001a, ++0xd5401a, ++0x8000c9, ++0xd5801a, ++0x96c0d5, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0x9ac003, ++0xd4006d, ++0xd4006e, ++0x800000, ++0xec007f, ++0x9ac0cc, ++0xd4006d, ++0x8001b8, ++0xd4006e, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0x7d9103, ++0x7dd583, ++0x7d190c, ++0x35cc1f, ++0x35701f, ++0x7cf0cb, ++0x7cd08b, ++0x880000, ++0x7e8e8b, ++0x95c004, ++0xd4006e, ++0x8001b8, ++0xd4001a, ++0xd4c01a, ++0xcc0803, ++0xcc0c03, ++0xcc1003, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0xcc2403, ++0xcc2803, ++0x35c41f, ++0x36b01f, ++0x7c704b, ++0x34f01f, ++0x7c704b, ++0x35701f, ++0x7c704b, ++0x7d8881, ++0x7dccc1, ++0x7e5101, ++0x7e9541, ++0x7c9082, ++0x7cd4c2, ++0x7c848b, ++0x9ac003, ++0x7c8c8b, ++0x2c8801, ++0x98809e, ++0xd4006d, ++0x98409c, ++0xd4006e, ++0xcc084c, ++0xcc0c4d, ++0xcc1048, ++0xd4801a, ++0xd4c01a, ++0x800101, ++0xd5001a, ++0xcc0832, ++0xd40032, ++0x9482d9, ++0xca0c00, ++0xd4401e, ++0x800000, ++0xd4001e, ++0xe4011e, ++0xd4001e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd4401e, ++0xca1400, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xd5401e, ++0xd54034, ++0x800000, ++0xee001e, ++0x280404, ++0xe2001a, ++0xe2001a, ++0xd4401a, ++0xca3800, ++0xcc0803, ++0xcc0c03, ++0xcc0c03, ++0xcc0c03, ++0x9882bd, ++0x000000, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0400, ++0xc2ff00, ++0xcc0834, ++0xc13fff, ++0x7c74cb, ++0x7cc90b, ++0x7d010f, ++0x9902b0, ++0x7c738b, ++0x8401bb, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0800, ++0x281900, ++0x7d898b, ++0x958014, ++0x281404, ++0xca0c00, ++0xca1000, ++0xca1c00, ++0xca2400, ++0xe2001f, ++0xd4c01a, ++0xd5001a, ++0xd5401a, ++0xcc1803, ++0xcc2c03, ++0xcc2c03, ++0xcc2c03, ++0x7da58b, ++0x7d9c47, ++0x984297, ++0x000000, ++0x800161, ++0xd4c01a, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0x248c06, ++0x0ccc06, ++0x98c006, ++0xcc104e, ++0x990004, ++0xd40073, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xca0800, ++0xca0c00, ++0x34d018, ++0x251001, ++0x950021, ++0xc17fff, ++0xca1000, ++0xca1400, ++0xca1800, ++0xd4801d, ++0xd4c01d, ++0x7db18b, ++0xc14202, ++0xc2c001, ++0xd5801d, ++0x34dc0e, ++0x7d5d4c, ++0x7f734c, ++0xd7401e, ++0xd5001e, ++0xd5401e, ++0xc14200, ++0xc2c000, ++0x099c01, ++0x31dc10, ++0x7f5f4c, ++0x7f734c, ++0x042802, ++0x7d8380, ++0xd5a86f, ++0xd58066, ++0xd7401e, ++0xec005e, ++0xc82402, ++0xc82402, ++0x8001b8, ++0xd60076, ++0xd4401e, ++0xd4801e, ++0xd4c01e, ++0x800000, ++0xee001e, ++0x800000, ++0xee001f, ++0xd4001f, ++0x800000, ++0xd4001f, ++0xd4001f, ++0x880000, ++0xd4001f, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x010171, ++0x020178, ++0x03008f, ++0x04007f, ++0x050003, ++0x06003f, ++0x070032, ++0x08012c, ++0x090046, ++0x0a0036, ++0x1001b6, ++0x1700a2, ++0x22013a, ++0x230149, ++0x2000b4, ++0x240125, ++0x27004d, ++0x28006a, ++0x2a0060, ++0x2b0052, ++0x2f0065, ++0x320087, ++0x34017f, ++0x3c0156, ++0x3f0072, ++0x41018c, ++0x44012e, ++0x550173, ++0x56017a, ++0x60000b, ++0x610034, ++0x620038, ++0x630038, ++0x640038, ++0x650038, ++0x660038, ++0x670038, ++0x68003a, ++0x690041, ++0x6a0048, ++0x6b0048, ++0x6c0048, ++0x6d0048, ++0x6e0048, ++0x6f0048, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++}; ++ ++static const u32 RS780_cp_microcode[][3] = { ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0000ffff, 0x00284621, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x000 }, ++ { 0x00010000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x622 }, ++ { 0x00000000, 0x00600000, 0x5d1 }, ++ { 0x00000000, 0x00600000, 0x5de }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000f00, 0x00281622, 0x000 }, ++ { 0x00000008, 0x00211625, 0x000 }, ++ { 0x00000018, 0x00203625, 0x000 }, ++ { 0x8d000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x002f0225, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x018 }, ++ { 0x00412000, 0x00404811, 0x019 }, ++ { 0x00422000, 0x00204811, 0x000 }, ++ { 0x8e000000, 0x00204411, 0x000 }, ++ { 0x00000028, 0x00204a2d, 0x000 }, ++ { 0x90000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x0000000c, 0x00211622, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000019, 0x00211a22, 0x000 }, ++ { 0x00000004, 0x00281a26, 0x000 }, ++ { 0x00000000, 0x002914c5, 0x000 }, ++ { 0x00000019, 0x00203625, 0x000 }, ++ { 0x00000000, 0x003a1402, 0x000 }, ++ { 0x00000016, 0x00211625, 0x000 }, ++ { 0x00000003, 0x00281625, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0xfffffffc, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002914a3, 0x000 }, ++ { 0x00000017, 0x00203625, 0x000 }, ++ { 0x00008000, 0x00280e22, 0x000 }, ++ { 0x00000007, 0x00220e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x20000000, 0x00280e22, 0x000 }, ++ { 0x00000006, 0x00210e23, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x00000000, 0x00220222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x038 }, ++ { 0x00000000, 0x2ee00000, 0x035 }, ++ { 0x00000000, 0x2ce00000, 0x037 }, ++ { 0x00000000, 0x00400e2d, 0x039 }, ++ { 0x00000008, 0x00200e2d, 0x000 }, ++ { 0x00000009, 0x0040122d, 0x046 }, ++ { 0x00000001, 0x00400e2d, 0x039 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x03e }, ++ { 0x00000008, 0x00401c11, 0x041 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x0000000f, 0x00281e27, 0x000 }, ++ { 0x00000003, 0x00221e27, 0x000 }, ++ { 0x7fc00000, 0x00281a23, 0x000 }, ++ { 0x00000014, 0x00211a26, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000008, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x00290cc7, 0x000 }, ++ { 0x00000027, 0x00203624, 0x000 }, ++ { 0x00007f00, 0x00281221, 0x000 }, ++ { 0x00001400, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x04b }, ++ { 0x00000001, 0x00290e23, 0x000 }, ++ { 0x0000000e, 0x00203623, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfff80000, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x003a2c02, 0x000 }, ++ { 0x00000002, 0x00220e2b, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x0000000f, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00204a2d, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000029, 0x00200e2d, 0x000 }, ++ { 0x060a0200, 0x00294a23, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x061 }, ++ { 0x00000000, 0x2ee00000, 0x05f }, ++ { 0x00000000, 0x2ce00000, 0x05e }, ++ { 0x00000000, 0x00400e2d, 0x062 }, ++ { 0x00000001, 0x00400e2d, 0x062 }, ++ { 0x0000000a, 0x00200e2d, 0x000 }, ++ { 0x0000000b, 0x0040122d, 0x06a }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x003ffffc, 0x00281223, 0x000 }, ++ { 0x00000002, 0x00221224, 0x000 }, ++ { 0x7fc00000, 0x00281623, 0x000 }, ++ { 0x00000014, 0x00211625, 0x000 }, ++ { 0x00000001, 0x00331625, 0x000 }, ++ { 0x80000000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00290ca3, 0x000 }, ++ { 0x3ffffc00, 0x00290e23, 0x000 }, ++ { 0x0000001f, 0x00211e23, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x06d }, ++ { 0x00000100, 0x00401c11, 0x070 }, ++ { 0x0000000d, 0x00201e2d, 0x000 }, ++ { 0x000000f0, 0x00281e27, 0x000 }, ++ { 0x00000004, 0x00221e27, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0xfffff0ff, 0x00281a30, 0x000 }, ++ { 0x0000a028, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948e6, 0x000 }, ++ { 0x0000a018, 0x00204411, 0x000 }, ++ { 0x3fffffff, 0x00284a23, 0x000 }, ++ { 0x0000a010, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000030, 0x0020162d, 0x000 }, ++ { 0x00000002, 0x00291625, 0x000 }, ++ { 0x00000030, 0x00203625, 0x000 }, ++ { 0x00000025, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a3, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x083 }, ++ { 0x00000026, 0x0020162d, 0x000 }, ++ { 0x00000000, 0x002f00a4, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x084 }, ++ { 0x00000000, 0x00400000, 0x08a }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203624, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x08a }, ++ { 0x00000000, 0x00600000, 0x5ff }, ++ { 0x00000000, 0x00600000, 0x5f3 }, ++ { 0x00000002, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x08d }, ++ { 0x00000012, 0xc0403620, 0x093 }, ++ { 0x00000000, 0x2ee00000, 0x091 }, ++ { 0x00000000, 0x2ce00000, 0x090 }, ++ { 0x00000002, 0x00400e2d, 0x092 }, ++ { 0x00000003, 0x00400e2d, 0x092 }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000012, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x098 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x0a0 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x2ee00000, 0x09e }, ++ { 0x00000000, 0x2ce00000, 0x09d }, ++ { 0x00000002, 0x00400e2d, 0x09f }, ++ { 0x00000003, 0x00400e2d, 0x09f }, ++ { 0x0000000c, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x003f0000, 0x00280e23, 0x000 }, ++ { 0x00000010, 0x00210e23, 0x000 }, ++ { 0x00000011, 0x00203623, 0x000 }, ++ { 0x0000001e, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0a7 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x0000001f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0aa }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000008, 0x00210e2b, 0x000 }, ++ { 0x0000007f, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0e1 }, ++ { 0x00000000, 0x27000000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x0b3 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000000c, 0x00221e30, 0x000 }, ++ { 0x99800000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x0020122d, 0x000 }, ++ { 0x00000008, 0x00221224, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00291ce4, 0x000 }, ++ { 0x00000000, 0x00604807, 0x12f }, ++ { 0x9b000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x9c000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x0033146f, 0x000 }, ++ { 0x00000001, 0x00333e23, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0x00203c05, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e007, 0x00204411, 0x000 }, ++ { 0x0000000f, 0x0021022b, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0cb }, ++ { 0x00f8ff08, 0x00204811, 0x000 }, ++ { 0x98000000, 0x00404811, 0x0dc }, ++ { 0x000000f0, 0x00280e22, 0x000 }, ++ { 0x000000a0, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x0da }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d5 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0d4 }, ++ { 0x00003f00, 0x00400c11, 0x0d6 }, ++ { 0x00001f00, 0x00400c11, 0x0d6 }, ++ { 0x00000f00, 0x00200c11, 0x000 }, ++ { 0x00380009, 0x00294a23, 0x000 }, ++ { 0x3f000000, 0x00280e2b, 0x000 }, ++ { 0x00000002, 0x00220e23, 0x000 }, ++ { 0x00000007, 0x00494a23, 0x0dc }, ++ { 0x00380f09, 0x00204811, 0x000 }, ++ { 0x68000007, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000a202, 0x00204411, 0x000 }, ++ { 0x00ff0000, 0x00280e22, 0x000 }, ++ { 0x00000080, 0x00294a23, 0x000 }, ++ { 0x00000027, 0x00200e2d, 0x000 }, ++ { 0x00000026, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x002f0083, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x0ea }, ++ { 0x00000000, 0x00600000, 0x5f9 }, ++ { 0x00000000, 0x00400000, 0x0eb }, ++ { 0x00000000, 0x00600000, 0x5fc }, ++ { 0x00000007, 0x0020222d, 0x000 }, ++ { 0x00000005, 0x00220e22, 0x000 }, ++ { 0x00100000, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000000, 0x003a0c02, 0x000 }, ++ { 0x000000ef, 0x00280e23, 0x000 }, ++ { 0x00000000, 0x00292068, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000003, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x0f8 }, ++ { 0x0000000b, 0x00210228, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0f8 }, ++ { 0x00000400, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000001c, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x0fd }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000001e, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x10b }, ++ { 0x0000a30f, 0x00204411, 0x000 }, ++ { 0x00000011, 0x00200e2d, 0x000 }, ++ { 0x00000001, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x104 }, ++ { 0xffffffff, 0x00404811, 0x10b }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x107 }, ++ { 0x0000ffff, 0x00404811, 0x10b }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x10a }, ++ { 0x000000ff, 0x00404811, 0x10b }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0002c400, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x00210e22, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x112 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000018, 0x40224a20, 0x000 }, ++ { 0x00000010, 0xc0424a20, 0x114 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x00000013, 0x00203623, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000000a, 0x00201011, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x11b }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00531224, 0x117 }, ++ { 0xffbfffff, 0x00283a2e, 0x000 }, ++ { 0x0000001b, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x12e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000d, 0x00204811, 0x000 }, ++ { 0x00000018, 0x00220e30, 0x000 }, ++ { 0xfc000000, 0x00280e23, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00201010, 0x000 }, ++ { 0x0000e00e, 0x00204411, 0x000 }, ++ { 0x07f8ff08, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00294a23, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a24, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00800000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204806, 0x000 }, ++ { 0x00000008, 0x00214a27, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x622 }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x621 }, ++ { 0x00000004, 0x00404c11, 0x135 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000001c, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x622 }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x13c }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40280620, 0x000 }, ++ { 0x00000010, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x00341461, 0x000 }, ++ { 0x00000000, 0x00741882, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x147 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x160 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0681a20, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x158 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00300a2f, 0x000 }, ++ { 0x00000001, 0x00210a22, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600000, 0x18f }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00202c08, 0x000 }, ++ { 0x00000000, 0x00202411, 0x000 }, ++ { 0x00000000, 0x00202811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00221e29, 0x000 }, ++ { 0x00000000, 0x007048eb, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000001, 0x40330620, 0x000 }, ++ { 0x00000000, 0xc0302409, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x181 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x186 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x186 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000001, 0x00530621, 0x182 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x197 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000011, 0x0020062d, 0x000 }, ++ { 0x00000000, 0x0078042a, 0x2fb }, ++ { 0x00000000, 0x00202809, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x174 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x194 }, ++ { 0x00000015, 0xc0203620, 0x000 }, ++ { 0x00000016, 0xc0203620, 0x000 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x46000000, 0x00600811, 0x1b2 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x19b }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00804811, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000ffff, 0x40281620, 0x000 }, ++ { 0x00000010, 0xc0811a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x00000008, 0x00221e30, 0x000 }, ++ { 0x00000029, 0x00201a2d, 0x000 }, ++ { 0x0000e000, 0x00204411, 0x000 }, ++ { 0xfffbff09, 0x00204811, 0x000 }, ++ { 0x0000000f, 0x0020222d, 0x000 }, ++ { 0x00001fff, 0x00294a28, 0x000 }, ++ { 0x00000006, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000100, 0x00201811, 0x000 }, ++ { 0x00000008, 0x00621e28, 0x12f }, ++ { 0x00000008, 0x00822228, 0x000 }, ++ { 0x0002c000, 0x00204411, 0x000 }, ++ { 0x00000015, 0x00600e2d, 0x1bd }, ++ { 0x00000016, 0x00600e2d, 0x1bd }, ++ { 0x0000c008, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00200e2d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x1b9 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x39000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00804802, 0x000 }, ++ { 0x00000018, 0x00202e2d, 0x000 }, ++ { 0x00000000, 0x003b0d63, 0x000 }, ++ { 0x00000008, 0x00224a23, 0x000 }, ++ { 0x00000010, 0x00224a23, 0x000 }, ++ { 0x00000018, 0x00224a23, 0x000 }, ++ { 0x00000000, 0x00804803, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00000007, 0x0021062f, 0x000 }, ++ { 0x00000013, 0x00200a2d, 0x000 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000ffff, 0x40282220, 0x000 }, ++ { 0x0000000f, 0x00262228, 0x000 }, ++ { 0x00000010, 0x40212620, 0x000 }, ++ { 0x0000000f, 0x00262629, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1e0 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000081, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000080, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1dc }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1d8 }, ++ { 0x00000001, 0x00202c11, 0x000 }, ++ { 0x0000001f, 0x00280a22, 0x000 }, ++ { 0x0000001f, 0x00282a2a, 0x000 }, ++ { 0x00000001, 0x00530621, 0x1d1 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00304a2f, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00301e2f, 0x000 }, ++ { 0x00000000, 0x002f0227, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x1e9 }, ++ { 0x00000001, 0x00531e27, 0x1e5 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x0000000f, 0x00260e23, 0x000 }, ++ { 0x00000010, 0xc0211220, 0x000 }, ++ { 0x0000000f, 0x00261224, 0x000 }, ++ { 0x00000000, 0x00201411, 0x000 }, ++ { 0x00000000, 0x00601811, 0x2bb }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022b, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x1f8 }, ++ { 0x00000010, 0x00221628, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a29, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x0020480a, 0x000 }, ++ { 0x00000000, 0x00202c11, 0x000 }, ++ { 0x00000010, 0x00221623, 0x000 }, ++ { 0xffff0000, 0x00281625, 0x000 }, ++ { 0x0000ffff, 0x00281a24, 0x000 }, ++ { 0x00000000, 0x002948c5, 0x000 }, ++ { 0x00000000, 0x00731503, 0x205 }, ++ { 0x00000000, 0x00201805, 0x000 }, ++ { 0x00000000, 0x00731524, 0x205 }, ++ { 0x00000000, 0x002d14c5, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00202802, 0x000 }, ++ { 0x00000000, 0x00202003, 0x000 }, ++ { 0x00000000, 0x00802404, 0x000 }, ++ { 0x0000000f, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x621 }, ++ { 0x00000000, 0x002b1405, 0x000 }, ++ { 0x00000001, 0x00901625, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001a, 0x00294a22, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a21, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0x40281220, 0x000 }, ++ { 0x00000010, 0xc0211a20, 0x000 }, ++ { 0x0000ffff, 0x40280e20, 0x000 }, ++ { 0x00000010, 0xc0211620, 0x000 }, ++ { 0x00000000, 0x00741465, 0x2bb }, ++ { 0x0001a1fd, 0x00604411, 0x2e0 }, ++ { 0x00000001, 0x00330621, 0x000 }, ++ { 0x00000000, 0x002f0221, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x219 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x212 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x5de }, ++ { 0x00000000, 0x0040040f, 0x213 }, ++ { 0x00000000, 0x00600000, 0x5d1 }, ++ { 0x00000000, 0x00600000, 0x5de }, ++ { 0x00000210, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00600000, 0x1a0 }, ++ { 0x00000000, 0x00600000, 0x19c }, ++ { 0x00000000, 0x00600000, 0x2bb }, ++ { 0x00000000, 0x00600000, 0x2a3 }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204808, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x232 }, ++ { 0x00000000, 0x00600000, 0x13a }, ++ { 0x00000000, 0x00400000, 0x236 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x236 }, ++ { 0x00000000, 0xc0404800, 0x233 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00600411, 0x2fb }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000000, 0x00600000, 0x5d1 }, ++ { 0x0000a00c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000018, 0x40210a20, 0x000 }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x24c }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x00080101, 0x00292228, 0x000 }, ++ { 0x00000014, 0x00203628, 0x000 }, ++ { 0x0000a30c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x251 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000010, 0x00600411, 0x315 }, ++ { 0x3f800000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00600000, 0x27c }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000001, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x26a }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x0000ffff, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00341c27, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x25f }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e5, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x262 }, ++ { 0x00000000, 0x00201407, 0x000 }, ++ { 0x00000012, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00211e27, 0x000 }, ++ { 0x00000000, 0x00341c47, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x267 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x08c00000, 0x26a }, ++ { 0x00000000, 0x00201807, 0x000 }, ++ { 0x00000000, 0x00600000, 0x2c1 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00342023, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x272 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x271 }, ++ { 0x00000016, 0x00404811, 0x276 }, ++ { 0x00000018, 0x00404811, 0x276 }, ++ { 0x00000000, 0x00342044, 0x000 }, ++ { 0x00000000, 0x12c00000, 0x275 }, ++ { 0x00000017, 0x00404811, 0x276 }, ++ { 0x00000019, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0x00604411, 0x2e9 }, ++ { 0x00003fff, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x256 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x00000010, 0x40210620, 0x000 }, ++ { 0x0000ffff, 0xc0280a20, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x00000010, 0x40211620, 0x000 }, ++ { 0x0000ffff, 0xc0881a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00042004, 0x00604411, 0x622 }, ++ { 0x00000000, 0x00600000, 0x5d1 }, ++ { 0x00000000, 0xc0600000, 0x2a3 }, ++ { 0x00000005, 0x00200a2d, 0x000 }, ++ { 0x00000008, 0x00220a22, 0x000 }, ++ { 0x0000002b, 0x00201a2d, 0x000 }, ++ { 0x0000001c, 0x00201e2d, 0x000 }, ++ { 0x00007000, 0x00281e27, 0x000 }, ++ { 0x00000000, 0x00311ce6, 0x000 }, ++ { 0x0000002a, 0x00201a2d, 0x000 }, ++ { 0x0000000c, 0x00221a26, 0x000 }, ++ { 0x00000000, 0x002f00e6, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x292 }, ++ { 0x00000000, 0x00201c11, 0x000 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000010, 0x00201811, 0x000 }, ++ { 0x00000000, 0x00691ce2, 0x12f }, ++ { 0x93800000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x95000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f022f, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x29d }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x92000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000001c, 0x00403627, 0x000 }, ++ { 0x0000000c, 0xc0220a20, 0x000 }, ++ { 0x00000029, 0x00203622, 0x000 }, ++ { 0x00000028, 0xc0403620, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000009, 0x00204811, 0x000 }, ++ { 0xa1000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00804811, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce3, 0x000 }, ++ { 0x00000021, 0x00203627, 0x000 }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002c1ce4, 0x000 }, ++ { 0x00000022, 0x00203627, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a3, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x00000000, 0x002d1d07, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203624, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000023, 0x00203627, 0x000 }, ++ { 0x00000000, 0x00311cc4, 0x000 }, ++ { 0x00000024, 0x00803627, 0x000 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x2dc }, ++ { 0x00000000, 0x00400000, 0x2d9 }, ++ { 0x0000001a, 0x00203627, 0x000 }, ++ { 0x0000001b, 0x00203628, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000002, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2d9 }, ++ { 0x00000003, 0x00210227, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x2dc }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e1, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120a1, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000024, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x002e00e2, 0x000 }, ++ { 0x00000000, 0x02c00000, 0x2dc }, ++ { 0x00000022, 0x00201e2d, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x00000000, 0x002e00e8, 0x000 }, ++ { 0x00000000, 0x06c00000, 0x2dc }, ++ { 0x00000000, 0x00600000, 0x5ff }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2b5 }, ++ { 0x00000000, 0x00600000, 0x5f6 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x00000000, 0x00600000, 0x2a7 }, ++ { 0x00000000, 0x00400000, 0x2de }, ++ { 0x0000001a, 0x00201e2d, 0x000 }, ++ { 0x0000001b, 0x0080222d, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000000, 0x00311ca1, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294847, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e21, 0x000 }, ++ { 0x00000000, 0x003120c2, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00311ca3, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294887, 0x000 }, ++ { 0x00000001, 0x00220a21, 0x000 }, ++ { 0x00000000, 0x003008a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000010, 0x00221e23, 0x000 }, ++ { 0x00000000, 0x003120c4, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x003808c5, 0x000 }, ++ { 0x00000000, 0x00300841, 0x000 }, ++ { 0x00000001, 0x00220a22, 0x000 }, ++ { 0x00000000, 0x003308a2, 0x000 }, ++ { 0x00000010, 0x00221e22, 0x000 }, ++ { 0x00000010, 0x00212222, 0x000 }, ++ { 0x00000000, 0x00894907, 0x000 }, ++ { 0x00000017, 0x0020222d, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x318 }, ++ { 0xffffffef, 0x00280621, 0x000 }, ++ { 0x00000014, 0x0020222d, 0x000 }, ++ { 0x0000f8e0, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00294901, 0x000 }, ++ { 0x00000000, 0x00894901, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x060a0200, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x97000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0204811, 0x000 }, ++ { 0x8a000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00002257, 0x00204411, 0x000 }, ++ { 0x00000003, 0xc0484a20, 0x000 }, ++ { 0x0000225d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0x00600000, 0x5de }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00384a22, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0001a1fd, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x00000001, 0x40304a20, 0x000 }, ++ { 0x00000002, 0xc0304a20, 0x000 }, ++ { 0x00000001, 0x00530a22, 0x355 }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x622 }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x35e }, ++ { 0x00000014, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x36c }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00604802, 0x374 }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x370 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x367 }, ++ { 0x00000028, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5ba }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x367 }, ++ { 0x0000002c, 0x00203626, 0x000 }, ++ { 0x00000049, 0x00201811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00331a26, 0x000 }, ++ { 0x00000000, 0x002f0226, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x376 }, ++ { 0x0000002c, 0x00801a2d, 0x000 }, ++ { 0x0000003f, 0xc0280a20, 0x000 }, ++ { 0x00000015, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x38c }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b7 }, ++ { 0x00000016, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3b9 }, ++ { 0x00000020, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3a2 }, ++ { 0x0000000f, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3ae }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x3ae }, ++ { 0x0000001e, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x396 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x08000000, 0x00290a22, 0x000 }, ++ { 0x00000003, 0x40210e20, 0x000 }, ++ { 0x0000000c, 0xc0211220, 0x000 }, ++ { 0x00080000, 0x00281224, 0x000 }, ++ { 0x00000014, 0xc0221620, 0x000 }, ++ { 0x00000000, 0x002914a4, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x002948a2, 0x000 }, ++ { 0x0000a1fe, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x622 }, ++ { 0x00000015, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x398 }, ++ { 0x0000210e, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000017, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x622 }, ++ { 0x00000003, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3a4 }, ++ { 0x00002108, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404802, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x80000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000010, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3b4 }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00404811, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x374 }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x0000001d, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3ce }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x00000018, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x622 }, ++ { 0x00000011, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x3c2 }, ++ { 0x00002100, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0xbabecafe, 0x00204811, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00404811, 0x000 }, ++ { 0x00002170, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000a, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3d3 }, ++ { 0x8c000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00003fff, 0x40280a20, 0x000 }, ++ { 0x80000000, 0x40280e20, 0x000 }, ++ { 0x40000000, 0xc0281220, 0x000 }, ++ { 0x00040000, 0x00694622, 0x622 }, ++ { 0x00000000, 0x00201410, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e1 }, ++ { 0x00000000, 0xc0401800, 0x3e4 }, ++ { 0x00003fff, 0xc0281a20, 0x000 }, ++ { 0x00040000, 0x00694626, 0x622 }, ++ { 0x00000000, 0x00201810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x3e7 }, ++ { 0x00000000, 0xc0401c00, 0x3ea }, ++ { 0x00003fff, 0xc0281e20, 0x000 }, ++ { 0x00040000, 0x00694627, 0x622 }, ++ { 0x00000000, 0x00201c10, 0x000 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0x002820c5, 0x000 }, ++ { 0x00000000, 0x004948e8, 0x000 }, ++ { 0xa5800000, 0x00200811, 0x000 }, ++ { 0x00002000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x40204800, 0x000 }, ++ { 0x0000001f, 0xc0210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x3f7 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00008000, 0x00204811, 0x000 }, ++ { 0x0000ffff, 0xc0481220, 0x3ff }, ++ { 0xa7800000, 0x00200811, 0x000 }, ++ { 0x0000a000, 0x00200c11, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0x00204402, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000ffff, 0xc0281220, 0x000 }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00304883, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x83000000, 0x00604411, 0x412 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xa9800000, 0x00200811, 0x000 }, ++ { 0x0000c000, 0x00400c11, 0x3fa }, ++ { 0xab800000, 0x00200811, 0x000 }, ++ { 0x0000f8e0, 0x00400c11, 0x3fa }, ++ { 0xad800000, 0x00200811, 0x000 }, ++ { 0x0000f880, 0x00400c11, 0x3fa }, ++ { 0xb3800000, 0x00200811, 0x000 }, ++ { 0x0000f3fc, 0x00400c11, 0x3fa }, ++ { 0xaf800000, 0x00200811, 0x000 }, ++ { 0x0000e000, 0x00400c11, 0x3fa }, ++ { 0xb1800000, 0x00200811, 0x000 }, ++ { 0x0000f000, 0x00400c11, 0x3fa }, ++ { 0x83000000, 0x00204411, 0x000 }, ++ { 0x00002148, 0x00204811, 0x000 }, ++ { 0x84000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x1d000000, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x01182000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0218a000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0318c000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0418f8e0, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0518f880, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0618e000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0718f000, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x0818f3fc, 0xc0304620, 0x000 }, ++ { 0x00000000, 0xd9004800, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x00000033, 0xc0300a20, 0x000 }, ++ { 0x00000000, 0xc0403440, 0x000 }, ++ { 0x00000030, 0x00200a2d, 0x000 }, ++ { 0x00000000, 0xc0290c40, 0x000 }, ++ { 0x00000030, 0x00203623, 0x000 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x00a0000a, 0x000 }, ++ { 0x86000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x85000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0x00404801, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x00000018, 0x40210220, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x447 }, ++ { 0x00800000, 0xc0494a20, 0x448 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x450 }, ++ { 0x00000004, 0x00200811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x622 }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00404c02, 0x450 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x00000000, 0xc0201400, 0x000 }, ++ { 0x00000000, 0xc0201800, 0x000 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x461 }, ++ { 0x00000000, 0xc0202000, 0x000 }, ++ { 0x00000004, 0x002f0228, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x461 }, ++ { 0x00000004, 0x00202011, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x00000010, 0x00280a23, 0x000 }, ++ { 0x00000010, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x469 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0x00694624, 0x622 }, ++ { 0x00000000, 0x00400000, 0x46e }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00604805, 0x627 }, ++ { 0x00000000, 0x002824f0, 0x000 }, ++ { 0x00000007, 0x00280a23, 0x000 }, ++ { 0x00000001, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x475 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x04e00000, 0x48e }, ++ { 0x00000000, 0x00400000, 0x49b }, ++ { 0x00000002, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x47a }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x02e00000, 0x48e }, ++ { 0x00000000, 0x00400000, 0x49b }, ++ { 0x00000003, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x47f }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x48e }, ++ { 0x00000000, 0x00400000, 0x49b }, ++ { 0x00000004, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x484 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x48e }, ++ { 0x00000000, 0x00400000, 0x49b }, ++ { 0x00000005, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x489 }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x06e00000, 0x48e }, ++ { 0x00000000, 0x00400000, 0x49b }, ++ { 0x00000006, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x48e }, ++ { 0x00000000, 0x002f00c9, 0x000 }, ++ { 0x00000000, 0x08e00000, 0x48e }, ++ { 0x00000000, 0x00400000, 0x49b }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x000 }, ++ { 0x00000008, 0x00210a23, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x498 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00007f00, 0x00280a21, 0x000 }, ++ { 0x00004500, 0x002f0222, 0x000 }, ++ { 0x00000000, 0x0ae00000, 0x4a1 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x00404c08, 0x461 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000010, 0x40210e20, 0x000 }, ++ { 0x00000011, 0x40211220, 0x000 }, ++ { 0x00000012, 0x40211620, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00210225, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4ab }, ++ { 0x00040000, 0xc0494a20, 0x4ac }, ++ { 0xfffbffff, 0xc0284a20, 0x000 }, ++ { 0x00000000, 0x00210223, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x4b8 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x0000000c, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00200010, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4b4 }, ++ { 0xa0000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000004, 0x00204811, 0x000 }, ++ { 0x0000216b, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000216c, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204810, 0x000 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0ce00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4b2 }, ++ { 0x00000000, 0xc0210a20, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4cb }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x627 }, ++ { 0x00000000, 0x00400000, 0x4cf }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00040000, 0xc0294620, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x622 }, ++ { 0x00000001, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4d6 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00404811, 0x000 }, ++ { 0x00000000, 0xc0204400, 0x000 }, ++ { 0x00000000, 0xc0404810, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x000021f8, 0x00204411, 0x000 }, ++ { 0x0000000e, 0x00204811, 0x000 }, ++ { 0x000421f9, 0x00604411, 0x622 }, ++ { 0x00000000, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x4d8 }, ++ { 0x00002180, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000003, 0x00333e2f, 0x000 }, ++ { 0x00000001, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14e00000, 0x508 }, ++ { 0x0000002c, 0x00200a2d, 0x000 }, ++ { 0x00040000, 0x18e00c11, 0x4f7 }, ++ { 0x00000001, 0x00333e2f, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xd8c04800, 0x4eb }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000002d, 0x0020122d, 0x000 }, ++ { 0x00000000, 0x00290c83, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204802, 0x000 }, ++ { 0x00000000, 0x00204803, 0x000 }, ++ { 0x00000008, 0x00300a22, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000011, 0x00210224, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000000, 0x00400000, 0x4b2 }, ++ { 0x0000002c, 0xc0203620, 0x000 }, ++ { 0x0000002d, 0xc0403620, 0x000 }, ++ { 0x0000000f, 0x00210221, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x50d }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00000000, 0xd9000000, 0x000 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0xb5000000, 0x00204411, 0x000 }, ++ { 0x00002000, 0x00204811, 0x000 }, ++ { 0xb6000000, 0x00204411, 0x000 }, ++ { 0x0000a000, 0x00204811, 0x000 }, ++ { 0xb7000000, 0x00204411, 0x000 }, ++ { 0x0000c000, 0x00204811, 0x000 }, ++ { 0xb8000000, 0x00204411, 0x000 }, ++ { 0x0000f8e0, 0x00204811, 0x000 }, ++ { 0xb9000000, 0x00204411, 0x000 }, ++ { 0x0000f880, 0x00204811, 0x000 }, ++ { 0xba000000, 0x00204411, 0x000 }, ++ { 0x0000e000, 0x00204811, 0x000 }, ++ { 0xbb000000, 0x00204411, 0x000 }, ++ { 0x0000f000, 0x00204811, 0x000 }, ++ { 0xbc000000, 0x00204411, 0x000 }, ++ { 0x0000f3fc, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000002, 0x00204811, 0x000 }, ++ { 0x000000ff, 0x00280e30, 0x000 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x521 }, ++ { 0x00000000, 0xc0200800, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x536 }, ++ { 0x00000000, 0x00200c11, 0x000 }, ++ { 0x0000001c, 0x00203623, 0x000 }, ++ { 0x0000002b, 0x00203623, 0x000 }, ++ { 0x00000029, 0x00203623, 0x000 }, ++ { 0x00000028, 0x00203623, 0x000 }, ++ { 0x00000017, 0x00203623, 0x000 }, ++ { 0x00000025, 0x00203623, 0x000 }, ++ { 0x00000026, 0x00203623, 0x000 }, ++ { 0x00000015, 0x00203623, 0x000 }, ++ { 0x00000016, 0x00203623, 0x000 }, ++ { 0xffffe000, 0x00200c11, 0x000 }, ++ { 0x00000021, 0x00203623, 0x000 }, ++ { 0x00000022, 0x00203623, 0x000 }, ++ { 0x00001fff, 0x00200c11, 0x000 }, ++ { 0x00000023, 0x00203623, 0x000 }, ++ { 0x00000024, 0x00203623, 0x000 }, ++ { 0xf1ffffff, 0x00283a2e, 0x000 }, ++ { 0x0000001a, 0xc0220e20, 0x000 }, ++ { 0x00000000, 0x0029386e, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000006, 0x00204811, 0x000 }, ++ { 0x0000002a, 0x40203620, 0x000 }, ++ { 0x87000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0x9d000000, 0x00204411, 0x000 }, ++ { 0x0000001f, 0x40214a20, 0x000 }, ++ { 0x96000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0200c00, 0x000 }, ++ { 0x00000000, 0xc0201000, 0x000 }, ++ { 0x0000001f, 0x00211624, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x0000001d, 0x00203623, 0x000 }, ++ { 0x00000003, 0x00281e23, 0x000 }, ++ { 0x00000008, 0x00222223, 0x000 }, ++ { 0xfffff000, 0x00282228, 0x000 }, ++ { 0x00000000, 0x002920e8, 0x000 }, ++ { 0x0000001f, 0x00203628, 0x000 }, ++ { 0x00000018, 0x00211e23, 0x000 }, ++ { 0x00000020, 0x00203627, 0x000 }, ++ { 0x00000002, 0x00221624, 0x000 }, ++ { 0x00000000, 0x003014a8, 0x000 }, ++ { 0x0000001e, 0x00203625, 0x000 }, ++ { 0x00000003, 0x00211a24, 0x000 }, ++ { 0x10000000, 0x00281a26, 0x000 }, ++ { 0xefffffff, 0x00283a2e, 0x000 }, ++ { 0x00000000, 0x004938ce, 0x610 }, ++ { 0x00000001, 0x40280a20, 0x000 }, ++ { 0x00000006, 0x40280e20, 0x000 }, ++ { 0x00000300, 0xc0281220, 0x000 }, ++ { 0x00000008, 0x00211224, 0x000 }, ++ { 0x00000000, 0xc0201620, 0x000 }, ++ { 0x00000000, 0xc0201a20, 0x000 }, ++ { 0x00000000, 0x00210222, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x56c }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x622 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00020000, 0x00294a26, 0x000 }, ++ { 0x00000000, 0x00204810, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x574 }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x582 }, ++ { 0x00000002, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x574 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00002258, 0x00300a24, 0x000 }, ++ { 0x00040000, 0x00694622, 0x622 }, ++ { 0x00000000, 0xc0201c10, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x582 }, ++ { 0x00000000, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x578 }, ++ { 0x00000000, 0xc0201c00, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x582 }, ++ { 0x00000004, 0x002f0223, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x580 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x0000216d, 0x00204411, 0x000 }, ++ { 0x00000000, 0xc0204800, 0x000 }, ++ { 0x00000000, 0xc0604800, 0x627 }, ++ { 0x00000000, 0x00401c10, 0x582 }, ++ { 0x00000000, 0xc0200000, 0x000 }, ++ { 0x00000000, 0xc0400000, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x584 }, ++ { 0x00000000, 0x00600000, 0x5c3 }, ++ { 0x00000000, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x592 }, ++ { 0x0000a2b7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x00000033, 0x0020262d, 0x000 }, ++ { 0x0000001a, 0x00212229, 0x000 }, ++ { 0x00000006, 0x00222629, 0x000 }, ++ { 0x0000a2c4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x590 }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d1, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000001, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5a0 }, ++ { 0x0000a2bb, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x00000034, 0x0020262d, 0x000 }, ++ { 0x0000001a, 0x00212229, 0x000 }, ++ { 0x00000006, 0x00222629, 0x000 }, ++ { 0x0000a2c5, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x59e }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d2, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x00000002, 0x002f0224, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x5ae }, ++ { 0x0000a2bf, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x00000035, 0x0020262d, 0x000 }, ++ { 0x0000001a, 0x00212229, 0x000 }, ++ { 0x00000006, 0x00222629, 0x000 }, ++ { 0x0000a2c6, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5ac }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d3, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x0000a2c3, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204807, 0x000 }, ++ { 0x00000036, 0x0020262d, 0x000 }, ++ { 0x0000001a, 0x00212229, 0x000 }, ++ { 0x00000006, 0x00222629, 0x000 }, ++ { 0x0000a2c7, 0x00204411, 0x000 }, ++ { 0x00000000, 0x003048e9, 0x000 }, ++ { 0x00000000, 0x00e00000, 0x5b8 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404808, 0x000 }, ++ { 0x0000a2d4, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00504a28, 0x000 }, ++ { 0x85000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0x0000304a, 0x00204411, 0x000 }, ++ { 0x01000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00400000, 0x5be }, ++ { 0xa4000000, 0xc0204411, 0x000 }, ++ { 0x00000000, 0xc0404800, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x5c3 }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x0000003f, 0x00204811, 0x000 }, ++ { 0x00000005, 0x00204811, 0x000 }, ++ { 0x0000a1f4, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x88000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0xff000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x00000002, 0x00804811, 0x000 }, ++ { 0x00000000, 0x0ee00000, 0x5d6 }, ++ { 0x00001000, 0x00200811, 0x000 }, ++ { 0x0000002b, 0x00203622, 0x000 }, ++ { 0x00000000, 0x00600000, 0x5da }, ++ { 0x00000000, 0x00600000, 0x5c3 }, ++ { 0x98000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00804811, 0x000 }, ++ { 0x00000000, 0xc0600000, 0x5da }, ++ { 0x00000000, 0xc0400400, 0x001 }, ++ { 0x0000a2a4, 0x00204411, 0x000 }, ++ { 0x00000022, 0x00204811, 0x000 }, ++ { 0x89000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00404811, 0x5cd }, ++ { 0x97000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x8a000000, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00404811, 0x5cd }, ++ { 0x00000000, 0x00600000, 0x5f3 }, ++ { 0x0001a2a4, 0xc0204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x374 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x09800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x622 }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x000 }, ++ { 0x00000004, 0x00404c11, 0x5ed }, ++ { 0x00000000, 0x00400000, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000004, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffffb, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0x00000008, 0x00291e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x00000017, 0x00201e2d, 0x000 }, ++ { 0xfffffff7, 0x00281e27, 0x000 }, ++ { 0x00000017, 0x00803627, 0x000 }, ++ { 0x0001a2a4, 0x00204411, 0x000 }, ++ { 0x00000016, 0x00604811, 0x374 }, ++ { 0x00002010, 0x00204411, 0x000 }, ++ { 0x00010000, 0x00204811, 0x000 }, ++ { 0x0000217c, 0x00204411, 0x000 }, ++ { 0x01800000, 0x00204811, 0x000 }, ++ { 0xffffffff, 0x00204811, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000000, 0x17000000, 0x000 }, ++ { 0x81000000, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0004217f, 0x00604411, 0x622 }, ++ { 0x0000001f, 0x00210230, 0x000 }, ++ { 0x00000000, 0x14c00000, 0x621 }, ++ { 0x00000010, 0x00404c11, 0x607 }, ++ { 0x00000000, 0xc0200400, 0x000 }, ++ { 0x00000000, 0x38c00000, 0x000 }, ++ { 0x0000001d, 0x00200a2d, 0x000 }, ++ { 0x0000001e, 0x00200e2d, 0x000 }, ++ { 0x0000001f, 0x0020122d, 0x000 }, ++ { 0x00000020, 0x0020162d, 0x000 }, ++ { 0x00002169, 0x00204411, 0x000 }, ++ { 0x00000000, 0x00204804, 0x000 }, ++ { 0x00000000, 0x00204805, 0x000 }, ++ { 0x00000000, 0x00204801, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000004, 0x00301224, 0x000 }, ++ { 0x00000000, 0x002f0064, 0x000 }, ++ { 0x00000000, 0x0cc00000, 0x620 }, ++ { 0x00000003, 0x00281a22, 0x000 }, ++ { 0x00000008, 0x00221222, 0x000 }, ++ { 0xfffff000, 0x00281224, 0x000 }, ++ { 0x00000000, 0x002910c4, 0x000 }, ++ { 0x0000001f, 0x00403624, 0x000 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x622 }, ++ { 0x9f000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x625 }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x1ac00000, 0x627 }, ++ { 0x9e000000, 0x00204411, 0x000 }, ++ { 0xcafebabe, 0x00204811, 0x000 }, ++ { 0x00000000, 0x1ae00000, 0x62a }, ++ { 0x00000000, 0x00800000, 0x000 }, ++ { 0x00000000, 0x00600000, 0x00b }, ++ { 0x00001000, 0x00600411, 0x315 }, ++ { 0x00000000, 0x00200411, 0x000 }, ++ { 0x00000000, 0x00600811, 0x1b2 }, ++ { 0x0000225c, 0x00204411, 0x000 }, ++ { 0x00000003, 0x00204811, 0x000 }, ++ { 0x00002256, 0x00204411, 0x000 }, ++ { 0x0000001b, 0x00204811, 0x000 }, ++ { 0x0000a1fc, 0x00204411, 0x000 }, ++ { 0x00000001, 0x00204811, 0x000 }, ++ { 0x0001a1fd, 0xc0204411, 0x000 }, ++ { 0x00000021, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000024, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000022, 0x0020222d, 0x000 }, ++ { 0x0000ffff, 0x00282228, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00204811, 0x000 }, ++ { 0x00000023, 0x00201e2d, 0x000 }, ++ { 0x00000010, 0x00221e27, 0x000 }, ++ { 0x00000000, 0x00294907, 0x000 }, ++ { 0x00000000, 0x00404811, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x00000000, 0x00000000, 0x000 }, ++ { 0x0142050a, 0x05ba0250, 0x000 }, ++ { 0x01c30168, 0x044105ba, 0x000 }, ++ { 0x02250209, 0x02500151, 0x000 }, ++ { 0x02230245, 0x02a00241, 0x000 }, ++ { 0x03d705ba, 0x05ba05ba, 0x000 }, ++ { 0x05e205e3, 0x031f05ba, 0x000 }, ++ { 0x032005bf, 0x0320034a, 0x000 }, ++ { 0x03340282, 0x034c033e, 0x000 }, ++ { 0x05ba05ba, 0x05ba05ba, 0x000 }, ++ { 0x05ba0557, 0x05ba032a, 0x000 }, ++ { 0x03bc05ba, 0x04c3034e, 0x000 }, ++ { 0x04a20455, 0x043f05ba, 0x000 }, ++ { 0x04d805ba, 0x044304e5, 0x000 }, ++ { 0x0455050f, 0x035b037b, 0x000 }, ++ { 0x05ba05ba, 0x05ba05ba, 0x000 }, ++ { 0x05ba05ba, 0x05ba05ba, 0x000 }, ++ { 0x05ba05ba, 0x05d805c1, 0x000 }, ++ { 0x05ba05ba, 0x000705ba, 0x000 }, ++ { 0x05ba05ba, 0x05ba05ba, 0x000 }, ++ { 0x05ba05ba, 0x05ba05ba, 0x000 }, ++ { 0x03f803ed, 0x04080406, 0x000 }, ++ { 0x040e040a, 0x040c0410, 0x000 }, ++ { 0x041c0418, 0x04240420, 0x000 }, ++ { 0x042c0428, 0x04340430, 0x000 }, ++ { 0x05ba05ba, 0x043a0438, 0x000 }, ++ { 0x05ba05ba, 0x05ba05ba, 0x000 }, ++ { 0x05ba05ba, 0x05ba05ba, 0x000 }, ++ { 0x0002060e, 0x062c0006, 0x000 }, ++}; ++ ++static const u32 RS780_pfp_microcode[] = { ++0xca0400, ++0xa00000, ++0x7e828b, ++0x7c038b, ++0x8001db, ++0x7c038b, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xc41838, ++0xca2400, ++0xca2800, ++0x9581cb, ++0xc41c3a, ++0xc3c000, ++0xca0800, ++0xca0c00, ++0x7c744b, ++0xc20005, ++0x99c000, ++0xc41c3a, ++0x7c744c, ++0xc0ffe0, ++0x042c08, ++0x309002, ++0x7d2500, ++0x351402, ++0x7d350b, ++0x255407, ++0x7cd580, ++0x259c07, ++0x95c004, ++0xd5001b, ++0x7eddc1, ++0x7d9d80, ++0xd6801b, ++0xd5801b, ++0xd4401e, ++0xd5401e, ++0xd6401e, ++0xd6801e, ++0xd4801e, ++0xd4c01e, ++0x9783d3, ++0xd5c01e, ++0xca0800, ++0x80001a, ++0xca0c00, ++0xe4011e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xe4013e, ++0xd4001e, ++0x80000c, ++0xc41838, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0xca0c00, ++0x8001db, ++0xd48024, ++0xca0800, ++0x7c00c0, ++0xc81425, ++0xc81824, ++0x7c9488, ++0x7c9880, ++0xc20003, ++0xd40075, ++0x7c744c, ++0x800064, ++0xd4401e, ++0xca1800, ++0xd4401e, ++0xd5801e, ++0x800062, ++0xd40075, ++0xd4401e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd48019, ++0xd4c018, ++0xd50017, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xe2001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xd40075, ++0xd4401e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd48019, ++0xd4c018, ++0xd50017, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0x248c01, ++0xd48060, ++0x94c003, ++0x041001, ++0x041002, ++0xd50025, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xd48061, ++0xd4401e, ++0x800000, ++0xd4801e, ++0xca0800, ++0xca0c00, ++0xd4401e, ++0xd48016, ++0xd4c016, ++0xd4801e, ++0x8001db, ++0xd4c01e, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x948004, ++0xca1400, ++0xe420f3, ++0xd42013, ++0xd56065, ++0xd4e01c, ++0xd5201c, ++0xd5601c, ++0x800000, ++0x062001, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9483f7, ++0xca1400, ++0xe420f3, ++0x80009c, ++0xd42013, ++0xc60843, ++0xca0c00, ++0xca1000, ++0x9883ef, ++0xca1400, ++0xd40064, ++0x8000b0, ++0x000000, ++0xc41432, ++0xc61843, ++0xc4082f, ++0x954005, ++0xc40c30, ++0xd4401e, ++0x800000, ++0xee001e, ++0x9583f5, ++0xc41031, ++0xd44033, ++0xd52065, ++0xd4a01c, ++0xd4e01c, ++0xd5201c, ++0xe4015e, ++0xd4001e, ++0x800000, ++0x062001, ++0xca1800, ++0x0a2001, ++0xd60076, ++0xc40836, ++0x988007, ++0xc61045, ++0x950110, ++0xd4001f, ++0xd46062, ++0x800000, ++0xd42062, ++0xcc3835, ++0xcc1433, ++0x8401de, ++0xd40072, ++0xd5401e, ++0x800000, ++0xee001e, ++0xe2001a, ++0x8401de, ++0xe2001a, ++0xcc104b, ++0xcc0447, ++0x2c9401, ++0x7d098b, ++0x984005, ++0x7d15cb, ++0xd4001a, ++0x8001db, ++0xd4006d, ++0x344401, ++0xcc0c48, ++0x98403a, ++0xcc2c4a, ++0x958004, ++0xcc0449, ++0x8001db, ++0xd4001a, ++0xd4c01a, ++0x282801, ++0x840113, ++0xcc1003, ++0x98801b, ++0x04380c, ++0x840113, ++0xcc1003, ++0x988017, ++0x043808, ++0x840113, ++0xcc1003, ++0x988013, ++0x043804, ++0x840113, ++0xcc1003, ++0x988014, ++0xcc104c, ++0x9a8009, ++0xcc144d, ++0x9840dc, ++0xd4006d, ++0xcc1848, ++0xd5001a, ++0xd5401a, ++0x8000ec, ++0xd5801a, ++0x96c0d5, ++0xd4006d, ++0x8001db, ++0xd4006e, ++0x9ac003, ++0xd4006d, ++0xd4006e, ++0x800000, ++0xec007f, ++0x9ac0cc, ++0xd4006d, ++0x8001db, ++0xd4006e, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0x7d9103, ++0x7dd583, ++0x7d190c, ++0x35cc1f, ++0x35701f, ++0x7cf0cb, ++0x7cd08b, ++0x880000, ++0x7e8e8b, ++0x95c004, ++0xd4006e, ++0x8001db, ++0xd4001a, ++0xd4c01a, ++0xcc0803, ++0xcc0c03, ++0xcc1003, ++0xcc1403, ++0xcc1803, ++0xcc1c03, ++0xcc2403, ++0xcc2803, ++0x35c41f, ++0x36b01f, ++0x7c704b, ++0x34f01f, ++0x7c704b, ++0x35701f, ++0x7c704b, ++0x7d8881, ++0x7dccc1, ++0x7e5101, ++0x7e9541, ++0x7c9082, ++0x7cd4c2, ++0x7c848b, ++0x9ac003, ++0x7c8c8b, ++0x2c8801, ++0x98809e, ++0xd4006d, ++0x98409c, ++0xd4006e, ++0xcc084c, ++0xcc0c4d, ++0xcc1048, ++0xd4801a, ++0xd4c01a, ++0x800124, ++0xd5001a, ++0xcc0832, ++0xd40032, ++0x9482b6, ++0xca0c00, ++0xd4401e, ++0x800000, ++0xd4001e, ++0xe4011e, ++0xd4001e, ++0xca0800, ++0xca0c00, ++0xca1000, ++0xd4401e, ++0xca1400, ++0xd4801e, ++0xd4c01e, ++0xd5001e, ++0xd5401e, ++0xd54034, ++0x800000, ++0xee001e, ++0x280404, ++0xe2001a, ++0xe2001a, ++0xd4401a, ++0xca3800, ++0xcc0803, ++0xcc0c03, ++0xcc0c03, ++0xcc0c03, ++0x98829a, ++0x000000, ++0x8401de, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0400, ++0xc2ff00, ++0xcc0834, ++0xc13fff, ++0x7c74cb, ++0x7cc90b, ++0x7d010f, ++0x99028d, ++0x7c738b, ++0x8401de, ++0xd7a06f, ++0x800000, ++0xee001f, ++0xca0800, ++0x281900, ++0x7d898b, ++0x958014, ++0x281404, ++0xca0c00, ++0xca1000, ++0xca1c00, ++0xca2400, ++0xe2001f, ++0xd4c01a, ++0xd5001a, ++0xd5401a, ++0xcc1803, ++0xcc2c03, ++0xcc2c03, ++0xcc2c03, ++0x7da58b, ++0x7d9c47, ++0x984274, ++0x000000, ++0x800184, ++0xd4c01a, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xe4013e, ++0xd4001e, ++0xd4401e, ++0xee001e, ++0xca0400, ++0xa00000, ++0x7e828b, ++0xca0800, ++0x248c06, ++0x0ccc06, ++0x98c006, ++0xcc104e, ++0x990004, ++0xd40073, ++0xe4011e, ++0xd4001e, ++0xd4401e, ++0xd4801e, ++0x800000, ++0xee001e, ++0xca0800, ++0xca0c00, ++0x34d018, ++0x251001, ++0x950021, ++0xc17fff, ++0xca1000, ++0xca1400, ++0xca1800, ++0xd4801d, ++0xd4c01d, ++0x7db18b, ++0xc14202, ++0xc2c001, ++0xd5801d, ++0x34dc0e, ++0x7d5d4c, ++0x7f734c, ++0xd7401e, ++0xd5001e, ++0xd5401e, ++0xc14200, ++0xc2c000, ++0x099c01, ++0x31dc10, ++0x7f5f4c, ++0x7f734c, ++0x042802, ++0x7d8380, ++0xd5a86f, ++0xd58066, ++0xd7401e, ++0xec005e, ++0xc82402, ++0xc82402, ++0x8001db, ++0xd60076, ++0xd4401e, ++0xd4801e, ++0xd4c01e, ++0x800000, ++0xee001e, ++0x800000, ++0xee001f, ++0xd4001f, ++0x800000, ++0xd4001f, ++0xd4001f, ++0x880000, ++0xd4001f, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x000000, ++0x010194, ++0x02019b, ++0x0300b2, ++0x0400a2, ++0x050003, ++0x06003f, ++0x070032, ++0x08014f, ++0x090046, ++0x0a0036, ++0x1001d9, ++0x1700c5, ++0x22015d, ++0x23016c, ++0x2000d7, ++0x240148, ++0x26004d, ++0x27005c, ++0x28008d, ++0x290051, ++0x2a007e, ++0x2b0061, ++0x2f0088, ++0x3200aa, ++0x3401a2, ++0x36006f, ++0x3c0179, ++0x3f0095, ++0x4101af, ++0x440151, ++0x550196, ++0x56019d, ++0x60000b, ++0x610034, ++0x620038, ++0x630038, ++0x640038, ++0x650038, ++0x660038, ++0x670038, ++0x68003a, ++0x690041, ++0x6a0048, ++0x6b0048, ++0x6c0048, ++0x6d0048, ++0x6e0048, ++0x6f0048, ++0x7301d9, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++0x000006, ++}; ++ ++static const u32 RV770_cp_microcode[] = { ++0xcc0003ea, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x80000001, ++0xd040007f, ++0x80000001, ++0xcc400041, ++0x7c40c000, ++0xc0160004, ++0x30d03fff, ++0x7d15000c, ++0xcc110000, ++0x28d8001e, ++0x31980001, ++0x28dc001f, ++0xc8200004, ++0x95c00006, ++0x7c424000, ++0xcc000062, ++0x7e56800c, ++0xcc290000, ++0xc8240004, ++0x7e26000b, ++0x95800006, ++0x7c42c000, ++0xcc000062, ++0x7ed7000c, ++0xcc310000, ++0xc82c0004, ++0x7e2e000c, ++0xcc000062, ++0x31103fff, ++0x80000001, ++0xce110000, ++0x7c40c000, ++0x80000001, ++0xcc400040, ++0x80000001, ++0xcc412257, ++0x7c418000, ++0xcc400045, ++0xcc400048, ++0xcc41225c, ++0xcc41a1fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xcc400045, ++0xcc400048, ++0x7c40c000, ++0xcc41225c, ++0xcc41a1fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xcc000045, ++0xcc000048, ++0xcc41225c, ++0xcc41a1fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x040ca1fd, ++0xc0120001, ++0xcc000045, ++0xcc000048, ++0x7cd0c00c, ++0xcc41225c, ++0xcc41a1fc, ++0xd04d0000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x80000001, ++0xcc41225d, ++0x7c408000, ++0x7c40c000, ++0xc02a0002, ++0x7c410000, ++0x7d29000c, ++0x30940001, ++0x30980006, ++0x309c0300, ++0x29dc0008, ++0x7c420000, ++0x7c424000, ++0x9540000f, ++0xc02e0004, ++0x05f02258, ++0x7f2f000c, ++0xcc310000, ++0xc8280004, ++0xccc12169, ++0xcd01216a, ++0xce81216b, ++0x0db40002, ++0xcc01216c, ++0x9740000e, ++0x0db40000, ++0x8000007b, ++0xc834000a, ++0x0db40002, ++0x97400009, ++0x0db40000, ++0xc02e0004, ++0x05f02258, ++0x7f2f000c, ++0xcc310000, ++0xc8280004, ++0x8000007b, ++0xc834000a, ++0x97400004, ++0x7e028000, ++0x8000007b, ++0xc834000a, ++0x0db40004, ++0x9740ff8c, ++0x00000000, ++0xce01216d, ++0xce41216e, ++0xc8280003, ++0xc834000a, ++0x9b400004, ++0x043c0005, ++0x8400026d, ++0xcc000062, ++0x0df40000, ++0x9740000b, ++0xc82c03e6, ++0xce81a2b7, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c4, ++0x80000001, ++0xcfc1a2d1, ++0x0df40001, ++0x9740000b, ++0xc82c03e7, ++0xce81a2bb, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c5, ++0x80000001, ++0xcfc1a2d2, ++0x0df40002, ++0x9740000b, ++0xc82c03e8, ++0xce81a2bf, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c6, ++0x80000001, ++0xcfc1a2d3, ++0xc82c03e9, ++0xce81a2c3, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c7, ++0x80000001, ++0xcfc1a2d4, ++0x80000001, ++0xcc400042, ++0x7c40c000, ++0x7c410000, ++0x2914001d, ++0x31540001, ++0x9940000d, ++0x31181000, ++0xc81c0011, ++0x09dc0001, ++0x95c0ffff, ++0xc81c0011, ++0xccc12100, ++0xcd012101, ++0xccc12102, ++0xcd012103, ++0x04180004, ++0x8000039f, ++0xcd81a2a4, ++0xc02a0004, ++0x95800008, ++0x36a821a3, ++0xcc290000, ++0xc8280004, ++0xc81c0011, ++0x0de40040, ++0x9640ffff, ++0xc81c0011, ++0xccc12170, ++0xcd012171, ++0xc8200012, ++0x96000000, ++0xc8200012, ++0x8000039f, ++0xcc000064, ++0x7c40c000, ++0x7c410000, ++0xcc000045, ++0xcc000048, ++0x40d40003, ++0xcd41225c, ++0xcd01a1fc, ++0xc01a0001, ++0x041ca1fd, ++0x7dd9c00c, ++0x7c420000, ++0x08cc0001, ++0x06240001, ++0x06280002, ++0xce1d0000, ++0xce5d0000, ++0x98c0fffa, ++0xce9d0000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x7c40c000, ++0x30d00001, ++0x28cc0001, ++0x7c414000, ++0x95000006, ++0x7c418000, ++0xcd41216d, ++0xcd81216e, ++0x800000f3, ++0xc81c0003, ++0xc0220004, ++0x7e16000c, ++0xcc210000, ++0xc81c0004, ++0x7c424000, ++0x98c00004, ++0x7c428000, ++0x80000001, ++0xcde50000, ++0xce412169, ++0xce81216a, ++0xcdc1216b, ++0x80000001, ++0xcc01216c, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0x7c41c000, ++0x28a40008, ++0x326400ff, ++0x0e68003c, ++0x9680000a, ++0x7c020000, ++0x7c420000, ++0x1e300003, ++0xcc00006a, ++0x9b000003, ++0x42200005, ++0x04200040, ++0x80000110, ++0x7c024000, ++0x7e024000, ++0x9a400000, ++0x0a640001, ++0x30ec0010, ++0x9ac0000a, ++0xcc000062, ++0xc02a0004, ++0xc82c0021, ++0x7e92800c, ++0xcc000041, ++0xcc290000, ++0xcec00021, ++0x80000120, ++0xc8300004, ++0xcd01216d, ++0xcd41216e, ++0xc8300003, ++0x7f1f000b, ++0x30f40007, ++0x27780001, ++0x9740002a, ++0x07b80125, ++0x9f800000, ++0x00000000, ++0x80000135, ++0x7f1b8004, ++0x80000139, ++0x7f1b8005, ++0x8000013d, ++0x7f1b8002, ++0x80000141, ++0x7f1b8003, ++0x80000145, ++0x7f1b8007, ++0x80000149, ++0x7f1b8006, ++0x8000014e, ++0x28a40008, ++0x9b800019, ++0x28a40008, ++0x8000015e, ++0x326400ff, ++0x9b800015, ++0x28a40008, ++0x8000015e, ++0x326400ff, ++0x9b800011, ++0x28a40008, ++0x8000015e, ++0x326400ff, ++0x9b80000d, ++0x28a40008, ++0x8000015e, ++0x326400ff, ++0x9b800009, ++0x28a40008, ++0x8000015e, ++0x326400ff, ++0x9b800005, ++0x28a40008, ++0x8000015e, ++0x326400ff, ++0x28a40008, ++0x326400ff, ++0x0e68003c, ++0x9a80feb1, ++0x28ec0008, ++0x7c434000, ++0x7c438000, ++0x7c43c000, ++0x96c00007, ++0xcc000062, ++0xcf412169, ++0xcf81216a, ++0xcfc1216b, ++0x80000001, ++0xcc01216c, ++0x80000001, ++0xcff50000, ++0xcc00006b, ++0x840003a2, ++0x0e68003c, ++0x9a800004, ++0xc8280015, ++0x80000001, ++0xd040007f, ++0x9680ffab, ++0x7e024000, ++0x8400023b, ++0xc00e0002, ++0xcc000041, ++0x80000239, ++0xccc1304a, ++0x7c40c000, ++0x7c410000, ++0xc01e0001, ++0x29240012, ++0xc0220002, ++0x96400005, ++0xc0260004, ++0xc027fffb, ++0x7d25000b, ++0xc0260000, ++0x7dd2800b, ++0x7e12c00b, ++0x7d25000c, ++0x7c414000, ++0x7c418000, ++0xccc12169, ++0x9a80000a, ++0xcd01216a, ++0xcd41216b, ++0x96c0fe82, ++0xcd81216c, ++0xc8300018, ++0x97000000, ++0xc8300018, ++0x80000001, ++0xcc000018, ++0x840003a2, ++0xcc00007f, ++0xc8140013, ++0xc8180014, ++0xcd41216b, ++0x96c0fe76, ++0xcd81216c, ++0x80000182, ++0xc8300018, ++0xc80c0008, ++0x98c00000, ++0xc80c0008, ++0x7c410000, ++0x95000002, ++0x00000000, ++0x7c414000, ++0xc8200009, ++0xcc400043, ++0xce01a1f4, ++0xcc400044, ++0xc00e8000, ++0x7c424000, ++0x7c428000, ++0x2aac001f, ++0x96c0fe63, ++0xc035f000, ++0xce4003e2, ++0x32780003, ++0x267c0008, ++0x7ff7c00b, ++0x7ffbc00c, ++0x2a780018, ++0xcfc003e3, ++0xcf8003e4, ++0x26b00002, ++0x7f3f0000, ++0xcf0003e5, ++0x8000031f, ++0x7c80c000, ++0x7c40c000, ++0x28d00008, ++0x3110000f, ++0x9500000f, ++0x25280001, ++0x06a801b3, ++0x9e800000, ++0x00000000, ++0x800001d4, ++0xc0120800, ++0x800001e2, ++0xc814000f, ++0x800001e9, ++0xc8140010, ++0x800001f0, ++0xccc1a2a4, ++0x800001f9, ++0xc8140011, ++0x30d0003f, ++0x0d280015, ++0x9a800012, ++0x0d28001e, ++0x9a80001e, ++0x0d280020, ++0x9a800023, ++0x0d24000f, ++0x0d280010, ++0x7e6a800c, ++0x9a800026, ++0x0d200004, ++0x0d240014, ++0x0d280028, ++0x7e62400c, ++0x7ea6800c, ++0x9a80002a, ++0xc8140011, ++0x80000001, ++0xccc1a2a4, ++0xc0120800, ++0x7c414000, ++0x7d0cc00c, ++0xc0120008, ++0x29580003, ++0x295c000c, ++0x7c420000, ++0x7dd1c00b, ++0x26200014, ++0x7e1e400c, ++0x7e4e800c, ++0xce81a2a4, ++0x80000001, ++0xcd81a1fe, ++0xc814000f, ++0x0410210e, ++0x95400000, ++0xc814000f, ++0xd0510000, ++0x80000001, ++0xccc1a2a4, ++0xc8140010, ++0x04102108, ++0x95400000, ++0xc8140010, ++0xd0510000, ++0x80000001, ++0xccc1a2a4, ++0xccc1a2a4, ++0x04100001, ++0xcd000019, ++0x840003a2, ++0xcc00007f, ++0xc8100019, ++0x99000000, ++0xc8100019, ++0x80000002, ++0x7c408000, ++0x04102100, ++0x09540001, ++0x9540ffff, ++0xc8140011, ++0xd0510000, ++0x8000039f, ++0xccc1a2a4, ++0x7c40c000, ++0xcc40000d, ++0x94c0fdff, ++0xcc40000e, ++0x7c410000, ++0x95000005, ++0x08cc0001, ++0xc8140005, ++0x99400014, ++0x00000000, ++0x98c0fffb, ++0x7c410000, ++0x80000002, ++0x7d008000, ++0xc8140005, ++0x7c40c000, ++0x9940000c, ++0xc818000c, ++0x7c410000, ++0x9580fdee, ++0xc820000e, ++0xc81c000d, ++0x66200020, ++0x7e1e002c, ++0x25240002, ++0x7e624020, ++0x80000001, ++0xcce60000, ++0x7c410000, ++0xcc00006c, ++0xcc00006d, ++0xc818001f, ++0xc81c001e, ++0x65980020, ++0x7dd9c02c, ++0x7cd4c00c, ++0xccde0000, ++0x45dc0004, ++0xc8280017, ++0x9680000f, ++0xc00e0001, ++0x28680008, ++0x2aac0016, ++0x32a800ff, ++0x0eb00049, ++0x7f2f000b, ++0x97000006, ++0x00000000, ++0xc8140005, ++0x7c40c000, ++0x80000223, ++0x7c410000, ++0x80000226, ++0xd040007f, ++0x8400023b, ++0xcc000041, ++0xccc1304a, ++0x94000000, ++0xc83c001a, ++0x043c0005, ++0xcfc1a2a4, ++0xc0361f90, ++0xc0387fff, ++0x7c03c010, ++0x7f7b400c, ++0xcf41217c, ++0xcfc1217d, ++0xcc01217e, ++0xc03a0004, ++0x0434217f, ++0x7f7b400c, ++0xcc350000, ++0xc83c0004, ++0x2bfc001f, ++0x04380020, ++0x97c00005, ++0xcc000062, ++0x9b800000, ++0x0bb80001, ++0x80000247, ++0xcc000071, ++0xcc01a1f4, ++0x04380016, ++0xc0360002, ++0xcf81a2a4, ++0x88000000, ++0xcf412010, ++0x7c40c000, ++0x28d0001c, ++0x95000005, ++0x04d40001, ++0xcd400065, ++0x80000001, ++0xcd400068, ++0x09540002, ++0x80000001, ++0xcd400066, ++0x8400026c, ++0xc81803ea, ++0x7c40c000, ++0x9980fd9d, ++0xc8140016, ++0x08d00001, ++0x9940002b, ++0xcd000068, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x043c0005, ++0xcfc1a2a4, ++0xcc01a1f4, ++0x840003a2, ++0xcc000046, ++0x88000000, ++0xcc00007f, ++0x8400027e, ++0xc81803ea, ++0x7c40c000, ++0x9980fd8b, ++0xc8140016, ++0x08d00001, ++0x99400019, ++0xcd000068, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x043c0022, ++0xcfc1a2a4, ++0x840003a2, ++0xcc000047, ++0x88000000, ++0xcc00007f, ++0xc8100016, ++0x9900000d, ++0xcc400067, ++0x80000002, ++0x7c408000, ++0xc81803ea, ++0x9980fd77, ++0x7c40c000, ++0x94c00003, ++0xc8100016, ++0x99000004, ++0xccc00068, ++0x80000002, ++0x7c408000, ++0x8400023b, ++0xc0148000, ++0xcc000041, ++0xcd41304a, ++0xc0148000, ++0x99000000, ++0xc8100016, ++0x80000002, ++0x7c408000, ++0xc0120001, ++0x7c51400c, ++0x80000001, ++0xd0550000, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0x291c001f, ++0xccc0004a, ++0xcd00004b, ++0x95c00003, ++0xc01c8000, ++0xcdc12010, ++0xdd830000, ++0x055c2000, ++0xcc000062, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc0004c, ++0xcd00004d, ++0xdd830000, ++0x055ca000, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc0004e, ++0xcd00004f, ++0xdd830000, ++0x055cc000, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00050, ++0xcd000051, ++0xdd830000, ++0x055cf8e0, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00052, ++0xcd000053, ++0xdd830000, ++0x055cf880, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00054, ++0xcd000055, ++0xdd830000, ++0x055ce000, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00056, ++0xcd000057, ++0xdd830000, ++0x055cf000, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00058, ++0xcd000059, ++0xdd830000, ++0x055cf3fc, ++0x80000001, ++0xd81f4100, ++0xd0432000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043a000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043c000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f8e0, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f880, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043e000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f3fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xc81403e0, ++0xcc430000, ++0xcc430000, ++0xcc430000, ++0x7d45c000, ++0xcdc30000, ++0xd0430000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x7c40c000, ++0xc81003e2, ++0xc81403e5, ++0xc81803e3, ++0xc81c03e4, ++0xcd812169, ++0xcdc1216a, ++0xccc1216b, ++0xcc01216c, ++0x04200004, ++0x7da18000, ++0x7d964002, ++0x9640fcd7, ++0xcd8003e3, ++0x31280003, ++0xc02df000, ++0x25180008, ++0x7dad800b, ++0x7da9800c, ++0x80000001, ++0xcd8003e3, ++0x308cffff, ++0xd04d0000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x7c40c000, ++0x7c410000, ++0x29240018, ++0x32640001, ++0x9a400013, ++0xc8140020, ++0x15580002, ++0x9580ffff, ++0xc8140020, ++0xcc00006e, ++0xccc12180, ++0xcd01218d, ++0xcc412181, ++0x2914001f, ++0x34588000, ++0xcd81218c, ++0x9540fcb9, ++0xcc412182, ++0xc8140020, ++0x9940ffff, ++0xc8140020, ++0x80000002, ++0x7c408000, ++0x7c414000, ++0x7c418000, ++0x7c41c000, ++0x65b40020, ++0x7f57402c, ++0xd4378100, ++0x47740004, ++0xd4378100, ++0x47740004, ++0xd4378100, ++0x47740004, ++0x09dc0004, ++0xd4378100, ++0x99c0fff8, ++0x47740004, ++0x2924001f, ++0xc0380019, ++0x9640fca1, ++0xc03e0004, ++0xcf8121f8, ++0x37e021f9, ++0xcc210000, ++0xc8200004, ++0x2a200018, ++0x32200001, ++0x9a00fffb, ++0xcf8121f8, ++0x80000002, ++0x7c408000, ++0x7c40c000, ++0x28d00018, ++0x31100001, ++0xc0160080, ++0x95000003, ++0xc02a0004, ++0x7cd4c00c, ++0xccc1217c, ++0xcc41217d, ++0xcc41217e, ++0x7c418000, ++0x1db00003, ++0x36a0217f, ++0x9b000003, ++0x419c0005, ++0x041c0040, ++0x99c00000, ++0x09dc0001, ++0xcc210000, ++0xc8240004, ++0x2a6c001f, ++0x419c0005, ++0x9ac0fffa, ++0xcc800062, ++0x80000002, ++0x7c408000, ++0x7c40c000, ++0x04d403e6, ++0x80000001, ++0xcc540000, ++0x8000039f, ++0xcc4003ea, ++0xc01c8000, ++0x044ca000, ++0xcdc12010, ++0x7c410000, ++0xc8140009, ++0x04180000, ++0x041c0008, ++0xcd800071, ++0x09dc0001, ++0x05980001, ++0xcd0d0000, ++0x99c0fffc, ++0xcc800062, ++0x8000039f, ++0xcd400071, ++0xc00e0100, ++0xcc000041, ++0xccc1304a, ++0xc83c007f, ++0xcc00007f, ++0x80000001, ++0xcc00007f, ++0xcc00007f, ++0x88000000, ++0xcc00007f, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00010333, ++0x00100004, ++0x00170006, ++0x00210008, ++0x00270028, ++0x00280023, ++0x00290029, ++0x002a0026, ++0x002b0029, ++0x002d0038, ++0x002e003f, ++0x002f004a, ++0x0034004c, ++0x00360030, ++0x003900af, ++0x003a00d0, ++0x003b00e5, ++0x003c00fd, ++0x003d016c, ++0x003f00ad, ++0x00410338, ++0x0043036c, ++0x0044018f, ++0x004500fd, ++0x004601ad, ++0x004701ad, ++0x00480200, ++0x0049020e, ++0x004a0257, ++0x004b0284, ++0x00520261, ++0x00530273, ++0x00540289, ++0x0057029b, ++0x0060029f, ++0x006102ae, ++0x006202b8, ++0x006302c2, ++0x006402cc, ++0x006502d6, ++0x006602e0, ++0x006702ea, ++0x006802f4, ++0x006902f8, ++0x006a02fc, ++0x006b0300, ++0x006c0304, ++0x006d0308, ++0x006e030c, ++0x006f0310, ++0x00700314, ++0x00720386, ++0x0074038c, ++0x0079038a, ++0x007c031e, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++0x000f039b, ++}; ++ ++static const u32 RV770_pfp_microcode[] = { ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0x80000000, ++0xdc030000, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xc818000e, ++0x31980001, ++0x7c424000, ++0x95800252, ++0x7c428000, ++0xc81c001c, ++0xc037c000, ++0x7c40c000, ++0x7c410000, ++0x7cb4800b, ++0xc0360003, ++0x99c00000, ++0xc81c001c, ++0x7cb4800c, ++0x24d40002, ++0x7d654000, ++0xcd400043, ++0xce800043, ++0xcd000043, ++0xcc800040, ++0xce400040, ++0xce800040, ++0xccc00040, ++0xdc3a0000, ++0x9780ffde, ++0xcd000040, ++0x7c40c000, ++0x80000018, ++0x7c410000, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xc818000e, ++0x8000000c, ++0x31980002, ++0xd40003c0, ++0xd4000fc0, ++0xd4000fa2, ++0xc818000e, ++0x288c0008, ++0x30cc000f, ++0x34100001, ++0x7d0d0008, ++0x8000000c, ++0x7d91800b, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xd40003c0, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xcc4003f9, ++0x80000261, ++0xcc4003f8, ++0xc82003f8, ++0xc81c03f9, ++0xc81803fb, ++0xc037ffff, ++0x7c414000, ++0xcf41a29e, ++0x66200020, ++0x7de1c02c, ++0x7d58c008, ++0x7cdcc020, ++0x68d00020, ++0xc0360003, ++0xcc000054, ++0x7cb4800c, ++0x8000006a, ++0xcc800040, ++0x7c418000, ++0xcd81a29e, ++0xcc800040, ++0xcd800040, ++0x80000068, ++0xcc000054, ++0xc019ffff, ++0xcc800040, ++0xcd81a29e, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0xccc1a1fa, ++0xcd01a1f9, ++0xcd41a29d, ++0xccc00040, ++0xcd000040, ++0xcd400040, ++0xcc400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xcc000054, ++0xcc800040, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0xccc1a1fa, ++0xcd01a1f9, ++0xcd41a29d, ++0xccc00040, ++0xcd000040, ++0xcd400040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0x7c40c000, ++0x30d00001, ++0xccc1a29f, ++0x95000003, ++0x04140001, ++0x04140002, ++0xcd4003fb, ++0xcc800040, ++0x80000000, ++0xccc00040, ++0x7c40c000, ++0xcc800040, ++0xccc1a2a2, ++0x80000000, ++0xccc00040, ++0x7c40c000, ++0x28d4001f, ++0xcc800040, ++0x95400003, ++0x7c410000, ++0xccc00057, ++0x2918001f, ++0xccc00040, ++0x95800003, ++0xcd000040, ++0xcd000058, ++0x80000261, ++0xcc00007f, ++0xc8200017, ++0xc8300022, ++0x9a000006, ++0x0e280001, ++0xc824001e, ++0x0a640001, ++0xd4001240, ++0xce400040, ++0xc036c000, ++0x96800007, ++0x37747900, ++0x041c0001, ++0xcf400040, ++0xcdc00040, ++0xcf0003fa, ++0x7c030000, ++0xca0c0010, ++0x7c410000, ++0x94c00004, ++0x7c414000, ++0xd42002c4, ++0xcde00044, ++0x9b00000b, ++0x7c418000, ++0xcc00004b, ++0xcda00049, ++0xcd200041, ++0xcd600041, ++0xcda00041, ++0x06200001, ++0xce000056, ++0x80000261, ++0xcc00007f, ++0xc8280020, ++0xc82c0021, ++0xcc000063, ++0x7eea4001, ++0x65740020, ++0x7f53402c, ++0x269c0002, ++0x7df5c020, ++0x69f80020, ++0xce80004b, ++0xce600049, ++0xcde00041, ++0xcfa00041, ++0xce600041, ++0x271c0002, ++0x7df5c020, ++0x69f80020, ++0x7db24001, ++0xcf00004b, ++0xce600049, ++0xcde00041, ++0xcfa00041, ++0x800000bd, ++0xce600041, ++0xc8200017, ++0xc8300022, ++0x9a000006, ++0x0e280001, ++0xc824001e, ++0x0a640001, ++0xd4001240, ++0xce400040, ++0xca0c0010, ++0x7c410000, ++0x94c0000b, ++0xc036c000, ++0x96800007, ++0x37747900, ++0x041c0001, ++0xcf400040, ++0xcdc00040, ++0xcf0003fa, ++0x7c030000, ++0x800000b6, ++0x7c414000, ++0xcc000048, ++0x800000ef, ++0x00000000, ++0xc8200017, ++0xc81c0023, ++0x0e240002, ++0x99c00015, ++0x7c418000, ++0x0a200001, ++0xce000056, ++0xd4000440, ++0xcc000040, ++0xc036c000, ++0xca140013, ++0x96400007, ++0x37747900, ++0xcf400040, ++0xcc000040, ++0xc83003fa, ++0x80000104, ++0xcf000022, ++0xcc000022, ++0x9540015d, ++0xcc00007f, ++0xcca00046, ++0x80000000, ++0xcc200046, ++0x80000261, ++0xcc000064, ++0xc8200017, ++0xc810001f, ++0x96000005, ++0x09100001, ++0xd4000440, ++0xcd000040, ++0xcd000022, ++0xcc800040, ++0xd0400040, ++0xc80c0025, ++0x94c0feeb, ++0xc8100008, ++0xcd000040, ++0xd4000fc0, ++0x80000000, ++0xd4000fa2, ++0x7c40c000, ++0x7c410000, ++0xccc003fd, ++0xcd0003fc, ++0xccc00042, ++0xcd000042, ++0x2914001f, ++0x29180010, ++0x31980007, ++0x3b5c0001, ++0x7d76000b, ++0x99800005, ++0x7d5e400b, ++0xcc000042, ++0x80000261, ++0xcc00004d, ++0x29980001, ++0x292c0008, ++0x9980003d, ++0x32ec0001, ++0x96000004, ++0x2930000c, ++0x80000261, ++0xcc000042, ++0x04140010, ++0xcd400042, ++0x33300001, ++0x34280001, ++0x8400015e, ++0xc8140003, ++0x9b40001b, ++0x0438000c, ++0x8400015e, ++0xc8140003, ++0x9b400017, ++0x04380008, ++0x8400015e, ++0xc8140003, ++0x9b400013, ++0x04380004, ++0x8400015e, ++0xc8140003, ++0x9b400015, ++0xc80c03fd, ++0x9a800009, ++0xc81003fc, ++0x9b000118, ++0xcc00004d, ++0x04140010, ++0xccc00042, ++0xcd000042, ++0x80000136, ++0xcd400042, ++0x96c00111, ++0xcc00004d, ++0x80000261, ++0xcc00004e, ++0x9ac00003, ++0xcc00004d, ++0xcc00004e, ++0xdf830000, ++0x80000000, ++0xd80301ff, ++0x9ac00107, ++0xcc00004d, ++0x80000261, ++0xcc00004e, ++0xc8180003, ++0xc81c0003, ++0xc8200003, ++0x7d5d4003, ++0x7da1c003, ++0x7d5d400c, ++0x2a10001f, ++0x299c001f, ++0x7d1d000b, ++0x7d17400b, ++0x88000000, ++0x7e92800b, ++0x96400004, ++0xcc00004e, ++0x80000261, ++0xcc000042, ++0x04380008, ++0xcf800042, ++0xc8080003, ++0xc80c0003, ++0xc8100003, ++0xc8140003, ++0xc8180003, ++0xc81c0003, ++0xc8240003, ++0xc8280003, ++0x29fc001f, ++0x2ab0001f, ++0x7ff3c00b, ++0x28f0001f, ++0x7ff3c00b, ++0x2970001f, ++0x7ff3c00b, ++0x7d888001, ++0x7dccc001, ++0x7e510001, ++0x7e954001, ++0x7c908002, ++0x7cd4c002, ++0x7cbc800b, ++0x9ac00003, ++0x7c8f400b, ++0x38b40001, ++0x9b4000d8, ++0xcc00004d, ++0x9bc000d6, ++0xcc00004e, ++0xc80c03fd, ++0xc81003fc, ++0xccc00042, ++0x8000016f, ++0xcd000042, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xcc400040, ++0xcc400040, ++0xcc400040, ++0x7c40c000, ++0xccc00040, ++0xccc0000d, ++0x80000000, ++0xd0400040, ++0x7c40c000, ++0x7c410000, ++0x65140020, ++0x7d4d402c, ++0x24580002, ++0x7d598020, ++0x7c41c000, ++0xcd800042, ++0x69980020, ++0xcd800042, ++0xcdc00042, ++0xc023c000, ++0x05e40002, ++0x7ca0800b, ++0x26640010, ++0x7ca4800c, ++0xcc800040, ++0xcdc00040, ++0xccc00040, ++0x95c0000e, ++0xcd000040, ++0x09dc0001, ++0xc8280003, ++0x96800008, ++0xce800040, ++0xc834001d, ++0x97400000, ++0xc834001d, ++0x26a80008, ++0x84000264, ++0xcc2b0000, ++0x99c0fff7, ++0x09dc0001, ++0xdc3a0000, ++0x97800004, ++0x7c418000, ++0x800001a3, ++0x25980002, ++0xa0000000, ++0x7d808000, ++0xc818001d, ++0x7c40c000, ++0x64d00008, ++0x95800000, ++0xc818001d, ++0xcc130000, ++0xcc800040, ++0xccc00040, ++0x80000000, ++0xcc400040, ++0xc810001f, ++0x7c40c000, ++0xcc800040, ++0x7cd1400c, ++0xcd400040, ++0x05180001, ++0x80000000, ++0xcd800022, ++0x7c40c000, ++0x64500020, ++0x84000264, ++0xcc000061, ++0x7cd0c02c, ++0xc8200017, ++0xc8d60000, ++0x99400008, ++0x7c438000, ++0xdf830000, ++0xcfa0004f, ++0x84000264, ++0xcc000062, ++0x80000000, ++0xd040007f, ++0x80000261, ++0xcc000062, ++0x84000264, ++0xcc000061, ++0xc8200017, ++0x7c40c000, ++0xc036ff00, ++0xc810000d, ++0xc0303fff, ++0x7cf5400b, ++0x7d51800b, ++0x7d81800f, ++0x99800008, ++0x7cf3800b, ++0xdf830000, ++0xcfa0004f, ++0x84000264, ++0xcc000062, ++0x80000000, ++0xd040007f, ++0x80000261, ++0xcc000062, ++0x84000264, ++0x7c40c000, ++0x28dc0008, ++0x95c00019, ++0x30dc0010, ++0x7c410000, ++0x99c00004, ++0x64540020, ++0x80000209, ++0xc91d0000, ++0x7d15002c, ++0xc91e0000, ++0x7c420000, ++0x7c424000, ++0x7c418000, ++0x7de5c00b, ++0x7de28007, ++0x9a80000e, ++0x41ac0005, ++0x9ac00000, ++0x0aec0001, ++0x30dc0010, ++0x99c00004, ++0x00000000, ++0x8000020c, ++0xc91d0000, ++0x8000020c, ++0xc91e0000, ++0xcc800040, ++0xccc00040, ++0xd0400040, ++0xc80c0025, ++0x94c0fde3, ++0xc8100008, ++0xcd000040, ++0xd4000fc0, ++0x80000000, ++0xd4000fa2, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xd40003c0, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0x7c40c000, ++0x30d00006, ++0x0d100006, ++0x99000007, ++0xc8140015, ++0x99400005, ++0xcc000052, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xccc00040, ++0x80000000, ++0xd0400040, ++0x7c40c000, ++0xcc4d0000, ++0xdc3a0000, ++0x9780fdbc, ++0x04cc0001, ++0x80000243, ++0xcc4d0000, ++0x7c40c000, ++0x7c410000, ++0x29240018, ++0x32640001, ++0x9640000f, ++0xcc800040, ++0x7c414000, ++0x7c418000, ++0x7c41c000, ++0xccc00043, ++0xcd000043, ++0x31dc7fff, ++0xcdc00043, ++0xccc00040, ++0xcd000040, ++0xcd400040, ++0xcd800040, ++0x80000000, ++0xcdc00040, ++0xccc00040, ++0xcd000040, ++0x80000000, ++0xd0400040, ++0x80000000, ++0xd040007f, ++0xcc00007f, ++0x80000000, ++0xcc00007f, ++0xcc00007f, ++0x88000000, ++0xcc00007f, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00030223, ++0x0004022b, ++0x000500a0, ++0x00020003, ++0x0006003c, ++0x00070027, ++0x00080192, ++0x00090044, ++0x000a002d, ++0x0010025f, ++0x001700f1, ++0x002201d8, ++0x002301e9, ++0x0026004c, ++0x0027005f, ++0x0020011b, ++0x00280093, ++0x0029004f, ++0x002a0084, ++0x002b0065, ++0x002f008e, ++0x003200d9, ++0x00340233, ++0x00360075, ++0x0039010b, ++0x003c01fd, ++0x003f00a0, ++0x00410248, ++0x00440195, ++0x0048019e, ++0x004901c6, ++0x004a01d0, ++0x00550226, ++0x0056022e, ++0x0060000a, ++0x0061002a, ++0x00620030, ++0x00630030, ++0x00640030, ++0x00650030, ++0x00660030, ++0x00670030, ++0x00680037, ++0x0069003f, ++0x006a0047, ++0x006b0047, ++0x006c0047, ++0x006d0047, ++0x006e0047, ++0x006f0047, ++0x00700047, ++0x0073025f, ++0x007b0241, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++}; ++ ++static const u32 RV730_pfp_microcode[] = { ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0x80000000, ++0xdc030000, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xc818000e, ++0x31980001, ++0x7c424000, ++0x9580023a, ++0x7c428000, ++0xc81c001c, ++0xc037c000, ++0x7c40c000, ++0x7c410000, ++0x7cb4800b, ++0xc0360003, ++0x99c00000, ++0xc81c001c, ++0x7cb4800c, ++0x24d40002, ++0x7d654000, ++0xcd400043, ++0xce800043, ++0xcd000043, ++0xcc800040, ++0xce400040, ++0xce800040, ++0xccc00040, ++0xdc3a0000, ++0x9780ffde, ++0xcd000040, ++0x7c40c000, ++0x80000018, ++0x7c410000, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xc818000e, ++0x8000000c, ++0x31980002, ++0xd40003c0, ++0xd4000fc0, ++0xd4000fa2, ++0xc818000e, ++0x288c0008, ++0x30cc000f, ++0x34100001, ++0x7d0d0008, ++0x8000000c, ++0x7d91800b, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xd40003c0, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xcc4003f9, ++0x80000249, ++0xcc4003f8, ++0xc037ffff, ++0x7c414000, ++0xcf41a29e, ++0xc82003f8, ++0xc81c03f9, ++0x66200020, ++0xc81803fb, ++0x7de1c02c, ++0x7d58c008, ++0x7cdcc020, ++0x69100020, ++0xc0360003, ++0xcc000054, ++0x7cb4800c, ++0x80000069, ++0xcc800040, ++0x7c418000, ++0xcd81a29e, ++0xcc800040, ++0x80000067, ++0xcd800040, ++0xc019ffff, ++0xcc800040, ++0xcd81a29e, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0xccc1a1fa, ++0xcd01a1f9, ++0xcd41a29d, ++0xccc00040, ++0xcd000040, ++0xcd400040, ++0xcc400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xcc000054, ++0xcc800040, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0xccc1a1fa, ++0xcd01a1f9, ++0xcd41a29d, ++0xccc00040, ++0xcd000040, ++0xcd400040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0x7c40c000, ++0x30d00001, ++0xccc1a29f, ++0x95000003, ++0x04140001, ++0x04140002, ++0xcd4003fb, ++0xcc800040, ++0x80000000, ++0xccc00040, ++0x7c40c000, ++0xcc800040, ++0xccc1a2a2, ++0x80000000, ++0xccc00040, ++0x7c40c000, ++0x28d4001f, ++0xcc800040, ++0x95400003, ++0x7c410000, ++0xccc00057, ++0x2918001f, ++0xccc00040, ++0x95800003, ++0xcd000040, ++0xcd000058, ++0x80000249, ++0xcc00007f, ++0xc8200017, ++0xc8300022, ++0x9a000006, ++0x0e280001, ++0xc824001e, ++0x0a640001, ++0xd4001240, ++0xce400040, ++0xc036c000, ++0x96800007, ++0x37747900, ++0x041c0001, ++0xcf400040, ++0xcdc00040, ++0xcf0003fa, ++0x7c030000, ++0xca0c0010, ++0x7c410000, ++0x94c00004, ++0x7c414000, ++0xd42002c4, ++0xcde00044, ++0x9b00000b, ++0x7c418000, ++0xcc00004b, ++0xcda00049, ++0xcd200041, ++0xcd600041, ++0xcda00041, ++0x06200001, ++0xce000056, ++0x80000249, ++0xcc00007f, ++0xc8280020, ++0xc82c0021, ++0xcc000063, ++0x7eea4001, ++0x65740020, ++0x7f53402c, ++0x269c0002, ++0x7df5c020, ++0x69f80020, ++0xce80004b, ++0xce600049, ++0xcde00041, ++0xcfa00041, ++0xce600041, ++0x271c0002, ++0x7df5c020, ++0x69f80020, ++0x7db24001, ++0xcf00004b, ++0xce600049, ++0xcde00041, ++0xcfa00041, ++0x800000bc, ++0xce600041, ++0xc8200017, ++0xc8300022, ++0x9a000006, ++0x0e280001, ++0xc824001e, ++0x0a640001, ++0xd4001240, ++0xce400040, ++0xca0c0010, ++0x7c410000, ++0x94c0000b, ++0xc036c000, ++0x96800007, ++0x37747900, ++0x041c0001, ++0xcf400040, ++0xcdc00040, ++0xcf0003fa, ++0x7c030000, ++0x800000b5, ++0x7c414000, ++0xcc000048, ++0x800000ee, ++0x00000000, ++0xc8200017, ++0xc81c0023, ++0x0e240002, ++0x99c00015, ++0x7c418000, ++0x0a200001, ++0xce000056, ++0xd4000440, ++0xcc000040, ++0xc036c000, ++0xca140013, ++0x96400007, ++0x37747900, ++0xcf400040, ++0xcc000040, ++0xc83003fa, ++0x80000103, ++0xcf000022, ++0xcc000022, ++0x95400146, ++0xcc00007f, ++0xcca00046, ++0x80000000, ++0xcc200046, ++0x80000249, ++0xcc000064, ++0xc8200017, ++0xc810001f, ++0x96000005, ++0x09100001, ++0xd4000440, ++0xcd000040, ++0xcd000022, ++0xcc800040, ++0xd0400040, ++0xc80c0025, ++0x94c0feec, ++0xc8100008, ++0xcd000040, ++0xd4000fc0, ++0x80000000, ++0xd4000fa2, ++0x7c40c000, ++0x7c410000, ++0xccc003fd, ++0xcd0003fc, ++0xccc00042, ++0xcd000042, ++0x2914001f, ++0x29180010, ++0x31980007, ++0x3b5c0001, ++0x7d76000b, ++0x99800005, ++0x7d5e400b, ++0xcc000042, ++0x80000249, ++0xcc00004d, ++0x29980001, ++0x292c0008, ++0x9980003d, ++0x32ec0001, ++0x96000004, ++0x2930000c, ++0x80000249, ++0xcc000042, ++0x04140010, ++0xcd400042, ++0x33300001, ++0x34280001, ++0x8400015d, ++0xc8140003, ++0x9b40001b, ++0x0438000c, ++0x8400015d, ++0xc8140003, ++0x9b400017, ++0x04380008, ++0x8400015d, ++0xc8140003, ++0x9b400013, ++0x04380004, ++0x8400015d, ++0xc8140003, ++0x9b400015, ++0xc80c03fd, ++0x9a800009, ++0xc81003fc, ++0x9b000101, ++0xcc00004d, ++0x04140010, ++0xccc00042, ++0xcd000042, ++0x80000135, ++0xcd400042, ++0x96c000fa, ++0xcc00004d, ++0x80000249, ++0xcc00004e, ++0x9ac00003, ++0xcc00004d, ++0xcc00004e, ++0xdf830000, ++0x80000000, ++0xd80301ff, ++0x9ac000f0, ++0xcc00004d, ++0x80000249, ++0xcc00004e, ++0xc8180003, ++0xc81c0003, ++0xc8200003, ++0x7d5d4003, ++0x7da1c003, ++0x7d5d400c, ++0x2a10001f, ++0x299c001f, ++0x7d1d000b, ++0x7d17400b, ++0x88000000, ++0x7e92800b, ++0x96400004, ++0xcc00004e, ++0x80000249, ++0xcc000042, ++0x04380008, ++0xcf800042, ++0xc8080003, ++0xc80c0003, ++0xc8100003, ++0xc8140003, ++0xc8180003, ++0xc81c0003, ++0xc8240003, ++0xc8280003, ++0x29fc001f, ++0x2ab0001f, ++0x7ff3c00b, ++0x28f0001f, ++0x7ff3c00b, ++0x2970001f, ++0x7ff3c00b, ++0x7d888001, ++0x7dccc001, ++0x7e510001, ++0x7e954001, ++0x7c908002, ++0x7cd4c002, ++0x7cbc800b, ++0x9ac00003, ++0x7c8f400b, ++0x38b40001, ++0x9b4000c1, ++0xcc00004d, ++0x9bc000bf, ++0xcc00004e, ++0xc80c03fd, ++0xc81003fc, ++0xccc00042, ++0x8000016e, ++0xcd000042, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xcc400040, ++0xcc400040, ++0xcc400040, ++0x7c40c000, ++0xccc00040, ++0xccc0000d, ++0x80000000, ++0xd0400040, ++0x7c40c000, ++0x7c410000, ++0x65140020, ++0x7d4d402c, ++0x24580002, ++0x7d598020, ++0x7c41c000, ++0xcd800042, ++0x69980020, ++0xcd800042, ++0xcdc00042, ++0xc023c000, ++0x05e40002, ++0x7ca0800b, ++0x26640010, ++0x7ca4800c, ++0xcc800040, ++0xcdc00040, ++0xccc00040, ++0x95c0000e, ++0xcd000040, ++0x09dc0001, ++0xc8280003, ++0x96800008, ++0xce800040, ++0xc834001d, ++0x97400000, ++0xc834001d, ++0x26a80008, ++0x8400024c, ++0xcc2b0000, ++0x99c0fff7, ++0x09dc0001, ++0xdc3a0000, ++0x97800004, ++0x7c418000, ++0x800001a2, ++0x25980002, ++0xa0000000, ++0x7d808000, ++0xc818001d, ++0x7c40c000, ++0x64d00008, ++0x95800000, ++0xc818001d, ++0xcc130000, ++0xcc800040, ++0xccc00040, ++0x80000000, ++0xcc400040, ++0xc810001f, ++0x7c40c000, ++0xcc800040, ++0x7cd1400c, ++0xcd400040, ++0x05180001, ++0x80000000, ++0xcd800022, ++0x7c40c000, ++0x64500020, ++0x8400024c, ++0xcc000061, ++0x7cd0c02c, ++0xc8200017, ++0xc8d60000, ++0x99400008, ++0x7c438000, ++0xdf830000, ++0xcfa0004f, ++0x8400024c, ++0xcc000062, ++0x80000000, ++0xd040007f, ++0x80000249, ++0xcc000062, ++0x8400024c, ++0xcc000061, ++0xc8200017, ++0x7c40c000, ++0xc036ff00, ++0xc810000d, ++0xc0303fff, ++0x7cf5400b, ++0x7d51800b, ++0x7d81800f, ++0x99800008, ++0x7cf3800b, ++0xdf830000, ++0xcfa0004f, ++0x8400024c, ++0xcc000062, ++0x80000000, ++0xd040007f, ++0x80000249, ++0xcc000062, ++0x8400024c, ++0x7c40c000, ++0x28dc0008, ++0x95c00019, ++0x30dc0010, ++0x7c410000, ++0x99c00004, ++0x64540020, ++0x80000208, ++0xc91d0000, ++0x7d15002c, ++0xc91e0000, ++0x7c420000, ++0x7c424000, ++0x7c418000, ++0x7de5c00b, ++0x7de28007, ++0x9a80000e, ++0x41ac0005, ++0x9ac00000, ++0x0aec0001, ++0x30dc0010, ++0x99c00004, ++0x00000000, ++0x8000020b, ++0xc91d0000, ++0x8000020b, ++0xc91e0000, ++0xcc800040, ++0xccc00040, ++0xd0400040, ++0xc80c0025, ++0x94c0fde4, ++0xc8100008, ++0xcd000040, ++0xd4000fc0, ++0x80000000, ++0xd4000fa2, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xd40003c0, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0x7c40c000, ++0x30d00006, ++0x0d100006, ++0x99000007, ++0xc8140015, ++0x99400005, ++0xcc000052, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xccc00040, ++0x80000000, ++0xd0400040, ++0x7c40c000, ++0xcc4d0000, ++0xdc3a0000, ++0x9780fdbd, ++0x04cc0001, ++0x80000242, ++0xcc4d0000, ++0x80000000, ++0xd040007f, ++0xcc00007f, ++0x80000000, ++0xcc00007f, ++0xcc00007f, ++0x88000000, ++0xcc00007f, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00030222, ++0x0004022a, ++0x0005009f, ++0x00020003, ++0x0006003c, ++0x00070027, ++0x00080191, ++0x00090044, ++0x000a002d, ++0x00100247, ++0x001700f0, ++0x002201d7, ++0x002301e8, ++0x0026004c, ++0x0027005f, ++0x0020011a, ++0x00280092, ++0x0029004f, ++0x002a0083, ++0x002b0064, ++0x002f008d, ++0x003200d8, ++0x00340232, ++0x00360074, ++0x0039010a, ++0x003c01fc, ++0x003f009f, ++0x00410005, ++0x00440194, ++0x0048019d, ++0x004901c5, ++0x004a01cf, ++0x00550225, ++0x0056022d, ++0x0060000a, ++0x0061002a, ++0x00620030, ++0x00630030, ++0x00640030, ++0x00650030, ++0x00660030, ++0x00670030, ++0x00680037, ++0x0069003f, ++0x006a0047, ++0x006b0047, ++0x006c0047, ++0x006d0047, ++0x006e0047, ++0x006f0047, ++0x00700047, ++0x00730247, ++0x007b0240, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++}; ++ ++static const u32 RV730_cp_microcode[] = { ++0xcc0003ea, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x80000001, ++0xd040007f, ++0x80000001, ++0xcc400041, ++0x7c40c000, ++0xc0160004, ++0x30d03fff, ++0x7d15000c, ++0xcc110000, ++0x28d8001e, ++0x31980001, ++0x28dc001f, ++0xc8200004, ++0x95c00006, ++0x7c424000, ++0xcc000062, ++0x7e56800c, ++0xcc290000, ++0xc8240004, ++0x7e26000b, ++0x95800006, ++0x7c42c000, ++0xcc000062, ++0x7ed7000c, ++0xcc310000, ++0xc82c0004, ++0x7e2e000c, ++0xcc000062, ++0x31103fff, ++0x80000001, ++0xce110000, ++0x7c40c000, ++0x80000001, ++0xcc400040, ++0x80000001, ++0xcc412257, ++0x7c418000, ++0xcc400045, ++0xcc400048, ++0xcc41225c, ++0xcc41a1fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xcc400045, ++0xcc400048, ++0x7c40c000, ++0xcc41225c, ++0xcc41a1fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xcc000045, ++0xcc000048, ++0xcc41225c, ++0xcc41a1fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x040ca1fd, ++0xc0120001, ++0xcc000045, ++0xcc000048, ++0x7cd0c00c, ++0xcc41225c, ++0xcc41a1fc, ++0xd04d0000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x80000001, ++0xcc41225d, ++0x7c408000, ++0x7c40c000, ++0xc02a0002, ++0x7c410000, ++0x7d29000c, ++0x30940001, ++0x30980006, ++0x309c0300, ++0x29dc0008, ++0x7c420000, ++0x7c424000, ++0x9540000f, ++0xc02e0004, ++0x05f02258, ++0x7f2f000c, ++0xcc310000, ++0xc8280004, ++0xccc12169, ++0xcd01216a, ++0xce81216b, ++0x0db40002, ++0xcc01216c, ++0x9740000e, ++0x0db40000, ++0x8000007b, ++0xc834000a, ++0x0db40002, ++0x97400009, ++0x0db40000, ++0xc02e0004, ++0x05f02258, ++0x7f2f000c, ++0xcc310000, ++0xc8280004, ++0x8000007b, ++0xc834000a, ++0x97400004, ++0x7e028000, ++0x8000007b, ++0xc834000a, ++0x0db40004, ++0x9740ff8c, ++0x00000000, ++0xce01216d, ++0xce41216e, ++0xc8280003, ++0xc834000a, ++0x9b400004, ++0x043c0005, ++0x8400026b, ++0xcc000062, ++0x0df40000, ++0x9740000b, ++0xc82c03e6, ++0xce81a2b7, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c4, ++0x80000001, ++0xcfc1a2d1, ++0x0df40001, ++0x9740000b, ++0xc82c03e7, ++0xce81a2bb, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c5, ++0x80000001, ++0xcfc1a2d2, ++0x0df40002, ++0x9740000b, ++0xc82c03e8, ++0xce81a2bf, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c6, ++0x80000001, ++0xcfc1a2d3, ++0xc82c03e9, ++0xce81a2c3, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c7, ++0x80000001, ++0xcfc1a2d4, ++0x80000001, ++0xcc400042, ++0x7c40c000, ++0x7c410000, ++0x2914001d, ++0x31540001, ++0x9940000c, ++0x31181000, ++0xc81c0011, ++0x95c00000, ++0xc81c0011, ++0xccc12100, ++0xcd012101, ++0xccc12102, ++0xcd012103, ++0x04180004, ++0x8000037c, ++0xcd81a2a4, ++0xc02a0004, ++0x95800008, ++0x36a821a3, ++0xcc290000, ++0xc8280004, ++0xc81c0011, ++0x0de40040, ++0x9640ffff, ++0xc81c0011, ++0xccc12170, ++0xcd012171, ++0xc8200012, ++0x96000000, ++0xc8200012, ++0x8000037c, ++0xcc000064, ++0x7c40c000, ++0x7c410000, ++0xcc000045, ++0xcc000048, ++0x40d40003, ++0xcd41225c, ++0xcd01a1fc, ++0xc01a0001, ++0x041ca1fd, ++0x7dd9c00c, ++0x7c420000, ++0x08cc0001, ++0x06240001, ++0x06280002, ++0xce1d0000, ++0xce5d0000, ++0x98c0fffa, ++0xce9d0000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x7c40c000, ++0x30d00001, ++0x28cc0001, ++0x7c414000, ++0x95000006, ++0x7c418000, ++0xcd41216d, ++0xcd81216e, ++0x800000f2, ++0xc81c0003, ++0xc0220004, ++0x7e16000c, ++0xcc210000, ++0xc81c0004, ++0x7c424000, ++0x98c00004, ++0x7c428000, ++0x80000001, ++0xcde50000, ++0xce412169, ++0xce81216a, ++0xcdc1216b, ++0x80000001, ++0xcc01216c, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0x7c41c000, ++0x28a40008, ++0x326400ff, ++0x0e68003c, ++0x9680000a, ++0x7c020000, ++0x7c420000, ++0x1e300003, ++0xcc00006a, ++0x9b000003, ++0x42200005, ++0x04200040, ++0x8000010f, ++0x7c024000, ++0x7e024000, ++0x9a400000, ++0x0a640001, ++0x30ec0010, ++0x9ac0000a, ++0xcc000062, ++0xc02a0004, ++0xc82c0021, ++0x7e92800c, ++0xcc000041, ++0xcc290000, ++0xcec00021, ++0x8000011f, ++0xc8300004, ++0xcd01216d, ++0xcd41216e, ++0xc8300003, ++0x7f1f000b, ++0x30f40007, ++0x27780001, ++0x9740002a, ++0x07b80124, ++0x9f800000, ++0x00000000, ++0x80000134, ++0x7f1b8004, ++0x80000138, ++0x7f1b8005, ++0x8000013c, ++0x7f1b8002, ++0x80000140, ++0x7f1b8003, ++0x80000144, ++0x7f1b8007, ++0x80000148, ++0x7f1b8006, ++0x8000014d, ++0x28a40008, ++0x9b800019, ++0x28a40008, ++0x8000015d, ++0x326400ff, ++0x9b800015, ++0x28a40008, ++0x8000015d, ++0x326400ff, ++0x9b800011, ++0x28a40008, ++0x8000015d, ++0x326400ff, ++0x9b80000d, ++0x28a40008, ++0x8000015d, ++0x326400ff, ++0x9b800009, ++0x28a40008, ++0x8000015d, ++0x326400ff, ++0x9b800005, ++0x28a40008, ++0x8000015d, ++0x326400ff, ++0x28a40008, ++0x326400ff, ++0x0e68003c, ++0x9a80feb2, ++0x28ec0008, ++0x7c434000, ++0x7c438000, ++0x7c43c000, ++0x96c00007, ++0xcc000062, ++0xcf412169, ++0xcf81216a, ++0xcfc1216b, ++0x80000001, ++0xcc01216c, ++0x80000001, ++0xcff50000, ++0xcc00006b, ++0x8400037f, ++0x0e68003c, ++0x9a800004, ++0xc8280015, ++0x80000001, ++0xd040007f, ++0x9680ffab, ++0x7e024000, ++0x84000239, ++0xc00e0002, ++0xcc000041, ++0x80000237, ++0xccc1304a, ++0x7c40c000, ++0x7c410000, ++0xc01e0001, ++0x29240012, ++0xc0220002, ++0x96400005, ++0xc0260004, ++0xc027fffb, ++0x7d25000b, ++0xc0260000, ++0x7dd2800b, ++0x7e12c00b, ++0x7d25000c, ++0x7c414000, ++0x7c418000, ++0xccc12169, ++0x9a80000a, ++0xcd01216a, ++0xcd41216b, ++0x96c0fe83, ++0xcd81216c, ++0xc8300018, ++0x97000000, ++0xc8300018, ++0x80000001, ++0xcc000018, ++0x8400037f, ++0xcc00007f, ++0xc8140013, ++0xc8180014, ++0xcd41216b, ++0x96c0fe77, ++0xcd81216c, ++0x80000181, ++0xc8300018, ++0xc80c0008, ++0x98c00000, ++0xc80c0008, ++0x7c410000, ++0x95000002, ++0x00000000, ++0x7c414000, ++0xc8200009, ++0xcc400043, ++0xce01a1f4, ++0xcc400044, ++0xc00e8000, ++0x7c424000, ++0x7c428000, ++0x2aac001f, ++0x96c0fe64, ++0xc035f000, ++0xce4003e2, ++0x32780003, ++0x267c0008, ++0x7ff7c00b, ++0x7ffbc00c, ++0x2a780018, ++0xcfc003e3, ++0xcf8003e4, ++0x26b00002, ++0x7f3f0000, ++0xcf0003e5, ++0x8000031d, ++0x7c80c000, ++0x7c40c000, ++0x28d00008, ++0x3110000f, ++0x9500000f, ++0x25280001, ++0x06a801b2, ++0x9e800000, ++0x00000000, ++0x800001d3, ++0xc0120800, ++0x800001e1, ++0xc814000f, ++0x800001e8, ++0xc8140010, ++0x800001ef, ++0xccc1a2a4, ++0x800001f8, ++0xc8140011, ++0x30d0003f, ++0x0d280015, ++0x9a800012, ++0x0d28001e, ++0x9a80001e, ++0x0d280020, ++0x9a800023, ++0x0d24000f, ++0x0d280010, ++0x7e6a800c, ++0x9a800026, ++0x0d200004, ++0x0d240014, ++0x0d280028, ++0x7e62400c, ++0x7ea6800c, ++0x9a80002a, ++0xc8140011, ++0x80000001, ++0xccc1a2a4, ++0xc0120800, ++0x7c414000, ++0x7d0cc00c, ++0xc0120008, ++0x29580003, ++0x295c000c, ++0x7c420000, ++0x7dd1c00b, ++0x26200014, ++0x7e1e400c, ++0x7e4e800c, ++0xce81a2a4, ++0x80000001, ++0xcd81a1fe, ++0xc814000f, ++0x0410210e, ++0x95400000, ++0xc814000f, ++0xd0510000, ++0x80000001, ++0xccc1a2a4, ++0xc8140010, ++0x04102108, ++0x95400000, ++0xc8140010, ++0xd0510000, ++0x80000001, ++0xccc1a2a4, ++0xccc1a2a4, ++0x04100001, ++0xcd000019, ++0x8400037f, ++0xcc00007f, ++0xc8100019, ++0x99000000, ++0xc8100019, ++0x80000002, ++0x7c408000, ++0x04102100, ++0x95400000, ++0xc8140011, ++0xd0510000, ++0x8000037c, ++0xccc1a2a4, ++0x7c40c000, ++0xcc40000d, ++0x94c0fe01, ++0xcc40000e, ++0x7c410000, ++0x95000005, ++0x08cc0001, ++0xc8140005, ++0x99400014, ++0x00000000, ++0x98c0fffb, ++0x7c410000, ++0x80000002, ++0x7d008000, ++0xc8140005, ++0x7c40c000, ++0x9940000c, ++0xc818000c, ++0x7c410000, ++0x9580fdf0, ++0xc820000e, ++0xc81c000d, ++0x66200020, ++0x7e1e002c, ++0x25240002, ++0x7e624020, ++0x80000001, ++0xcce60000, ++0x7c410000, ++0xcc00006c, ++0xcc00006d, ++0xc818001f, ++0xc81c001e, ++0x65980020, ++0x7dd9c02c, ++0x7cd4c00c, ++0xccde0000, ++0x45dc0004, ++0xc8280017, ++0x9680000f, ++0xc00e0001, ++0x28680008, ++0x2aac0016, ++0x32a800ff, ++0x0eb00049, ++0x7f2f000b, ++0x97000006, ++0x00000000, ++0xc8140005, ++0x7c40c000, ++0x80000221, ++0x7c410000, ++0x80000224, ++0xd040007f, ++0x84000239, ++0xcc000041, ++0xccc1304a, ++0x94000000, ++0xc83c001a, ++0x043c0005, ++0xcfc1a2a4, ++0xc0361f90, ++0xc0387fff, ++0x7c03c010, ++0x7f7b400c, ++0xcf41217c, ++0xcfc1217d, ++0xcc01217e, ++0xc03a0004, ++0x0434217f, ++0x7f7b400c, ++0xcc350000, ++0xc83c0004, ++0x2bfc001f, ++0x04380020, ++0x97c00005, ++0xcc000062, ++0x9b800000, ++0x0bb80001, ++0x80000245, ++0xcc000071, ++0xcc01a1f4, ++0x04380016, ++0xc0360002, ++0xcf81a2a4, ++0x88000000, ++0xcf412010, ++0x7c40c000, ++0x28d0001c, ++0x95000005, ++0x04d40001, ++0xcd400065, ++0x80000001, ++0xcd400068, ++0x09540002, ++0x80000001, ++0xcd400066, ++0x8400026a, ++0xc81803ea, ++0x7c40c000, ++0x9980fd9f, ++0xc8140016, ++0x08d00001, ++0x9940002b, ++0xcd000068, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x043c0005, ++0xcfc1a2a4, ++0xcc01a1f4, ++0x8400037f, ++0xcc000046, ++0x88000000, ++0xcc00007f, ++0x8400027c, ++0xc81803ea, ++0x7c40c000, ++0x9980fd8d, ++0xc8140016, ++0x08d00001, ++0x99400019, ++0xcd000068, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x043c0022, ++0xcfc1a2a4, ++0x8400037f, ++0xcc000047, ++0x88000000, ++0xcc00007f, ++0xc8100016, ++0x9900000d, ++0xcc400067, ++0x80000002, ++0x7c408000, ++0xc81803ea, ++0x9980fd79, ++0x7c40c000, ++0x94c00003, ++0xc8100016, ++0x99000004, ++0xccc00068, ++0x80000002, ++0x7c408000, ++0x84000239, ++0xc0148000, ++0xcc000041, ++0xcd41304a, ++0xc0148000, ++0x99000000, ++0xc8100016, ++0x80000002, ++0x7c408000, ++0xc0120001, ++0x7c51400c, ++0x80000001, ++0xd0550000, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0x291c001f, ++0xccc0004a, ++0xcd00004b, ++0x95c00003, ++0xc01c8000, ++0xcdc12010, ++0xdd830000, ++0x055c2000, ++0xcc000062, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc0004c, ++0xcd00004d, ++0xdd830000, ++0x055ca000, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc0004e, ++0xcd00004f, ++0xdd830000, ++0x055cc000, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00050, ++0xcd000051, ++0xdd830000, ++0x055cf8e0, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00052, ++0xcd000053, ++0xdd830000, ++0x055cf880, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00054, ++0xcd000055, ++0xdd830000, ++0x055ce000, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00056, ++0xcd000057, ++0xdd830000, ++0x055cf000, ++0x80000001, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00058, ++0xcd000059, ++0xdd830000, ++0x055cf3fc, ++0x80000001, ++0xd81f4100, ++0xd0432000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043a000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043c000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f8e0, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f880, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043e000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f3fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xc81403e0, ++0xcc430000, ++0xcc430000, ++0xcc430000, ++0x7d45c000, ++0xcdc30000, ++0xd0430000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x7c40c000, ++0xc81003e2, ++0xc81403e5, ++0xc81803e3, ++0xc81c03e4, ++0xcd812169, ++0xcdc1216a, ++0xccc1216b, ++0xcc01216c, ++0x04200004, ++0x7da18000, ++0x7d964002, ++0x9640fcd9, ++0xcd8003e3, ++0x31280003, ++0xc02df000, ++0x25180008, ++0x7dad800b, ++0x7da9800c, ++0x80000001, ++0xcd8003e3, ++0x308cffff, ++0xd04d0000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xc8140020, ++0x15580002, ++0x9580ffff, ++0xc8140020, ++0xcc00006e, ++0xcc412180, ++0x7c40c000, ++0xccc1218d, ++0xcc412181, ++0x28d0001f, ++0x34588000, ++0xcd81218c, ++0x9500fcbf, ++0xcc412182, ++0xc8140020, ++0x9940ffff, ++0xc8140020, ++0x80000002, ++0x7c408000, ++0x7c40c000, ++0x28d00018, ++0x31100001, ++0xc0160080, ++0x95000003, ++0xc02a0004, ++0x7cd4c00c, ++0xccc1217c, ++0xcc41217d, ++0xcc41217e, ++0x7c418000, ++0x1db00003, ++0x36a0217f, ++0x9b000003, ++0x419c0005, ++0x041c0040, ++0x99c00000, ++0x09dc0001, ++0xcc210000, ++0xc8240004, ++0x2a6c001f, ++0x419c0005, ++0x9ac0fffa, ++0xcc800062, ++0x80000002, ++0x7c408000, ++0x7c40c000, ++0x04d403e6, ++0x80000001, ++0xcc540000, ++0x8000037c, ++0xcc4003ea, ++0xc01c8000, ++0x044ca000, ++0xcdc12010, ++0x7c410000, ++0xc8140009, ++0x04180000, ++0x041c0008, ++0xcd800071, ++0x09dc0001, ++0x05980001, ++0xcd0d0000, ++0x99c0fffc, ++0xcc800062, ++0x8000037c, ++0xcd400071, ++0xc00e0100, ++0xcc000041, ++0xccc1304a, ++0xc83c007f, ++0xcc00007f, ++0x80000001, ++0xcc00007f, ++0xcc00007f, ++0x88000000, ++0xcc00007f, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00010331, ++0x00100004, ++0x00170006, ++0x00210008, ++0x00270028, ++0x00280023, ++0x00290029, ++0x002a0026, ++0x002b0029, ++0x002d0038, ++0x002e003f, ++0x002f004a, ++0x0034004c, ++0x00360030, ++0x003900af, ++0x003a00cf, ++0x003b00e4, ++0x003c00fc, ++0x003d016b, ++0x003f00ad, ++0x00410336, ++0x00430349, ++0x0044018e, ++0x004500fc, ++0x004601ac, ++0x004701ac, ++0x004801fe, ++0x0049020c, ++0x004a0255, ++0x004b0282, ++0x0052025f, ++0x00530271, ++0x00540287, ++0x00570299, ++0x0060029d, ++0x006102ac, ++0x006202b6, ++0x006302c0, ++0x006402ca, ++0x006502d4, ++0x006602de, ++0x006702e8, ++0x006802f2, ++0x006902f6, ++0x006a02fa, ++0x006b02fe, ++0x006c0302, ++0x006d0306, ++0x006e030a, ++0x006f030e, ++0x00700312, ++0x00720363, ++0x00740369, ++0x00790367, ++0x007c031c, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++0x000f0378, ++}; ++ ++static const u32 RV710_pfp_microcode[] = { ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0x80000000, ++0xdc030000, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xc818000e, ++0x31980001, ++0x7c424000, ++0x9580023a, ++0x7c428000, ++0xc81c001c, ++0xc037c000, ++0x7c40c000, ++0x7c410000, ++0x7cb4800b, ++0xc0360003, ++0x99c00000, ++0xc81c001c, ++0x7cb4800c, ++0x24d40002, ++0x7d654000, ++0xcd400043, ++0xce800043, ++0xcd000043, ++0xcc800040, ++0xce400040, ++0xce800040, ++0xccc00040, ++0xdc3a0000, ++0x9780ffde, ++0xcd000040, ++0x7c40c000, ++0x80000018, ++0x7c410000, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xc818000e, ++0x8000000c, ++0x31980002, ++0xd40003c0, ++0xd4000fc0, ++0xd4000fa2, ++0xc818000e, ++0x288c0008, ++0x30cc000f, ++0x34100001, ++0x7d0d0008, ++0x8000000c, ++0x7d91800b, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xd40003c0, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xcc4003f9, ++0x80000249, ++0xcc4003f8, ++0xc037ffff, ++0x7c414000, ++0xcf41a29e, ++0xc82003f8, ++0xc81c03f9, ++0x66200020, ++0xc81803fb, ++0x7de1c02c, ++0x7d58c008, ++0x7cdcc020, ++0x69100020, ++0xc0360003, ++0xcc000054, ++0x7cb4800c, ++0x80000069, ++0xcc800040, ++0x7c418000, ++0xcd81a29e, ++0xcc800040, ++0x80000067, ++0xcd800040, ++0xc019ffff, ++0xcc800040, ++0xcd81a29e, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0xccc1a1fa, ++0xcd01a1f9, ++0xcd41a29d, ++0xccc00040, ++0xcd000040, ++0xcd400040, ++0xcc400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xcc000054, ++0xcc800040, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0xccc1a1fa, ++0xcd01a1f9, ++0xcd41a29d, ++0xccc00040, ++0xcd000040, ++0xcd400040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0x7c40c000, ++0x30d00001, ++0xccc1a29f, ++0x95000003, ++0x04140001, ++0x04140002, ++0xcd4003fb, ++0xcc800040, ++0x80000000, ++0xccc00040, ++0x7c40c000, ++0xcc800040, ++0xccc1a2a2, ++0x80000000, ++0xccc00040, ++0x7c40c000, ++0x28d4001f, ++0xcc800040, ++0x95400003, ++0x7c410000, ++0xccc00057, ++0x2918001f, ++0xccc00040, ++0x95800003, ++0xcd000040, ++0xcd000058, ++0x80000249, ++0xcc00007f, ++0xc8200017, ++0xc8300022, ++0x9a000006, ++0x0e280001, ++0xc824001e, ++0x0a640001, ++0xd4001240, ++0xce400040, ++0xc036c000, ++0x96800007, ++0x37747900, ++0x041c0001, ++0xcf400040, ++0xcdc00040, ++0xcf0003fa, ++0x7c030000, ++0xca0c0010, ++0x7c410000, ++0x94c00004, ++0x7c414000, ++0xd42002c4, ++0xcde00044, ++0x9b00000b, ++0x7c418000, ++0xcc00004b, ++0xcda00049, ++0xcd200041, ++0xcd600041, ++0xcda00041, ++0x06200001, ++0xce000056, ++0x80000249, ++0xcc00007f, ++0xc8280020, ++0xc82c0021, ++0xcc000063, ++0x7eea4001, ++0x65740020, ++0x7f53402c, ++0x269c0002, ++0x7df5c020, ++0x69f80020, ++0xce80004b, ++0xce600049, ++0xcde00041, ++0xcfa00041, ++0xce600041, ++0x271c0002, ++0x7df5c020, ++0x69f80020, ++0x7db24001, ++0xcf00004b, ++0xce600049, ++0xcde00041, ++0xcfa00041, ++0x800000bc, ++0xce600041, ++0xc8200017, ++0xc8300022, ++0x9a000006, ++0x0e280001, ++0xc824001e, ++0x0a640001, ++0xd4001240, ++0xce400040, ++0xca0c0010, ++0x7c410000, ++0x94c0000b, ++0xc036c000, ++0x96800007, ++0x37747900, ++0x041c0001, ++0xcf400040, ++0xcdc00040, ++0xcf0003fa, ++0x7c030000, ++0x800000b5, ++0x7c414000, ++0xcc000048, ++0x800000ee, ++0x00000000, ++0xc8200017, ++0xc81c0023, ++0x0e240002, ++0x99c00015, ++0x7c418000, ++0x0a200001, ++0xce000056, ++0xd4000440, ++0xcc000040, ++0xc036c000, ++0xca140013, ++0x96400007, ++0x37747900, ++0xcf400040, ++0xcc000040, ++0xc83003fa, ++0x80000103, ++0xcf000022, ++0xcc000022, ++0x95400146, ++0xcc00007f, ++0xcca00046, ++0x80000000, ++0xcc200046, ++0x80000249, ++0xcc000064, ++0xc8200017, ++0xc810001f, ++0x96000005, ++0x09100001, ++0xd4000440, ++0xcd000040, ++0xcd000022, ++0xcc800040, ++0xd0400040, ++0xc80c0025, ++0x94c0feec, ++0xc8100008, ++0xcd000040, ++0xd4000fc0, ++0x80000000, ++0xd4000fa2, ++0x7c40c000, ++0x7c410000, ++0xccc003fd, ++0xcd0003fc, ++0xccc00042, ++0xcd000042, ++0x2914001f, ++0x29180010, ++0x31980007, ++0x3b5c0001, ++0x7d76000b, ++0x99800005, ++0x7d5e400b, ++0xcc000042, ++0x80000249, ++0xcc00004d, ++0x29980001, ++0x292c0008, ++0x9980003d, ++0x32ec0001, ++0x96000004, ++0x2930000c, ++0x80000249, ++0xcc000042, ++0x04140010, ++0xcd400042, ++0x33300001, ++0x34280001, ++0x8400015d, ++0xc8140003, ++0x9b40001b, ++0x0438000c, ++0x8400015d, ++0xc8140003, ++0x9b400017, ++0x04380008, ++0x8400015d, ++0xc8140003, ++0x9b400013, ++0x04380004, ++0x8400015d, ++0xc8140003, ++0x9b400015, ++0xc80c03fd, ++0x9a800009, ++0xc81003fc, ++0x9b000101, ++0xcc00004d, ++0x04140010, ++0xccc00042, ++0xcd000042, ++0x80000135, ++0xcd400042, ++0x96c000fa, ++0xcc00004d, ++0x80000249, ++0xcc00004e, ++0x9ac00003, ++0xcc00004d, ++0xcc00004e, ++0xdf830000, ++0x80000000, ++0xd80301ff, ++0x9ac000f0, ++0xcc00004d, ++0x80000249, ++0xcc00004e, ++0xc8180003, ++0xc81c0003, ++0xc8200003, ++0x7d5d4003, ++0x7da1c003, ++0x7d5d400c, ++0x2a10001f, ++0x299c001f, ++0x7d1d000b, ++0x7d17400b, ++0x88000000, ++0x7e92800b, ++0x96400004, ++0xcc00004e, ++0x80000249, ++0xcc000042, ++0x04380008, ++0xcf800042, ++0xc8080003, ++0xc80c0003, ++0xc8100003, ++0xc8140003, ++0xc8180003, ++0xc81c0003, ++0xc8240003, ++0xc8280003, ++0x29fc001f, ++0x2ab0001f, ++0x7ff3c00b, ++0x28f0001f, ++0x7ff3c00b, ++0x2970001f, ++0x7ff3c00b, ++0x7d888001, ++0x7dccc001, ++0x7e510001, ++0x7e954001, ++0x7c908002, ++0x7cd4c002, ++0x7cbc800b, ++0x9ac00003, ++0x7c8f400b, ++0x38b40001, ++0x9b4000c1, ++0xcc00004d, ++0x9bc000bf, ++0xcc00004e, ++0xc80c03fd, ++0xc81003fc, ++0xccc00042, ++0x8000016e, ++0xcd000042, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xcc400040, ++0xcc400040, ++0xcc400040, ++0x7c40c000, ++0xccc00040, ++0xccc0000d, ++0x80000000, ++0xd0400040, ++0x7c40c000, ++0x7c410000, ++0x65140020, ++0x7d4d402c, ++0x24580002, ++0x7d598020, ++0x7c41c000, ++0xcd800042, ++0x69980020, ++0xcd800042, ++0xcdc00042, ++0xc023c000, ++0x05e40002, ++0x7ca0800b, ++0x26640010, ++0x7ca4800c, ++0xcc800040, ++0xcdc00040, ++0xccc00040, ++0x95c0000e, ++0xcd000040, ++0x09dc0001, ++0xc8280003, ++0x96800008, ++0xce800040, ++0xc834001d, ++0x97400000, ++0xc834001d, ++0x26a80008, ++0x8400024c, ++0xcc2b0000, ++0x99c0fff7, ++0x09dc0001, ++0xdc3a0000, ++0x97800004, ++0x7c418000, ++0x800001a2, ++0x25980002, ++0xa0000000, ++0x7d808000, ++0xc818001d, ++0x7c40c000, ++0x64d00008, ++0x95800000, ++0xc818001d, ++0xcc130000, ++0xcc800040, ++0xccc00040, ++0x80000000, ++0xcc400040, ++0xc810001f, ++0x7c40c000, ++0xcc800040, ++0x7cd1400c, ++0xcd400040, ++0x05180001, ++0x80000000, ++0xcd800022, ++0x7c40c000, ++0x64500020, ++0x8400024c, ++0xcc000061, ++0x7cd0c02c, ++0xc8200017, ++0xc8d60000, ++0x99400008, ++0x7c438000, ++0xdf830000, ++0xcfa0004f, ++0x8400024c, ++0xcc000062, ++0x80000000, ++0xd040007f, ++0x80000249, ++0xcc000062, ++0x8400024c, ++0xcc000061, ++0xc8200017, ++0x7c40c000, ++0xc036ff00, ++0xc810000d, ++0xc0303fff, ++0x7cf5400b, ++0x7d51800b, ++0x7d81800f, ++0x99800008, ++0x7cf3800b, ++0xdf830000, ++0xcfa0004f, ++0x8400024c, ++0xcc000062, ++0x80000000, ++0xd040007f, ++0x80000249, ++0xcc000062, ++0x8400024c, ++0x7c40c000, ++0x28dc0008, ++0x95c00019, ++0x30dc0010, ++0x7c410000, ++0x99c00004, ++0x64540020, ++0x80000208, ++0xc91d0000, ++0x7d15002c, ++0xc91e0000, ++0x7c420000, ++0x7c424000, ++0x7c418000, ++0x7de5c00b, ++0x7de28007, ++0x9a80000e, ++0x41ac0005, ++0x9ac00000, ++0x0aec0001, ++0x30dc0010, ++0x99c00004, ++0x00000000, ++0x8000020b, ++0xc91d0000, ++0x8000020b, ++0xc91e0000, ++0xcc800040, ++0xccc00040, ++0xd0400040, ++0xc80c0025, ++0x94c0fde4, ++0xc8100008, ++0xcd000040, ++0xd4000fc0, ++0x80000000, ++0xd4000fa2, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0xd40003c0, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xd0400040, ++0x7c408000, ++0xa0000000, ++0x7e82800b, ++0x7c40c000, ++0x30d00006, ++0x0d100006, ++0x99000007, ++0xc8140015, ++0x99400005, ++0xcc000052, ++0xd4000340, ++0xd4000fc0, ++0xd4000fa2, ++0xcc800040, ++0xccc00040, ++0x80000000, ++0xd0400040, ++0x7c40c000, ++0xcc4d0000, ++0xdc3a0000, ++0x9780fdbd, ++0x04cc0001, ++0x80000242, ++0xcc4d0000, ++0x80000000, ++0xd040007f, ++0xcc00007f, ++0x80000000, ++0xcc00007f, ++0xcc00007f, ++0x88000000, ++0xcc00007f, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00030222, ++0x0004022a, ++0x0005009f, ++0x00020003, ++0x0006003c, ++0x00070027, ++0x00080191, ++0x00090044, ++0x000a002d, ++0x00100247, ++0x001700f0, ++0x002201d7, ++0x002301e8, ++0x0026004c, ++0x0027005f, ++0x0020011a, ++0x00280092, ++0x0029004f, ++0x002a0083, ++0x002b0064, ++0x002f008d, ++0x003200d8, ++0x00340232, ++0x00360074, ++0x0039010a, ++0x003c01fc, ++0x003f009f, ++0x00410005, ++0x00440194, ++0x0048019d, ++0x004901c5, ++0x004a01cf, ++0x00550225, ++0x0056022d, ++0x0060000a, ++0x0061002a, ++0x00620030, ++0x00630030, ++0x00640030, ++0x00650030, ++0x00660030, ++0x00670030, ++0x00680037, ++0x0069003f, ++0x006a0047, ++0x006b0047, ++0x006c0047, ++0x006d0047, ++0x006e0047, ++0x006f0047, ++0x00700047, ++0x00730247, ++0x007b0240, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++0x00000005, ++}; ++ ++static const u32 RV710_cp_microcode[] = { ++0xcc0003ea, ++0x04080003, ++0xcc800043, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x80000003, ++0xd040007f, ++0x80000003, ++0xcc400041, ++0x7c40c000, ++0xc0160004, ++0x30d03fff, ++0x7d15000c, ++0xcc110000, ++0x28d8001e, ++0x31980001, ++0x28dc001f, ++0xc8200004, ++0x95c00006, ++0x7c424000, ++0xcc000062, ++0x7e56800c, ++0xcc290000, ++0xc8240004, ++0x7e26000b, ++0x95800006, ++0x7c42c000, ++0xcc000062, ++0x7ed7000c, ++0xcc310000, ++0xc82c0004, ++0x7e2e000c, ++0xcc000062, ++0x31103fff, ++0x80000003, ++0xce110000, ++0x7c40c000, ++0x80000003, ++0xcc400040, ++0x80000003, ++0xcc412257, ++0x7c418000, ++0xcc400045, ++0xcc400048, ++0xcc41225c, ++0xcc41a1fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xcc400045, ++0xcc400048, ++0x7c40c000, ++0xcc41225c, ++0xcc41a1fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xcc000045, ++0xcc000048, ++0xcc41225c, ++0xcc41a1fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x040ca1fd, ++0xc0120001, ++0xcc000045, ++0xcc000048, ++0x7cd0c00c, ++0xcc41225c, ++0xcc41a1fc, ++0xd04d0000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x80000003, ++0xcc41225d, ++0x7c408000, ++0x7c40c000, ++0xc02a0002, ++0x7c410000, ++0x7d29000c, ++0x30940001, ++0x30980006, ++0x309c0300, ++0x29dc0008, ++0x7c420000, ++0x7c424000, ++0x9540000f, ++0xc02e0004, ++0x05f02258, ++0x7f2f000c, ++0xcc310000, ++0xc8280004, ++0xccc12169, ++0xcd01216a, ++0xce81216b, ++0x0db40002, ++0xcc01216c, ++0x9740000e, ++0x0db40000, ++0x8000007d, ++0xc834000a, ++0x0db40002, ++0x97400009, ++0x0db40000, ++0xc02e0004, ++0x05f02258, ++0x7f2f000c, ++0xcc310000, ++0xc8280004, ++0x8000007d, ++0xc834000a, ++0x97400004, ++0x7e028000, ++0x8000007d, ++0xc834000a, ++0x0db40004, ++0x9740ff8c, ++0x00000000, ++0xce01216d, ++0xce41216e, ++0xc8280003, ++0xc834000a, ++0x9b400004, ++0x043c0005, ++0x8400026d, ++0xcc000062, ++0x0df40000, ++0x9740000b, ++0xc82c03e6, ++0xce81a2b7, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c4, ++0x80000003, ++0xcfc1a2d1, ++0x0df40001, ++0x9740000b, ++0xc82c03e7, ++0xce81a2bb, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c5, ++0x80000003, ++0xcfc1a2d2, ++0x0df40002, ++0x9740000b, ++0xc82c03e8, ++0xce81a2bf, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c6, ++0x80000003, ++0xcfc1a2d3, ++0xc82c03e9, ++0xce81a2c3, ++0xc0300006, ++0x7ef34028, ++0xc0300020, ++0x7f6b8020, ++0x7fb3c029, ++0xcf81a2c7, ++0x80000003, ++0xcfc1a2d4, ++0x80000003, ++0xcc400042, ++0x7c40c000, ++0x7c410000, ++0x2914001d, ++0x31540001, ++0x9940000c, ++0x31181000, ++0xc81c0011, ++0x95c00000, ++0xc81c0011, ++0xccc12100, ++0xcd012101, ++0xccc12102, ++0xcd012103, ++0x04180004, ++0x8000037e, ++0xcd81a2a4, ++0xc02a0004, ++0x95800008, ++0x36a821a3, ++0xcc290000, ++0xc8280004, ++0xc81c0011, ++0x0de40040, ++0x9640ffff, ++0xc81c0011, ++0xccc12170, ++0xcd012171, ++0xc8200012, ++0x96000000, ++0xc8200012, ++0x8000037e, ++0xcc000064, ++0x7c40c000, ++0x7c410000, ++0xcc000045, ++0xcc000048, ++0x40d40003, ++0xcd41225c, ++0xcd01a1fc, ++0xc01a0001, ++0x041ca1fd, ++0x7dd9c00c, ++0x7c420000, ++0x08cc0001, ++0x06240001, ++0x06280002, ++0xce1d0000, ++0xce5d0000, ++0x98c0fffa, ++0xce9d0000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x7c40c000, ++0x30d00001, ++0x28cc0001, ++0x7c414000, ++0x95000006, ++0x7c418000, ++0xcd41216d, ++0xcd81216e, ++0x800000f4, ++0xc81c0003, ++0xc0220004, ++0x7e16000c, ++0xcc210000, ++0xc81c0004, ++0x7c424000, ++0x98c00004, ++0x7c428000, ++0x80000003, ++0xcde50000, ++0xce412169, ++0xce81216a, ++0xcdc1216b, ++0x80000003, ++0xcc01216c, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0x7c41c000, ++0x28a40008, ++0x326400ff, ++0x0e68003c, ++0x9680000a, ++0x7c020000, ++0x7c420000, ++0x1e300003, ++0xcc00006a, ++0x9b000003, ++0x42200005, ++0x04200040, ++0x80000111, ++0x7c024000, ++0x7e024000, ++0x9a400000, ++0x0a640001, ++0x30ec0010, ++0x9ac0000a, ++0xcc000062, ++0xc02a0004, ++0xc82c0021, ++0x7e92800c, ++0xcc000041, ++0xcc290000, ++0xcec00021, ++0x80000121, ++0xc8300004, ++0xcd01216d, ++0xcd41216e, ++0xc8300003, ++0x7f1f000b, ++0x30f40007, ++0x27780001, ++0x9740002a, ++0x07b80126, ++0x9f800000, ++0x00000000, ++0x80000136, ++0x7f1b8004, ++0x8000013a, ++0x7f1b8005, ++0x8000013e, ++0x7f1b8002, ++0x80000142, ++0x7f1b8003, ++0x80000146, ++0x7f1b8007, ++0x8000014a, ++0x7f1b8006, ++0x8000014f, ++0x28a40008, ++0x9b800019, ++0x28a40008, ++0x8000015f, ++0x326400ff, ++0x9b800015, ++0x28a40008, ++0x8000015f, ++0x326400ff, ++0x9b800011, ++0x28a40008, ++0x8000015f, ++0x326400ff, ++0x9b80000d, ++0x28a40008, ++0x8000015f, ++0x326400ff, ++0x9b800009, ++0x28a40008, ++0x8000015f, ++0x326400ff, ++0x9b800005, ++0x28a40008, ++0x8000015f, ++0x326400ff, ++0x28a40008, ++0x326400ff, ++0x0e68003c, ++0x9a80feb2, ++0x28ec0008, ++0x7c434000, ++0x7c438000, ++0x7c43c000, ++0x96c00007, ++0xcc000062, ++0xcf412169, ++0xcf81216a, ++0xcfc1216b, ++0x80000003, ++0xcc01216c, ++0x80000003, ++0xcff50000, ++0xcc00006b, ++0x84000381, ++0x0e68003c, ++0x9a800004, ++0xc8280015, ++0x80000003, ++0xd040007f, ++0x9680ffab, ++0x7e024000, ++0x8400023b, ++0xc00e0002, ++0xcc000041, ++0x80000239, ++0xccc1304a, ++0x7c40c000, ++0x7c410000, ++0xc01e0001, ++0x29240012, ++0xc0220002, ++0x96400005, ++0xc0260004, ++0xc027fffb, ++0x7d25000b, ++0xc0260000, ++0x7dd2800b, ++0x7e12c00b, ++0x7d25000c, ++0x7c414000, ++0x7c418000, ++0xccc12169, ++0x9a80000a, ++0xcd01216a, ++0xcd41216b, ++0x96c0fe83, ++0xcd81216c, ++0xc8300018, ++0x97000000, ++0xc8300018, ++0x80000003, ++0xcc000018, ++0x84000381, ++0xcc00007f, ++0xc8140013, ++0xc8180014, ++0xcd41216b, ++0x96c0fe77, ++0xcd81216c, ++0x80000183, ++0xc8300018, ++0xc80c0008, ++0x98c00000, ++0xc80c0008, ++0x7c410000, ++0x95000002, ++0x00000000, ++0x7c414000, ++0xc8200009, ++0xcc400043, ++0xce01a1f4, ++0xcc400044, ++0xc00e8000, ++0x7c424000, ++0x7c428000, ++0x2aac001f, ++0x96c0fe64, ++0xc035f000, ++0xce4003e2, ++0x32780003, ++0x267c0008, ++0x7ff7c00b, ++0x7ffbc00c, ++0x2a780018, ++0xcfc003e3, ++0xcf8003e4, ++0x26b00002, ++0x7f3f0000, ++0xcf0003e5, ++0x8000031f, ++0x7c80c000, ++0x7c40c000, ++0x28d00008, ++0x3110000f, ++0x9500000f, ++0x25280001, ++0x06a801b4, ++0x9e800000, ++0x00000000, ++0x800001d5, ++0xc0120800, ++0x800001e3, ++0xc814000f, ++0x800001ea, ++0xc8140010, ++0x800001f1, ++0xccc1a2a4, ++0x800001fa, ++0xc8140011, ++0x30d0003f, ++0x0d280015, ++0x9a800012, ++0x0d28001e, ++0x9a80001e, ++0x0d280020, ++0x9a800023, ++0x0d24000f, ++0x0d280010, ++0x7e6a800c, ++0x9a800026, ++0x0d200004, ++0x0d240014, ++0x0d280028, ++0x7e62400c, ++0x7ea6800c, ++0x9a80002a, ++0xc8140011, ++0x80000003, ++0xccc1a2a4, ++0xc0120800, ++0x7c414000, ++0x7d0cc00c, ++0xc0120008, ++0x29580003, ++0x295c000c, ++0x7c420000, ++0x7dd1c00b, ++0x26200014, ++0x7e1e400c, ++0x7e4e800c, ++0xce81a2a4, ++0x80000003, ++0xcd81a1fe, ++0xc814000f, ++0x0410210e, ++0x95400000, ++0xc814000f, ++0xd0510000, ++0x80000003, ++0xccc1a2a4, ++0xc8140010, ++0x04102108, ++0x95400000, ++0xc8140010, ++0xd0510000, ++0x80000003, ++0xccc1a2a4, ++0xccc1a2a4, ++0x04100001, ++0xcd000019, ++0x84000381, ++0xcc00007f, ++0xc8100019, ++0x99000000, ++0xc8100019, ++0x80000004, ++0x7c408000, ++0x04102100, ++0x95400000, ++0xc8140011, ++0xd0510000, ++0x8000037e, ++0xccc1a2a4, ++0x7c40c000, ++0xcc40000d, ++0x94c0fe01, ++0xcc40000e, ++0x7c410000, ++0x95000005, ++0x08cc0001, ++0xc8140005, ++0x99400014, ++0x00000000, ++0x98c0fffb, ++0x7c410000, ++0x80000004, ++0x7d008000, ++0xc8140005, ++0x7c40c000, ++0x9940000c, ++0xc818000c, ++0x7c410000, ++0x9580fdf0, ++0xc820000e, ++0xc81c000d, ++0x66200020, ++0x7e1e002c, ++0x25240002, ++0x7e624020, ++0x80000003, ++0xcce60000, ++0x7c410000, ++0xcc00006c, ++0xcc00006d, ++0xc818001f, ++0xc81c001e, ++0x65980020, ++0x7dd9c02c, ++0x7cd4c00c, ++0xccde0000, ++0x45dc0004, ++0xc8280017, ++0x9680000f, ++0xc00e0001, ++0x28680008, ++0x2aac0016, ++0x32a800ff, ++0x0eb00049, ++0x7f2f000b, ++0x97000006, ++0x00000000, ++0xc8140005, ++0x7c40c000, ++0x80000223, ++0x7c410000, ++0x80000226, ++0xd040007f, ++0x8400023b, ++0xcc000041, ++0xccc1304a, ++0x94000000, ++0xc83c001a, ++0x043c0005, ++0xcfc1a2a4, ++0xc0361f90, ++0xc0387fff, ++0x7c03c010, ++0x7f7b400c, ++0xcf41217c, ++0xcfc1217d, ++0xcc01217e, ++0xc03a0004, ++0x0434217f, ++0x7f7b400c, ++0xcc350000, ++0xc83c0004, ++0x2bfc001f, ++0x04380020, ++0x97c00005, ++0xcc000062, ++0x9b800000, ++0x0bb80001, ++0x80000247, ++0xcc000071, ++0xcc01a1f4, ++0x04380016, ++0xc0360002, ++0xcf81a2a4, ++0x88000000, ++0xcf412010, ++0x7c40c000, ++0x28d0001c, ++0x95000005, ++0x04d40001, ++0xcd400065, ++0x80000003, ++0xcd400068, ++0x09540002, ++0x80000003, ++0xcd400066, ++0x8400026c, ++0xc81803ea, ++0x7c40c000, ++0x9980fd9f, ++0xc8140016, ++0x08d00001, ++0x9940002b, ++0xcd000068, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x043c0005, ++0xcfc1a2a4, ++0xcc01a1f4, ++0x84000381, ++0xcc000046, ++0x88000000, ++0xcc00007f, ++0x8400027e, ++0xc81803ea, ++0x7c40c000, ++0x9980fd8d, ++0xc8140016, ++0x08d00001, ++0x99400019, ++0xcd000068, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x043c0022, ++0xcfc1a2a4, ++0x84000381, ++0xcc000047, ++0x88000000, ++0xcc00007f, ++0xc8100016, ++0x9900000d, ++0xcc400067, ++0x80000004, ++0x7c408000, ++0xc81803ea, ++0x9980fd79, ++0x7c40c000, ++0x94c00003, ++0xc8100016, ++0x99000004, ++0xccc00068, ++0x80000004, ++0x7c408000, ++0x8400023b, ++0xc0148000, ++0xcc000041, ++0xcd41304a, ++0xc0148000, ++0x99000000, ++0xc8100016, ++0x80000004, ++0x7c408000, ++0xc0120001, ++0x7c51400c, ++0x80000003, ++0xd0550000, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0x291c001f, ++0xccc0004a, ++0xcd00004b, ++0x95c00003, ++0xc01c8000, ++0xcdc12010, ++0xdd830000, ++0x055c2000, ++0xcc000062, ++0x80000003, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc0004c, ++0xcd00004d, ++0xdd830000, ++0x055ca000, ++0x80000003, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc0004e, ++0xcd00004f, ++0xdd830000, ++0x055cc000, ++0x80000003, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00050, ++0xcd000051, ++0xdd830000, ++0x055cf8e0, ++0x80000003, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00052, ++0xcd000053, ++0xdd830000, ++0x055cf880, ++0x80000003, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00054, ++0xcd000055, ++0xdd830000, ++0x055ce000, ++0x80000003, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00056, ++0xcd000057, ++0xdd830000, ++0x055cf000, ++0x80000003, ++0xd81f4100, ++0x7c40c000, ++0x7c410000, ++0x7c414000, ++0x7c418000, ++0xccc00058, ++0xcd000059, ++0xdd830000, ++0x055cf3fc, ++0x80000003, ++0xd81f4100, ++0xd0432000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043a000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043c000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f8e0, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f880, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043e000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xd043f3fc, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xc81403e0, ++0xcc430000, ++0xcc430000, ++0xcc430000, ++0x7d45c000, ++0xcdc30000, ++0xd0430000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0x7c40c000, ++0xc81003e2, ++0xc81403e5, ++0xc81803e3, ++0xc81c03e4, ++0xcd812169, ++0xcdc1216a, ++0xccc1216b, ++0xcc01216c, ++0x04200004, ++0x7da18000, ++0x7d964002, ++0x9640fcd9, ++0xcd8003e3, ++0x31280003, ++0xc02df000, ++0x25180008, ++0x7dad800b, ++0x7da9800c, ++0x80000003, ++0xcd8003e3, ++0x308cffff, ++0xd04d0000, ++0x7c408000, ++0xa0000000, ++0xcc800062, ++0xc8140020, ++0x15580002, ++0x9580ffff, ++0xc8140020, ++0xcc00006e, ++0xcc412180, ++0x7c40c000, ++0xccc1218d, ++0xcc412181, ++0x28d0001f, ++0x34588000, ++0xcd81218c, ++0x9500fcbf, ++0xcc412182, ++0xc8140020, ++0x9940ffff, ++0xc8140020, ++0x80000004, ++0x7c408000, ++0x7c40c000, ++0x28d00018, ++0x31100001, ++0xc0160080, ++0x95000003, ++0xc02a0004, ++0x7cd4c00c, ++0xccc1217c, ++0xcc41217d, ++0xcc41217e, ++0x7c418000, ++0x1db00003, ++0x36a0217f, ++0x9b000003, ++0x419c0005, ++0x041c0040, ++0x99c00000, ++0x09dc0001, ++0xcc210000, ++0xc8240004, ++0x2a6c001f, ++0x419c0005, ++0x9ac0fffa, ++0xcc800062, ++0x80000004, ++0x7c408000, ++0x7c40c000, ++0x04d403e6, ++0x80000003, ++0xcc540000, ++0x8000037e, ++0xcc4003ea, ++0xc01c8000, ++0x044ca000, ++0xcdc12010, ++0x7c410000, ++0xc8140009, ++0x04180000, ++0x041c0008, ++0xcd800071, ++0x09dc0001, ++0x05980001, ++0xcd0d0000, ++0x99c0fffc, ++0xcc800062, ++0x8000037e, ++0xcd400071, ++0xc00e0100, ++0xcc000041, ++0xccc1304a, ++0xc83c007f, ++0xcc00007f, ++0x80000003, ++0xcc00007f, ++0xcc00007f, ++0x88000000, ++0xcc00007f, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00000000, ++0x00010333, ++0x00100006, ++0x00170008, ++0x0021000a, ++0x0027002a, ++0x00280025, ++0x0029002b, ++0x002a0028, ++0x002b002b, ++0x002d003a, ++0x002e0041, ++0x002f004c, ++0x0034004e, ++0x00360032, ++0x003900b1, ++0x003a00d1, ++0x003b00e6, ++0x003c00fe, ++0x003d016d, ++0x003f00af, ++0x00410338, ++0x0043034b, ++0x00440190, ++0x004500fe, ++0x004601ae, ++0x004701ae, ++0x00480200, ++0x0049020e, ++0x004a0257, ++0x004b0284, ++0x00520261, ++0x00530273, ++0x00540289, ++0x0057029b, ++0x0060029f, ++0x006102ae, ++0x006202b8, ++0x006302c2, ++0x006402cc, ++0x006502d6, ++0x006602e0, ++0x006702ea, ++0x006802f4, ++0x006902f8, ++0x006a02fc, ++0x006b0300, ++0x006c0304, ++0x006d0308, ++0x006e030c, ++0x006f0310, ++0x00700314, ++0x00720365, ++0x0074036b, ++0x00790369, ++0x007c031e, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++0x000f037a, ++}; ++ ++#endif +diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c +index 92965db..77a7a4d 100644 +--- a/drivers/gpu/drm/radeon/radeon_cp.c ++++ b/drivers/gpu/drm/radeon/radeon_cp.c +@@ -43,6 +43,78 @@ + static int radeon_do_cleanup_cp(struct drm_device * dev); + static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); + ++u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off) ++{ ++ u32 val; ++ ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ val = DRM_READ32(dev_priv->ring_rptr, off); ++ } else { ++ val = *(((volatile u32 *) ++ dev_priv->ring_rptr->handle) + ++ (off / sizeof(u32))); ++ val = le32_to_cpu(val); ++ } ++ return val; ++} ++ ++u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv) ++{ ++ if (dev_priv->writeback_works) ++ return radeon_read_ring_rptr(dev_priv, 0); ++ else { ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return RADEON_READ(R600_CP_RB_RPTR); ++ else ++ return RADEON_READ(RADEON_CP_RB_RPTR); ++ } ++} ++ ++void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val) ++{ ++ if (dev_priv->flags & RADEON_IS_AGP) ++ DRM_WRITE32(dev_priv->ring_rptr, off, val); ++ else ++ *(((volatile u32 *) dev_priv->ring_rptr->handle) + ++ (off / sizeof(u32))) = cpu_to_le32(val); ++} ++ ++void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val) ++{ ++ radeon_write_ring_rptr(dev_priv, 0, val); ++} ++ ++u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index) ++{ ++ if (dev_priv->writeback_works) { ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return radeon_read_ring_rptr(dev_priv, ++ R600_SCRATCHOFF(index)); ++ else ++ return radeon_read_ring_rptr(dev_priv, ++ RADEON_SCRATCHOFF(index)); ++ } else { ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return RADEON_READ(R600_SCRATCH_REG0 + 4*index); ++ else ++ return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index); ++ } ++} ++ ++u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr) ++{ ++ u32 ret; ++ ++ if (addr < 0x10000) ++ ret = DRM_READ32(dev_priv->mmio, addr); ++ else { ++ DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr); ++ ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA); ++ } ++ ++ return ret; ++} ++ + static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) + { + u32 ret; +@@ -70,11 +142,22 @@ static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) + return ret; + } + ++static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) ++{ ++ u32 ret; ++ RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) | ++ RS600_MC_IND_CITF_ARB0)); ++ ret = RADEON_READ(RS600_MC_DATA); ++ return ret; ++} ++ + static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) + { + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + return RS690_READ_MCIND(dev_priv, addr); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) ++ return RS600_READ_MCIND(dev_priv, addr); + else + return RS480_READ_MCIND(dev_priv, addr); + } +@@ -82,11 +165,17 @@ static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) + u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) + { + +- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) ++ return RADEON_READ(R700_MC_VM_FB_LOCATION); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return RADEON_READ(R600_MC_VM_FB_LOCATION); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); + else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) ++ return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) + return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); + else +@@ -95,42 +184,66 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) + + static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) + { +- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) ++ RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); + else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) ++ RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) + R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); + else + RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); + } + +-static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) ++void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) + { +- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ++ /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { ++ RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ ++ RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); ++ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { ++ RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ ++ RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); ++ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); + else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) ++ RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) + R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); + else + RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); + } + +-static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) ++void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) + { + u32 agp_base_hi = upper_32_bits(agp_base); + u32 agp_base_lo = agp_base & 0xffffffff; +- +- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { ++ u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff; ++ ++ /* R6xx/R7xx must be aligned to a 4MB boundry */ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) ++ RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { + R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); + R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); + RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); ++ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { ++ RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo); ++ RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { + R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); + R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); +@@ -145,6 +258,25 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) + } + } + ++void radeon_enable_bm(struct drm_radeon_private *dev_priv) ++{ ++ u32 tmp; ++ /* Turn on bus mastering */ ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { ++ /* rs600/rs690/rs740 */ ++ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; ++ RADEON_WRITE(RADEON_BUS_CNTL, tmp); ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { ++ /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ ++ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; ++ RADEON_WRITE(RADEON_BUS_CNTL, tmp); ++ } /* PCIE cards appears to not need this */ ++} ++ + static int RADEON_READ_PLL(struct drm_device * dev, int addr) + { + drm_radeon_private_t *dev_priv = dev->dev_private; +@@ -302,7 +434,7 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { + RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); +- RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); ++ RADEON_WRITE(R300_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); + } + RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); + radeon_do_wait_for_idle(dev_priv); +@@ -382,6 +514,14 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) + RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, + RS690_cp_microcode[i][0]); + } ++ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { ++ DRM_INFO("Loading RS600 Microcode\n"); ++ for (i = 0; i < 256; i++) { ++ RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, ++ RS600_cp_microcode[i][1]); ++ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, ++ RS600_cp_microcode[i][0]); ++ } + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || +@@ -562,7 +702,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, + { + struct drm_radeon_master_private *master_priv; + u32 ring_start, cur_read_ptr; +- u32 tmp; + + /* Initialize the memory controller. With new memory map, the fb location + * is not changed, it should have been properly initialized already. Part +@@ -611,17 +750,10 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, + } else + #endif + { +- struct drm_sg_mem *entry = dev->sg; +- unsigned long tmp_ofs, page_ofs; +- +- tmp_ofs = dev_priv->ring_rptr->offset - +- (unsigned long)dev->sg->virtual; +- page_ofs = tmp_ofs >> PAGE_SHIFT; +- +- RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); +- DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n", +- (unsigned long)entry->busaddr[page_ofs], +- entry->handle + tmp_ofs); ++ RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, ++ dev_priv->ring_rptr->offset ++ - ((unsigned long) dev->sg->virtual) ++ + dev_priv->gart_vm_start); + } + + /* Set ring buffer size */ +@@ -649,34 +781,17 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, + RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + + RADEON_SCRATCH_REG_OFFSET); + +- dev_priv->scratch = ((__volatile__ u32 *) +- dev_priv->ring_rptr->handle + +- (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); +- + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); + +- /* Turn on bus mastering */ +- if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || +- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { +- /* rs600/rs690/rs740 */ +- tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; +- RADEON_WRITE(RADEON_BUS_CNTL, tmp); +- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || +- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || +- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || +- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { +- /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ +- tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; +- RADEON_WRITE(RADEON_BUS_CNTL, tmp); +- } /* PCIE cards appears to not need this */ ++ radeon_enable_bm(dev_priv); + +- dev_priv->scratch[0] = 0; ++ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0); + RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); + +- dev_priv->scratch[1] = 0; ++ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); + RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); + +- dev_priv->scratch[2] = 0; ++ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0); + RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); + + /* reset sarea copies of these */ +@@ -708,12 +823,15 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) + /* Writeback doesn't seem to work everywhere, test it here and possibly + * enable it if it appears to work + */ +- DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); ++ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); ++ + RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); + + for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { +- if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == +- 0xdeadbeef) ++ u32 val; ++ ++ val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); ++ if (val == 0xdeadbeef) + break; + DRM_UDELAY(1); + } +@@ -809,6 +927,82 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) + } + } + ++/* Enable or disable IGP GART on the chip */ ++static void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on) ++{ ++ u32 temp; ++ int i; ++ ++ if (on) { ++ DRM_DEBUG("programming igp gart %08X %08lX %08X\n", ++ dev_priv->gart_vm_start, ++ (long)dev_priv->gart_info.bus_addr, ++ dev_priv->gart_size); ++ ++ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | ++ RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); ++ ++ for (i = 0; i < 19; i++) ++ IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, ++ (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | ++ RS600_SYSTEM_ACCESS_MODE_IN_SYS | ++ RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH | ++ RS600_EFFECTIVE_L1_CACHE_SIZE(3) | ++ RS600_ENABLE_FRAGMENT_PROCESSING | ++ RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); ++ ++ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | ++ RS600_PAGE_TABLE_TYPE_FLAT)); ++ ++ /* disable all other contexts */ ++ for (i = 1; i < 8; i++) ++ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); ++ ++ /* setup the page table aperture */ ++ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, ++ dev_priv->gart_info.bus_addr); ++ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, ++ dev_priv->gart_vm_start); ++ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, ++ (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); ++ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); ++ ++ /* setup the system aperture */ ++ IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, ++ dev_priv->gart_vm_start); ++ IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, ++ (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); ++ ++ /* enable page tables */ ++ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); ++ ++ temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); ++ IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); ++ ++ /* invalidate the cache */ ++ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ ++ temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); ++ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); ++ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ ++ temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; ++ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); ++ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ ++ temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); ++ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); ++ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ ++ } else { ++ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); ++ temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); ++ temp &= ~RS600_ENABLE_PAGE_TABLES; ++ IGP_WRITE_MCIND(RS600_MC_CNTL1, temp); ++ } ++} ++ + static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) + { + u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); +@@ -850,6 +1044,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) + return; + } + ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { ++ rs600_set_igpgart(dev_priv, on); ++ return; ++ } ++ + if (dev_priv->flags & RADEON_IS_PCIE) { + radeon_set_pciegart(dev_priv, on); + return; +@@ -881,6 +1080,46 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) + } + } + ++static int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv) ++{ ++ struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; ++ struct radeon_virt_surface *vp; ++ int i; ++ ++ for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) { ++ if (!dev_priv->virt_surfaces[i].file_priv || ++ dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV) ++ break; ++ } ++ if (i >= 2 * RADEON_MAX_SURFACES) ++ return -ENOMEM; ++ vp = &dev_priv->virt_surfaces[i]; ++ ++ for (i = 0; i < RADEON_MAX_SURFACES; i++) { ++ struct radeon_surface *sp = &dev_priv->surfaces[i]; ++ if (sp->refcount) ++ continue; ++ ++ vp->surface_index = i; ++ vp->lower = gart_info->bus_addr; ++ vp->upper = vp->lower + gart_info->table_size; ++ vp->flags = 0; ++ vp->file_priv = PCIGART_FILE_PRIV; ++ ++ sp->refcount = 1; ++ sp->lower = vp->lower; ++ sp->upper = vp->upper; ++ sp->flags = 0; ++ ++ RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags); ++ RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower); ++ RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper); ++ return 0; ++ } ++ ++ return -ENOMEM; ++} ++ + static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, + struct drm_file *file_priv) + { +@@ -1062,11 +1301,12 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, + } else + #endif + { +- dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; ++ dev_priv->cp_ring->handle = ++ (void *)(unsigned long)dev_priv->cp_ring->offset; + dev_priv->ring_rptr->handle = +- (void *)dev_priv->ring_rptr->offset; ++ (void *)(unsigned long)dev_priv->ring_rptr->offset; + dev->agp_buffer_map->handle = +- (void *)dev->agp_buffer_map->offset; ++ (void *)(unsigned long)dev->agp_buffer_map->offset; + + DRM_DEBUG("dev_priv->cp_ring->handle %p\n", + dev_priv->cp_ring->handle); +@@ -1173,11 +1413,14 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, + } else + #endif + { ++ u32 sctrl; ++ int ret; ++ + dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); + /* if we have an offset set from userspace */ + if (dev_priv->pcigart_offset_set) { + dev_priv->gart_info.bus_addr = +- dev_priv->pcigart_offset + dev_priv->fb_location; ++ (resource_size_t)dev_priv->pcigart_offset + dev_priv->fb_location; + dev_priv->gart_info.mapping.offset = + dev_priv->pcigart_offset + dev_priv->fb_aper_offset; + dev_priv->gart_info.mapping.size = +@@ -1214,12 +1457,31 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, + } + } + +- if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { ++ sctrl = RADEON_READ(RADEON_SURFACE_CNTL); ++ RADEON_WRITE(RADEON_SURFACE_CNTL, 0); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) ++ ret = r600_page_table_init(dev); ++ else ++ ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info); ++ RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl); ++ ++ if (!ret) { + DRM_ERROR("failed to init PCI GART!\n"); + radeon_do_cleanup_cp(dev); + return -ENOMEM; + } + ++ ret = radeon_setup_pcigart_surface(dev_priv); ++ if (ret) { ++ DRM_ERROR("failed to setup GART surface!\n"); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) ++ r600_page_table_cleanup(dev, &dev_priv->gart_info); ++ else ++ drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); ++ radeon_do_cleanup_cp(dev); ++ return ret; ++ } ++ + /* Turn on PCI GART */ + radeon_set_pcigart(dev_priv, 1); + } +@@ -1268,14 +1530,18 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) + if (dev_priv->gart_info.bus_addr) { + /* Turn off PCI GART */ + radeon_set_pcigart(dev_priv, 0); +- if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) +- DRM_ERROR("failed to cleanup PCI GART!\n"); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) ++ r600_page_table_cleanup(dev, &dev_priv->gart_info); ++ else { ++ if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) ++ DRM_ERROR("failed to cleanup PCI GART!\n"); ++ } + } + + if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) + { + drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); +- dev_priv->gart_info.addr = 0; ++ dev_priv->gart_info.addr = NULL; + } + } + /* only clear to the start of flags */ +@@ -1326,6 +1592,7 @@ static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_pri + + int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) + { ++ drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_init_t *init = data; + + LOCK_TEST_WITH_RETURN(dev, file_priv); +@@ -1338,8 +1605,13 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri + case RADEON_INIT_R200_CP: + case RADEON_INIT_R300_CP: + return radeon_do_init_cp(dev, init, file_priv); ++ case RADEON_INIT_R600_CP: ++ return r600_do_init_cp(dev, init, file_priv); + case RADEON_CLEANUP_CP: +- return radeon_do_cleanup_cp(dev); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return r600_do_cleanup_cp(dev); ++ else ++ return radeon_do_cleanup_cp(dev); + } + + return -EINVAL; +@@ -1362,7 +1634,10 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr + return 0; + } + +- radeon_do_cp_start(dev_priv); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ r600_do_cp_start(dev_priv); ++ else ++ radeon_do_cp_start(dev_priv); + + return 0; + } +@@ -1393,7 +1668,10 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri + * code so that the DRM ioctl wrapper can try again. + */ + if (stop->idle) { +- ret = radeon_do_cp_idle(dev_priv); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ ret = r600_do_cp_idle(dev_priv); ++ else ++ ret = radeon_do_cp_idle(dev_priv); + if (ret) + return ret; + } +@@ -1402,10 +1680,16 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri + * we will get some dropped triangles as they won't be fully + * rendered before the CP is shut down. + */ +- radeon_do_cp_stop(dev_priv); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ r600_do_cp_stop(dev_priv); ++ else ++ radeon_do_cp_stop(dev_priv); + + /* Reset the engine */ +- radeon_do_engine_reset(dev); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ r600_do_engine_reset(dev); ++ else ++ radeon_do_engine_reset(dev); + + return 0; + } +@@ -1418,29 +1702,47 @@ void radeon_do_release(struct drm_device * dev) + if (dev_priv) { + if (dev_priv->cp_running) { + /* Stop the cp */ +- while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { +- DRM_DEBUG("radeon_do_cp_idle %d\n", ret); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { ++ while ((ret = r600_do_cp_idle(dev_priv)) != 0) { ++ DRM_DEBUG("radeon_do_cp_idle %d\n", ret); ++#ifdef __linux__ ++ schedule(); ++#else ++ tsleep(&ret, PZERO, "rdnrel", 1); ++#endif ++ } ++ } else { ++ while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { ++ DRM_DEBUG("radeon_do_cp_idle %d\n", ret); + #ifdef __linux__ +- schedule(); ++ schedule(); + #else +- tsleep(&ret, PZERO, "rdnrel", 1); ++ tsleep(&ret, PZERO, "rdnrel", 1); + #endif ++ } ++ } ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { ++ r600_do_cp_stop(dev_priv); ++ r600_do_engine_reset(dev); ++ } else { ++ radeon_do_cp_stop(dev_priv); ++ radeon_do_engine_reset(dev); + } +- radeon_do_cp_stop(dev_priv); +- radeon_do_engine_reset(dev); + } + +- /* Disable *all* interrupts */ +- if (dev_priv->mmio) /* remove this after permanent addmaps */ +- RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); +- +- if (dev_priv->mmio) { /* remove all surfaces */ +- for (i = 0; i < RADEON_MAX_SURFACES; i++) { +- RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); +- RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + +- 16 * i, 0); +- RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + +- 16 * i, 0); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) { ++ /* Disable *all* interrupts */ ++ if (dev_priv->mmio) /* remove this after permanent addmaps */ ++ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); ++ ++ if (dev_priv->mmio) { /* remove all surfaces */ ++ for (i = 0; i < RADEON_MAX_SURFACES; i++) { ++ RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); ++ RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + ++ 16 * i, 0); ++ RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + ++ 16 * i, 0); ++ } + } + } + +@@ -1449,7 +1751,10 @@ void radeon_do_release(struct drm_device * dev) + radeon_mem_takedown(&(dev_priv->fb_heap)); + + /* deallocate kernel resources */ +- radeon_do_cleanup_cp(dev); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ r600_do_cleanup_cp(dev); ++ else ++ radeon_do_cleanup_cp(dev); + } + } + +@@ -1467,7 +1772,10 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr + return -EINVAL; + } + +- radeon_do_cp_reset(dev_priv); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ r600_do_cp_reset(dev_priv); ++ else ++ radeon_do_cp_reset(dev_priv); + + /* The CP is no longer running after an engine reset */ + dev_priv->cp_running = 0; +@@ -1482,23 +1790,36 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri + + LOCK_TEST_WITH_RETURN(dev, file_priv); + +- return radeon_do_cp_idle(dev_priv); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return r600_do_cp_idle(dev_priv); ++ else ++ return radeon_do_cp_idle(dev_priv); + } + + /* Added by Charl P. Botha to call radeon_do_resume_cp(). + */ + int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) + { +- return radeon_do_resume_cp(dev, file_priv); ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ DRM_DEBUG("\n"); ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return r600_do_resume_cp(dev, file_priv); ++ else ++ return radeon_do_resume_cp(dev, file_priv); + } + + int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) + { ++ drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + + LOCK_TEST_WITH_RETURN(dev, file_priv); + +- return radeon_do_engine_reset(dev); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return r600_do_engine_reset(dev); ++ else ++ return radeon_do_engine_reset(dev); + } + + /* ================================================================ +@@ -1548,7 +1869,7 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) + start = dev_priv->last_buf; + + for (t = 0; t < dev_priv->usec_timeout; t++) { +- u32 done_age = GET_SCRATCH(1); ++ u32 done_age = GET_SCRATCH(dev_priv, 1); + DRM_DEBUG("done_age = %d\n", done_age); + for (i = start; i < dma->buf_count; i++) { + buf = dma->buflist[i]; +@@ -1582,8 +1903,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) + struct drm_buf *buf; + int i, t; + int start; +- u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); ++ u32 done_age; + ++ done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); + if (++dev_priv->last_buf >= dma->buf_count) + dev_priv->last_buf = 0; + +@@ -1854,3 +2176,41 @@ int radeon_driver_unload(struct drm_device *dev) + dev->dev_private = NULL; + return 0; + } ++ ++void radeon_commit_ring(drm_radeon_private_t *dev_priv) ++{ ++ int i; ++ u32 *ring; ++ int tail_aligned; ++ ++ /* check if the ring is padded out to 16-dword alignment */ ++ ++ tail_aligned = dev_priv->ring.tail & 0xf; ++ if (tail_aligned) { ++ int num_p2 = 16 - tail_aligned; ++ ++ ring = dev_priv->ring.start; ++ /* pad with some CP_PACKET2 */ ++ for (i = 0; i < num_p2; i++) ++ ring[dev_priv->ring.tail + i] = CP_PACKET2(); ++ ++ dev_priv->ring.tail += i; ++ ++ dev_priv->ring.space -= num_p2 * sizeof(u32); ++ } ++ ++ dev_priv->ring.tail &= dev_priv->ring.tail_mask; ++ ++ DRM_MEMORYBARRIER(); ++ GET_RING_HEAD( dev_priv ); ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { ++ RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); ++ /* read from PCI bus to ensure correct posting */ ++ RADEON_READ(R600_CP_RB_RPTR); ++ } else { ++ RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); ++ /* read from PCI bus to ensure correct posting */ ++ RADEON_READ(RADEON_CP_RB_RPTR); ++ } ++} +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index fef2078..13a60f4 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -41,23 +41,15 @@ int radeon_no_wb; + MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); + module_param_named(no_wb, radeon_no_wb, int, 0444); + +-static int dri_library_name(struct drm_device *dev, char *buf) +-{ +- drm_radeon_private_t *dev_priv = dev->dev_private; +- int family = dev_priv->flags & RADEON_FAMILY_MASK; +- +- return snprintf(buf, PAGE_SIZE, "%s\n", +- (family < CHIP_R200) ? "radeon" : +- ((family < CHIP_R300) ? "r200" : +- "r300")); +-} +- + static int radeon_suspend(struct drm_device *dev, pm_message_t state) + { + drm_radeon_private_t *dev_priv = dev->dev_private; + ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return 0; ++ + /* Disable *all* interrupts */ +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + RADEON_WRITE(R500_DxMODE_INT_MASK, 0); + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); + return 0; +@@ -67,8 +59,11 @@ static int radeon_resume(struct drm_device *dev) + { + drm_radeon_private_t *dev_priv = dev->dev_private; + ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ return 0; ++ + /* Restore interrupt registers */ +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); + RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); + return 0; +@@ -95,7 +90,6 @@ static struct drm_driver driver = { + .get_vblank_counter = radeon_get_vblank_counter, + .enable_vblank = radeon_enable_vblank, + .disable_vblank = radeon_disable_vblank, +- .dri_library_name = dri_library_name, + .master_create = radeon_master_create, + .master_destroy = radeon_master_destroy, + .irq_preinstall = radeon_driver_irq_preinstall, +diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h +index 490bc7c..ed4d27e 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.h ++++ b/drivers/gpu/drm/radeon/radeon_drv.h +@@ -126,6 +126,7 @@ enum radeon_family { + CHIP_RV410, + CHIP_RS400, + CHIP_RS480, ++ CHIP_RS600, + CHIP_RS690, + CHIP_RS740, + CHIP_RV515, +@@ -134,6 +135,16 @@ enum radeon_family { + CHIP_RV560, + CHIP_RV570, + CHIP_R580, ++ CHIP_R600, ++ CHIP_RV610, ++ CHIP_RV630, ++ CHIP_RV620, ++ CHIP_RV635, ++ CHIP_RV670, ++ CHIP_RS780, ++ CHIP_RV770, ++ CHIP_RV730, ++ CHIP_RV710, + CHIP_LAST, + }; + +@@ -160,10 +171,6 @@ enum radeon_chip_flags { + RADEON_IS_IGPGART = 0x01000000UL, + }; + +-#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ +- DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR)) +-#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) +- + typedef struct drm_radeon_freelist { + unsigned int age; + struct drm_buf *buf; +@@ -221,10 +228,11 @@ struct radeon_virt_surface { + u32 upper; + u32 flags; + struct drm_file *file_priv; ++#define PCIGART_FILE_PRIV ((void *) -1L) + }; + +-#define RADEON_FLUSH_EMITED (1 < 0) +-#define RADEON_PURGE_EMITED (1 < 1) ++#define RADEON_FLUSH_EMITED (1 << 0) ++#define RADEON_PURGE_EMITED (1 << 1) + + struct drm_radeon_master_private { + drm_local_map_t *sarea; +@@ -248,7 +256,6 @@ typedef struct drm_radeon_private { + drm_radeon_freelist_t *head; + drm_radeon_freelist_t *tail; + int last_buf; +- volatile u32 *scratch; + int writeback_works; + + int usec_timeout; +@@ -316,11 +323,31 @@ typedef struct drm_radeon_private { + + /* starting from here on, data is preserved accross an open */ + uint32_t flags; /* see radeon_chip_flags */ +- unsigned long fb_aper_offset; ++ resource_size_t fb_aper_offset; + + int num_gb_pipes; + int track_flush; + drm_local_map_t *mmio; ++ ++ /* r6xx/r7xx pipe/shader config */ ++ int r600_max_pipes; ++ int r600_max_tile_pipes; ++ int r600_max_simds; ++ int r600_max_backends; ++ int r600_max_gprs; ++ int r600_max_threads; ++ int r600_max_stack_entries; ++ int r600_max_hw_contexts; ++ int r600_max_gs_threads; ++ int r600_sx_max_export_size; ++ int r600_sx_max_export_pos_size; ++ int r600_sx_max_export_smx_size; ++ int r600_sq_num_cf_insts; ++ int r700_sx_num_of_sets; ++ int r700_sc_prim_fifo_size; ++ int r700_sc_hiz_tile_fifo_size; ++ int r700_sc_earlyz_tile_fifo_fize; ++ + } drm_radeon_private_t; + + typedef struct drm_radeon_buf_priv { +@@ -338,6 +365,12 @@ extern int radeon_no_wb; + extern struct drm_ioctl_desc radeon_ioctls[]; + extern int radeon_max_ioctl; + ++extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv); ++extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val); ++ ++#define GET_RING_HEAD(dev_priv) radeon_get_ring_head(dev_priv) ++#define SET_RING_HEAD(dev_priv, val) radeon_set_ring_head(dev_priv, val) ++ + /* Check whether the given hardware address is inside the framebuffer or the + * GART area. + */ +@@ -364,6 +397,9 @@ extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_fi + extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); + extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); + extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv); ++extern void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc); ++extern void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base); ++extern u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr); + + extern void radeon_freelist_reset(struct drm_device * dev); + extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); +@@ -383,6 +419,10 @@ extern void radeon_mem_takedown(struct mem_block **heap); + extern void radeon_mem_release(struct drm_file *file_priv, + struct mem_block *heap); + ++extern void radeon_enable_bm(struct drm_radeon_private *dev_priv); ++extern u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off); ++extern void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val); ++ + /* radeon_irq.c */ + extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state); + extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); +@@ -423,6 +463,21 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + struct drm_file *file_priv, + drm_radeon_kcmd_buffer_t *cmdbuf); + ++/* r600_cp.c */ ++extern int r600_do_engine_reset(struct drm_device *dev); ++extern int r600_do_cleanup_cp(struct drm_device *dev); ++extern int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, ++ struct drm_file *file_priv); ++extern int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv); ++extern int r600_do_cp_idle(drm_radeon_private_t *dev_priv); ++extern void r600_do_cp_start(drm_radeon_private_t *dev_priv); ++extern void r600_do_cp_reset(drm_radeon_private_t *dev_priv); ++extern void r600_do_cp_stop(drm_radeon_private_t *dev_priv); ++extern int r600_cp_dispatch_indirect(struct drm_device *dev, ++ struct drm_buf *buf, int start, int end); ++extern int r600_page_table_init(struct drm_device *dev); ++extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); ++ + /* Flags for stats.boxes + */ + #define RADEON_BOX_DMA_IDLE 0x1 +@@ -434,6 +489,8 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + /* Register definitions, register access macros and drmAddMap constants + * for Radeon kernel driver. + */ ++#define RADEON_MM_INDEX 0x0000 ++#define RADEON_MM_DATA 0x0004 + + #define RADEON_AGP_COMMAND 0x0f60 + #define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ +@@ -556,6 +613,56 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + #define RS690_MC_AGP_BASE 0x102 + #define RS690_MC_AGP_BASE_2 0x103 + ++#define RS600_MC_INDEX 0x70 ++# define RS600_MC_ADDR_MASK 0xffff ++# define RS600_MC_IND_SEQ_RBS_0 (1 << 16) ++# define RS600_MC_IND_SEQ_RBS_1 (1 << 17) ++# define RS600_MC_IND_SEQ_RBS_2 (1 << 18) ++# define RS600_MC_IND_SEQ_RBS_3 (1 << 19) ++# define RS600_MC_IND_AIC_RBS (1 << 20) ++# define RS600_MC_IND_CITF_ARB0 (1 << 21) ++# define RS600_MC_IND_CITF_ARB1 (1 << 22) ++# define RS600_MC_IND_WR_EN (1 << 23) ++#define RS600_MC_DATA 0x74 ++ ++#define RS600_MC_STATUS 0x0 ++# define RS600_MC_IDLE (1 << 1) ++#define RS600_MC_FB_LOCATION 0x4 ++#define RS600_MC_AGP_LOCATION 0x5 ++#define RS600_AGP_BASE 0x6 ++#define RS600_AGP_BASE_2 0x7 ++#define RS600_MC_CNTL1 0x9 ++# define RS600_ENABLE_PAGE_TABLES (1 << 26) ++#define RS600_MC_PT0_CNTL 0x100 ++# define RS600_ENABLE_PT (1 << 0) ++# define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15) ++# define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21) ++# define RS600_INVALIDATE_ALL_L1_TLBS (1 << 28) ++# define RS600_INVALIDATE_L2_CACHE (1 << 29) ++#define RS600_MC_PT0_CONTEXT0_CNTL 0x102 ++# define RS600_ENABLE_PAGE_TABLE (1 << 0) ++# define RS600_PAGE_TABLE_TYPE_FLAT (0 << 1) ++#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x112 ++#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x114 ++#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c ++#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x12c ++#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x13c ++#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x14c ++#define RS600_MC_PT0_CLIENT0_CNTL 0x16c ++# define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE (1 << 0) ++# define RS600_TRANSLATION_MODE_OVERRIDE (1 << 1) ++# define RS600_SYSTEM_ACCESS_MODE_MASK (3 << 8) ++# define RS600_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 8) ++# define RS600_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 8) ++# define RS600_SYSTEM_ACCESS_MODE_IN_SYS (2 << 8) ++# define RS600_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 8) ++# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH (0 << 10) ++# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 10) ++# define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11) ++# define RS600_ENABLE_FRAGMENT_PROCESSING (1 << 14) ++# define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) ++# define RS600_INVALIDATE_L1_TLB (1 << 20) ++ + #define R520_MC_IND_INDEX 0x70 + #define R520_MC_IND_WR_EN (1 << 24) + #define R520_MC_IND_DATA 0x74 +@@ -580,7 +687,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + /* pipe config regs */ + #define R400_GB_PIPE_SELECT 0x402c + #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ +-#define R500_SU_REG_DEST 0x42c8 + #define R300_GB_TILE_CONFIG 0x4018 + # define R300_ENABLE_TILING (1 << 0) + # define R300_PIPE_COUNT_RV350 (0 << 1) +@@ -639,9 +745,22 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + + #define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) + +-#define GET_SCRATCH( x ) (dev_priv->writeback_works \ +- ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ +- : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) ++extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); ++ ++#define GET_SCRATCH(dev_priv, x) radeon_get_scratch(dev_priv, x) ++ ++#define R600_SCRATCH_REG0 0x8500 ++#define R600_SCRATCH_REG1 0x8504 ++#define R600_SCRATCH_REG2 0x8508 ++#define R600_SCRATCH_REG3 0x850c ++#define R600_SCRATCH_REG4 0x8510 ++#define R600_SCRATCH_REG5 0x8514 ++#define R600_SCRATCH_REG6 0x8518 ++#define R600_SCRATCH_REG7 0x851c ++#define R600_SCRATCH_UMSK 0x8540 ++#define R600_SCRATCH_ADDR 0x8544 ++ ++#define R600_SCRATCHOFF(x) (R600_SCRATCH_REG_OFFSET + 4*(x)) + + #define RADEON_GEN_INT_CNTL 0x0040 + # define RADEON_CRTC_VBLANK_MASK (1 << 0) +@@ -922,6 +1041,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + #define RADEON_CP_RB_CNTL 0x0704 + # define RADEON_BUF_SWAP_32BIT (2 << 16) + # define RADEON_RB_NO_UPDATE (1 << 27) ++# define RADEON_RB_RPTR_WR_ENA (1 << 31) + #define RADEON_CP_RB_RPTR_ADDR 0x070c + #define RADEON_CP_RB_RPTR 0x0710 + #define RADEON_CP_RB_WPTR 0x0714 +@@ -983,6 +1103,14 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 + # define RADEON_CNTL_SET_SCISSORS 0xC0001E00 + ++# define R600_IT_INDIRECT_BUFFER 0x00003200 ++# define R600_IT_ME_INITIALIZE 0x00004400 ++# define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) ++# define R600_IT_EVENT_WRITE 0x00004600 ++# define R600_IT_SET_CONFIG_REG 0x00006800 ++# define R600_SET_CONFIG_REG_OFFSET 0x00008000 ++# define R600_SET_CONFIG_REG_END 0x0000ac00 ++ + #define RADEON_CP_PACKET_MASK 0xC0000000 + #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 + #define RADEON_CP_PACKET0_REG_MASK 0x000007ff +@@ -1181,6 +1309,422 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + #define R500_D1_VBLANK_INTERRUPT (1 << 4) + #define R500_D2_VBLANK_INTERRUPT (1 << 5) + ++/* R6xx/R7xx registers */ ++#define R600_MC_VM_FB_LOCATION 0x2180 ++#define R600_MC_VM_AGP_TOP 0x2184 ++#define R600_MC_VM_AGP_BOT 0x2188 ++#define R600_MC_VM_AGP_BASE 0x218c ++#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 ++#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 ++#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 ++ ++#define R700_MC_VM_FB_LOCATION 0x2024 ++#define R700_MC_VM_AGP_TOP 0x2028 ++#define R700_MC_VM_AGP_BOT 0x202c ++#define R700_MC_VM_AGP_BASE 0x2030 ++#define R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 ++#define R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 ++#define R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203c ++ ++#define R600_MCD_RD_A_CNTL 0x219c ++#define R600_MCD_RD_B_CNTL 0x21a0 ++ ++#define R600_MCD_WR_A_CNTL 0x21a4 ++#define R600_MCD_WR_B_CNTL 0x21a8 ++ ++#define R600_MCD_RD_SYS_CNTL 0x2200 ++#define R600_MCD_WR_SYS_CNTL 0x2214 ++ ++#define R600_MCD_RD_GFX_CNTL 0x21fc ++#define R600_MCD_RD_HDP_CNTL 0x2204 ++#define R600_MCD_RD_PDMA_CNTL 0x2208 ++#define R600_MCD_RD_SEM_CNTL 0x220c ++#define R600_MCD_WR_GFX_CNTL 0x2210 ++#define R600_MCD_WR_HDP_CNTL 0x2218 ++#define R600_MCD_WR_PDMA_CNTL 0x221c ++#define R600_MCD_WR_SEM_CNTL 0x2220 ++ ++# define R600_MCD_L1_TLB (1 << 0) ++# define R600_MCD_L1_FRAG_PROC (1 << 1) ++# define R600_MCD_L1_STRICT_ORDERING (1 << 2) ++ ++# define R600_MCD_SYSTEM_ACCESS_MODE_MASK (3 << 6) ++# define R600_MCD_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6) ++# define R600_MCD_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6) ++# define R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS (2 << 6) ++# define R600_MCD_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6) ++ ++# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8) ++# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8) ++ ++# define R600_MCD_SEMAPHORE_MODE (1 << 10) ++# define R600_MCD_WAIT_L2_QUERY (1 << 11) ++# define R600_MCD_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 12) ++# define R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) ++ ++#define R700_MC_VM_MD_L1_TLB0_CNTL 0x2654 ++#define R700_MC_VM_MD_L1_TLB1_CNTL 0x2658 ++#define R700_MC_VM_MD_L1_TLB2_CNTL 0x265c ++ ++#define R700_MC_VM_MB_L1_TLB0_CNTL 0x2234 ++#define R700_MC_VM_MB_L1_TLB1_CNTL 0x2238 ++#define R700_MC_VM_MB_L1_TLB2_CNTL 0x223c ++#define R700_MC_VM_MB_L1_TLB3_CNTL 0x2240 ++ ++# define R700_ENABLE_L1_TLB (1 << 0) ++# define R700_ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) ++# define R700_SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) ++# define R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) ++# define R700_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 15) ++# define R700_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 18) ++ ++#define R700_MC_ARB_RAMCFG 0x2760 ++# define R700_NOOFBANK_SHIFT 0 ++# define R700_NOOFBANK_MASK 0x3 ++# define R700_NOOFRANK_SHIFT 2 ++# define R700_NOOFRANK_MASK 0x1 ++# define R700_NOOFROWS_SHIFT 3 ++# define R700_NOOFROWS_MASK 0x7 ++# define R700_NOOFCOLS_SHIFT 6 ++# define R700_NOOFCOLS_MASK 0x3 ++# define R700_CHANSIZE_SHIFT 8 ++# define R700_CHANSIZE_MASK 0x1 ++# define R700_BURSTLENGTH_SHIFT 9 ++# define R700_BURSTLENGTH_MASK 0x1 ++#define R600_RAMCFG 0x2408 ++# define R600_NOOFBANK_SHIFT 0 ++# define R600_NOOFBANK_MASK 0x1 ++# define R600_NOOFRANK_SHIFT 1 ++# define R600_NOOFRANK_MASK 0x1 ++# define R600_NOOFROWS_SHIFT 2 ++# define R600_NOOFROWS_MASK 0x7 ++# define R600_NOOFCOLS_SHIFT 5 ++# define R600_NOOFCOLS_MASK 0x3 ++# define R600_CHANSIZE_SHIFT 7 ++# define R600_CHANSIZE_MASK 0x1 ++# define R600_BURSTLENGTH_SHIFT 8 ++# define R600_BURSTLENGTH_MASK 0x1 ++ ++#define R600_VM_L2_CNTL 0x1400 ++# define R600_VM_L2_CACHE_EN (1 << 0) ++# define R600_VM_L2_FRAG_PROC (1 << 1) ++# define R600_VM_ENABLE_PTE_CACHE_LRU_W (1 << 9) ++# define R600_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 13) ++# define R700_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 14) ++ ++#define R600_VM_L2_CNTL2 0x1404 ++# define R600_VM_L2_CNTL2_INVALIDATE_ALL_L1_TLBS (1 << 0) ++# define R600_VM_L2_CNTL2_INVALIDATE_L2_CACHE (1 << 1) ++#define R600_VM_L2_CNTL3 0x1408 ++# define R600_VM_L2_CNTL3_BANK_SELECT_0(x) ((x) << 0) ++# define R600_VM_L2_CNTL3_BANK_SELECT_1(x) ((x) << 5) ++# define R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 10) ++# define R700_VM_L2_CNTL3_BANK_SELECT(x) ((x) << 0) ++# define R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 6) ++ ++#define R600_VM_L2_STATUS 0x140c ++ ++#define R600_VM_CONTEXT0_CNTL 0x1410 ++# define R600_VM_ENABLE_CONTEXT (1 << 0) ++# define R600_VM_PAGE_TABLE_DEPTH_FLAT (0 << 1) ++ ++#define R600_VM_CONTEXT0_CNTL2 0x1430 ++#define R600_VM_CONTEXT0_REQUEST_RESPONSE 0x1470 ++#define R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490 ++#define R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14b0 ++#define R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574 ++#define R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594 ++#define R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15b4 ++ ++#define R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153c ++#define R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155c ++#define R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157c ++ ++#define R600_HDP_HOST_PATH_CNTL 0x2c00 ++ ++#define R600_GRBM_CNTL 0x8000 ++# define R600_GRBM_READ_TIMEOUT(x) ((x) << 0) ++ ++#define R600_GRBM_STATUS 0x8010 ++# define R600_CMDFIFO_AVAIL_MASK 0x1f ++# define R700_CMDFIFO_AVAIL_MASK 0xf ++# define R600_GUI_ACTIVE (1 << 31) ++#define R600_GRBM_STATUS2 0x8014 ++#define R600_GRBM_SOFT_RESET 0x8020 ++# define R600_SOFT_RESET_CP (1 << 0) ++#define R600_WAIT_UNTIL 0x8040 ++ ++#define R600_CP_SEM_WAIT_TIMER 0x85bc ++#define R600_CP_ME_CNTL 0x86d8 ++# define R600_CP_ME_HALT (1 << 28) ++#define R600_CP_QUEUE_THRESHOLDS 0x8760 ++# define R600_ROQ_IB1_START(x) ((x) << 0) ++# define R600_ROQ_IB2_START(x) ((x) << 8) ++#define R600_CP_MEQ_THRESHOLDS 0x8764 ++# define R700_STQ_SPLIT(x) ((x) << 0) ++# define R600_MEQ_END(x) ((x) << 16) ++# define R600_ROQ_END(x) ((x) << 24) ++#define R600_CP_PERFMON_CNTL 0x87fc ++#define R600_CP_RB_BASE 0xc100 ++#define R600_CP_RB_CNTL 0xc104 ++# define R600_RB_BUFSZ(x) ((x) << 0) ++# define R600_RB_BLKSZ(x) ((x) << 8) ++# define R600_RB_NO_UPDATE (1 << 27) ++# define R600_RB_RPTR_WR_ENA (1 << 31) ++#define R600_CP_RB_RPTR_WR 0xc108 ++#define R600_CP_RB_RPTR_ADDR 0xc10c ++#define R600_CP_RB_RPTR_ADDR_HI 0xc110 ++#define R600_CP_RB_WPTR 0xc114 ++#define R600_CP_RB_WPTR_ADDR 0xc118 ++#define R600_CP_RB_WPTR_ADDR_HI 0xc11c ++#define R600_CP_RB_RPTR 0x8700 ++#define R600_CP_RB_WPTR_DELAY 0x8704 ++#define R600_CP_PFP_UCODE_ADDR 0xc150 ++#define R600_CP_PFP_UCODE_DATA 0xc154 ++#define R600_CP_ME_RAM_RADDR 0xc158 ++#define R600_CP_ME_RAM_WADDR 0xc15c ++#define R600_CP_ME_RAM_DATA 0xc160 ++#define R600_CP_DEBUG 0xc1fc ++ ++#define R600_PA_CL_ENHANCE 0x8a14 ++# define R600_CLIP_VTX_REORDER_ENA (1 << 0) ++# define R600_NUM_CLIP_SEQ(x) ((x) << 1) ++#define R600_PA_SC_LINE_STIPPLE_STATE 0x8b10 ++#define R600_PA_SC_MULTI_CHIP_CNTL 0x8b20 ++#define R700_PA_SC_FORCE_EOV_MAX_CNTS 0x8b24 ++# define R700_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) ++# define R700_FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) ++#define R600_PA_SC_AA_SAMPLE_LOCS_2S 0x8b40 ++#define R600_PA_SC_AA_SAMPLE_LOCS_4S 0x8b44 ++#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8b48 ++#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8b4c ++# define R600_S0_X(x) ((x) << 0) ++# define R600_S0_Y(x) ((x) << 4) ++# define R600_S1_X(x) ((x) << 8) ++# define R600_S1_Y(x) ((x) << 12) ++# define R600_S2_X(x) ((x) << 16) ++# define R600_S2_Y(x) ((x) << 20) ++# define R600_S3_X(x) ((x) << 24) ++# define R600_S3_Y(x) ((x) << 28) ++# define R600_S4_X(x) ((x) << 0) ++# define R600_S4_Y(x) ((x) << 4) ++# define R600_S5_X(x) ((x) << 8) ++# define R600_S5_Y(x) ((x) << 12) ++# define R600_S6_X(x) ((x) << 16) ++# define R600_S6_Y(x) ((x) << 20) ++# define R600_S7_X(x) ((x) << 24) ++# define R600_S7_Y(x) ((x) << 28) ++#define R600_PA_SC_FIFO_SIZE 0x8bd0 ++# define R600_SC_PRIM_FIFO_SIZE(x) ((x) << 0) ++# define R600_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 8) ++# define R600_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 16) ++#define R700_PA_SC_FIFO_SIZE_R7XX 0x8bcc ++# define R700_SC_PRIM_FIFO_SIZE(x) ((x) << 0) ++# define R700_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) ++# define R700_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) ++#define R600_PA_SC_ENHANCE 0x8bf0 ++# define R600_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) ++# define R600_FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12) ++#define R600_PA_SC_CLIPRECT_RULE 0x2820c ++#define R700_PA_SC_EDGERULE 0x28230 ++#define R600_PA_SC_LINE_STIPPLE 0x28a0c ++#define R600_PA_SC_MODE_CNTL 0x28a4c ++#define R600_PA_SC_AA_CONFIG 0x28c04 ++ ++#define R600_SX_EXPORT_BUFFER_SIZES 0x900c ++# define R600_COLOR_BUFFER_SIZE(x) ((x) << 0) ++# define R600_POSITION_BUFFER_SIZE(x) ((x) << 8) ++# define R600_SMX_BUFFER_SIZE(x) ((x) << 16) ++#define R600_SX_DEBUG_1 0x9054 ++# define R600_SMX_EVENT_RELEASE (1 << 0) ++# define R600_ENABLE_NEW_SMX_ADDRESS (1 << 16) ++#define R700_SX_DEBUG_1 0x9058 ++# define R700_ENABLE_NEW_SMX_ADDRESS (1 << 16) ++#define R600_SX_MISC 0x28350 ++ ++#define R600_DB_DEBUG 0x9830 ++# define R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) ++#define R600_DB_WATERMARKS 0x9838 ++# define R600_DEPTH_FREE(x) ((x) << 0) ++# define R600_DEPTH_FLUSH(x) ((x) << 5) ++# define R600_DEPTH_PENDING_FREE(x) ((x) << 15) ++# define R600_DEPTH_CACHELINE_FREE(x) ((x) << 20) ++#define R700_DB_DEBUG3 0x98b0 ++# define R700_DB_CLK_OFF_DELAY(x) ((x) << 11) ++#define RV700_DB_DEBUG4 0x9b8c ++# define RV700_DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6) ++ ++#define R600_VGT_CACHE_INVALIDATION 0x88c4 ++# define R600_CACHE_INVALIDATION(x) ((x) << 0) ++# define R600_VC_ONLY 0 ++# define R600_TC_ONLY 1 ++# define R600_VC_AND_TC 2 ++# define R700_AUTO_INVLD_EN(x) ((x) << 6) ++# define R700_NO_AUTO 0 ++# define R700_ES_AUTO 1 ++# define R700_GS_AUTO 2 ++# define R700_ES_AND_GS_AUTO 3 ++#define R600_VGT_GS_PER_ES 0x88c8 ++#define R600_VGT_ES_PER_GS 0x88cc ++#define R600_VGT_GS_PER_VS 0x88e8 ++#define R600_VGT_GS_VERTEX_REUSE 0x88d4 ++#define R600_VGT_NUM_INSTANCES 0x8974 ++#define R600_VGT_STRMOUT_EN 0x28ab0 ++#define R600_VGT_EVENT_INITIATOR 0x28a90 ++# define R600_CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) ++#define R600_VGT_VERTEX_REUSE_BLOCK_CNTL 0x28c58 ++# define R600_VTX_REUSE_DEPTH_MASK 0xff ++#define R600_VGT_OUT_DEALLOC_CNTL 0x28c5c ++# define R600_DEALLOC_DIST_MASK 0x7f ++ ++#define R600_CB_COLOR0_BASE 0x28040 ++#define R600_CB_COLOR1_BASE 0x28044 ++#define R600_CB_COLOR2_BASE 0x28048 ++#define R600_CB_COLOR3_BASE 0x2804c ++#define R600_CB_COLOR4_BASE 0x28050 ++#define R600_CB_COLOR5_BASE 0x28054 ++#define R600_CB_COLOR6_BASE 0x28058 ++#define R600_CB_COLOR7_BASE 0x2805c ++#define R600_CB_COLOR7_FRAG 0x280fc ++ ++#define R600_TC_CNTL 0x9608 ++# define R600_TC_L2_SIZE(x) ((x) << 5) ++# define R600_L2_DISABLE_LATE_HIT (1 << 9) ++ ++#define R600_ARB_POP 0x2418 ++# define R600_ENABLE_TC128 (1 << 30) ++#define R600_ARB_GDEC_RD_CNTL 0x246c ++ ++#define R600_TA_CNTL_AUX 0x9508 ++# define R600_DISABLE_CUBE_WRAP (1 << 0) ++# define R600_DISABLE_CUBE_ANISO (1 << 1) ++# define R700_GETLOD_SELECT(x) ((x) << 2) ++# define R600_SYNC_GRADIENT (1 << 24) ++# define R600_SYNC_WALKER (1 << 25) ++# define R600_SYNC_ALIGNER (1 << 26) ++# define R600_BILINEAR_PRECISION_6_BIT (0 << 31) ++# define R600_BILINEAR_PRECISION_8_BIT (1 << 31) ++ ++#define R700_TCP_CNTL 0x9610 ++ ++#define R600_SMX_DC_CTL0 0xa020 ++# define R700_USE_HASH_FUNCTION (1 << 0) ++# define R700_CACHE_DEPTH(x) ((x) << 1) ++# define R700_FLUSH_ALL_ON_EVENT (1 << 10) ++# define R700_STALL_ON_EVENT (1 << 11) ++#define R700_SMX_EVENT_CTL 0xa02c ++# define R700_ES_FLUSH_CTL(x) ((x) << 0) ++# define R700_GS_FLUSH_CTL(x) ((x) << 3) ++# define R700_ACK_FLUSH_CTL(x) ((x) << 6) ++# define R700_SYNC_FLUSH_CTL (1 << 8) ++ ++#define R600_SQ_CONFIG 0x8c00 ++# define R600_VC_ENABLE (1 << 0) ++# define R600_EXPORT_SRC_C (1 << 1) ++# define R600_DX9_CONSTS (1 << 2) ++# define R600_ALU_INST_PREFER_VECTOR (1 << 3) ++# define R600_DX10_CLAMP (1 << 4) ++# define R600_CLAUSE_SEQ_PRIO(x) ((x) << 8) ++# define R600_PS_PRIO(x) ((x) << 24) ++# define R600_VS_PRIO(x) ((x) << 26) ++# define R600_GS_PRIO(x) ((x) << 28) ++# define R600_ES_PRIO(x) ((x) << 30) ++#define R600_SQ_GPR_RESOURCE_MGMT_1 0x8c04 ++# define R600_NUM_PS_GPRS(x) ((x) << 0) ++# define R600_NUM_VS_GPRS(x) ((x) << 16) ++# define R700_DYN_GPR_ENABLE (1 << 27) ++# define R600_NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) ++#define R600_SQ_GPR_RESOURCE_MGMT_2 0x8c08 ++# define R600_NUM_GS_GPRS(x) ((x) << 0) ++# define R600_NUM_ES_GPRS(x) ((x) << 16) ++#define R600_SQ_THREAD_RESOURCE_MGMT 0x8c0c ++# define R600_NUM_PS_THREADS(x) ((x) << 0) ++# define R600_NUM_VS_THREADS(x) ((x) << 8) ++# define R600_NUM_GS_THREADS(x) ((x) << 16) ++# define R600_NUM_ES_THREADS(x) ((x) << 24) ++#define R600_SQ_STACK_RESOURCE_MGMT_1 0x8c10 ++# define R600_NUM_PS_STACK_ENTRIES(x) ((x) << 0) ++# define R600_NUM_VS_STACK_ENTRIES(x) ((x) << 16) ++#define R600_SQ_STACK_RESOURCE_MGMT_2 0x8c14 ++# define R600_NUM_GS_STACK_ENTRIES(x) ((x) << 0) ++# define R600_NUM_ES_STACK_ENTRIES(x) ((x) << 16) ++#define R600_SQ_MS_FIFO_SIZES 0x8cf0 ++# define R600_CACHE_FIFO_SIZE(x) ((x) << 0) ++# define R600_FETCH_FIFO_HIWATER(x) ((x) << 8) ++# define R600_DONE_FIFO_HIWATER(x) ((x) << 16) ++# define R600_ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) ++#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8db0 ++# define R700_SIMDA_RING0(x) ((x) << 0) ++# define R700_SIMDA_RING1(x) ((x) << 8) ++# define R700_SIMDB_RING0(x) ((x) << 16) ++# define R700_SIMDB_RING1(x) ((x) << 24) ++#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8db4 ++#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8db8 ++#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8dbc ++#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8dc0 ++#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8dc4 ++#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8dc8 ++#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8dcc ++ ++#define R600_SPI_PS_IN_CONTROL_0 0x286cc ++# define R600_NUM_INTERP(x) ((x) << 0) ++# define R600_POSITION_ENA (1 << 8) ++# define R600_POSITION_CENTROID (1 << 9) ++# define R600_POSITION_ADDR(x) ((x) << 10) ++# define R600_PARAM_GEN(x) ((x) << 15) ++# define R600_PARAM_GEN_ADDR(x) ((x) << 19) ++# define R600_BARYC_SAMPLE_CNTL(x) ((x) << 26) ++# define R600_PERSP_GRADIENT_ENA (1 << 28) ++# define R600_LINEAR_GRADIENT_ENA (1 << 29) ++# define R600_POSITION_SAMPLE (1 << 30) ++# define R600_BARYC_AT_SAMPLE_ENA (1 << 31) ++#define R600_SPI_PS_IN_CONTROL_1 0x286d0 ++# define R600_GEN_INDEX_PIX (1 << 0) ++# define R600_GEN_INDEX_PIX_ADDR(x) ((x) << 1) ++# define R600_FRONT_FACE_ENA (1 << 8) ++# define R600_FRONT_FACE_CHAN(x) ((x) << 9) ++# define R600_FRONT_FACE_ALL_BITS (1 << 11) ++# define R600_FRONT_FACE_ADDR(x) ((x) << 12) ++# define R600_FOG_ADDR(x) ((x) << 17) ++# define R600_FIXED_PT_POSITION_ENA (1 << 24) ++# define R600_FIXED_PT_POSITION_ADDR(x) ((x) << 25) ++# define R700_POSITION_ULC (1 << 30) ++#define R600_SPI_INPUT_Z 0x286d8 ++ ++#define R600_SPI_CONFIG_CNTL 0x9100 ++# define R600_GPR_WRITE_PRIORITY(x) ((x) << 0) ++# define R600_DISABLE_INTERP_1 (1 << 5) ++#define R600_SPI_CONFIG_CNTL_1 0x913c ++# define R600_VTX_DONE_DELAY(x) ((x) << 0) ++# define R600_INTERP_ONE_PRIM_PER_ROW (1 << 4) ++ ++#define R600_GB_TILING_CONFIG 0x98f0 ++# define R600_PIPE_TILING(x) ((x) << 1) ++# define R600_BANK_TILING(x) ((x) << 4) ++# define R600_GROUP_SIZE(x) ((x) << 6) ++# define R600_ROW_TILING(x) ((x) << 8) ++# define R600_BANK_SWAPS(x) ((x) << 11) ++# define R600_SAMPLE_SPLIT(x) ((x) << 14) ++# define R600_BACKEND_MAP(x) ((x) << 16) ++#define R600_DCP_TILING_CONFIG 0x6ca0 ++#define R600_HDP_TILING_CONFIG 0x2f3c ++ ++#define R600_CC_RB_BACKEND_DISABLE 0x98f4 ++#define R700_CC_SYS_RB_BACKEND_DISABLE 0x3f88 ++# define R600_BACKEND_DISABLE(x) ((x) << 16) ++ ++#define R600_CC_GC_SHADER_PIPE_CONFIG 0x8950 ++#define R600_GC_USER_SHADER_PIPE_CONFIG 0x8954 ++# define R600_INACTIVE_QD_PIPES(x) ((x) << 8) ++# define R600_INACTIVE_QD_PIPES_MASK (0xff << 8) ++# define R600_INACTIVE_SIMDS(x) ((x) << 16) ++# define R600_INACTIVE_SIMDS_MASK (0xff << 16) ++ ++#define R700_CGTS_SYS_TCC_DISABLE 0x3f90 ++#define R700_CGTS_USER_SYS_TCC_DISABLE 0x3f94 ++#define R700_CGTS_TCC_DISABLE 0x9148 ++#define R700_CGTS_USER_TCC_DISABLE 0x914c ++ + /* Constants */ + #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ + +@@ -1190,6 +1734,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + #define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3 + #define RADEON_LAST_DISPATCH 1 + ++#define R600_LAST_FRAME_REG R600_SCRATCH_REG0 ++#define R600_LAST_DISPATCH_REG R600_SCRATCH_REG1 ++#define R600_LAST_CLEAR_REG R600_SCRATCH_REG2 ++#define R600_LAST_SWI_REG R600_SCRATCH_REG3 ++ + #define RADEON_MAX_VB_AGE 0x7fffffff + #define RADEON_MAX_VB_VERTS (0xffff) + +@@ -1198,7 +1747,15 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, + #define RADEON_PCIGART_TABLE_SIZE (32*1024) + + #define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) +-#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) ++#define RADEON_WRITE(reg, val) \ ++do { \ ++ if (reg < 0x10000) { \ ++ DRM_WRITE32(dev_priv->mmio, (reg), (val)); \ ++ } else { \ ++ DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, (reg)); \ ++ DRM_WRITE32(dev_priv->mmio, RADEON_MM_DATA, (val)); \ ++ } \ ++} while (0) + #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) + #define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) + +@@ -1238,11 +1795,19 @@ do { \ + RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ + } while (0) + ++#define RS600_WRITE_MCIND(addr, val) \ ++do { \ ++ RADEON_WRITE(RS600_MC_INDEX, RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | ((addr) & RS600_MC_ADDR_MASK)); \ ++ RADEON_WRITE(RS600_MC_DATA, val); \ ++} while (0) ++ + #define IGP_WRITE_MCIND(addr, val) \ + do { \ + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ + RS690_WRITE_MCIND(addr, val); \ ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) \ ++ RS600_WRITE_MCIND(addr, val); \ + else \ + RS480_WRITE_MCIND(addr, val); \ + } while (0) +@@ -1346,7 +1911,11 @@ do { \ + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \ + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \ + if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ +- int __ret = radeon_do_cp_idle( dev_priv ); \ ++ int __ret; \ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) \ ++ __ret = r600_do_cp_idle(dev_priv); \ ++ else \ ++ __ret = radeon_do_cp_idle(dev_priv); \ + if ( __ret ) return __ret; \ + sarea_priv->last_dispatch = 0; \ + radeon_freelist_reset( dev ); \ +@@ -1368,21 +1937,40 @@ do { \ + OUT_RING( age ); \ + } while (0) + ++#define R600_DISPATCH_AGE(age) do { \ ++ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ ++ OUT_RING((R600_LAST_DISPATCH_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ ++ OUT_RING(age); \ ++} while (0) ++ ++#define R600_FRAME_AGE(age) do { \ ++ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ ++ OUT_RING((R600_LAST_FRAME_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ ++ OUT_RING(age); \ ++} while (0) ++ ++#define R600_CLEAR_AGE(age) do { \ ++ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ ++ OUT_RING((R600_LAST_CLEAR_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ ++ OUT_RING(age); \ ++} while (0) ++ + /* ================================================================ + * Ring control + */ + + #define RADEON_VERBOSE 0 + +-#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; ++#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; + + #define BEGIN_RING( n ) do { \ + if ( RADEON_VERBOSE ) { \ + DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ + } \ +- if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ ++ _align_nr = (n + 0xf) & ~0xf; \ ++ if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ + COMMIT_RING(); \ +- radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ ++ radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \ + } \ + _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ + ring = dev_priv->ring.start; \ +@@ -1399,19 +1987,16 @@ do { \ + DRM_ERROR( \ + "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ + ((dev_priv->ring.tail + _nr) & mask), \ +- write, __LINE__); \ ++ write, __LINE__); \ + } else \ + dev_priv->ring.tail = write; \ + } while (0) + ++extern void radeon_commit_ring(drm_radeon_private_t *dev_priv); ++ + #define COMMIT_RING() do { \ +- /* Flush writes to ring */ \ +- DRM_MEMORYBARRIER(); \ +- GET_RING_HEAD( dev_priv ); \ +- RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ +- /* read from PCI bus to ensure correct posting */ \ +- RADEON_READ( RADEON_CP_RB_RPTR ); \ +-} while (0) ++ radeon_commit_ring(dev_priv); \ ++ } while(0) + + #define OUT_RING( x ) do { \ + if ( RADEON_VERBOSE ) { \ +diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c +index 8289e16..9836c70 100644 +--- a/drivers/gpu/drm/radeon/radeon_irq.c ++++ b/drivers/gpu/drm/radeon/radeon_irq.c +@@ -65,7 +65,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc) + { + drm_radeon_private_t *dev_priv = dev->dev_private; + +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + switch (crtc) { + case 0: + r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); +@@ -100,7 +100,7 @@ void radeon_disable_vblank(struct drm_device *dev, int crtc) + { + drm_radeon_private_t *dev_priv = dev->dev_private; + +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + switch (crtc) { + case 0: + r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); +@@ -135,7 +135,7 @@ static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r + u32 irq_mask = RADEON_SW_INT_TEST; + + *r500_disp_int = 0; +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + /* vbl interrupts in a different place */ + + if (irqs & R500_DISPLAY_INT_STATUS) { +@@ -202,7 +202,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) + DRM_WAKEUP(&dev_priv->swi_queue); + + /* VBLANK interrupt */ +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) + drm_handle_vblank(dev, 0); + if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) +@@ -265,7 +265,7 @@ u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) + return -EINVAL; + } + +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + if (crtc == 0) + return RADEON_READ(R500_D1CRTC_FRAME_COUNT); + else +@@ -327,7 +327,7 @@ void radeon_driver_irq_preinstall(struct drm_device * dev) + u32 dummy; + + /* Disable *all* interrupts */ +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + RADEON_WRITE(R500_DxMODE_INT_MASK, 0); + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); + +@@ -357,7 +357,7 @@ void radeon_driver_irq_uninstall(struct drm_device * dev) + if (!dev_priv) + return; + +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + RADEON_WRITE(R500_DxMODE_INT_MASK, 0); + /* Disable *all* interrupts */ + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); +diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c +index ef940a0..fa728ec 100644 +--- a/drivers/gpu/drm/radeon/radeon_state.c ++++ b/drivers/gpu/drm/radeon/radeon_state.c +@@ -1556,9 +1556,15 @@ static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master * + buf_priv->age = ++master_priv->sarea_priv->last_dispatch; + + /* Emit the vertex buffer age */ +- BEGIN_RING(2); +- RADEON_DISPATCH_AGE(buf_priv->age); +- ADVANCE_RING(); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { ++ BEGIN_RING(3); ++ R600_DISPATCH_AGE(buf_priv->age); ++ ADVANCE_RING(); ++ } else { ++ BEGIN_RING(2); ++ RADEON_DISPATCH_AGE(buf_priv->age); ++ ADVANCE_RING(); ++ } + + buf->pending = 1; + buf->used = 0; +@@ -1980,7 +1986,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new, + + /* find a virtual surface */ + for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) +- if (dev_priv->virt_surfaces[i].file_priv == 0) ++ if (dev_priv->virt_surfaces[i].file_priv == NULL) + break; + if (i == 2 * RADEON_MAX_SURFACES) { + return -1; +@@ -2473,24 +2479,25 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil + + buf->used = indirect->end; + +- /* Wait for the 3D stream to idle before the indirect buffer +- * containing 2D acceleration commands is processed. +- */ +- BEGIN_RING(2); +- +- RADEON_WAIT_UNTIL_3D_IDLE(); +- +- ADVANCE_RING(); +- + /* Dispatch the indirect buffer full of commands from the + * X server. This is insecure and is thus only available to + * privileged clients. + */ +- radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); +- if (indirect->discard) { +- radeon_cp_discard_buffer(dev, file_priv->master, buf); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); ++ else { ++ /* Wait for the 3D stream to idle before the indirect buffer ++ * containing 2D acceleration commands is processed. ++ */ ++ BEGIN_RING(2); ++ RADEON_WAIT_UNTIL_3D_IDLE(); ++ ADVANCE_RING(); ++ radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); + } + ++ if (indirect->discard) ++ radeon_cp_discard_buffer(dev, file_priv->master, buf); ++ + COMMIT_RING(); + return 0; + } +@@ -3010,14 +3017,14 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil + break; + case RADEON_PARAM_LAST_FRAME: + dev_priv->stats.last_frame_reads++; +- value = GET_SCRATCH(0); ++ value = GET_SCRATCH(dev_priv, 0); + break; + case RADEON_PARAM_LAST_DISPATCH: +- value = GET_SCRATCH(1); ++ value = GET_SCRATCH(dev_priv, 1); + break; + case RADEON_PARAM_LAST_CLEAR: + dev_priv->stats.last_clear_reads++; +- value = GET_SCRATCH(2); ++ value = GET_SCRATCH(dev_priv, 2); + break; + case RADEON_PARAM_IRQ_NR: + value = drm_dev_to_irq(dev); +@@ -3052,7 +3059,10 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil + case RADEON_PARAM_SCRATCH_OFFSET: + if (!dev_priv->writeback_works) + return -EINVAL; +- value = RADEON_SCRATCH_REG_OFFSET; ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) ++ value = R600_SCRATCH_REG_OFFSET; ++ else ++ value = RADEON_SCRATCH_REG_OFFSET; + break; + case RADEON_PARAM_CARD_TYPE: + if (dev_priv->flags & RADEON_IS_PCIE) +@@ -3155,6 +3165,7 @@ void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) + + void radeon_driver_lastclose(struct drm_device *dev) + { ++ radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private); + radeon_do_release(dev); + } + +diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c +index d465b2f..456cd04 100644 +--- a/drivers/gpu/drm/savage/savage_bci.c ++++ b/drivers/gpu/drm/savage/savage_bci.c +@@ -599,8 +599,8 @@ int savage_driver_firstopen(struct drm_device *dev) + drm_mtrr_add(dev_priv->mtrr[2].base, + dev_priv->mtrr[2].size, DRM_MTRR_WC); + } else { +- DRM_ERROR("strange pci_resource_len %08lx\n", +- drm_get_resource_len(dev, 0)); ++ DRM_ERROR("strange pci_resource_len %08llx\n", ++ (unsigned long long)drm_get_resource_len(dev, 0)); + } + } else if (dev_priv->chipset != S3_SUPERSAVAGE && + dev_priv->chipset != S3_SAVAGE2000) { +@@ -620,8 +620,8 @@ int savage_driver_firstopen(struct drm_device *dev) + drm_mtrr_add(dev_priv->mtrr[0].base, + dev_priv->mtrr[0].size, DRM_MTRR_WC); + } else { +- DRM_ERROR("strange pci_resource_len %08lx\n", +- drm_get_resource_len(dev, 1)); ++ DRM_ERROR("strange pci_resource_len %08llx\n", ++ (unsigned long long)drm_get_resource_len(dev, 1)); + } + } else { + mmio_base = drm_get_resource_start(dev, 0); +diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c +index 0993b44..bc2f518 100644 +--- a/drivers/gpu/drm/via/via_drv.c ++++ b/drivers/gpu/drm/via/via_drv.c +@@ -28,11 +28,6 @@ + + #include "drm_pciids.h" + +-static int dri_library_name(struct drm_device *dev, char *buf) +-{ +- return snprintf(buf, PAGE_SIZE, "unichrome"); +-} +- + static struct pci_device_id pciidlist[] = { + viadrv_PCI_IDS + }; +@@ -52,7 +47,6 @@ static struct drm_driver driver = { + .irq_uninstall = via_driver_irq_uninstall, + .irq_handler = via_driver_irq_handler, + .dma_quiescent = via_driver_dma_quiescent, +- .dri_library_name = dri_library_name, + .reclaim_buffers = drm_core_reclaim_buffers, + .reclaim_buffers_locked = NULL, + .reclaim_buffers_idlelocked = via_reclaim_buffers_locked, +diff --git a/include/drm/drm.h b/include/drm/drm.h +index 8e77357..7cb50bd 100644 +--- a/include/drm/drm.h ++++ b/include/drm/drm.h +@@ -36,8 +36,7 @@ + #ifndef _DRM_H_ + #define _DRM_H_ + +-#if defined(__KERNEL__) +-#endif ++#include + #include /* For _IO* macros */ + #define DRM_IOCTL_NR(n) _IOC_NR(n) + #define DRM_IOC_VOID _IOC_NONE +@@ -497,8 +496,8 @@ union drm_wait_vblank { + * \sa drmModesetCtl(). + */ + struct drm_modeset_ctl { +- uint32_t crtc; +- uint32_t cmd; ++ __u32 crtc; ++ __u32 cmd; + }; + + /** +@@ -574,29 +573,29 @@ struct drm_set_version { + /** DRM_IOCTL_GEM_CLOSE ioctl argument type */ + struct drm_gem_close { + /** Handle of the object to be closed. */ +- uint32_t handle; +- uint32_t pad; ++ __u32 handle; ++ __u32 pad; + }; + + /** DRM_IOCTL_GEM_FLINK ioctl argument type */ + struct drm_gem_flink { + /** Handle for the object being named */ +- uint32_t handle; ++ __u32 handle; + + /** Returned global name */ +- uint32_t name; ++ __u32 name; + }; + + /** DRM_IOCTL_GEM_OPEN ioctl argument type */ + struct drm_gem_open { + /** Name of object being opened */ +- uint32_t name; ++ __u32 name; + + /** Returned handle for the object */ +- uint32_t handle; ++ __u32 handle; + + /** Returned size of the object */ +- uint64_t size; ++ __u64 size; + }; + + #include "drm_mode.h" +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index e5f4ae9..c8c4221 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -281,16 +281,16 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, + + struct drm_ioctl_desc { + unsigned int cmd; +- drm_ioctl_t *func; + int flags; ++ drm_ioctl_t *func; + }; + + /** + * Creates a driver or general drm_ioctl_desc array entry for the given + * ioctl, for use by drm_ioctl(). + */ +-#define DRM_IOCTL_DEF(ioctl, func, flags) \ +- [DRM_IOCTL_NR(ioctl)] = {ioctl, func, flags} ++#define DRM_IOCTL_DEF(ioctl, _func, _flags) \ ++ [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags} + + struct drm_magic_entry { + struct list_head head; +@@ -523,19 +523,32 @@ struct drm_mm { + + + /** ++ * Kernel side of a mapping ++ */ ++struct drm_local_map { ++ resource_size_t offset; /**< Requested physical address (0 for SAREA)*/ ++ unsigned long size; /**< Requested physical size (bytes) */ ++ enum drm_map_type type; /**< Type of memory to map */ ++ enum drm_map_flags flags; /**< Flags */ ++ void *handle; /**< User-space: "Handle" to pass to mmap() */ ++ /**< Kernel-space: kernel-virtual address */ ++ int mtrr; /**< MTRR slot used */ ++}; ++ ++typedef struct drm_local_map drm_local_map_t; ++ ++/** + * Mappings list + */ + struct drm_map_list { + struct list_head head; /**< list head */ + struct drm_hash_item hash; +- struct drm_map *map; /**< mapping */ ++ struct drm_local_map *map; /**< mapping */ + uint64_t user_token; + struct drm_master *master; + struct drm_mm_node *file_offset_node; /**< fake offset */ + }; + +-typedef struct drm_map drm_local_map_t; +- + /** + * Context handle list + */ +@@ -560,7 +573,7 @@ struct drm_ati_pcigart_info { + dma_addr_t bus_addr; + dma_addr_t table_mask; + struct drm_dma_handle *table_handle; +- drm_local_map_t mapping; ++ struct drm_local_map mapping; + int table_size; + }; + +@@ -675,7 +688,6 @@ struct drm_driver { + int (*kernel_context_switch) (struct drm_device *dev, int old, + int new); + void (*kernel_context_switch_unlock) (struct drm_device *dev); +- int (*dri_library_name) (struct drm_device *dev, char *buf); + + /** + * get_vblank_counter - get raw hardware vblank counter +@@ -747,8 +759,8 @@ struct drm_driver { + struct drm_file *file_priv); + void (*reclaim_buffers_idlelocked) (struct drm_device *dev, + struct drm_file *file_priv); +- unsigned long (*get_map_ofs) (struct drm_map * map); +- unsigned long (*get_reg_ofs) (struct drm_device *dev); ++ resource_size_t (*get_map_ofs) (struct drm_local_map * map); ++ resource_size_t (*get_reg_ofs) (struct drm_device *dev); + void (*set_version) (struct drm_device *dev, + struct drm_set_version *sv); + +@@ -758,6 +770,8 @@ struct drm_driver { + + int (*proc_init)(struct drm_minor *minor); + void (*proc_cleanup)(struct drm_minor *minor); ++ int (*debugfs_init)(struct drm_minor *minor); ++ void (*debugfs_cleanup)(struct drm_minor *minor); + + /** + * Driver-specific constructor for drm_gem_objects, to set up +@@ -793,6 +807,48 @@ struct drm_driver { + #define DRM_MINOR_CONTROL 2 + #define DRM_MINOR_RENDER 3 + ++ ++/** ++ * debugfs node list. This structure represents a debugfs file to ++ * be created by the drm core ++ */ ++struct drm_debugfs_list { ++ const char *name; /** file name */ ++ int (*show)(struct seq_file*, void*); /** show callback */ ++ u32 driver_features; /**< Required driver features for this entry */ ++}; ++ ++/** ++ * debugfs node structure. This structure represents a debugfs file. ++ */ ++struct drm_debugfs_node { ++ struct list_head list; ++ struct drm_minor *minor; ++ struct drm_debugfs_list *debugfs_ent; ++ struct dentry *dent; ++}; ++ ++/** ++ * Info file list entry. This structure represents a debugfs or proc file to ++ * be created by the drm core ++ */ ++struct drm_info_list { ++ const char *name; /** file name */ ++ int (*show)(struct seq_file*, void*); /** show callback */ ++ u32 driver_features; /**< Required driver features for this entry */ ++ void *data; ++}; ++ ++/** ++ * debugfs node structure. This structure represents a debugfs file. ++ */ ++struct drm_info_node { ++ struct list_head list; ++ struct drm_minor *minor; ++ struct drm_info_list *info_ent; ++ struct dentry *dent; ++}; ++ + /** + * DRM minor structure. This structure represents a drm minor number. + */ +@@ -802,7 +858,12 @@ struct drm_minor { + dev_t device; /**< Device number for mknod */ + struct device kdev; /**< Linux device */ + struct drm_device *dev; +- struct proc_dir_entry *dev_root; /**< proc directory entry */ ++ ++ struct proc_dir_entry *proc_root; /**< proc directory entry */ ++ struct drm_info_node proc_nodes; ++ struct dentry *debugfs_root; ++ struct drm_info_node debugfs_nodes; ++ + struct drm_master *master; /* currently active master for this node */ + struct list_head master_list; + struct drm_mode_group mode_group; +@@ -932,7 +993,7 @@ struct drm_device { + sigset_t sigmask; + + struct drm_driver *driver; +- drm_local_map_t *agp_buffer_map; ++ struct drm_local_map *agp_buffer_map; + unsigned int agp_buffer_token; + struct drm_minor *control; /**< Control node for card */ + struct drm_minor *primary; /**< render type primary screen head */ +@@ -1049,8 +1110,8 @@ extern int drm_release(struct inode *inode, struct file *filp); + extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); + extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); + extern void drm_vm_open_locked(struct vm_area_struct *vma); +-extern unsigned long drm_core_get_map_ofs(struct drm_map * map); +-extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev); ++extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map); ++extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev); + extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); + + /* Memory management support (drm_memory.h) */ +@@ -1153,13 +1214,13 @@ extern int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv + /* Buffer management support (drm_bufs.h) */ + extern int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc * request); + extern int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc * request); +-extern int drm_addmap(struct drm_device *dev, unsigned int offset, ++extern int drm_addmap(struct drm_device *dev, resource_size_t offset, + unsigned int size, enum drm_map_type type, +- enum drm_map_flags flags, drm_local_map_t ** map_ptr); ++ enum drm_map_flags flags, struct drm_local_map **map_ptr); + extern int drm_addmap_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +-extern int drm_rmmap(struct drm_device *dev, drm_local_map_t *map); +-extern int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map); ++extern int drm_rmmap(struct drm_device *dev, struct drm_local_map *map); ++extern int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map); + extern int drm_rmmap_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + extern int drm_addbufs(struct drm_device *dev, void *data, +@@ -1173,10 +1234,10 @@ extern int drm_freebufs(struct drm_device *dev, void *data, + extern int drm_mapbufs(struct drm_device *dev, void *data, + struct drm_file *file_priv); + extern int drm_order(unsigned long size); +-extern unsigned long drm_get_resource_start(struct drm_device *dev, ++extern resource_size_t drm_get_resource_start(struct drm_device *dev, ++ unsigned int resource); ++extern resource_size_t drm_get_resource_len(struct drm_device *dev, + unsigned int resource); +-extern unsigned long drm_get_resource_len(struct drm_device *dev, +- unsigned int resource); + + /* DMA support (drm_dma.h) */ + extern int drm_dma_setup(struct drm_device *dev); +@@ -1252,22 +1313,48 @@ extern struct drm_master *drm_master_get(struct drm_master *master); + extern void drm_master_put(struct drm_master **master); + extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, + struct drm_driver *driver); +-extern int drm_put_dev(struct drm_device *dev); ++extern void drm_put_dev(struct drm_device *dev); + extern int drm_put_minor(struct drm_minor **minor); + extern unsigned int drm_debug; + + extern struct class *drm_class; + extern struct proc_dir_entry *drm_proc_root; ++extern struct dentry *drm_debugfs_root; + + extern struct idr drm_minors_idr; + +-extern drm_local_map_t *drm_getsarea(struct drm_device *dev); ++extern struct drm_local_map *drm_getsarea(struct drm_device *dev); + + /* Proc support (drm_proc.h) */ + extern int drm_proc_init(struct drm_minor *minor, int minor_id, + struct proc_dir_entry *root); + extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root); + ++ /* Debugfs support */ ++#if defined(CONFIG_DEBUG_FS) ++extern int drm_debugfs_init(struct drm_minor *minor, int minor_id, ++ struct dentry *root); ++extern int drm_debugfs_create_files(struct drm_info_list *files, int count, ++ struct dentry *root, struct drm_minor *minor); ++extern int drm_debugfs_remove_files(struct drm_info_list *files, int count, ++ struct drm_minor *minor); ++extern int drm_debugfs_cleanup(struct drm_minor *minor); ++#endif ++ ++ /* Info file support */ ++extern int drm_name_info(struct seq_file *m, void *data); ++extern int drm_vm_info(struct seq_file *m, void *data); ++extern int drm_queues_info(struct seq_file *m, void *data); ++extern int drm_bufs_info(struct seq_file *m, void *data); ++extern int drm_vblank_info(struct seq_file *m, void *data); ++extern int drm_clients_info(struct seq_file *m, void* data); ++extern int drm_gem_name_info(struct seq_file *m, void *data); ++extern int drm_gem_object_info(struct seq_file *m, void* data); ++ ++#if DRM_DEBUG_CODE ++extern int drm_vma_info(struct seq_file *m, void *data); ++#endif ++ + /* Scatter Gather Support (drm_scatter.h) */ + extern void drm_sg_cleanup(struct drm_sg_mem * entry); + extern int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, +@@ -1378,12 +1465,12 @@ int drm_gem_open_ioctl(struct drm_device *dev, void *data, + void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); + void drm_gem_release(struct drm_device *dev, struct drm_file *file_private); + +-extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); +-extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev); +-extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); ++extern void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev); ++extern void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev); ++extern void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev); + +-static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, +- unsigned int token) ++static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev, ++ unsigned int token) + { + struct drm_map_list *_entry; + list_for_each_entry(_entry, &dev->maplist, head) +@@ -1410,7 +1497,7 @@ static __inline__ int drm_device_is_pcie(struct drm_device *dev) + return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); + } + +-static __inline__ void drm_core_dropmap(struct drm_map *map) ++static __inline__ void drm_core_dropmap(struct drm_local_map *map) + { + } + +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index 5ded1ac..3c1924c 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -550,7 +550,7 @@ struct drm_mode_config { + int min_width, min_height; + int max_width, max_height; + struct drm_mode_config_funcs *funcs; +- unsigned long fb_base; ++ resource_size_t fb_base; + + /* pointers to standard properties */ + struct list_head property_blob_list; +@@ -613,7 +613,8 @@ extern void drm_fb_release(struct drm_file *file_priv); + extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); + extern struct edid *drm_get_edid(struct drm_connector *connector, + struct i2c_adapter *adapter); +-extern unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter); ++extern int drm_do_probe_ddc_edid(struct i2c_adapter *adapter, ++ unsigned char *buf, int len); + extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); + extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); + extern void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode); +@@ -731,4 +732,5 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); + extern int drm_mode_gamma_set_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); ++extern bool drm_detect_hdmi_monitor(struct edid *edid); + #endif /* __DRM_CRTC_H__ */ +diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h +index c7d4b2e..ec073d8 100644 +--- a/include/drm/drm_crtc_helper.h ++++ b/include/drm/drm_crtc_helper.h +@@ -33,7 +33,6 @@ + #ifndef __DRM_CRTC_HELPER_H__ + #define __DRM_CRTC_HELPER_H__ + +-#include + #include + #include + #include +@@ -92,7 +91,7 @@ struct drm_connector_helper_funcs { + extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); + extern void drm_helper_disable_unused_functions(struct drm_device *dev); + extern int drm_helper_hotplug_stage_two(struct drm_device *dev); +-extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow); ++extern bool drm_helper_initial_config(struct drm_device *dev); + extern int drm_crtc_helper_set_config(struct drm_mode_set *set); + extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, + struct drm_display_mode *mode, +diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h +index 601d2bd..ae304cc 100644 +--- a/include/drm/drm_mode.h ++++ b/include/drm/drm_mode.h +@@ -27,11 +27,8 @@ + #ifndef _DRM_MODE_H + #define _DRM_MODE_H + +-#if !defined(__KERNEL__) && !defined(_KERNEL) +-#include +-#else + #include +-#endif ++#include + + #define DRM_DISPLAY_INFO_LEN 32 + #define DRM_CONNECTOR_NAME_LEN 32 +@@ -81,41 +78,41 @@ + #define DRM_MODE_DITHERING_ON 1 + + struct drm_mode_modeinfo { +- uint32_t clock; +- uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew; +- uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan; ++ __u32 clock; ++ __u16 hdisplay, hsync_start, hsync_end, htotal, hskew; ++ __u16 vdisplay, vsync_start, vsync_end, vtotal, vscan; + +- uint32_t vrefresh; /* vertical refresh * 1000 */ ++ __u32 vrefresh; /* vertical refresh * 1000 */ + +- uint32_t flags; +- uint32_t type; ++ __u32 flags; ++ __u32 type; + char name[DRM_DISPLAY_MODE_LEN]; + }; + + struct drm_mode_card_res { +- uint64_t fb_id_ptr; +- uint64_t crtc_id_ptr; +- uint64_t connector_id_ptr; +- uint64_t encoder_id_ptr; +- uint32_t count_fbs; +- uint32_t count_crtcs; +- uint32_t count_connectors; +- uint32_t count_encoders; +- uint32_t min_width, max_width; +- uint32_t min_height, max_height; ++ __u64 fb_id_ptr; ++ __u64 crtc_id_ptr; ++ __u64 connector_id_ptr; ++ __u64 encoder_id_ptr; ++ __u32 count_fbs; ++ __u32 count_crtcs; ++ __u32 count_connectors; ++ __u32 count_encoders; ++ __u32 min_width, max_width; ++ __u32 min_height, max_height; + }; + + struct drm_mode_crtc { +- uint64_t set_connectors_ptr; +- uint32_t count_connectors; ++ __u64 set_connectors_ptr; ++ __u32 count_connectors; + +- uint32_t crtc_id; /**< Id */ +- uint32_t fb_id; /**< Id of framebuffer */ ++ __u32 crtc_id; /**< Id */ ++ __u32 fb_id; /**< Id of framebuffer */ + +- uint32_t x, y; /**< Position on the frameuffer */ ++ __u32 x, y; /**< Position on the frameuffer */ + +- uint32_t gamma_size; +- uint32_t mode_valid; ++ __u32 gamma_size; ++ __u32 mode_valid; + struct drm_mode_modeinfo mode; + }; + +@@ -126,13 +123,13 @@ struct drm_mode_crtc { + #define DRM_MODE_ENCODER_TVDAC 4 + + struct drm_mode_get_encoder { +- uint32_t encoder_id; +- uint32_t encoder_type; ++ __u32 encoder_id; ++ __u32 encoder_type; + +- uint32_t crtc_id; /**< Id of crtc */ ++ __u32 crtc_id; /**< Id of crtc */ + +- uint32_t possible_crtcs; +- uint32_t possible_clones; ++ __u32 possible_crtcs; ++ __u32 possible_clones; + }; + + /* This is for connectors with multiple signal types. */ +@@ -161,23 +158,23 @@ struct drm_mode_get_encoder { + + struct drm_mode_get_connector { + +- uint64_t encoders_ptr; +- uint64_t modes_ptr; +- uint64_t props_ptr; +- uint64_t prop_values_ptr; ++ __u64 encoders_ptr; ++ __u64 modes_ptr; ++ __u64 props_ptr; ++ __u64 prop_values_ptr; + +- uint32_t count_modes; +- uint32_t count_props; +- uint32_t count_encoders; ++ __u32 count_modes; ++ __u32 count_props; ++ __u32 count_encoders; + +- uint32_t encoder_id; /**< Current Encoder */ +- uint32_t connector_id; /**< Id */ +- uint32_t connector_type; +- uint32_t connector_type_id; ++ __u32 encoder_id; /**< Current Encoder */ ++ __u32 connector_id; /**< Id */ ++ __u32 connector_type; ++ __u32 connector_type_id; + +- uint32_t connection; +- uint32_t mm_width, mm_height; /**< HxW in millimeters */ +- uint32_t subpixel; ++ __u32 connection; ++ __u32 mm_width, mm_height; /**< HxW in millimeters */ ++ __u32 subpixel; + }; + + #define DRM_MODE_PROP_PENDING (1<<0) +@@ -187,46 +184,46 @@ struct drm_mode_get_connector { + #define DRM_MODE_PROP_BLOB (1<<4) + + struct drm_mode_property_enum { +- uint64_t value; ++ __u64 value; + char name[DRM_PROP_NAME_LEN]; + }; + + struct drm_mode_get_property { +- uint64_t values_ptr; /* values and blob lengths */ +- uint64_t enum_blob_ptr; /* enum and blob id ptrs */ ++ __u64 values_ptr; /* values and blob lengths */ ++ __u64 enum_blob_ptr; /* enum and blob id ptrs */ + +- uint32_t prop_id; +- uint32_t flags; ++ __u32 prop_id; ++ __u32 flags; + char name[DRM_PROP_NAME_LEN]; + +- uint32_t count_values; +- uint32_t count_enum_blobs; ++ __u32 count_values; ++ __u32 count_enum_blobs; + }; + + struct drm_mode_connector_set_property { +- uint64_t value; +- uint32_t prop_id; +- uint32_t connector_id; ++ __u64 value; ++ __u32 prop_id; ++ __u32 connector_id; + }; + + struct drm_mode_get_blob { +- uint32_t blob_id; +- uint32_t length; +- uint64_t data; ++ __u32 blob_id; ++ __u32 length; ++ __u64 data; + }; + + struct drm_mode_fb_cmd { +- uint32_t fb_id; +- uint32_t width, height; +- uint32_t pitch; +- uint32_t bpp; +- uint32_t depth; ++ __u32 fb_id; ++ __u32 width, height; ++ __u32 pitch; ++ __u32 bpp; ++ __u32 depth; + /* driver specific handle */ +- uint32_t handle; ++ __u32 handle; + }; + + struct drm_mode_mode_cmd { +- uint32_t connector_id; ++ __u32 connector_id; + struct drm_mode_modeinfo mode; + }; + +@@ -248,24 +245,24 @@ struct drm_mode_mode_cmd { + * y + */ + struct drm_mode_cursor { +- uint32_t flags; +- uint32_t crtc_id; +- int32_t x; +- int32_t y; +- uint32_t width; +- uint32_t height; ++ __u32 flags; ++ __u32 crtc_id; ++ __s32 x; ++ __s32 y; ++ __u32 width; ++ __u32 height; + /* driver specific handle */ +- uint32_t handle; ++ __u32 handle; + }; + + struct drm_mode_crtc_lut { +- uint32_t crtc_id; +- uint32_t gamma_size; ++ __u32 crtc_id; ++ __u32 gamma_size; + + /* pointers to arrays */ +- uint64_t red; +- uint64_t green; +- uint64_t blue; ++ __u64 red; ++ __u64 green; ++ __u64 blue; + }; + + #endif +diff --git a/include/drm/drm_os_linux.h b/include/drm/drm_os_linux.h +index 8dbd257..26641e9 100644 +--- a/include/drm/drm_os_linux.h ++++ b/include/drm/drm_os_linux.h +@@ -6,6 +6,19 @@ + #include /* For task queue support */ + #include + ++#ifndef readq ++static inline u64 readq(void __iomem *reg) ++{ ++ return ((u64) readl(reg)) | (((u64) readl(reg + 4UL)) << 32); ++} ++ ++static inline void writeq(u64 val, void __iomem *reg) ++{ ++ writel(val & 0xffffffff, reg); ++ writel(val >> 32, reg + 0x4UL); ++} ++#endif ++ + /** Current process ID */ + #define DRM_CURRENTPID task_pid_nr(current) + #define DRM_SUSER(p) capable(CAP_SYS_ADMIN) +@@ -23,6 +36,12 @@ + /** Write a dword into a MMIO region */ + #define DRM_WRITE32(map, offset, val) writel(val, ((void __iomem *)(map)->handle) + (offset)) + /** Read memory barrier */ ++ ++/** Read a qword from a MMIO region - be careful using these unless you really understand them */ ++#define DRM_READ64(map, offset) readq(((void __iomem *)(map)->handle) + (offset)) ++/** Write a qword into a MMIO region */ ++#define DRM_WRITE64(map, offset, val) writeq(val, ((void __iomem *)(map)->handle) + (offset)) ++ + #define DRM_READMEMORYBARRIER() rmb() + /** Write memory barrier */ + #define DRM_WRITEMEMORYBARRIER() wmb() +diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +index 5165f24..2df74eb 100644 +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -239,10 +239,123 @@ + {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ + {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ ++ {0x1002, 0x793f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x7941, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x7942, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x796c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ + {0x1002, 0x796d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ + {0x1002, 0x796e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ + {0x1002, 0x796f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ ++ {0x1002, 0x9400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9402, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9403, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x940A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x940B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x940F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9442, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9444, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x944A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x944B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x944C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x944E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9456, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x945A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x945B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x946A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x946B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x947A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x947B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9487, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9488, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9489, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x948F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9490, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9491, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9498, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x949C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x949E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x949F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94C3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94C4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94C5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94C6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94C8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94C9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x94CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9500, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9501, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9504, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9505, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9506, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9507, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9508, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9509, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x950F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9515, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9517, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9519, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9540, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9541, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9542, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x954E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x954F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9553, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9555, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9581, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9583, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9586, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9587, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9588, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9589, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x958A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x958B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x958C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x958D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x958E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x958F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9590, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9593, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9595, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9596, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9597, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9598, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9599, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x959B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95C5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95C6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95C9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95C2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95C4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95CE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x95CF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x9610, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9611, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9612, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9613, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9614, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9615, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9616, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0, 0, 0} + + #define r128_PCI_IDS \ +@@ -418,4 +531,6 @@ + {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ ++ {0x8086, 0xa001, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ ++ {0x8086, 0xa011, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0, 0, 0} +diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h +index 912cd52..67e3353 100644 +--- a/include/drm/i915_drm.h ++++ b/include/drm/i915_drm.h +@@ -30,7 +30,7 @@ + /* Please note that modifications to all structs defined here are + * subject to backwards-compatibility constraints. + */ +- ++#include + #include "drm.h" + + /* Each region is a minimum of 16k, and there are at most 255 of them. +@@ -116,15 +116,15 @@ typedef struct _drm_i915_sarea { + + /* fill out some space for old userspace triple buffer */ + drm_handle_t unused_handle; +- uint32_t unused1, unused2, unused3; ++ __u32 unused1, unused2, unused3; + + /* buffer object handles for static buffers. May change + * over the lifetime of the client. + */ +- uint32_t front_bo_handle; +- uint32_t back_bo_handle; +- uint32_t unused_bo_handle; +- uint32_t depth_bo_handle; ++ __u32 front_bo_handle; ++ __u32 back_bo_handle; ++ __u32 unused_bo_handle; ++ __u32 depth_bo_handle; + + } drm_i915_sarea_t; + +@@ -327,7 +327,7 @@ typedef struct drm_i915_vblank_swap { + } drm_i915_vblank_swap_t; + + typedef struct drm_i915_hws_addr { +- uint64_t addr; ++ __u64 addr; + } drm_i915_hws_addr_t; + + struct drm_i915_gem_init { +@@ -335,12 +335,12 @@ struct drm_i915_gem_init { + * Beginning offset in the GTT to be managed by the DRM memory + * manager. + */ +- uint64_t gtt_start; ++ __u64 gtt_start; + /** + * Ending offset in the GTT to be managed by the DRM memory + * manager. + */ +- uint64_t gtt_end; ++ __u64 gtt_end; + }; + + struct drm_i915_gem_create { +@@ -349,94 +349,94 @@ struct drm_i915_gem_create { + * + * The (page-aligned) allocated size for the object will be returned. + */ +- uint64_t size; ++ __u64 size; + /** + * Returned handle for the object. + * + * Object handles are nonzero. + */ +- uint32_t handle; +- uint32_t pad; ++ __u32 handle; ++ __u32 pad; + }; + + struct drm_i915_gem_pread { + /** Handle for the object being read. */ +- uint32_t handle; +- uint32_t pad; ++ __u32 handle; ++ __u32 pad; + /** Offset into the object to read from */ +- uint64_t offset; ++ __u64 offset; + /** Length of data to read */ +- uint64_t size; ++ __u64 size; + /** + * Pointer to write the data into. + * + * This is a fixed-size type for 32/64 compatibility. + */ +- uint64_t data_ptr; ++ __u64 data_ptr; + }; + + struct drm_i915_gem_pwrite { + /** Handle for the object being written to. */ +- uint32_t handle; +- uint32_t pad; ++ __u32 handle; ++ __u32 pad; + /** Offset into the object to write to */ +- uint64_t offset; ++ __u64 offset; + /** Length of data to write */ +- uint64_t size; ++ __u64 size; + /** + * Pointer to read the data from. + * + * This is a fixed-size type for 32/64 compatibility. + */ +- uint64_t data_ptr; ++ __u64 data_ptr; + }; + + struct drm_i915_gem_mmap { + /** Handle for the object being mapped. */ +- uint32_t handle; +- uint32_t pad; ++ __u32 handle; ++ __u32 pad; + /** Offset in the object to map. */ +- uint64_t offset; ++ __u64 offset; + /** + * Length of data to map. + * + * The value will be page-aligned. + */ +- uint64_t size; ++ __u64 size; + /** + * Returned pointer the data was mapped at. + * + * This is a fixed-size type for 32/64 compatibility. + */ +- uint64_t addr_ptr; ++ __u64 addr_ptr; + }; + + struct drm_i915_gem_mmap_gtt { + /** Handle for the object being mapped. */ +- uint32_t handle; +- uint32_t pad; ++ __u32 handle; ++ __u32 pad; + /** + * Fake offset to use for subsequent mmap call + * + * This is a fixed-size type for 32/64 compatibility. + */ +- uint64_t offset; ++ __u64 offset; + }; + + struct drm_i915_gem_set_domain { + /** Handle for the object */ +- uint32_t handle; ++ __u32 handle; + + /** New read domains */ +- uint32_t read_domains; ++ __u32 read_domains; + + /** New write domain */ +- uint32_t write_domain; ++ __u32 write_domain; + }; + + struct drm_i915_gem_sw_finish { + /** Handle for the object */ +- uint32_t handle; ++ __u32 handle; + }; + + struct drm_i915_gem_relocation_entry { +@@ -448,16 +448,16 @@ struct drm_i915_gem_relocation_entry { + * a relocation list for state buffers and not re-write it per + * exec using the buffer. + */ +- uint32_t target_handle; ++ __u32 target_handle; + + /** + * Value to be added to the offset of the target buffer to make up + * the relocation entry. + */ +- uint32_t delta; ++ __u32 delta; + + /** Offset in the buffer the relocation entry will be written into */ +- uint64_t offset; ++ __u64 offset; + + /** + * Offset value of the target buffer that the relocation entry was last +@@ -467,12 +467,12 @@ struct drm_i915_gem_relocation_entry { + * and writing the relocation. This value is written back out by + * the execbuffer ioctl when the relocation is written. + */ +- uint64_t presumed_offset; ++ __u64 presumed_offset; + + /** + * Target memory domains read by this operation. + */ +- uint32_t read_domains; ++ __u32 read_domains; + + /** + * Target memory domains written by this operation. +@@ -481,7 +481,7 @@ struct drm_i915_gem_relocation_entry { + * execbuffer operation, so that where there are conflicts, + * the application will get -EINVAL back. + */ +- uint32_t write_domain; ++ __u32 write_domain; + }; + + /** @{ +@@ -512,24 +512,24 @@ struct drm_i915_gem_exec_object { + * User's handle for a buffer to be bound into the GTT for this + * operation. + */ +- uint32_t handle; ++ __u32 handle; + + /** Number of relocations to be performed on this buffer */ +- uint32_t relocation_count; ++ __u32 relocation_count; + /** + * Pointer to array of struct drm_i915_gem_relocation_entry containing + * the relocations to be performed in this buffer. + */ +- uint64_t relocs_ptr; ++ __u64 relocs_ptr; + + /** Required alignment in graphics aperture */ +- uint64_t alignment; ++ __u64 alignment; + + /** + * Returned value of the updated offset of the object, for future + * presumed_offset writes. + */ +- uint64_t offset; ++ __u64 offset; + }; + + struct drm_i915_gem_execbuffer { +@@ -543,44 +543,44 @@ struct drm_i915_gem_execbuffer { + * a buffer is performing refer to buffers that have already appeared + * in the validate list. + */ +- uint64_t buffers_ptr; +- uint32_t buffer_count; ++ __u64 buffers_ptr; ++ __u32 buffer_count; + + /** Offset in the batchbuffer to start execution from. */ +- uint32_t batch_start_offset; ++ __u32 batch_start_offset; + /** Bytes used in batchbuffer from batch_start_offset */ +- uint32_t batch_len; +- uint32_t DR1; +- uint32_t DR4; +- uint32_t num_cliprects; ++ __u32 batch_len; ++ __u32 DR1; ++ __u32 DR4; ++ __u32 num_cliprects; + /** This is a struct drm_clip_rect *cliprects */ +- uint64_t cliprects_ptr; ++ __u64 cliprects_ptr; + }; + + struct drm_i915_gem_pin { + /** Handle of the buffer to be pinned. */ +- uint32_t handle; +- uint32_t pad; ++ __u32 handle; ++ __u32 pad; + + /** alignment required within the aperture */ +- uint64_t alignment; ++ __u64 alignment; + + /** Returned GTT offset of the buffer. */ +- uint64_t offset; ++ __u64 offset; + }; + + struct drm_i915_gem_unpin { + /** Handle of the buffer to be unpinned. */ +- uint32_t handle; +- uint32_t pad; ++ __u32 handle; ++ __u32 pad; + }; + + struct drm_i915_gem_busy { + /** Handle of the buffer to check for busy */ +- uint32_t handle; ++ __u32 handle; + + /** Return busy status (1 if busy, 0 if idle) */ +- uint32_t busy; ++ __u32 busy; + }; + + #define I915_TILING_NONE 0 +@@ -597,7 +597,7 @@ struct drm_i915_gem_busy { + + struct drm_i915_gem_set_tiling { + /** Handle of the buffer to have its tiling state updated */ +- uint32_t handle; ++ __u32 handle; + + /** + * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X, +@@ -611,47 +611,47 @@ struct drm_i915_gem_set_tiling { + * + * Buffer contents become undefined when changing tiling_mode. + */ +- uint32_t tiling_mode; ++ __u32 tiling_mode; + + /** + * Stride in bytes for the object when in I915_TILING_X or + * I915_TILING_Y. + */ +- uint32_t stride; ++ __u32 stride; + + /** + * Returned address bit 6 swizzling required for CPU access through + * mmap mapping. + */ +- uint32_t swizzle_mode; ++ __u32 swizzle_mode; + }; + + struct drm_i915_gem_get_tiling { + /** Handle of the buffer to get tiling state for. */ +- uint32_t handle; ++ __u32 handle; + + /** + * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X, + * I915_TILING_Y). + */ +- uint32_t tiling_mode; ++ __u32 tiling_mode; + + /** + * Returned address bit 6 swizzling required for CPU access through + * mmap mapping. + */ +- uint32_t swizzle_mode; ++ __u32 swizzle_mode; + }; + + struct drm_i915_gem_get_aperture { + /** Total size of the aperture used by i915_gem_execbuffer, in bytes */ +- uint64_t aper_size; ++ __u64 aper_size; + + /** + * Available space in the aperture used by i915_gem_execbuffer, in + * bytes + */ +- uint64_t aper_available_size; ++ __u64 aper_available_size; + }; + + #endif /* _I915_DRM_H_ */ +diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h +index 944b50a..325fd6f 100644 +--- a/include/drm/mga_drm.h ++++ b/include/drm/mga_drm.h +@@ -35,6 +35,8 @@ + #ifndef __MGA_DRM_H__ + #define __MGA_DRM_H__ + ++#include ++ + /* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (mga_sarea.h) + */ +@@ -255,8 +257,8 @@ typedef struct _drm_mga_sarea { + #define DRM_IOCTL_MGA_ILOAD DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t) + #define DRM_IOCTL_MGA_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t) + #define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t) +-#define DRM_IOCTL_MGA_SET_FENCE DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_SET_FENCE, uint32_t) +-#define DRM_IOCTL_MGA_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_WAIT_FENCE, uint32_t) ++#define DRM_IOCTL_MGA_SET_FENCE DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_SET_FENCE, __u32) ++#define DRM_IOCTL_MGA_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_WAIT_FENCE, __u32) + #define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t) + + typedef struct _drm_mga_warp_index { +@@ -310,7 +312,7 @@ typedef struct drm_mga_dma_bootstrap { + */ + /*@{ */ + unsigned long texture_handle; /**< Handle used to map AGP textures. */ +- uint32_t texture_size; /**< Size of the AGP texture region. */ ++ __u32 texture_size; /**< Size of the AGP texture region. */ + /*@} */ + + /** +@@ -319,7 +321,7 @@ typedef struct drm_mga_dma_bootstrap { + * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be + * filled in with the actual AGP mode. If AGP was not available + */ +- uint32_t primary_size; ++ __u32 primary_size; + + /** + * Requested number of secondary DMA buffers. +@@ -329,7 +331,7 @@ typedef struct drm_mga_dma_bootstrap { + * allocated. Particularly when PCI DMA is used, this may be + * (subtantially) less than the number requested. + */ +- uint32_t secondary_bin_count; ++ __u32 secondary_bin_count; + + /** + * Requested size of each secondary DMA buffer. +@@ -338,7 +340,7 @@ typedef struct drm_mga_dma_bootstrap { + * dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed + * to reduce dma_mga_dma_bootstrap::secondary_bin_size. + */ +- uint32_t secondary_bin_size; ++ __u32 secondary_bin_size; + + /** + * Bit-wise mask of AGPSTAT2_* values. Currently only \c AGPSTAT2_1X, +@@ -350,12 +352,12 @@ typedef struct drm_mga_dma_bootstrap { + * filled in with the actual AGP mode. If AGP was not available + * (i.e., PCI DMA was used), this value will be zero. + */ +- uint32_t agp_mode; ++ __u32 agp_mode; + + /** + * Desired AGP GART size, measured in megabytes. + */ +- uint8_t agp_size; ++ __u8 agp_size; + } drm_mga_dma_bootstrap_t; + + typedef struct drm_mga_clear { +diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h +index 73ff51f..fe3e3a4 100644 +--- a/include/drm/radeon_drm.h ++++ b/include/drm/radeon_drm.h +@@ -33,6 +33,8 @@ + #ifndef __RADEON_DRM_H__ + #define __RADEON_DRM_H__ + ++#include ++ + /* WARNING: If you change any of these defines, make sure to change the + * defines in the X server file (radeon_sarea.h) + */ +@@ -304,6 +306,8 @@ typedef union { + + #define RADEON_SCRATCH_REG_OFFSET 32 + ++#define R600_SCRATCH_REG_OFFSET 256 ++ + #define RADEON_NR_SAREA_CLIPRECTS 12 + + /* There are 2 heaps (local/GART). Each region within a heap is a +@@ -526,7 +530,8 @@ typedef struct drm_radeon_init { + RADEON_INIT_CP = 0x01, + RADEON_CLEANUP_CP = 0x02, + RADEON_INIT_R200_CP = 0x03, +- RADEON_INIT_R300_CP = 0x04 ++ RADEON_INIT_R300_CP = 0x04, ++ RADEON_INIT_R600_CP = 0x05 + } func; + unsigned long sarea_priv_offset; + int is_pci; +@@ -722,7 +727,7 @@ typedef struct drm_radeon_irq_wait { + + typedef struct drm_radeon_setparam { + unsigned int param; +- int64_t value; ++ __s64 value; + } drm_radeon_setparam_t; + + #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ +diff --git a/include/drm/via_drm.h b/include/drm/via_drm.h +index a3b5c10..170786e 100644 +--- a/include/drm/via_drm.h ++++ b/include/drm/via_drm.h +@@ -24,6 +24,8 @@ + #ifndef _VIA_DRM_H_ + #define _VIA_DRM_H_ + ++#include ++ + /* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ +@@ -114,19 +116,19 @@ + #define VIA_MEM_UNKNOWN 4 + + typedef struct { +- uint32_t offset; +- uint32_t size; ++ __u32 offset; ++ __u32 size; + } drm_via_agp_t; + + typedef struct { +- uint32_t offset; +- uint32_t size; ++ __u32 offset; ++ __u32 size; + } drm_via_fb_t; + + typedef struct { +- uint32_t context; +- uint32_t type; +- uint32_t size; ++ __u32 context; ++ __u32 type; ++ __u32 size; + unsigned long index; + unsigned long offset; + } drm_via_mem_t; +@@ -148,9 +150,9 @@ typedef struct _drm_via_futex { + VIA_FUTEX_WAIT = 0x00, + VIA_FUTEX_WAKE = 0X01 + } func; +- uint32_t ms; +- uint32_t lock; +- uint32_t val; ++ __u32 ms; ++ __u32 lock; ++ __u32 val; + } drm_via_futex_t; + + typedef struct _drm_via_dma_init { +@@ -211,7 +213,7 @@ typedef struct _drm_via_cmdbuf_size { + VIA_CMDBUF_LAG = 0x02 + } func; + int wait; +- uint32_t size; ++ __u32 size; + } drm_via_cmdbuf_size_t; + + typedef enum { +@@ -236,8 +238,8 @@ enum drm_via_irqs { + struct drm_via_wait_irq_request { + unsigned irq; + via_irq_seq_type_t type; +- uint32_t sequence; +- uint32_t signal; ++ __u32 sequence; ++ __u32 signal; + }; + + typedef union drm_via_irqwait { +@@ -246,7 +248,7 @@ typedef union drm_via_irqwait { + } drm_via_irqwait_t; + + typedef struct drm_via_blitsync { +- uint32_t sync_handle; ++ __u32 sync_handle; + unsigned engine; + } drm_via_blitsync_t; + +@@ -257,16 +259,16 @@ typedef struct drm_via_blitsync { + */ + + typedef struct drm_via_dmablit { +- uint32_t num_lines; +- uint32_t line_length; ++ __u32 num_lines; ++ __u32 line_length; + +- uint32_t fb_addr; +- uint32_t fb_stride; ++ __u32 fb_addr; ++ __u32 fb_stride; + + unsigned char *mem_addr; +- uint32_t mem_stride; ++ __u32 mem_stride; + +- uint32_t flags; ++ __u32 flags; + int to_fb; + + drm_via_blitsync_t sync; diff --git a/packages/linux/patches/1812_drm-modesetting-radeon-0.1.diff b/packages/linux/patches/1812_drm-modesetting-radeon-0.1.diff new file mode 100644 index 0000000000..8fb9b2666e --- /dev/null +++ b/packages/linux/patches/1812_drm-modesetting-radeon-0.1.diff @@ -0,0 +1,37701 @@ +diff -Naur linux-2.6.29.1/arch/x86/mm/pat.c linux-2.6.29.1.patch/arch/x86/mm/pat.c +--- linux-2.6.29.1/arch/x86/mm/pat.c 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1.patch/arch/x86/mm/pat.c 2009-04-26 02:53:58.762725123 +0200 +@@ -30,6 +30,7 @@ + + #ifdef CONFIG_X86_PAT + int __read_mostly pat_enabled = 1; ++EXPORT_SYMBOL_GPL(pat_enabled); + + void __cpuinit pat_disable(char *reason) + { +diff -Naur linux-2.6.29.1/drivers/gpu/drm/ati_pcigart.c linux-2.6.29.1.patch/drivers/gpu/drm/ati_pcigart.c +--- linux-2.6.29.1/drivers/gpu/drm/ati_pcigart.c 2009-04-26 02:52:17.107975258 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/ati_pcigart.c 2009-04-26 02:54:09.594725507 +0200 +@@ -34,9 +34,67 @@ + #include "drmP.h" + + # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ ++# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) + +-static int drm_ati_alloc_pcigart_table(struct drm_device *dev, +- struct drm_ati_pcigart_info *gart_info) ++#define ATI_PCIE_WRITE 0x4 ++#define ATI_PCIE_READ 0x8 ++ ++static __inline__ void gart_insert_page_into_table(struct drm_ati_pcigart_info *gart_info, dma_addr_t addr, volatile u32 *pci_gart, int gart_idx) ++{ ++ struct drm_local_map *map = &gart_info->mapping; ++ u32 page_base; ++ ++ page_base = (u32)addr & ATI_PCIGART_PAGE_MASK; ++ switch(gart_info->gart_reg_if) { ++ case DRM_ATI_GART_IGP: ++ page_base |= (upper_32_bits(addr) & 0xff) << 4; ++ page_base |= 0xc; ++ break; ++ case DRM_ATI_GART_PCIE: ++ page_base >>= 8; ++ page_base |= (upper_32_bits(addr) & 0xff) << 24; ++ page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE; ++ break; ++ default: ++ case DRM_ATI_GART_PCI: ++ break; ++ } ++ if ((gart_info->gart_table_location == DRM_ATI_GART_MAIN) || (map->handle == NULL)) ++ pci_gart[gart_idx] = cpu_to_le32(page_base); ++ else ++ DRM_WRITE32(map, gart_idx * sizeof(u32), page_base); ++} ++ ++static __inline__ dma_addr_t gart_get_page_from_table(struct drm_ati_pcigart_info *gart_info, volatile u32 *pci_gart, int gart_idx) ++{ ++ struct drm_local_map *map = &gart_info->mapping; ++ u32 page_base; ++ dma_addr_t retval; ++ ++ if ((gart_info->gart_table_location == DRM_ATI_GART_MAIN) || (map->handle == NULL)) ++ page_base = le32_to_cpu(pci_gart[gart_idx]); ++ else ++ page_base = DRM_READ32(map, gart_idx * sizeof(u32)); ++ ++ switch(gart_info->gart_reg_if) { ++ case DRM_ATI_GART_IGP: ++ retval = (page_base & ATI_PCIGART_PAGE_MASK); ++ retval += (((page_base & 0xf0) >> 4) << 16) << 16; ++ break; ++ case DRM_ATI_GART_PCIE: ++ retval = (page_base & ~0xc); ++ retval <<= 8; ++ break; ++ case DRM_ATI_GART_PCI: ++ retval = page_base; ++ break; ++ } ++ ++ return retval; ++} ++ ++int drm_ati_alloc_pcigart_table(struct drm_device *dev, ++ struct drm_ati_pcigart_info *gart_info) + { + gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, + PAGE_SIZE, +@@ -44,12 +102,25 @@ + if (gart_info->table_handle == NULL) + return -ENOMEM; + ++#ifdef CONFIG_X86 ++ /* IGPs only exist on x86 in any case */ ++ if (gart_info->gart_reg_if == DRM_ATI_GART_IGP) ++ set_memory_uc((unsigned long)gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT); ++#endif ++ ++ memset(gart_info->table_handle->vaddr, 0, gart_info->table_size); + return 0; + } ++EXPORT_SYMBOL(drm_ati_alloc_pcigart_table); + + static void drm_ati_free_pcigart_table(struct drm_device *dev, + struct drm_ati_pcigart_info *gart_info) + { ++#ifdef CONFIG_X86 ++ /* IGPs only exist on x86 in any case */ ++ if (gart_info->gart_reg_if == DRM_ATI_GART_IGP) ++ set_memory_wb((unsigned long)gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT); ++#endif + drm_pci_free(dev, gart_info->table_handle); + gart_info->table_handle = NULL; + } +@@ -63,7 +134,6 @@ + + /* we need to support large memory configurations */ + if (!entry) { +- DRM_ERROR("no scatter/gather memory!\n"); + return 0; + } + +@@ -99,17 +169,13 @@ + struct drm_sg_mem *entry = dev->sg; + void *address = NULL; + unsigned long pages; +- u32 *pci_gart = NULL, page_base, gart_idx; ++ u32 *pci_gart = NULL, gart_idx; + dma_addr_t bus_address = 0; + int i, j, ret = 0; + int max_ati_pages, max_real_pages; ++ dma_addr_t entry_addr; + +- if (!entry) { +- DRM_ERROR("no scatter/gather memory!\n"); +- goto done; +- } +- +- if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { ++ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN && gart_info->table_handle == NULL) { + DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); + + ret = drm_ati_alloc_pcigart_table(dev, gart_info); +@@ -117,16 +183,20 @@ + DRM_ERROR("cannot allocate PCI GART page!\n"); + goto done; + } ++ } + ++ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { + pci_gart = gart_info->table_handle->vaddr; + address = gart_info->table_handle->vaddr; + bus_address = gart_info->table_handle->busaddr; + } else { + address = gart_info->addr; + bus_address = gart_info->bus_addr; +- DRM_DEBUG("PCI: Gart Table: VRAM %08LX mapped at %08lX\n", +- (unsigned long long)bus_address, +- (unsigned long)address); ++ } ++ ++ if (!entry) { ++ DRM_ERROR("no scatter/gather memory!\n"); ++ goto done; + } + + +@@ -153,39 +223,19 @@ + bus_address = 0; + goto done; + } +- page_base = (u32) entry->busaddr[i]; + ++ entry_addr = entry->busaddr[i]; + for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { +- u32 val; + +- switch(gart_info->gart_reg_if) { +- case DRM_ATI_GART_IGP: +- val = page_base | 0xc; +- break; +- case DRM_ATI_GART_PCIE: +- val = (page_base >> 8) | 0xc; +- break; +- default: +- case DRM_ATI_GART_PCI: +- val = page_base; +- break; +- } +- if (gart_info->gart_table_location == +- DRM_ATI_GART_MAIN) +- pci_gart[gart_idx] = cpu_to_le32(val); +- else +- DRM_WRITE32(map, gart_idx * sizeof(u32), val); ++ gart_insert_page_into_table(gart_info, entry_addr, pci_gart, gart_idx); + gart_idx++; +- page_base += ATI_PCIGART_PAGE_SIZE; ++ entry_addr += ATI_PCIGART_PAGE_SIZE; + } + } ++ + ret = 1; + +-#if defined(__i386__) || defined(__x86_64__) +- wbinvd(); +-#else + mb(); +-#endif + + done: + gart_info->addr = address; +@@ -193,3 +243,146 @@ + return ret; + } + EXPORT_SYMBOL(drm_ati_pcigart_init); ++ ++static int ati_pcigart_needs_unbind_cache_adjust(struct drm_ttm_backend *backend) ++{ ++ return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1); ++} ++ ++static int ati_pcigart_populate(struct drm_ttm_backend *backend, ++ unsigned long num_pages, ++ struct page **pages, ++ struct page *dummy_read_page) ++{ ++ struct ati_pcigart_ttm_backend *atipci_be = ++ container_of(backend, struct ati_pcigart_ttm_backend, backend); ++ ++ atipci_be->pages = pages; ++ atipci_be->num_pages = num_pages; ++ atipci_be->populated = 1; ++ return 0; ++} ++ ++static int ati_pcigart_bind_ttm(struct drm_ttm_backend *backend, ++ struct drm_bo_mem_reg *bo_mem) ++{ ++ struct ati_pcigart_ttm_backend *atipci_be = ++ container_of(backend, struct ati_pcigart_ttm_backend, backend); ++ off_t j; ++ int i; ++ struct drm_ati_pcigart_info *info = atipci_be->gart_info; ++ volatile u32 *pci_gart; ++ dma_addr_t offset = bo_mem->mm_node->start; ++ dma_addr_t page_base; ++ ++ pci_gart = info->addr; ++ ++#if 0 ++ j = offset; ++ while (j < (offset + atipci_be->num_pages)) { ++ if (gart_get_page_from_table(info, pci_gart, j)) ++ return -EBUSY; ++ j++; ++ } ++#endif ++ for (i = 0, j = offset; i < atipci_be->num_pages; i++, j++) { ++ struct page *cur_page = atipci_be->pages[i]; ++ /* write value */ ++ page_base = page_to_phys(cur_page); ++ gart_insert_page_into_table(info, page_base, pci_gart, j); ++ } ++ ++ mb(); ++ atipci_be->gart_flush_fn(atipci_be->dev); ++ ++ atipci_be->bound = 1; ++ atipci_be->offset = offset; ++ /* need to traverse table and add entries */ ++ DRM_DEBUG("\n"); ++ return 0; ++} ++ ++static int ati_pcigart_unbind_ttm(struct drm_ttm_backend *backend) ++{ ++ struct ati_pcigart_ttm_backend *atipci_be = ++ container_of(backend, struct ati_pcigart_ttm_backend, backend); ++ struct drm_ati_pcigart_info *info = atipci_be->gart_info; ++ unsigned long offset = atipci_be->offset; ++ int i; ++ off_t j; ++ volatile u32 *pci_gart = info->addr; ++ ++ if (atipci_be->bound != 1) ++ return -EINVAL; ++ ++ for (i = 0, j = offset; i < atipci_be->num_pages; i++, j++) { ++ if (info->gart_table_location == DRM_ATI_GART_MAIN || info->mapping.handle == NULL) ++ pci_gart[j] = 0; ++ else ++ DRM_WRITE32(&info->mapping, j * sizeof(u32), 0); ++ } ++ ++ mb(); ++ atipci_be->gart_flush_fn(atipci_be->dev); ++ atipci_be->bound = 0; ++ atipci_be->offset = 0; ++ return 0; ++} ++ ++static void ati_pcigart_clear_ttm(struct drm_ttm_backend *backend) ++{ ++ struct ati_pcigart_ttm_backend *atipci_be = ++ container_of(backend, struct ati_pcigart_ttm_backend, backend); ++ ++ DRM_DEBUG("\n"); ++ if (atipci_be->pages) { ++ backend->func->unbind(backend); ++ atipci_be->pages = NULL; ++ ++ } ++ atipci_be->num_pages = 0; ++} ++ ++static void ati_pcigart_destroy_ttm(struct drm_ttm_backend *backend) ++{ ++ struct ati_pcigart_ttm_backend *atipci_be; ++ if (backend) { ++ DRM_DEBUG("\n"); ++ atipci_be = container_of(backend, struct ati_pcigart_ttm_backend, backend); ++ if (atipci_be) { ++ if (atipci_be->pages) { ++ backend->func->clear(backend); ++ } ++ drm_ctl_free(atipci_be, sizeof(*atipci_be), DRM_MEM_TTM); ++ } ++ } ++} ++ ++static struct drm_ttm_backend_func ati_pcigart_ttm_backend = ++{ ++ .needs_ub_cache_adjust = ati_pcigart_needs_unbind_cache_adjust, ++ .populate = ati_pcigart_populate, ++ .clear = ati_pcigart_clear_ttm, ++ .bind = ati_pcigart_bind_ttm, ++ .unbind = ati_pcigart_unbind_ttm, ++ .destroy = ati_pcigart_destroy_ttm, ++}; ++ ++struct drm_ttm_backend *ati_pcigart_init_ttm(struct drm_device *dev, struct drm_ati_pcigart_info *info, void (*gart_flush_fn)(struct drm_device *dev)) ++{ ++ struct ati_pcigart_ttm_backend *atipci_be; ++ ++ atipci_be = drm_ctl_calloc(1, sizeof (*atipci_be), DRM_MEM_TTM); ++ if (!atipci_be) ++ return NULL; ++ ++ atipci_be->populated = 0; ++ atipci_be->backend.func = &ati_pcigart_ttm_backend; ++// atipci_be->backend.mem_type = DRM_BO_MEM_TT; ++ atipci_be->gart_info = info; ++ atipci_be->gart_flush_fn = gart_flush_fn; ++ atipci_be->dev = dev; ++ ++ return &atipci_be->backend; ++} ++EXPORT_SYMBOL(ati_pcigart_init_ttm); +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_agpsupport.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_agpsupport.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_agpsupport.c 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_agpsupport.c 2009-04-26 02:54:17.639725207 +0200 +@@ -497,6 +497,177 @@ + } + EXPORT_SYMBOL(drm_agp_bind_pages); + ++/* ++ * AGP ttm backend interface. ++ */ ++ ++#ifndef AGP_USER_TYPES ++#define AGP_USER_TYPES (1 << 16) ++#define AGP_USER_MEMORY (AGP_USER_TYPES) ++#define AGP_USER_CACHED_MEMORY (AGP_USER_TYPES + 1) ++#endif ++#define AGP_REQUIRED_MAJOR 0 ++#define AGP_REQUIRED_MINOR 102 ++ ++static int drm_agp_needs_unbind_cache_adjust(struct drm_ttm_backend *backend) ++{ ++ return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1); ++} ++ ++ ++static int drm_agp_populate(struct drm_ttm_backend *backend, ++ unsigned long num_pages, struct page **pages, ++ struct page *dummy_read_page) ++{ ++ struct drm_agp_ttm_backend *agp_be = ++ container_of(backend, struct drm_agp_ttm_backend, backend); ++ struct page **cur_page, **last_page = pages + num_pages; ++ DRM_AGP_MEM *mem; ++ int dummy_page_count = 0; ++ ++ if (drm_alloc_memctl(num_pages * sizeof(void *))) ++ return -1; ++ ++ DRM_DEBUG("drm_agp_populate_ttm\n"); ++ mem = drm_agp_allocate_memory(agp_be->bridge, num_pages, AGP_USER_MEMORY); ++ if (!mem) { ++ drm_free_memctl(num_pages * sizeof(void *)); ++ return -1; ++ } ++ ++ DRM_DEBUG("Current page count is %ld\n", (long) mem->page_count); ++ mem->page_count = 0; ++ for (cur_page = pages; cur_page < last_page; ++cur_page) { ++ struct page *page = *cur_page; ++ if (!page) { ++ page = dummy_read_page; ++ ++dummy_page_count; ++ } ++ mem->memory[mem->page_count++] = phys_to_gart(page_to_phys(page)); ++ } ++ if (dummy_page_count) ++ DRM_DEBUG("Mapped %d dummy pages\n", dummy_page_count); ++ agp_be->mem = mem; ++ return 0; ++} ++ ++static int drm_agp_bind_ttm(struct drm_ttm_backend *backend, ++ struct drm_bo_mem_reg *bo_mem) ++{ ++ struct drm_agp_ttm_backend *agp_be = ++ container_of(backend, struct drm_agp_ttm_backend, backend); ++ DRM_AGP_MEM *mem = agp_be->mem; ++ int ret; ++ int snooped = (bo_mem->flags & DRM_BO_FLAG_CACHED) && !(bo_mem->flags & DRM_BO_FLAG_CACHED_MAPPED); ++ ++ DRM_DEBUG("drm_agp_bind_ttm\n"); ++ mem->is_flushed = true; ++ mem->type = AGP_USER_MEMORY; ++ /* CACHED MAPPED implies not snooped memory */ ++ if (snooped) ++ mem->type = AGP_USER_CACHED_MEMORY; ++ ++ ret = drm_agp_bind_memory(mem, bo_mem->mm_node->start); ++ if (ret) ++ DRM_ERROR("AGP Bind memory failed\n"); ++ ++ DRM_FLAG_MASKED(backend->flags, (bo_mem->flags & DRM_BO_FLAG_CACHED) ? ++ DRM_BE_FLAG_BOUND_CACHED : 0, ++ DRM_BE_FLAG_BOUND_CACHED); ++ return ret; ++} ++ ++static int drm_agp_unbind_ttm(struct drm_ttm_backend *backend) ++{ ++ struct drm_agp_ttm_backend *agp_be = ++ container_of(backend, struct drm_agp_ttm_backend, backend); ++ ++ DRM_DEBUG("drm_agp_unbind_ttm\n"); ++ if (agp_be->mem->is_bound) ++ return drm_agp_unbind_memory(agp_be->mem); ++ else ++ return 0; ++} ++ ++static void drm_agp_clear_ttm(struct drm_ttm_backend *backend) ++{ ++ struct drm_agp_ttm_backend *agp_be = ++ container_of(backend, struct drm_agp_ttm_backend, backend); ++ DRM_AGP_MEM *mem = agp_be->mem; ++ ++ DRM_DEBUG("drm_agp_clear_ttm\n"); ++ if (mem) { ++ unsigned long num_pages = mem->page_count; ++ backend->func->unbind(backend); ++ agp_free_memory(mem); ++ drm_free_memctl(num_pages * sizeof(void *)); ++ } ++ agp_be->mem = NULL; ++} ++ ++static void drm_agp_destroy_ttm(struct drm_ttm_backend *backend) ++{ ++ struct drm_agp_ttm_backend *agp_be; ++ ++ if (backend) { ++ DRM_DEBUG("drm_agp_destroy_ttm\n"); ++ agp_be = container_of(backend, struct drm_agp_ttm_backend, backend); ++ if (agp_be) { ++ if (agp_be->mem) ++ backend->func->clear(backend); ++ drm_ctl_free(agp_be, sizeof(*agp_be), DRM_MEM_TTM); ++ } ++ } ++} ++ ++static struct drm_ttm_backend_func agp_ttm_backend = { ++ .needs_ub_cache_adjust = drm_agp_needs_unbind_cache_adjust, ++ .populate = drm_agp_populate, ++ .clear = drm_agp_clear_ttm, ++ .bind = drm_agp_bind_ttm, ++ .unbind = drm_agp_unbind_ttm, ++ .destroy = drm_agp_destroy_ttm, ++}; ++ ++struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev) ++{ ++ ++ struct drm_agp_ttm_backend *agp_be; ++ struct agp_kern_info *info; ++ ++ if (!dev->agp) { ++ DRM_ERROR("AGP is not initialized.\n"); ++ return NULL; ++ } ++ info = &dev->agp->agp_info; ++ ++ if (info->version.major != AGP_REQUIRED_MAJOR || ++ info->version.minor < AGP_REQUIRED_MINOR) { ++ DRM_ERROR("Wrong agpgart version %d.%d\n" ++ "\tYou need at least version %d.%d.\n", ++ info->version.major, ++ info->version.minor, ++ AGP_REQUIRED_MAJOR, ++ AGP_REQUIRED_MINOR); ++ return NULL; ++ } ++ ++ ++ agp_be = drm_ctl_calloc(1, sizeof(*agp_be), DRM_MEM_TTM); ++ if (!agp_be) ++ return NULL; ++ ++ agp_be->mem = NULL; ++ ++ agp_be->bridge = dev->agp->bridge; ++ agp_be->populated = false; ++ agp_be->backend.func = &agp_ttm_backend; ++ agp_be->backend.dev = dev; ++ ++ return &agp_be->backend; ++} ++EXPORT_SYMBOL(drm_agp_init_ttm); ++ + void drm_agp_chipset_flush(struct drm_device *dev) + { + agp_flush_chipset(dev->agp->bridge); +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_bo.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_bo.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_bo.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_bo.c 2009-04-26 02:58:23.193724802 +0200 +@@ -0,0 +1,2161 @@ ++/************************************************************************** ++ * ++ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ **************************************************************************/ ++/* ++ * Authors: Thomas Hellström ++ */ ++ ++#include "drmP.h" ++ ++/* ++ * Locking may look a bit complicated but isn't really: ++ * ++ * The buffer usage atomic_t needs to be protected by dev->struct_mutex ++ * when there is a chance that it can be zero before or after the operation. ++ * ++ * dev->struct_mutex also protects all lists and list heads, ++ * Hash tables and hash heads. ++ * ++ * bo->mutex protects the buffer object itself excluding the usage field. ++ * bo->mutex does also protect the buffer list heads, so to manipulate those, ++ * we need both the bo->mutex and the dev->struct_mutex. ++ * ++ * Locking order is bo->mutex, dev->struct_mutex. Therefore list traversal ++ * is a bit complicated. When dev->struct_mutex is released to grab bo->mutex, ++ * the list traversal will, in general, need to be restarted. ++ * ++ */ ++ ++static void drm_bo_destroy_locked(struct drm_buffer_object *bo); ++static int drm_bo_setup_vm_locked(struct drm_buffer_object *bo); ++static void drm_bo_unmap_virtual(struct drm_buffer_object *bo); ++ ++static inline uint64_t drm_bo_type_flags(unsigned type) ++{ ++ return (1ULL << (24 + type)); ++} ++ ++/* ++ * bo locked. dev->struct_mutex locked. ++ */ ++ ++void drm_bo_add_to_pinned_lru(struct drm_buffer_object *bo) ++{ ++ struct drm_mem_type_manager *man; ++ ++ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex); ++ DRM_ASSERT_LOCKED(&bo->mutex); ++ ++ man = &bo->dev->bm.man[bo->pinned_mem_type]; ++ list_add_tail(&bo->pinned_lru, &man->pinned); ++} ++ ++void drm_bo_add_to_lru(struct drm_buffer_object *bo) ++{ ++ struct drm_mem_type_manager *man; ++ ++ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex); ++ ++ if (!(bo->mem.proposed_flags & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT)) ++ || bo->mem.mem_type != bo->pinned_mem_type) { ++ man = &bo->dev->bm.man[bo->mem.mem_type]; ++ list_add_tail(&bo->lru, &man->lru); ++ } else { ++ INIT_LIST_HEAD(&bo->lru); ++ } ++} ++ ++static int drm_bo_vm_pre_move(struct drm_buffer_object *bo, int old_is_pci) ++{ ++#ifdef DRM_ODD_MM_COMPAT ++ int ret; ++ ++ if (!bo->map_list.map) ++ return 0; ++ ++ ret = drm_bo_lock_kmm(bo); ++ if (ret) ++ return ret; ++ drm_bo_unmap_virtual(bo); ++ if (old_is_pci) ++ drm_bo_finish_unmap(bo); ++#else ++ if (!bo->map_list.map) ++ return 0; ++ ++ drm_bo_unmap_virtual(bo); ++#endif ++ return 0; ++} ++ ++static void drm_bo_vm_post_move(struct drm_buffer_object *bo) ++{ ++#ifdef DRM_ODD_MM_COMPAT ++ int ret; ++ ++ if (!bo->map_list.map) ++ return; ++ ++ ret = drm_bo_remap_bound(bo); ++ if (ret) { ++ DRM_ERROR("Failed to remap a bound buffer object.\n" ++ "\tThis might cause a sigbus later.\n"); ++ } ++ drm_bo_unlock_kmm(bo); ++#endif ++} ++ ++/* ++ * Call bo->mutex locked. ++ */ ++ ++int drm_bo_add_ttm(struct drm_buffer_object *bo) ++{ ++ struct drm_device *dev = bo->dev; ++ int ret = 0; ++ uint32_t page_flags = 0; ++ ++ DRM_ASSERT_LOCKED(&bo->mutex); ++ bo->ttm = NULL; ++ ++ if (bo->mem.proposed_flags & DRM_BO_FLAG_WRITE) ++ page_flags |= DRM_TTM_PAGE_WRITE; ++ ++ switch (bo->type) { ++ case drm_bo_type_device: ++ case drm_bo_type_kernel: ++ bo->ttm = drm_ttm_create(dev, bo->num_pages << PAGE_SHIFT, ++ page_flags, dev->bm.dummy_read_page); ++ if (!bo->ttm) ++ ret = -ENOMEM; ++ break; ++ case drm_bo_type_user: ++ bo->ttm = drm_ttm_create(dev, bo->num_pages << PAGE_SHIFT, ++ page_flags | DRM_TTM_PAGE_USER, ++ dev->bm.dummy_read_page); ++ if (!bo->ttm) ++ ret = -ENOMEM; ++ ++ ret = drm_ttm_set_user(bo->ttm, current, ++ bo->buffer_start, ++ bo->num_pages); ++ if (ret) ++ return ret; ++ ++ break; ++ default: ++ DRM_ERROR("Illegal buffer object type\n"); ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(drm_bo_add_ttm); ++ ++static int drm_bo_handle_move_mem(struct drm_buffer_object *bo, ++ struct drm_bo_mem_reg *mem, ++ int evict, int no_wait) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_buffer_manager *bm = &dev->bm; ++ int old_is_pci = drm_mem_reg_is_pci(dev, &bo->mem); ++ int new_is_pci = drm_mem_reg_is_pci(dev, mem); ++ struct drm_mem_type_manager *old_man = &bm->man[bo->mem.mem_type]; ++ struct drm_mem_type_manager *new_man = &bm->man[mem->mem_type]; ++ int ret = 0; ++ ++ if (old_is_pci || new_is_pci || ++ ((mem->flags ^ bo->mem.flags) & DRM_BO_FLAG_CACHED)) ++ ret = drm_bo_vm_pre_move(bo, old_is_pci); ++ if (ret) ++ return ret; ++ ++ /* ++ * Create and bind a ttm if required. ++ */ ++ ++ if (!(new_man->flags & _DRM_FLAG_MEMTYPE_FIXED) && (bo->ttm == NULL)) { ++ ret = drm_bo_add_ttm(bo); ++ if (ret) ++ goto out_err; ++ ++ if (mem->mem_type != DRM_BO_MEM_LOCAL) { ++ ret = drm_ttm_bind(bo->ttm, mem); ++ if (ret) ++ goto out_err; ++ } ++ ++ if (bo->mem.mem_type == DRM_BO_MEM_LOCAL) { ++ ++ struct drm_bo_mem_reg *old_mem = &bo->mem; ++ uint64_t save_flags = old_mem->flags; ++ uint64_t save_proposed_flags = old_mem->proposed_flags; ++ ++ *old_mem = *mem; ++ mem->mm_node = NULL; ++ old_mem->proposed_flags = save_proposed_flags; ++ DRM_FLAG_MASKED(save_flags, mem->flags, ++ DRM_BO_MASK_MEMTYPE); ++ goto moved; ++ } ++ ++ } ++ ++ if (!(old_man->flags & _DRM_FLAG_MEMTYPE_FIXED) && ++ !(new_man->flags & _DRM_FLAG_MEMTYPE_FIXED)) ++ ret = drm_bo_move_ttm(bo, evict, no_wait, mem); ++ else if (dev->driver->bo_driver->move) ++ ret = dev->driver->bo_driver->move(bo, evict, no_wait, mem); ++ else ++ ret = drm_bo_move_memcpy(bo, evict, no_wait, mem); ++ ++ if (ret) ++ goto out_err; ++ ++moved: ++ if (old_is_pci || new_is_pci) ++ drm_bo_vm_post_move(bo); ++ ++ if (bo->priv_flags & _DRM_BO_FLAG_EVICTED) { ++ ret = ++ dev->driver->bo_driver->invalidate_caches(dev, ++ bo->mem.flags); ++ if (ret) ++ DRM_ERROR("Can not flush read caches\n"); ++ } ++ ++ DRM_FLAG_MASKED(bo->priv_flags, ++ (evict) ? _DRM_BO_FLAG_EVICTED : 0, ++ _DRM_BO_FLAG_EVICTED); ++ ++ if (bo->mem.mm_node) ++ bo->offset = (bo->mem.mm_node->start << PAGE_SHIFT) + ++ bm->man[bo->mem.mem_type].gpu_offset; ++ ++ ++ return 0; ++ ++out_err: ++ if (old_is_pci || new_is_pci) ++ drm_bo_vm_post_move(bo); ++ ++ new_man = &bm->man[bo->mem.mem_type]; ++ if ((new_man->flags & _DRM_FLAG_MEMTYPE_FIXED) && bo->ttm) { ++ drm_ttm_unbind(bo->ttm); ++ drm_ttm_destroy(bo->ttm); ++ bo->ttm = NULL; ++ } ++ ++ return ret; ++} ++ ++/* ++ * Call bo->mutex locked. ++ * Returns -EBUSY if the buffer is currently rendered to or from. 0 otherwise. ++ */ ++ ++static int drm_bo_busy(struct drm_buffer_object *bo, int check_unfenced) ++{ ++ struct drm_fence_object *fence = bo->fence; ++ ++ if (check_unfenced && (bo->priv_flags & _DRM_BO_FLAG_UNFENCED)) ++ return -EBUSY; ++ ++ if (fence) { ++ if (drm_fence_object_signaled(fence, bo->fence_type)) { ++ drm_fence_usage_deref_unlocked(&bo->fence); ++ return 0; ++ } ++ drm_fence_object_flush(fence, DRM_FENCE_TYPE_EXE); ++ if (drm_fence_object_signaled(fence, bo->fence_type)) { ++ drm_fence_usage_deref_unlocked(&bo->fence); ++ return 0; ++ } ++ return -EBUSY; ++ } ++ return 0; ++} ++ ++static int drm_bo_check_unfenced(struct drm_buffer_object *bo) ++{ ++ int ret; ++ ++ mutex_lock(&bo->mutex); ++ ret = (bo->priv_flags & _DRM_BO_FLAG_UNFENCED); ++ mutex_unlock(&bo->mutex); ++ return ret; ++} ++ ++ ++/* ++ * Call bo->mutex locked. ++ * Wait until the buffer is idle. ++ */ ++ ++int drm_bo_wait(struct drm_buffer_object *bo, int lazy, int interruptible, ++ int no_wait, int check_unfenced) ++{ ++ int ret; ++ ++ DRM_ASSERT_LOCKED(&bo->mutex); ++ while(unlikely(drm_bo_busy(bo, check_unfenced))) { ++ if (no_wait) ++ return -EBUSY; ++ ++ if (check_unfenced && (bo->priv_flags & _DRM_BO_FLAG_UNFENCED)) { ++ mutex_unlock(&bo->mutex); ++ wait_event(bo->event_queue, !drm_bo_check_unfenced(bo)); ++ mutex_lock(&bo->mutex); ++ bo->priv_flags |= _DRM_BO_FLAG_UNLOCKED; ++ } ++ ++ if (bo->fence) { ++ struct drm_fence_object *fence; ++ uint32_t fence_type = bo->fence_type; ++ ++ drm_fence_reference_unlocked(&fence, bo->fence); ++ mutex_unlock(&bo->mutex); ++ ++ ret = drm_fence_object_wait(fence, lazy, !interruptible, ++ fence_type); ++ ++ drm_fence_usage_deref_unlocked(&fence); ++ mutex_lock(&bo->mutex); ++ bo->priv_flags |= _DRM_BO_FLAG_UNLOCKED; ++ if (ret) ++ return ret; ++ } ++ ++ } ++ return 0; ++} ++EXPORT_SYMBOL(drm_bo_wait); ++ ++static int drm_bo_expire_fence(struct drm_buffer_object *bo, int allow_errors) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_buffer_manager *bm = &dev->bm; ++ ++ if (bo->fence) { ++ if (bm->nice_mode) { ++ unsigned long _end = jiffies + 3 * DRM_HZ; ++ int ret; ++ do { ++ ret = drm_bo_wait(bo, 0, 0, 0, 0); ++ if (ret && allow_errors) ++ return ret; ++ ++ } while (ret && !time_after_eq(jiffies, _end)); ++ ++ if (bo->fence) { ++ bm->nice_mode = 0; ++ DRM_ERROR("Detected GPU lockup or " ++ "fence driver was taken down. " ++ "Evicting buffer.\n"); ++ } ++ } ++ if (bo->fence) ++ drm_fence_usage_deref_unlocked(&bo->fence); ++ } ++ return 0; ++} ++ ++/* ++ * Call dev->struct_mutex locked. ++ * Attempts to remove all private references to a buffer by expiring its ++ * fence object and removing from lru lists and memory managers. ++ */ ++ ++static void drm_bo_cleanup_refs(struct drm_buffer_object *bo, int remove_all) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_buffer_manager *bm = &dev->bm; ++ ++ DRM_ASSERT_LOCKED(&dev->struct_mutex); ++ ++ atomic_inc(&bo->usage); ++ mutex_unlock(&dev->struct_mutex); ++ mutex_lock(&bo->mutex); ++ ++ DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED); ++ ++ if (bo->fence && drm_fence_object_signaled(bo->fence, ++ bo->fence_type)) ++ drm_fence_usage_deref_unlocked(&bo->fence); ++ ++ if (bo->fence && remove_all) ++ (void)drm_bo_expire_fence(bo, 0); ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ if (!atomic_dec_and_test(&bo->usage)) ++ goto out; ++ ++ if (!bo->fence) { ++ list_del_init(&bo->lru); ++ if (bo->mem.mm_node) { ++ drm_mm_put_block(bo->mem.mm_node); ++ if (bo->pinned_node == bo->mem.mm_node) ++ bo->pinned_node = NULL; ++ bo->mem.mm_node = NULL; ++ } ++ list_del_init(&bo->pinned_lru); ++ if (bo->pinned_node) { ++ drm_mm_put_block(bo->pinned_node); ++ bo->pinned_node = NULL; ++ } ++ list_del_init(&bo->ddestroy); ++ mutex_unlock(&bo->mutex); ++ drm_bo_destroy_locked(bo); ++ return; ++ } ++ ++ if (list_empty(&bo->ddestroy)) { ++ drm_fence_object_flush(bo->fence, bo->fence_type); ++ list_add_tail(&bo->ddestroy, &bm->ddestroy); ++ schedule_delayed_work(&bm->wq, ++ ((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100); ++ } ++ ++out: ++ mutex_unlock(&bo->mutex); ++ return; ++} ++ ++/* ++ * Verify that refcount is 0 and that there are no internal references ++ * to the buffer object. Then destroy it. ++ */ ++ ++static void drm_bo_destroy_locked(struct drm_buffer_object *bo) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_buffer_manager *bm = &dev->bm; ++ ++ DRM_ASSERT_LOCKED(&dev->struct_mutex); ++ ++ DRM_DEBUG("freeing %p\n", bo); ++ if (list_empty(&bo->lru) && bo->mem.mm_node == NULL && ++ list_empty(&bo->pinned_lru) && bo->pinned_node == NULL && ++ list_empty(&bo->ddestroy) && atomic_read(&bo->usage) == 0) { ++ if (bo->fence != NULL) { ++ DRM_ERROR("Fence was non-zero.\n"); ++ drm_bo_cleanup_refs(bo, 0); ++ return; ++ } ++ ++#ifdef DRM_ODD_MM_COMPAT ++ BUG_ON(!list_empty(&bo->vma_list)); ++ BUG_ON(!list_empty(&bo->p_mm_list)); ++#endif ++ ++ if (bo->ttm) { ++ drm_ttm_unbind(bo->ttm); ++ drm_ttm_destroy(bo->ttm); ++ bo->ttm = NULL; ++ } ++ ++ atomic_dec(&bm->count); ++ ++ drm_ctl_free(bo, sizeof(*bo), DRM_MEM_BUFOBJ); ++ ++ return; ++ } ++ ++ /* ++ * Some stuff is still trying to reference the buffer object. ++ * Get rid of those references. ++ */ ++ ++ drm_bo_cleanup_refs(bo, 0); ++ ++ return; ++} ++ ++/* ++ * Call dev->struct_mutex locked. ++ */ ++ ++static void drm_bo_delayed_delete(struct drm_device *dev, int remove_all) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ ++ struct drm_buffer_object *entry, *nentry; ++ struct list_head *list, *next; ++ ++ list_for_each_safe(list, next, &bm->ddestroy) { ++ entry = list_entry(list, struct drm_buffer_object, ddestroy); ++ ++ nentry = NULL; ++ DRM_DEBUG("bo is %p, %d\n", entry, entry->num_pages); ++ if (next != &bm->ddestroy) { ++ nentry = list_entry(next, struct drm_buffer_object, ++ ddestroy); ++ atomic_inc(&nentry->usage); ++ } ++ ++ drm_bo_cleanup_refs(entry, remove_all); ++ ++ if (nentry) ++ atomic_dec(&nentry->usage); ++ } ++} ++ ++static void drm_bo_delayed_workqueue(struct work_struct *work) ++{ ++ struct drm_buffer_manager *bm = ++ container_of(work, struct drm_buffer_manager, wq.work); ++ struct drm_device *dev = container_of(bm, struct drm_device, bm); ++ ++ DRM_DEBUG("Delayed delete Worker\n"); ++ ++ mutex_lock(&dev->struct_mutex); ++ if (!bm->initialized) { ++ mutex_unlock(&dev->struct_mutex); ++ return; ++ } ++ drm_bo_delayed_delete(dev, 0); ++ if (bm->initialized && !list_empty(&bm->ddestroy)) { ++ schedule_delayed_work(&bm->wq, ++ ((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100); ++ } ++ mutex_unlock(&dev->struct_mutex); ++} ++ ++void drm_bo_usage_deref_locked(struct drm_buffer_object **bo) ++{ ++ struct drm_buffer_object *tmp_bo = *bo; ++ bo = NULL; ++ ++ DRM_ASSERT_LOCKED(&tmp_bo->dev->struct_mutex); ++ ++ if (atomic_dec_and_test(&tmp_bo->usage)) ++ drm_bo_destroy_locked(tmp_bo); ++} ++EXPORT_SYMBOL(drm_bo_usage_deref_locked); ++ ++void drm_bo_usage_deref_unlocked(struct drm_buffer_object **bo) ++{ ++ struct drm_buffer_object *tmp_bo = *bo; ++ struct drm_device *dev = tmp_bo->dev; ++ ++ *bo = NULL; ++ if (atomic_dec_and_test(&tmp_bo->usage)) { ++ mutex_lock(&dev->struct_mutex); ++ if (atomic_read(&tmp_bo->usage) == 0) ++ drm_bo_destroy_locked(tmp_bo); ++ mutex_unlock(&dev->struct_mutex); ++ } ++} ++EXPORT_SYMBOL(drm_bo_usage_deref_unlocked); ++ ++void drm_putback_buffer_objects(struct drm_device *dev) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct list_head *list = &bm->unfenced; ++ struct drm_buffer_object *entry, *next; ++ ++ mutex_lock(&dev->struct_mutex); ++ list_for_each_entry_safe(entry, next, list, lru) { ++ atomic_inc(&entry->usage); ++ mutex_unlock(&dev->struct_mutex); ++ ++ mutex_lock(&entry->mutex); ++ BUG_ON(!(entry->priv_flags & _DRM_BO_FLAG_UNFENCED)); ++ mutex_lock(&dev->struct_mutex); ++ ++ list_del_init(&entry->lru); ++ DRM_FLAG_MASKED(entry->priv_flags, 0, _DRM_BO_FLAG_UNFENCED); ++ wake_up_all(&entry->event_queue); ++ ++ /* ++ * FIXME: Might want to put back on head of list ++ * instead of tail here. ++ */ ++ ++ drm_bo_add_to_lru(entry); ++ mutex_unlock(&entry->mutex); ++ drm_bo_usage_deref_locked(&entry); ++ } ++ mutex_unlock(&dev->struct_mutex); ++} ++EXPORT_SYMBOL(drm_putback_buffer_objects); ++ ++/* ++ * Note. The caller has to register (if applicable) ++ * and deregister fence object usage. ++ */ ++ ++int drm_fence_buffer_objects(struct drm_device *dev, ++ struct list_head *list, ++ uint32_t fence_flags, ++ struct drm_fence_object *fence, ++ struct drm_fence_object **used_fence) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_buffer_object *entry; ++ uint32_t fence_type = 0; ++ uint32_t fence_class = ~0; ++ int count = 0; ++ int ret = 0; ++ struct list_head *l; ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ if (!list) ++ list = &bm->unfenced; ++ ++ if (fence) ++ fence_class = fence->fence_class; ++ ++ list_for_each_entry(entry, list, lru) { ++ BUG_ON(!(entry->priv_flags & _DRM_BO_FLAG_UNFENCED)); ++ fence_type |= entry->new_fence_type; ++ if (fence_class == ~0) ++ fence_class = entry->new_fence_class; ++ else if (entry->new_fence_class != fence_class) { ++ DRM_ERROR("Unmatching fence classes on unfenced list: " ++ "%d and %d.\n", ++ fence_class, ++ entry->new_fence_class); ++ ret = -EINVAL; ++ goto out; ++ } ++ count++; ++ } ++ ++ if (!count) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (fence) { ++ if ((fence_type & fence->type) != fence_type || ++ (fence->fence_class != fence_class)) { ++ DRM_ERROR("Given fence doesn't match buffers " ++ "on unfenced list.\n"); ++ ret = -EINVAL; ++ goto out; ++ } ++ } else { ++ mutex_unlock(&dev->struct_mutex); ++ ret = drm_fence_object_create(dev, fence_class, fence_type, ++ fence_flags | DRM_FENCE_FLAG_EMIT, ++ &fence); ++ mutex_lock(&dev->struct_mutex); ++ if (ret) ++ goto out; ++ } ++ ++ count = 0; ++ l = list->next; ++ while (l != list) { ++ prefetch(l->next); ++ entry = list_entry(l, struct drm_buffer_object, lru); ++ atomic_inc(&entry->usage); ++ mutex_unlock(&dev->struct_mutex); ++ mutex_lock(&entry->mutex); ++ mutex_lock(&dev->struct_mutex); ++ list_del_init(l); ++ if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) { ++ count++; ++ if (entry->fence) ++ drm_fence_usage_deref_locked(&entry->fence); ++ entry->fence = drm_fence_reference_locked(fence); ++ entry->fence_class = entry->new_fence_class; ++ entry->fence_type = entry->new_fence_type; ++ DRM_FLAG_MASKED(entry->priv_flags, 0, ++ _DRM_BO_FLAG_UNFENCED); ++ wake_up_all(&entry->event_queue); ++ drm_bo_add_to_lru(entry); ++ } ++ mutex_unlock(&entry->mutex); ++ drm_bo_usage_deref_locked(&entry); ++ l = list->next; ++ } ++ DRM_DEBUG("Fenced %d buffers\n", count); ++out: ++ mutex_unlock(&dev->struct_mutex); ++ *used_fence = fence; ++ return ret; ++} ++EXPORT_SYMBOL(drm_fence_buffer_objects); ++ ++/* if we discard a buffer with no backing store - ++ * we can just set it back to a clean state ++ */ ++static int drm_bo_reset_local(struct drm_buffer_object *bo) ++{ ++ int ret = 0; ++ struct drm_device *dev = bo->dev; ++ struct drm_bo_mem_reg *old_mem = &bo->mem; ++ int old_is_pci = drm_mem_reg_is_pci(dev, &bo->mem); ++ ++ ret = drm_bo_vm_pre_move(bo, old_is_pci); ++ if (ret) ++ return ret; ++ ++ mutex_lock(&dev->struct_mutex); ++ list_del_init(&bo->lru); ++ mutex_unlock(&dev->struct_mutex); ++ ++ if (old_mem->mm_node) { ++ mutex_lock(&dev->struct_mutex); ++ drm_mm_put_block(old_mem->mm_node); ++ mutex_unlock(&dev->struct_mutex); ++ } ++ old_mem->mm_node = NULL; ++ ++ bo->mem.mem_type = DRM_BO_MEM_LOCAL; ++ ++ bo->mem.flags &= ~DRM_BO_MASK_MEMTYPE; ++ bo->mem.flags |= (DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_DISCARDABLE | ++ DRM_BO_FLAG_CLEAN); ++ ++ bo->mem.proposed_flags = bo->mem.flags; ++ return 0; ++} ++/* ++ * bo->mutex locked ++ */ ++ ++static int drm_bo_evict(struct drm_buffer_object *bo, unsigned mem_type, ++ int no_wait) ++{ ++ int ret = 0; ++ struct drm_device *dev = bo->dev; ++ struct drm_bo_mem_reg evict_mem; ++ ++ /* ++ * Someone might have modified the buffer before we took the ++ * buffer mutex. ++ */ ++ ++ do { ++ bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED; ++ ++ if (unlikely(bo->mem.flags & ++ (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))) ++ goto out_unlock; ++ if (unlikely(bo->priv_flags & _DRM_BO_FLAG_UNFENCED)) ++ goto out_unlock; ++ if (unlikely(bo->mem.mem_type != mem_type)) ++ goto out_unlock; ++ ret = drm_bo_wait(bo, 0, 1, no_wait, 0); ++ if (ret) ++ goto out_unlock; ++ ++ } while(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED); ++ ++ /* if in VRAM and discardable - discard it */ ++ if (bo->mem.mem_type == DRM_BO_MEM_VRAM && bo->mem.flags & DRM_BO_FLAG_DISCARDABLE) { ++ drm_bo_reset_local(bo); ++ goto out_unlock; ++ } ++ ++ evict_mem = bo->mem; ++ evict_mem.mm_node = NULL; ++ ++ evict_mem = bo->mem; ++ evict_mem.proposed_flags = dev->driver->bo_driver->evict_flags(bo); ++ ++ mutex_lock(&dev->struct_mutex); ++ list_del_init(&bo->lru); ++ mutex_unlock(&dev->struct_mutex); ++ ++ ret = drm_bo_mem_space(bo, &evict_mem, no_wait); ++ ++ if (ret) { ++ if (ret != -EAGAIN) ++ DRM_ERROR("Failed to find memory space for " ++ "buffer 0x%p eviction.\n", bo); ++ goto out; ++ } ++ ++ ret = drm_bo_handle_move_mem(bo, &evict_mem, 1, no_wait); ++ ++ if (ret) { ++ if (ret != -EAGAIN) ++ DRM_ERROR("Buffer eviction failed\n"); ++ goto out; ++ } ++ ++ DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_EVICTED, ++ _DRM_BO_FLAG_EVICTED); ++ ++out: ++ mutex_lock(&dev->struct_mutex); ++ if (evict_mem.mm_node) { ++ if (evict_mem.mm_node != bo->pinned_node) ++ drm_mm_put_block(evict_mem.mm_node); ++ evict_mem.mm_node = NULL; ++ } ++ drm_bo_add_to_lru(bo); ++ BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED); ++ mutex_unlock(&dev->struct_mutex); ++out_unlock: ++ ++ return ret; ++} ++ ++/** ++ * Repeatedly evict memory from the LRU for @mem_type until we create enough ++ * space, or we've evicted everything and there isn't enough space. ++ */ ++static int drm_bo_mem_force_space(struct drm_device *dev, ++ struct drm_bo_mem_reg *mem, ++ uint32_t mem_type, int no_wait) ++{ ++ struct drm_mm_node *node; ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_buffer_object *entry; ++ struct drm_mem_type_manager *man = &bm->man[mem_type]; ++ struct list_head *lru; ++ unsigned long num_pages = mem->num_pages; ++ int ret; ++ ++ mutex_lock(&dev->struct_mutex); ++ do { ++ node = drm_mm_search_free(&man->manager, num_pages, ++ mem->page_alignment, 1); ++ if (node) ++ break; ++ ++ lru = &man->lru; ++ if (lru->next == lru) ++ break; ++ ++ entry = list_entry(lru->next, struct drm_buffer_object, lru); ++ atomic_inc(&entry->usage); ++ mutex_unlock(&dev->struct_mutex); ++ mutex_lock(&entry->mutex); ++ ret = drm_bo_evict(entry, mem_type, no_wait); ++ mutex_unlock(&entry->mutex); ++ drm_bo_usage_deref_unlocked(&entry); ++ if (ret) ++ return ret; ++ mutex_lock(&dev->struct_mutex); ++ } while (1); ++ ++ if (!node) { ++ mutex_unlock(&dev->struct_mutex); ++ return -ENOMEM; ++ } ++ ++ node = drm_mm_get_block(node, num_pages, mem->page_alignment); ++ if (unlikely(!node)) { ++ mutex_unlock(&dev->struct_mutex); ++ return -ENOMEM; ++ } ++ ++ mutex_unlock(&dev->struct_mutex); ++ mem->mm_node = node; ++ mem->mem_type = mem_type; ++ return 0; ++} ++ ++static int drm_bo_mt_compatible(struct drm_mem_type_manager *man, ++ int disallow_fixed, ++ uint32_t mem_type, ++ uint64_t mask, uint32_t *res_mask) ++{ ++ uint64_t cur_flags = drm_bo_type_flags(mem_type); ++ uint64_t flag_diff; ++ ++ if ((man->flags & _DRM_FLAG_MEMTYPE_FIXED) && disallow_fixed) ++ return 0; ++ if (man->flags & _DRM_FLAG_MEMTYPE_CACHED) ++ cur_flags |= DRM_BO_FLAG_CACHED; ++ if (man->flags & _DRM_FLAG_MEMTYPE_MAPPABLE) ++ cur_flags |= DRM_BO_FLAG_MAPPABLE; ++ if (man->flags & _DRM_FLAG_MEMTYPE_CSELECT) ++ DRM_FLAG_MASKED(cur_flags, mask, DRM_BO_FLAG_CACHED); ++ ++ if ((cur_flags & mask & DRM_BO_MASK_MEM) == 0) ++ return 0; ++ ++ if (mem_type == DRM_BO_MEM_LOCAL) { ++ *res_mask = cur_flags; ++ return 1; ++ } ++ ++ flag_diff = (mask ^ cur_flags); ++ if (flag_diff & DRM_BO_FLAG_CACHED_MAPPED) ++ cur_flags |= DRM_BO_FLAG_CACHED_MAPPED; ++ ++ if ((flag_diff & DRM_BO_FLAG_CACHED) && ++ (!(mask & DRM_BO_FLAG_CACHED) || ++ (mask & DRM_BO_FLAG_FORCE_CACHING))) ++ return 0; ++ ++ if ((flag_diff & DRM_BO_FLAG_MAPPABLE) && ++ ((mask & DRM_BO_FLAG_MAPPABLE) || ++ (mask & DRM_BO_FLAG_FORCE_MAPPABLE))) ++ return 0; ++ ++ *res_mask = cur_flags; ++ return 1; ++} ++ ++/** ++ * Creates space for memory region @mem according to its type. ++ * ++ * This function first searches for free space in compatible memory types in ++ * the priority order defined by the driver. If free space isn't found, then ++ * drm_bo_mem_force_space is attempted in priority order to evict and find ++ * space. ++ */ ++int drm_bo_mem_space(struct drm_buffer_object *bo, ++ struct drm_bo_mem_reg *mem, int no_wait) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_mem_type_manager *man; ++ ++ uint32_t num_prios = dev->driver->bo_driver->num_mem_type_prio; ++ const uint32_t *prios = dev->driver->bo_driver->mem_type_prio; ++ uint32_t i; ++ uint32_t mem_type = DRM_BO_MEM_LOCAL; ++ uint32_t cur_flags; ++ int type_found = 0; ++ int type_ok = 0; ++ int has_eagain = 0; ++ struct drm_mm_node *node = NULL; ++ int ret; ++ ++ mem->mm_node = NULL; ++ for (i = 0; i < num_prios; ++i) { ++ mem_type = prios[i]; ++ man = &bm->man[mem_type]; ++ ++ type_ok = drm_bo_mt_compatible(man, ++ bo->type == drm_bo_type_user, ++ mem_type, mem->proposed_flags, ++ &cur_flags); ++ ++ if (!type_ok) ++ continue; ++ ++ if (mem_type == DRM_BO_MEM_LOCAL) ++ break; ++ ++ if ((mem_type == bo->pinned_mem_type) && ++ (bo->pinned_node != NULL)) { ++ node = bo->pinned_node; ++ break; ++ } ++ ++ mutex_lock(&dev->struct_mutex); ++ if (man->has_type && man->use_type) { ++ type_found = 1; ++ node = drm_mm_search_free(&man->manager, mem->num_pages, ++ mem->page_alignment, 1); ++ if (node) ++ node = drm_mm_get_block(node, mem->num_pages, ++ mem->page_alignment); ++ } ++ mutex_unlock(&dev->struct_mutex); ++ if (node) ++ break; ++ } ++ ++ if ((type_ok && (mem_type == DRM_BO_MEM_LOCAL)) || node) { ++ mem->mm_node = node; ++ mem->mem_type = mem_type; ++ mem->flags = cur_flags; ++ return 0; ++ } ++ ++ if (!type_found) ++ return -EINVAL; ++ ++ num_prios = dev->driver->bo_driver->num_mem_busy_prio; ++ prios = dev->driver->bo_driver->mem_busy_prio; ++ ++ for (i = 0; i < num_prios; ++i) { ++ mem_type = prios[i]; ++ man = &bm->man[mem_type]; ++ ++ if (!man->has_type) ++ continue; ++ ++ if (!drm_bo_mt_compatible(man, ++ bo->type == drm_bo_type_user, ++ mem_type, ++ mem->proposed_flags, ++ &cur_flags)) ++ continue; ++ ++ ret = drm_bo_mem_force_space(dev, mem, mem_type, no_wait); ++ ++ if (ret == 0 && mem->mm_node) { ++ mem->flags = cur_flags; ++ return 0; ++ } ++ ++ if (ret == -EAGAIN) ++ has_eagain = 1; ++ } ++ ++ ret = (has_eagain) ? -EAGAIN : -ENOMEM; ++ return ret; ++} ++EXPORT_SYMBOL(drm_bo_mem_space); ++ ++/* ++ * drm_bo_propose_flags: ++ * ++ * @bo: the buffer object getting new flags ++ * ++ * @new_flags: the new set of proposed flag bits ++ * ++ * @new_mask: the mask of bits changed in new_flags ++ * ++ * Modify the proposed_flag bits in @bo ++ */ ++static int drm_bo_modify_proposed_flags (struct drm_buffer_object *bo, ++ uint64_t new_flags, uint64_t new_mask) ++{ ++ uint32_t new_access; ++ ++ /* Copy unchanging bits from existing proposed_flags */ ++ DRM_FLAG_MASKED(new_flags, bo->mem.proposed_flags, ~new_mask); ++ ++ if (bo->type == drm_bo_type_user && ++ ((new_flags & (DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING)) != ++ (DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING))) { ++ DRM_ERROR("User buffers require cache-coherent memory.\n"); ++ return -EINVAL; ++ } ++ ++ if (bo->type != drm_bo_type_kernel && (new_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) { ++ DRM_ERROR("DRM_BO_FLAG_NO_EVICT is only available to priviliged processes.\n"); ++ return -EPERM; ++ } ++ ++ if (likely(new_mask & DRM_BO_MASK_MEM) && ++ (bo->mem.flags & DRM_BO_FLAG_NO_EVICT) && ++ !DRM_SUSER(DRM_CURPROC)) { ++ if (likely(bo->mem.flags & new_flags & new_mask & ++ DRM_BO_MASK_MEM)) ++ new_flags = (new_flags & ~DRM_BO_MASK_MEM) | ++ (bo->mem.flags & DRM_BO_MASK_MEM); ++ else { ++ DRM_ERROR("Incompatible memory type specification " ++ "for NO_EVICT buffer.\n"); ++ return -EPERM; ++ } ++ } ++ ++ if ((new_flags & DRM_BO_FLAG_NO_MOVE)) { ++ DRM_ERROR("DRM_BO_FLAG_NO_MOVE is not properly implemented yet.\n"); ++ return -EPERM; ++ } ++ ++ new_access = new_flags & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE | ++ DRM_BO_FLAG_READ); ++ ++ if (new_access == 0) { ++ DRM_ERROR("Invalid buffer object rwx properties\n"); ++ return -EINVAL; ++ } ++ ++ bo->mem.proposed_flags = new_flags; ++ return 0; ++} ++ ++/* ++ * Call bo->mutex locked. ++ * Returns -EBUSY if the buffer is currently rendered to or from. 0 otherwise. ++ * Doesn't do any fence flushing as opposed to the drm_bo_busy function. ++ */ ++ ++int drm_bo_quick_busy(struct drm_buffer_object *bo, int check_unfenced) ++{ ++ struct drm_fence_object *fence = bo->fence; ++ ++ if (check_unfenced && (bo->priv_flags & _DRM_BO_FLAG_UNFENCED)) ++ return -EBUSY; ++ ++ if (fence) { ++ if (drm_fence_object_signaled(fence, bo->fence_type)) { ++ drm_fence_usage_deref_unlocked(&bo->fence); ++ return 0; ++ } ++ return -EBUSY; ++ } ++ return 0; ++} ++ ++int drm_bo_evict_cached(struct drm_buffer_object *bo) ++{ ++ int ret = 0; ++ ++ BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED); ++ if (bo->mem.mm_node) ++ ret = drm_bo_evict(bo, DRM_BO_MEM_TT, 1); ++ return ret; ++} ++ ++EXPORT_SYMBOL(drm_bo_evict_cached); ++/* ++ * Wait until a buffer is unmapped. ++ */ ++ ++static int drm_bo_wait_unmapped(struct drm_buffer_object *bo, int no_wait) ++{ ++ int ret = 0; ++ ++ if (likely(atomic_read(&bo->mapped)) == 0) ++ return 0; ++ ++ if (unlikely(no_wait)) ++ return -EBUSY; ++ ++ do { ++ mutex_unlock(&bo->mutex); ++ ret = wait_event_interruptible(bo->event_queue, ++ atomic_read(&bo->mapped) == 0); ++ mutex_lock(&bo->mutex); ++ bo->priv_flags |= _DRM_BO_FLAG_UNLOCKED; ++ ++ if (ret == -ERESTARTSYS) ++ ret = -EAGAIN; ++ } while((ret == 0) && atomic_read(&bo->mapped) > 0); ++ ++ return ret; ++} ++ ++/* ++ * bo->mutex locked. ++ * Note that new_mem_flags are NOT transferred to the bo->mem.proposed_flags. ++ */ ++ ++int drm_bo_move_buffer(struct drm_buffer_object *bo, uint64_t new_mem_flags, ++ int no_wait, int move_unfenced) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_buffer_manager *bm = &dev->bm; ++ int ret = 0; ++ struct drm_bo_mem_reg mem; ++ ++ BUG_ON(bo->fence != NULL); ++ ++ mem.num_pages = bo->num_pages; ++ mem.size = mem.num_pages << PAGE_SHIFT; ++ mem.proposed_flags = new_mem_flags; ++ mem.page_alignment = bo->mem.page_alignment; ++ ++ mutex_lock(&bm->evict_mutex); ++ mutex_lock(&dev->struct_mutex); ++ list_del_init(&bo->lru); ++ mutex_unlock(&dev->struct_mutex); ++ ++ /* ++ * Determine where to move the buffer. ++ */ ++ ret = drm_bo_mem_space(bo, &mem, no_wait); ++ if (ret) ++ goto out_unlock; ++ ++ ret = drm_bo_handle_move_mem(bo, &mem, 0, no_wait); ++ ++out_unlock: ++ mutex_lock(&dev->struct_mutex); ++ if (ret || !move_unfenced) { ++ if (mem.mm_node) { ++ if (mem.mm_node != bo->pinned_node) ++ drm_mm_put_block(mem.mm_node); ++ mem.mm_node = NULL; ++ } ++ drm_bo_add_to_lru(bo); ++ if (bo->priv_flags & _DRM_BO_FLAG_UNFENCED) { ++ wake_up_all(&bo->event_queue); ++ DRM_FLAG_MASKED(bo->priv_flags, 0, ++ _DRM_BO_FLAG_UNFENCED); ++ } ++ } else { ++ list_add_tail(&bo->lru, &bm->unfenced); ++ DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_UNFENCED, ++ _DRM_BO_FLAG_UNFENCED); ++ } ++ /* clear the clean flags */ ++ bo->mem.flags &= ~DRM_BO_FLAG_CLEAN; ++ bo->mem.proposed_flags &= ~DRM_BO_FLAG_CLEAN; ++ ++ mutex_unlock(&dev->struct_mutex); ++ mutex_unlock(&bm->evict_mutex); ++ return ret; ++} ++ ++static int drm_bo_mem_compat(struct drm_bo_mem_reg *mem) ++{ ++ uint32_t flag_diff = (mem->proposed_flags ^ mem->flags); ++ ++ if ((mem->proposed_flags & mem->flags & DRM_BO_MASK_MEM) == 0) ++ return 0; ++ if ((flag_diff & DRM_BO_FLAG_CACHED) && ++ (/* !(mem->proposed_flags & DRM_BO_FLAG_CACHED) ||*/ ++ (mem->proposed_flags & DRM_BO_FLAG_FORCE_CACHING))) ++ return 0; ++ ++ if ((flag_diff & DRM_BO_FLAG_MAPPABLE) && ++ ((mem->proposed_flags & DRM_BO_FLAG_MAPPABLE) || ++ (mem->proposed_flags & DRM_BO_FLAG_FORCE_MAPPABLE))) ++ return 0; ++ return 1; ++} ++ ++/** ++ * drm_buffer_object_validate: ++ * ++ * @bo: the buffer object to modify ++ * ++ * @fence_class: the new fence class covering this buffer ++ * ++ * @move_unfenced: a boolean indicating whether switching the ++ * memory space of this buffer should cause the buffer to ++ * be placed on the unfenced list. ++ * ++ * @no_wait: whether this function should return -EBUSY instead ++ * of waiting. ++ * ++ * Change buffer access parameters. This can involve moving ++ * the buffer to the correct memory type, pinning the buffer ++ * or changing the class/type of fence covering this buffer ++ * ++ * Must be called with bo locked. ++ */ ++ ++static int drm_buffer_object_validate(struct drm_buffer_object *bo, ++ uint32_t fence_class, ++ int move_unfenced, int no_wait, ++ int move_buffer) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_buffer_manager *bm = &dev->bm; ++ int ret; ++ ++ if (move_buffer) { ++ ret = drm_bo_move_buffer(bo, bo->mem.proposed_flags, no_wait, ++ move_unfenced); ++ if (ret) { ++ if (ret != -EAGAIN) ++ DRM_ERROR("Failed moving buffer. %p %d %llx %llx\n", bo, bo->num_pages, bo->mem.proposed_flags, bo->mem.flags ); ++ if (ret == -ENOMEM) ++ DRM_ERROR("Out of aperture space or " ++ "DRM memory quota.\n"); ++ return ret; ++ } ++ } ++ ++ /* ++ * Pinned buffers. ++ */ ++ ++ if (bo->mem.proposed_flags & (DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE)) { ++ bo->pinned_mem_type = bo->mem.mem_type; ++ mutex_lock(&dev->struct_mutex); ++ list_del_init(&bo->pinned_lru); ++ drm_bo_add_to_pinned_lru(bo); ++ ++ if (bo->pinned_node != bo->mem.mm_node) { ++ if (bo->pinned_node != NULL) ++ drm_mm_put_block(bo->pinned_node); ++ bo->pinned_node = bo->mem.mm_node; ++ } ++ ++ mutex_unlock(&dev->struct_mutex); ++ ++ } else if (bo->pinned_node != NULL) { ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ if (bo->pinned_node != bo->mem.mm_node) ++ drm_mm_put_block(bo->pinned_node); ++ ++ list_del_init(&bo->pinned_lru); ++ bo->pinned_node = NULL; ++ mutex_unlock(&dev->struct_mutex); ++ ++ } ++ ++ /* ++ * We might need to add a TTM. ++ */ ++ ++ if (bo->mem.mem_type == DRM_BO_MEM_LOCAL && bo->ttm == NULL) { ++ ret = drm_bo_add_ttm(bo); ++ if (ret) ++ return ret; ++ } ++ /* ++ * Validation has succeeded, move the access and other ++ * non-mapping-related flag bits from the proposed flags to ++ * the active flags ++ */ ++ ++ DRM_FLAG_MASKED(bo->mem.flags, bo->mem.proposed_flags, ~DRM_BO_MASK_MEMTYPE); ++ ++ /* ++ * Finally, adjust lru to be sure. ++ */ ++ ++ mutex_lock(&dev->struct_mutex); ++ list_del(&bo->lru); ++ if (move_unfenced) { ++ list_add_tail(&bo->lru, &bm->unfenced); ++ DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_UNFENCED, ++ _DRM_BO_FLAG_UNFENCED); ++ } else { ++ drm_bo_add_to_lru(bo); ++ if (bo->priv_flags & _DRM_BO_FLAG_UNFENCED) { ++ wake_up_all(&bo->event_queue); ++ DRM_FLAG_MASKED(bo->priv_flags, 0, ++ _DRM_BO_FLAG_UNFENCED); ++ } ++ } ++ mutex_unlock(&dev->struct_mutex); ++ ++ return 0; ++} ++ ++/* ++ * This function is called with bo->mutex locked, but may release it ++ * temporarily to wait for events. ++ */ ++ ++static int drm_bo_prepare_for_validate(struct drm_buffer_object *bo, ++ uint64_t flags, ++ uint64_t mask, ++ uint32_t hint, ++ uint32_t fence_class, ++ int no_wait, ++ int *move_buffer) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_bo_driver *driver = dev->driver->bo_driver; ++ uint32_t ftype; ++ ++ int ret; ++ ++ ++ ret = drm_bo_modify_proposed_flags (bo, flags, mask); ++ if (ret) ++ return ret; ++ ++ DRM_DEBUG("Proposed flags 0x%016llx, Old flags 0x%016llx\n", ++ (unsigned long long) bo->mem.proposed_flags, ++ (unsigned long long) bo->mem.flags); ++ ++ ret = drm_bo_wait_unmapped(bo, no_wait); ++ if (ret) ++ return ret; ++ ++ ret = driver->fence_type(bo, &fence_class, &ftype); ++ ++ if (ret) { ++ DRM_ERROR("Driver did not support given buffer permissions.\n"); ++ return ret; ++ } ++ ++ /* ++ * We're switching command submission mechanism, ++ * or cannot simply rely on the hardware serializing for us. ++ * Insert a driver-dependant barrier or wait for buffer idle. ++ */ ++ ++ if ((fence_class != bo->fence_class) || ++ ((ftype ^ bo->fence_type) & bo->fence_type)) { ++ ++ ret = -EINVAL; ++ if (driver->command_stream_barrier) { ++ ret = driver->command_stream_barrier(bo, ++ fence_class, ++ ftype, ++ no_wait); ++ } ++ if (ret && ret != -EAGAIN) ++ ret = drm_bo_wait(bo, 0, 1, no_wait, 1); ++ ++ if (ret) ++ return ret; ++ } ++ ++ bo->new_fence_class = fence_class; ++ bo->new_fence_type = ftype; ++ ++ /* ++ * Check whether we need to move buffer. ++ */ ++ ++ *move_buffer = 0; ++ if (!drm_bo_mem_compat(&bo->mem)) { ++ *move_buffer = 1; ++ ret = drm_bo_wait(bo, 0, 1, no_wait, 1); ++ } ++ ++ return ret; ++} ++ ++/** ++ * drm_bo_do_validate: ++ * ++ * @bo: the buffer object ++ * ++ * @flags: access rights, mapping parameters and cacheability. See ++ * the DRM_BO_FLAG_* values in drm.h ++ * ++ * @mask: Which flag values to change; this allows callers to modify ++ * things without knowing the current state of other flags. ++ * ++ * @hint: changes the proceedure for this operation, see the DRM_BO_HINT_* ++ * values in drm.h. ++ * ++ * @fence_class: a driver-specific way of doing fences. Presumably, ++ * this would be used if the driver had more than one submission and ++ * fencing mechanism. At this point, there isn't any use of this ++ * from the user mode code. ++ * ++ * @rep: To be stuffed with the reply from validation ++ * ++ * 'validate' a buffer object. This changes where the buffer is ++ * located, along with changing access modes. ++ */ ++ ++int drm_bo_do_validate(struct drm_buffer_object *bo, ++ uint64_t flags, uint64_t mask, uint32_t hint, ++ uint32_t fence_class) ++{ ++ int ret; ++ int no_wait = (hint & DRM_BO_HINT_DONT_BLOCK) != 0; ++ int move_buffer; ++ ++ mutex_lock(&bo->mutex); ++ ++ do { ++ bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED; ++ ++ ret = drm_bo_prepare_for_validate(bo, flags, mask, hint, ++ fence_class, no_wait, ++ &move_buffer); ++ if (ret) ++ goto out; ++ ++ } while(unlikely(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED)); ++ ++ ret = drm_buffer_object_validate(bo, ++ fence_class, ++ !(hint & DRM_BO_HINT_DONT_FENCE), ++ no_wait, ++ move_buffer); ++ ++ BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED); ++out: ++ mutex_unlock(&bo->mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL(drm_bo_do_validate); ++ ++int drm_buffer_object_create(struct drm_device *dev, ++ unsigned long size, ++ enum drm_bo_type type, ++ uint64_t flags, ++ uint32_t hint, ++ uint32_t page_alignment, ++ unsigned long buffer_start, ++ struct drm_buffer_object **buf_obj) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_buffer_object *bo; ++ int ret = 0; ++ unsigned long num_pages; ++ ++ size += buffer_start & ~PAGE_MASK; ++ num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ if (num_pages == 0) { ++ DRM_ERROR("Illegal buffer object size %ld.\n", size); ++ return -EINVAL; ++ } ++ ++ bo = drm_ctl_calloc(1, sizeof(*bo), DRM_MEM_BUFOBJ); ++ ++ if (!bo) ++ return -ENOMEM; ++ ++ mutex_init(&bo->mutex); ++ mutex_lock(&bo->mutex); ++ ++ atomic_set(&bo->usage, 1); ++ atomic_set(&bo->mapped, 0); ++ DRM_INIT_WAITQUEUE(&bo->event_queue); ++ INIT_LIST_HEAD(&bo->lru); ++ INIT_LIST_HEAD(&bo->pinned_lru); ++ INIT_LIST_HEAD(&bo->ddestroy); ++#ifdef DRM_ODD_MM_COMPAT ++ INIT_LIST_HEAD(&bo->p_mm_list); ++ INIT_LIST_HEAD(&bo->vma_list); ++#endif ++ bo->dev = dev; ++ bo->type = type; ++ bo->num_pages = num_pages; ++ bo->mem.mem_type = DRM_BO_MEM_LOCAL; ++ bo->mem.num_pages = bo->num_pages; ++ bo->mem.mm_node = NULL; ++ bo->mem.page_alignment = page_alignment; ++ bo->buffer_start = buffer_start & PAGE_MASK; ++ bo->priv_flags = 0; ++ bo->mem.flags = (DRM_BO_FLAG_MEM_LOCAL | ++ DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_CLEAN); ++ bo->mem.proposed_flags = 0; ++ atomic_inc(&bm->count); ++ ++ bo->mem.flags |= DRM_BO_FLAG_CACHED; ++ /* ++ * Use drm_bo_modify_proposed_flags to error-check the proposed flags ++ */ ++ flags |= DRM_BO_FLAG_CLEAN; ++ ++ ret = drm_bo_modify_proposed_flags (bo, flags, flags); ++ if (ret) ++ goto out_err; ++ ++ /* ++ * For drm_bo_type_device buffers, allocate ++ * address space from the device so that applications ++ * can mmap the buffer from there ++ */ ++ if (bo->type == drm_bo_type_device) { ++ mutex_lock(&dev->struct_mutex); ++ ret = drm_bo_setup_vm_locked(bo); ++ mutex_unlock(&dev->struct_mutex); ++ if (ret) ++ goto out_err; ++ } ++ ++ mutex_unlock(&bo->mutex); ++ ret = drm_bo_do_validate(bo, 0, 0, hint | DRM_BO_HINT_DONT_FENCE, ++ 0); ++ if (ret) ++ goto out_err_unlocked; ++ ++ *buf_obj = bo; ++ return 0; ++ ++out_err: ++ mutex_unlock(&bo->mutex); ++out_err_unlocked: ++ drm_bo_usage_deref_unlocked(&bo); ++ return ret; ++} ++EXPORT_SYMBOL(drm_buffer_object_create); ++ ++static int drm_bo_leave_list(struct drm_buffer_object *bo, ++ uint32_t mem_type, ++ int free_pinned, ++ int allow_errors) ++{ ++ struct drm_device *dev = bo->dev; ++ int ret = 0; ++ ++ mutex_lock(&bo->mutex); ++ ++ ret = drm_bo_expire_fence(bo, allow_errors); ++ if (ret) ++ goto out; ++ ++ if (free_pinned) { ++ DRM_FLAG_MASKED(bo->mem.flags, 0, DRM_BO_FLAG_NO_MOVE); ++ mutex_lock(&dev->struct_mutex); ++ list_del_init(&bo->pinned_lru); ++ if (bo->pinned_node == bo->mem.mm_node) ++ bo->pinned_node = NULL; ++ if (bo->pinned_node != NULL) { ++ drm_mm_put_block(bo->pinned_node); ++ bo->pinned_node = NULL; ++ } ++ mutex_unlock(&dev->struct_mutex); ++ } ++ ++ if (bo->mem.flags & DRM_BO_FLAG_NO_EVICT) { ++ DRM_ERROR("A DRM_BO_NO_EVICT buffer present at " ++ "cleanup. Removing flag and evicting.\n"); ++ bo->mem.flags &= ~DRM_BO_FLAG_NO_EVICT; ++ bo->mem.proposed_flags &= ~DRM_BO_FLAG_NO_EVICT; ++ } ++ ++ if (bo->mem.mem_type == mem_type) ++ ret = drm_bo_evict(bo, mem_type, 0); ++ ++ if (ret) { ++ if (allow_errors) { ++ goto out; ++ } else { ++ ret = 0; ++ DRM_ERROR("Cleanup eviction failed\n"); ++ } ++ } ++ ++out: ++ mutex_unlock(&bo->mutex); ++ return ret; ++} ++ ++ ++static struct drm_buffer_object *drm_bo_entry(struct list_head *list, ++ int pinned_list) ++{ ++ if (pinned_list) ++ return list_entry(list, struct drm_buffer_object, pinned_lru); ++ else ++ return list_entry(list, struct drm_buffer_object, lru); ++} ++ ++/* ++ * dev->struct_mutex locked. ++ */ ++ ++static int drm_bo_force_list_clean(struct drm_device *dev, ++ struct list_head *head, ++ unsigned mem_type, ++ int free_pinned, ++ int allow_errors, ++ int pinned_list) ++{ ++ struct list_head *list, *next, *prev; ++ struct drm_buffer_object *entry, *nentry; ++ int ret; ++ int do_restart; ++ ++ /* ++ * The list traversal is a bit odd here, because an item may ++ * disappear from the list when we release the struct_mutex or ++ * when we decrease the usage count. Also we're not guaranteed ++ * to drain pinned lists, so we can't always restart. ++ */ ++ ++restart: ++ nentry = NULL; ++ list_for_each_safe(list, next, head) { ++ prev = list->prev; ++ ++ entry = (nentry != NULL) ? nentry: drm_bo_entry(list, pinned_list); ++ atomic_inc(&entry->usage); ++ if (nentry) { ++ atomic_dec(&nentry->usage); ++ nentry = NULL; ++ } ++ ++ /* ++ * Protect the next item from destruction, so we can check ++ * its list pointers later on. ++ */ ++ ++ if (next != head) { ++ nentry = drm_bo_entry(next, pinned_list); ++ atomic_inc(&nentry->usage); ++ } ++ mutex_unlock(&dev->struct_mutex); ++ ++ ret = drm_bo_leave_list(entry, mem_type, free_pinned, ++ allow_errors); ++ mutex_lock(&dev->struct_mutex); ++ ++ drm_bo_usage_deref_locked(&entry); ++ if (ret) ++ return ret; ++ ++ /* ++ * Has the next item disappeared from the list? ++ */ ++ ++ do_restart = ((next->prev != list) && (next->prev != prev)); ++ ++ if (nentry != NULL && do_restart) ++ drm_bo_usage_deref_locked(&nentry); ++ ++ if (do_restart) ++ goto restart; ++ } ++ return 0; ++} ++ ++int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type, int kern_clean) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_mem_type_manager *man = &bm->man[mem_type]; ++ int ret = -EINVAL; ++ ++ if (mem_type >= DRM_BO_MEM_TYPES) { ++ DRM_ERROR("Illegal memory type %d\n", mem_type); ++ return ret; ++ } ++ ++ if (!man->has_type) { ++ DRM_ERROR("Trying to take down uninitialized " ++ "memory manager type %u\n", mem_type); ++ return ret; ++ } ++ ++ if ((man->kern_init_type) && (kern_clean == 0)) { ++ DRM_ERROR("Trying to take down kernel initialized " ++ "memory manager type %u\n", mem_type); ++ return -EPERM; ++ } ++ ++ man->use_type = 0; ++ man->has_type = 0; ++ ++ ret = 0; ++ if (mem_type > 0) { ++ BUG_ON(!list_empty(&bm->unfenced)); ++ drm_bo_force_list_clean(dev, &man->lru, mem_type, 1, 0, 0); ++ drm_bo_force_list_clean(dev, &man->pinned, mem_type, 1, 0, 1); ++ ++ if (drm_mm_clean(&man->manager)) { ++ drm_mm_takedown(&man->manager); ++ } else { ++ ret = -EBUSY; ++ } ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(drm_bo_clean_mm); ++ ++/** ++ *Evict all buffers of a particular mem_type, but leave memory manager ++ *regions for NO_MOVE buffers intact. New buffers cannot be added at this ++ *point since we have the hardware lock. ++ */ ++ ++int drm_bo_lock_mm(struct drm_device *dev, unsigned mem_type) ++{ ++ int ret; ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_mem_type_manager *man = &bm->man[mem_type]; ++ ++ if (mem_type == 0 || mem_type >= DRM_BO_MEM_TYPES) { ++ DRM_ERROR("Illegal memory manager memory type %u.\n", mem_type); ++ return -EINVAL; ++ } ++ ++ if (!man->has_type) { ++ DRM_ERROR("Memory type %u has not been initialized.\n", ++ mem_type); ++ return 0; ++ } ++ ++ ret = drm_bo_force_list_clean(dev, &man->lru, mem_type, 0, 1, 0); ++ if (ret) ++ return ret; ++ ret = drm_bo_force_list_clean(dev, &man->pinned, mem_type, 0, 1, 1); ++ ++ return ret; ++} ++ ++int drm_bo_init_mm(struct drm_device *dev, unsigned type, ++ unsigned long p_offset, unsigned long p_size, ++ int kern_init) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ int ret = -EINVAL; ++ struct drm_mem_type_manager *man; ++ ++ if (type >= DRM_BO_MEM_TYPES) { ++ DRM_ERROR("Illegal memory type %d\n", type); ++ return ret; ++ } ++ ++ man = &bm->man[type]; ++ if (man->has_type) { ++ DRM_ERROR("Memory manager already initialized for type %d\n", ++ type); ++ return ret; ++ } ++ ++ ret = dev->driver->bo_driver->init_mem_type(dev, type, man); ++ if (ret) ++ return ret; ++ ++ ret = 0; ++ if (type != DRM_BO_MEM_LOCAL) { ++ if (!p_size) { ++ DRM_ERROR("Zero size memory manager type %d\n", type); ++ return ret; ++ } ++ ret = drm_mm_init(&man->manager, p_offset, p_size); ++ if (ret) ++ return ret; ++ } ++ man->has_type = 1; ++ man->use_type = 1; ++ man->kern_init_type = kern_init; ++ man->size = p_size; ++ ++ INIT_LIST_HEAD(&man->lru); ++ INIT_LIST_HEAD(&man->pinned); ++ ++ return 0; ++} ++EXPORT_SYMBOL(drm_bo_init_mm); ++ ++/* ++ * This function is intended to be called on drm driver unload. ++ * If you decide to call it from lastclose, you must protect the call ++ * from a potentially racing drm_bo_driver_init in firstopen. ++ * (This may happen on X server restart). ++ */ ++ ++int drm_bo_driver_finish(struct drm_device *dev) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ int ret = 0; ++ unsigned i = DRM_BO_MEM_TYPES; ++ struct drm_mem_type_manager *man; ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ if (!bm->initialized) ++ goto out; ++ bm->initialized = 0; ++ ++ while (i--) { ++ man = &bm->man[i]; ++ if (man->has_type) { ++ man->use_type = 0; ++ if ((i != DRM_BO_MEM_LOCAL) && drm_bo_clean_mm(dev, i, 1)) { ++ ret = -EBUSY; ++ DRM_ERROR("DRM memory manager type %d " ++ "is not clean.\n", i); ++ } ++ man->has_type = 0; ++ } ++ } ++ mutex_unlock(&dev->struct_mutex); ++ ++ if (!cancel_delayed_work(&bm->wq)) ++ flush_scheduled_work(); ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_bo_delayed_delete(dev, 1); ++ if (list_empty(&bm->ddestroy)) ++ DRM_DEBUG("Delayed destroy list was clean\n"); ++ ++ if (list_empty(&bm->man[0].lru)) ++ DRM_DEBUG("Swap list was clean\n"); ++ ++ if (list_empty(&bm->man[0].pinned)) ++ DRM_DEBUG("NO_MOVE list was clean\n"); ++ ++ if (list_empty(&bm->unfenced)) ++ DRM_DEBUG("Unfenced list was clean\n"); ++ ++ if (bm->dummy_read_page) ++ __free_page(bm->dummy_read_page); ++ ++ drm_page_alloc_fini(); ++out: ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++EXPORT_SYMBOL(drm_bo_driver_finish); ++ ++/* ++ * This function is intended to be called on drm driver load. ++ * If you decide to call it from firstopen, you must protect the call ++ * from a potentially racing drm_bo_driver_finish in lastclose. ++ * (This may happen on X server restart). ++ */ ++ ++int drm_bo_driver_init(struct drm_device *dev) ++{ ++ struct drm_bo_driver *driver = dev->driver->bo_driver; ++ struct drm_buffer_manager *bm = &dev->bm; ++ int ret = -EINVAL; ++ ++ drm_page_alloc_init(); ++ ++ bm->dummy_read_page = NULL; ++ mutex_lock(&dev->struct_mutex); ++ if (!driver) ++ goto out_unlock; ++ ++ bm->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); ++ if (!bm->dummy_read_page) { ++ ret = -ENOMEM; ++ goto out_unlock; ++ } ++ ++ /* ++ * Initialize the system memory buffer type. ++ * Other types need to be driver / IOCTL initialized. ++ */ ++ ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0, 1); ++ if (ret) { ++ __free_page(bm->dummy_read_page); ++ bm->dummy_read_page = NULL; ++ goto out_unlock; ++ } ++ ++ INIT_DELAYED_WORK(&bm->wq, drm_bo_delayed_workqueue); ++ bm->initialized = 1; ++ bm->nice_mode = 1; ++ atomic_set(&bm->count, 0); ++ bm->cur_pages = 0; ++ INIT_LIST_HEAD(&bm->unfenced); ++ INIT_LIST_HEAD(&bm->ddestroy); ++out_unlock: ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++EXPORT_SYMBOL(drm_bo_driver_init); ++ ++/* ++ * buffer object vm functions. ++ */ ++ ++int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg *mem) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_mem_type_manager *man = &bm->man[mem->mem_type]; ++ ++ if (!(man->flags & _DRM_FLAG_MEMTYPE_FIXED)) { ++ if (mem->mem_type == DRM_BO_MEM_LOCAL) ++ return 0; ++ ++ if (man->flags & _DRM_FLAG_MEMTYPE_CMA) ++ return 0; ++ ++ if (mem->flags & DRM_BO_FLAG_CACHED) ++ return 0; ++ } ++ return 1; ++} ++EXPORT_SYMBOL(drm_mem_reg_is_pci); ++ ++/** ++ * \c Get the PCI offset for the buffer object memory. ++ * ++ * \param bo The buffer object. ++ * \param bus_base On return the base of the PCI region ++ * \param bus_offset On return the byte offset into the PCI region ++ * \param bus_size On return the byte size of the buffer object or zero if ++ * the buffer object memory is not accessible through a PCI region. ++ * \return Failure indication. ++ * ++ * Returns -EINVAL if the buffer object is currently not mappable. ++ * Otherwise returns zero. ++ */ ++ ++int drm_bo_pci_offset(struct drm_device *dev, ++ struct drm_bo_mem_reg *mem, ++ unsigned long *bus_base, ++ unsigned long *bus_offset, unsigned long *bus_size) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_mem_type_manager *man = &bm->man[mem->mem_type]; ++ ++ *bus_size = 0; ++ if (!(man->flags & _DRM_FLAG_MEMTYPE_MAPPABLE)) ++ return -EINVAL; ++ ++ if (drm_mem_reg_is_pci(dev, mem)) { ++ *bus_offset = mem->mm_node->start << PAGE_SHIFT; ++ *bus_size = mem->num_pages << PAGE_SHIFT; ++ *bus_base = man->io_offset; ++ } ++ ++ return 0; ++} ++ ++/** ++ * \c Kill all user-space virtual mappings of this buffer object. ++ * ++ * \param bo The buffer object. ++ * ++ * Call bo->mutex locked. ++ */ ++ ++void drm_bo_unmap_virtual(struct drm_buffer_object *bo) ++{ ++ struct drm_device *dev = bo->dev; ++ loff_t offset = ((loff_t) bo->map_list.hash.key) << PAGE_SHIFT; ++ loff_t holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT; ++ ++ if (!dev->dev_mapping) ++ return; ++ ++ unmap_mapping_range(dev->dev_mapping, offset, holelen, 1); ++} ++ ++/** ++ * drm_bo_takedown_vm_locked: ++ * ++ * @bo: the buffer object to remove any drm device mapping ++ * ++ * Remove any associated vm mapping on the drm device node that ++ * would have been created for a drm_bo_type_device buffer ++ */ ++void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo) ++{ ++ struct drm_map_list *list; ++ drm_local_map_t *map; ++ struct drm_device *dev = bo->dev; ++ ++ DRM_ASSERT_LOCKED(&dev->struct_mutex); ++ if (bo->type != drm_bo_type_device) ++ return; ++ ++ list = &bo->map_list; ++ if (list->user_token) { ++ drm_ht_remove_item(&dev->map_hash, &list->hash); ++ list->user_token = 0; ++ } ++ if (list->file_offset_node) { ++ drm_mm_put_block(list->file_offset_node); ++ list->file_offset_node = NULL; ++ } ++ ++ map = list->map; ++ if (!map) ++ return; ++ ++ drm_ctl_free(map, sizeof(*map), DRM_MEM_BUFOBJ); ++ list->map = NULL; ++ list->user_token = 0ULL; ++ drm_bo_usage_deref_locked(&bo); ++} ++EXPORT_SYMBOL(drm_bo_takedown_vm_locked); ++ ++/** ++ * drm_bo_setup_vm_locked: ++ * ++ * @bo: the buffer to allocate address space for ++ * ++ * Allocate address space in the drm device so that applications ++ * can mmap the buffer and access the contents. This only ++ * applies to drm_bo_type_device objects as others are not ++ * placed in the drm device address space. ++ */ ++static int drm_bo_setup_vm_locked(struct drm_buffer_object *bo) ++{ ++ struct drm_map_list *list = &bo->map_list; ++ drm_local_map_t *map; ++ struct drm_device *dev = bo->dev; ++ ++ DRM_ASSERT_LOCKED(&dev->struct_mutex); ++ list->map = drm_ctl_calloc(1, sizeof(*map), DRM_MEM_BUFOBJ); ++ if (!list->map) ++ return -ENOMEM; ++ ++ map = list->map; ++ map->offset = 0; ++ map->type = _DRM_TTM; ++ map->flags = _DRM_REMOVABLE; ++ map->size = bo->mem.num_pages * PAGE_SIZE; ++ atomic_inc(&bo->usage); ++ map->handle = (void *)bo; ++ ++ list->file_offset_node = drm_mm_search_free(&dev->offset_manager, ++ bo->mem.num_pages, 0, 0); ++ ++ if (unlikely(!list->file_offset_node)) { ++ drm_bo_takedown_vm_locked(bo); ++ return -ENOMEM; ++ } ++ ++ list->file_offset_node = drm_mm_get_block(list->file_offset_node, ++ bo->mem.num_pages, 0); ++ ++ if (unlikely(!list->file_offset_node)) { ++ drm_bo_takedown_vm_locked(bo); ++ return -ENOMEM; ++ } ++ ++ list->hash.key = list->file_offset_node->start; ++ if (drm_ht_insert_item(&dev->map_hash, &list->hash)) { ++ drm_bo_takedown_vm_locked(bo); ++ return -ENOMEM; ++ } ++ ++ list->user_token = ((uint64_t) list->hash.key) << PAGE_SHIFT; ++ ++ return 0; ++} ++ ++/* used to EVICT VRAM lru at suspend time */ ++void drm_bo_evict_mm(struct drm_device *dev, int mem_type, int no_wait) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_mem_type_manager *man = &bm->man[mem_type]; ++ struct drm_buffer_object *entry; ++ /* we need to migrate all objects in VRAM */ ++ struct list_head *lru; ++ int ret; ++ /* evict all buffers on the LRU - won't evict pinned buffers */ ++ ++ mutex_lock(&dev->struct_mutex); ++ do { ++ lru = &man->lru; ++ ++redo: ++ if (lru->next == &man->lru) { ++ DRM_ERROR("lru empty\n"); ++ break; ++ } ++ ++ entry = list_entry(lru->next, struct drm_buffer_object, lru); ++ ++ // if (entry->mem.flags & DRM_BO_FLAG_DISCARDABLE) { ++ // lru = lru->next; ++ // goto redo; ++ // } ++ ++ atomic_inc(&entry->usage); ++ mutex_unlock(&dev->struct_mutex); ++ mutex_lock(&entry->mutex); ++ ++ ret = drm_bo_evict(entry, mem_type, no_wait); ++ mutex_unlock(&entry->mutex); ++ ++ if (ret) ++ DRM_ERROR("Evict failed for BO\n"); ++ ++ mutex_lock(&entry->mutex); ++ (void)drm_bo_expire_fence(entry, 0); ++ mutex_unlock(&entry->mutex); ++ drm_bo_usage_deref_unlocked(&entry); ++ ++ mutex_lock(&dev->struct_mutex); ++ } while(1); ++ ++ mutex_unlock(&dev->struct_mutex); ++ ++} ++EXPORT_SYMBOL(drm_bo_evict_mm); +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_bo_move.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_bo_move.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_bo_move.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_bo_move.c 2009-04-26 02:58:36.490726177 +0200 +@@ -0,0 +1,709 @@ ++/************************************************************************** ++ * ++ * Copyright (c) 2007 Tungsten Graphics, Inc., Cedar Park, TX., USA ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ **************************************************************************/ ++/* ++ * Authors: Thomas Hellström ++ */ ++ ++#include "drmP.h" ++ ++#if defined(CONFIG_X86) ++#include ++#endif ++ ++/** ++ * Free the old memory node unless it's a pinned region and we ++ * have not been requested to free also pinned regions. ++ */ ++ ++static void drm_bo_free_old_node(struct drm_buffer_object *bo) ++{ ++ struct drm_bo_mem_reg *old_mem = &bo->mem; ++ ++ if (old_mem->mm_node && (old_mem->mm_node != bo->pinned_node)) { ++ mutex_lock(&bo->dev->struct_mutex); ++ drm_mm_put_block(old_mem->mm_node); ++ mutex_unlock(&bo->dev->struct_mutex); ++ } ++ old_mem->mm_node = NULL; ++} ++ ++int drm_bo_move_ttm(struct drm_buffer_object *bo, ++ int evict, int no_wait, struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_ttm *ttm = bo->ttm; ++ struct drm_bo_mem_reg *old_mem = &bo->mem; ++ uint64_t save_flags = old_mem->flags; ++ uint64_t save_proposed_flags = old_mem->proposed_flags; ++ int ret; ++ ++ if (old_mem->mem_type != DRM_BO_MEM_LOCAL) { ++ if (evict) ++ drm_ttm_evict(ttm); ++ else ++ drm_ttm_unbind(ttm); ++ ++ drm_bo_free_old_node(bo); ++ DRM_FLAG_MASKED(old_mem->flags, ++ DRM_BO_FLAG_CACHED | DRM_BO_FLAG_MAPPABLE | ++ DRM_BO_FLAG_MEM_LOCAL, DRM_BO_MASK_MEMTYPE); ++ old_mem->mem_type = DRM_BO_MEM_LOCAL; ++ save_flags = old_mem->flags; ++ } ++ if (new_mem->mem_type != DRM_BO_MEM_LOCAL) { ++ ret = drm_ttm_bind(ttm, new_mem); ++ if (ret) ++ return ret; ++ } ++ ++ *old_mem = *new_mem; ++ new_mem->mm_node = NULL; ++ old_mem->proposed_flags = save_proposed_flags; ++ DRM_FLAG_MASKED(save_flags, new_mem->flags, DRM_BO_MASK_MEMTYPE); ++ return 0; ++} ++EXPORT_SYMBOL(drm_bo_move_ttm); ++ ++/** ++ * \c Return a kernel virtual address to the buffer object PCI memory. ++ * ++ * \param bo The buffer object. ++ * \return Failure indication. ++ * ++ * Returns -EINVAL if the buffer object is currently not mappable. ++ * Returns -ENOMEM if the ioremap operation failed. ++ * Otherwise returns zero. ++ * ++ * After a successfull call, bo->iomap contains the virtual address, or NULL ++ * if the buffer object content is not accessible through PCI space. ++ * Call bo->mutex locked. ++ */ ++ ++int drm_mem_reg_ioremap(struct drm_device *dev, struct drm_bo_mem_reg *mem, ++ void **virtual) ++{ ++ struct drm_buffer_manager *bm = &dev->bm; ++ struct drm_mem_type_manager *man = &bm->man[mem->mem_type]; ++ unsigned long bus_offset; ++ unsigned long bus_size; ++ unsigned long bus_base; ++ int ret; ++ void *addr; ++ ++ *virtual = NULL; ++ ret = drm_bo_pci_offset(dev, mem, &bus_base, &bus_offset, &bus_size); ++ if (ret || bus_size == 0) ++ return ret; ++ ++ if (!(man->flags & _DRM_FLAG_NEEDS_IOREMAP)) ++ addr = (void *)(((u8 *) man->io_addr) + bus_offset); ++ else { ++ addr = ioremap_nocache(bus_base + bus_offset, bus_size); ++ if (!addr) ++ return -ENOMEM; ++ } ++ *virtual = addr; ++ return 0; ++} ++EXPORT_SYMBOL(drm_mem_reg_ioremap); ++ ++/** ++ * \c Unmap mapping obtained using drm_bo_ioremap ++ * ++ * \param bo The buffer object. ++ * ++ * Call bo->mutex locked. ++ */ ++ ++void drm_mem_reg_iounmap(struct drm_device *dev, struct drm_bo_mem_reg *mem, ++ void *virtual) ++{ ++ struct drm_buffer_manager *bm; ++ struct drm_mem_type_manager *man; ++ ++ bm = &dev->bm; ++ man = &bm->man[mem->mem_type]; ++ ++ if (virtual && (man->flags & _DRM_FLAG_NEEDS_IOREMAP)) ++ iounmap(virtual); ++} ++EXPORT_SYMBOL(drm_mem_reg_iounmap); ++ ++static int drm_copy_io_page(void *dst, void *src, unsigned long page) ++{ ++ uint32_t *dstP = ++ (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT)); ++ uint32_t *srcP = ++ (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT)); ++ ++ int i; ++ for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i) ++ iowrite32(ioread32(srcP++), dstP++); ++ return 0; ++} ++ ++static int drm_copy_io_ttm_page(struct drm_ttm *ttm, void *src, ++ unsigned long page) ++{ ++ struct page *d = drm_ttm_get_page(ttm, page); ++ void *dst; ++ ++ if (!d) ++ return -ENOMEM; ++ ++ src = (void *)((unsigned long)src + (page << PAGE_SHIFT)); ++ dst = kmap(d); ++ if (!dst) ++ return -ENOMEM; ++ ++ memcpy_fromio(dst, src, PAGE_SIZE); ++ kunmap(d); ++ return 0; ++} ++ ++static int drm_copy_ttm_io_page(struct drm_ttm *ttm, void *dst, unsigned long page) ++{ ++ struct page *s = drm_ttm_get_page(ttm, page); ++ void *src; ++ ++ if (!s) ++ return -ENOMEM; ++ ++ dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT)); ++ src = kmap(s); ++ if (!src) ++ return -ENOMEM; ++ ++ memcpy_toio(dst, src, PAGE_SIZE); ++ kunmap(s); ++ return 0; ++} ++ ++int drm_bo_move_memcpy(struct drm_buffer_object *bo, ++ int evict, int no_wait, struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_mem_type_manager *man = &dev->bm.man[new_mem->mem_type]; ++ struct drm_ttm *ttm = bo->ttm; ++ struct drm_bo_mem_reg *old_mem = &bo->mem; ++ struct drm_bo_mem_reg old_copy = *old_mem; ++ void *old_iomap; ++ void *new_iomap; ++ int ret; ++ uint64_t save_flags = old_mem->flags; ++ uint64_t save_proposed_flags = old_mem->proposed_flags; ++ unsigned long i; ++ unsigned long page; ++ unsigned long add = 0; ++ int dir; ++ ++ ret = drm_mem_reg_ioremap(dev, old_mem, &old_iomap); ++ if (ret) ++ return ret; ++ ret = drm_mem_reg_ioremap(dev, new_mem, &new_iomap); ++ if (ret) ++ goto out; ++ ++ if (old_iomap == NULL && new_iomap == NULL) ++ goto out2; ++ if (old_iomap == NULL && ttm == NULL) ++ goto out2; ++ ++ add = 0; ++ dir = 1; ++ ++ if ((old_mem->mem_type == new_mem->mem_type) && ++ (new_mem->mm_node->start < ++ old_mem->mm_node->start + old_mem->mm_node->size)) { ++ dir = -1; ++ add = new_mem->num_pages - 1; ++ } ++ ++ for (i = 0; i < new_mem->num_pages; ++i) { ++ page = i * dir + add; ++ if (old_iomap == NULL) ++ ret = drm_copy_ttm_io_page(ttm, new_iomap, page); ++ else if (new_iomap == NULL) ++ ret = drm_copy_io_ttm_page(ttm, old_iomap, page); ++ else ++ ret = drm_copy_io_page(new_iomap, old_iomap, page); ++ if (ret) ++ goto out1; ++ } ++ mb(); ++out2: ++ drm_bo_free_old_node(bo); ++ ++ *old_mem = *new_mem; ++ new_mem->mm_node = NULL; ++ old_mem->proposed_flags = save_proposed_flags; ++ DRM_FLAG_MASKED(save_flags, new_mem->flags, DRM_BO_MASK_MEMTYPE); ++ ++ if ((man->flags & _DRM_FLAG_MEMTYPE_FIXED) && (ttm != NULL)) { ++ drm_ttm_unbind(ttm); ++ drm_ttm_destroy(ttm); ++ bo->ttm = NULL; ++ } ++ ++out1: ++ drm_mem_reg_iounmap(dev, new_mem, new_iomap); ++out: ++ drm_mem_reg_iounmap(dev, &old_copy, old_iomap); ++ return ret; ++} ++EXPORT_SYMBOL(drm_bo_move_memcpy); ++ ++static int drm_memset_io_page(void *dst, unsigned long page) ++{ ++ dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT)); ++ memset_io(dst, 0, PAGE_SIZE); ++ return 0; ++} ++ ++static int drm_memset_ttm_page(struct drm_ttm *ttm, unsigned long page) ++{ ++ struct page *d = drm_ttm_get_page(ttm, page); ++ void *dst; ++ ++ dst = kmap(d); ++ if (!dst) ++ return -ENOMEM; ++ ++ memset_io(dst, 0, PAGE_SIZE); ++ kunmap(d); ++ return 0; ++} ++ ++int drm_bo_move_zero(struct drm_buffer_object *bo, ++ int evict, int no_wait, struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_mem_type_manager *man = &dev->bm.man[new_mem->mem_type]; ++ struct drm_ttm *ttm = bo->ttm; ++ void *new_iomap; ++ int ret; ++ struct drm_bo_mem_reg *old_mem = &bo->mem; ++ uint64_t save_flags = old_mem->flags; ++ uint64_t save_proposed_flags = old_mem->proposed_flags; ++ unsigned long i; ++ unsigned long page; ++ ++ ret = drm_mem_reg_ioremap(dev, new_mem, &new_iomap); ++ if (ret) ++ goto out; ++ ++ if (new_iomap == NULL && ttm == NULL) ++ goto out2; ++ ++ for (i = 0; i < new_mem->num_pages; ++i) { ++ if (new_iomap == NULL) ++ ret = drm_memset_ttm_page(ttm, i); ++ else ++ ret = drm_memset_io_page(new_iomap, i); ++ if (ret) ++ goto out1; ++ } ++ mb(); ++out2: ++ drm_bo_free_old_node(bo); ++ ++ *old_mem = *new_mem; ++ new_mem->mm_node = NULL; ++ old_mem->proposed_flags = save_proposed_flags; ++ DRM_FLAG_MASKED(save_flags, new_mem->flags, DRM_BO_MASK_MEMTYPE); ++ ++ if ((man->flags & _DRM_FLAG_MEMTYPE_FIXED) && (ttm != NULL)) { ++ drm_ttm_unbind(ttm); ++ drm_ttm_destroy(ttm); ++ bo->ttm = NULL; ++ } ++out1: ++ drm_mem_reg_iounmap(dev, new_mem, new_iomap); ++out: ++ return ret; ++} ++EXPORT_SYMBOL(drm_bo_move_zero); ++ ++/* ++ * Transfer a buffer object's memory and LRU status to a newly ++ * created object. User-space references remains with the old ++ * object. Call bo->mutex locked. ++ */ ++ ++int drm_buffer_object_transfer(struct drm_buffer_object *bo, ++ struct drm_buffer_object **new_obj) ++{ ++ struct drm_buffer_object *fbo; ++ struct drm_device *dev = bo->dev; ++ struct drm_buffer_manager *bm = &dev->bm; ++ ++ fbo = drm_ctl_calloc(1, sizeof(*fbo), DRM_MEM_BUFOBJ); ++ if (!fbo) ++ return -ENOMEM; ++ ++ *fbo = *bo; ++ mutex_init(&fbo->mutex); ++ mutex_lock(&fbo->mutex); ++ mutex_lock(&dev->struct_mutex); ++ ++ DRM_INIT_WAITQUEUE(&bo->event_queue); ++ INIT_LIST_HEAD(&fbo->ddestroy); ++ INIT_LIST_HEAD(&fbo->lru); ++ INIT_LIST_HEAD(&fbo->pinned_lru); ++#ifdef DRM_ODD_MM_COMPAT ++ INIT_LIST_HEAD(&fbo->vma_list); ++ INIT_LIST_HEAD(&fbo->p_mm_list); ++#endif ++ ++ fbo->fence = drm_fence_reference_locked(bo->fence); ++ fbo->pinned_node = NULL; ++ fbo->mem.mm_node->private = (void *)fbo; ++ atomic_set(&fbo->usage, 1); ++ atomic_inc(&bm->count); ++ mutex_unlock(&dev->struct_mutex); ++ mutex_unlock(&fbo->mutex); ++ ++ *new_obj = fbo; ++ return 0; ++} ++ ++/* ++ * Since move is underway, we need to block signals in this function. ++ * We cannot restart until it has finished. ++ */ ++ ++int drm_bo_move_accel_cleanup(struct drm_buffer_object *bo, ++ int evict, int no_wait, uint32_t fence_class, ++ uint32_t fence_type, uint32_t fence_flags, ++ struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_mem_type_manager *man = &dev->bm.man[new_mem->mem_type]; ++ struct drm_bo_mem_reg *old_mem = &bo->mem; ++ int ret; ++ uint64_t save_flags = old_mem->flags; ++ uint64_t save_proposed_flags = old_mem->proposed_flags; ++ struct drm_buffer_object *old_obj; ++ ++ if (bo->fence) ++ drm_fence_usage_deref_unlocked(&bo->fence); ++ ret = drm_fence_object_create(dev, fence_class, fence_type, ++ fence_flags | DRM_FENCE_FLAG_EMIT, ++ &bo->fence); ++ bo->fence_type = fence_type; ++ if (ret) ++ return ret; ++ ++#ifdef DRM_ODD_MM_COMPAT ++ /* ++ * In this mode, we don't allow pipelining a copy blit, ++ * since the buffer will be accessible from user space ++ * the moment we return and rebuild the page tables. ++ * ++ * With normal vm operation, page tables are rebuilt ++ * on demand using fault(), which waits for buffer idle. ++ */ ++ if (1) ++#else ++ if (evict || ((bo->mem.mm_node == bo->pinned_node) && ++ bo->mem.mm_node != NULL)) ++#endif ++ { ++ if (bo->fence) { ++ (void) drm_fence_object_wait(bo->fence, 0, 1, ++ bo->fence_type); ++ drm_fence_usage_deref_unlocked(&bo->fence); ++ } ++ drm_bo_free_old_node(bo); ++ ++ if ((man->flags & _DRM_FLAG_MEMTYPE_FIXED) && (bo->ttm != NULL)) { ++ drm_ttm_unbind(bo->ttm); ++ drm_ttm_destroy(bo->ttm); ++ bo->ttm = NULL; ++ } ++ } else { ++ ++ /* This should help pipeline ordinary buffer moves. ++ * ++ * Hang old buffer memory on a new buffer object, ++ * and leave it to be released when the GPU ++ * operation has completed. ++ */ ++ ++ ret = drm_buffer_object_transfer(bo, &old_obj); ++ ++ if (ret) ++ return ret; ++ ++ if (!(man->flags & _DRM_FLAG_MEMTYPE_FIXED)) ++ old_obj->ttm = NULL; ++ else ++ bo->ttm = NULL; ++ ++ mutex_lock(&dev->struct_mutex); ++ list_del_init(&old_obj->lru); ++ DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED); ++ drm_bo_add_to_lru(old_obj); ++ ++ drm_bo_usage_deref_locked(&old_obj); ++ mutex_unlock(&dev->struct_mutex); ++ ++ } ++ ++ *old_mem = *new_mem; ++ new_mem->mm_node = NULL; ++ old_mem->proposed_flags = save_proposed_flags; ++ DRM_FLAG_MASKED(save_flags, new_mem->flags, DRM_BO_MASK_MEMTYPE); ++ return 0; ++} ++EXPORT_SYMBOL(drm_bo_move_accel_cleanup); ++ ++int drm_bo_same_page(unsigned long offset, ++ unsigned long offset2) ++{ ++ return (offset & PAGE_MASK) == (offset2 & PAGE_MASK); ++} ++EXPORT_SYMBOL(drm_bo_same_page); ++ ++unsigned long drm_bo_offset_end(unsigned long offset, ++ unsigned long end) ++{ ++ offset = (offset + PAGE_SIZE) & PAGE_MASK; ++ return (end < offset) ? end : offset; ++} ++EXPORT_SYMBOL(drm_bo_offset_end); ++ ++static pgprot_t drm_kernel_io_prot(uint32_t map_type) ++{ ++ pgprot_t tmp = PAGE_KERNEL; ++ ++#if defined(__i386__) || defined(__x86_64__) ++ if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) { ++ pgprot_val(tmp) |= _PAGE_PCD; ++ pgprot_val(tmp) &= ~_PAGE_PWT; ++#if defined(CONFIG_X86_PAT) ++ /* for a scatter gather backed map, use ++ WC page bits */ ++ if (((map_type == _DRM_FRAME_BUFFER) || (map_type == _DRM_SCATTER_GATHER)) && pat_enabled) ++ tmp = PAGE_KERNEL_WC; ++#endif ++ } ++#elif defined(__powerpc__) ++ pgprot_val(tmp) |= _PAGE_NO_CACHE; ++ if (map_type == _DRM_REGISTERS) ++ pgprot_val(tmp) |= _PAGE_GUARDED; ++#endif ++#if defined(__ia64__) ++ if (map_type == _DRM_TTM) ++ tmp = pgprot_writecombine(tmp); ++ else ++ tmp = pgprot_noncached(tmp); ++#endif ++ return tmp; ++} ++ ++static int drm_bo_ioremap(struct drm_buffer_object *bo, unsigned long bus_base, ++ unsigned long bus_offset, unsigned long bus_size, ++ struct drm_bo_kmap_obj *map) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_bo_mem_reg *mem = &bo->mem; ++ struct drm_mem_type_manager *man = &dev->bm.man[mem->mem_type]; ++ ++ if (!(man->flags & _DRM_FLAG_NEEDS_IOREMAP)) { ++ map->bo_kmap_type = bo_map_premapped; ++ map->virtual = (void *)(((u8 *) man->io_addr) + bus_offset); ++ } else { ++ map->bo_kmap_type = bo_map_iomap; ++ map->virtual = ioremap_nocache(bus_base + bus_offset, bus_size); ++ } ++ return (!map->virtual) ? -ENOMEM : 0; ++} ++ ++static int drm_bo_kmap_ttm(struct drm_buffer_object *bo, ++ unsigned long start_page, unsigned long num_pages, ++ struct drm_bo_kmap_obj *map) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_bo_mem_reg *mem = &bo->mem; ++ struct drm_mem_type_manager *man = &dev->bm.man[mem->mem_type]; ++ pgprot_t prot; ++ struct drm_ttm *ttm = bo->ttm; ++ struct page *d; ++ int i; ++ ++ BUG_ON(!ttm); ++ ++ if (num_pages == 1 && (mem->flags & DRM_BO_FLAG_CACHED)) { ++ ++ /* ++ * We're mapping a single page, and the desired ++ * page protection is consistent with the bo. ++ */ ++ ++ map->bo_kmap_type = bo_map_kmap; ++ map->page = drm_ttm_get_page(ttm, start_page); ++ map->virtual = kmap(map->page); ++ } else { ++ /* ++ * Populate the part we're mapping; ++ */ ++ ++ for (i = start_page; i < start_page + num_pages; ++i) { ++ d = drm_ttm_get_page(ttm, i); ++ if (!d) ++ return -ENOMEM; ++ } ++ ++ /* ++ * We need to use vmap to get the desired page protection ++ * or to make the buffer object look contigous. ++ */ ++ ++ prot = (mem->flags & DRM_BO_FLAG_CACHED) ? ++ PAGE_KERNEL : ++ drm_kernel_io_prot(man->drm_bus_maptype); ++ map->bo_kmap_type = bo_map_vmap; ++ map->virtual = vmap(ttm->pages + start_page, ++ num_pages, 0, prot); ++ } ++ return (!map->virtual) ? -ENOMEM : 0; ++} ++ ++/* ++ * This function is to be used for kernel mapping of buffer objects. ++ * It chooses the appropriate mapping method depending on the memory type ++ * and caching policy the buffer currently has. ++ * Mapping multiple pages or buffers that live in io memory is a bit slow and ++ * consumes vmalloc space. Be restrictive with such mappings. ++ * Mapping single pages usually returns the logical kernel address, ++ * (which is fast) ++ * BUG may use slower temporary mappings for high memory pages or ++ * uncached / write-combined pages. ++ * ++ * The function fills in a drm_bo_kmap_obj which can be used to return the ++ * kernel virtual address of the buffer. ++ * ++ * Code servicing a non-priviliged user request is only allowed to map one ++ * page at a time. We might need to implement a better scheme to stop such ++ * processes from consuming all vmalloc space. ++ */ ++ ++int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page, ++ unsigned long num_pages, struct drm_bo_kmap_obj *map) ++{ ++ int ret; ++ unsigned long bus_base; ++ unsigned long bus_offset; ++ unsigned long bus_size; ++ ++ map->virtual = NULL; ++ ++ if (num_pages > bo->num_pages) ++ return -EINVAL; ++ if (start_page > bo->num_pages) ++ return -EINVAL; ++#if 0 ++ if (num_pages > 1 && !DRM_SUSER(DRM_CURPROC)) ++ return -EPERM; ++#endif ++ ret = drm_bo_pci_offset(bo->dev, &bo->mem, &bus_base, ++ &bus_offset, &bus_size); ++ ++ if (ret) ++ return ret; ++ ++ /* clear the clean flags */ ++ bo->mem.flags &= ~DRM_BO_FLAG_CLEAN; ++ bo->mem.proposed_flags &= ~DRM_BO_FLAG_CLEAN; ++ ++ if (bus_size == 0) { ++ return drm_bo_kmap_ttm(bo, start_page, num_pages, map); ++ } else { ++ bus_offset += start_page << PAGE_SHIFT; ++ bus_size = num_pages << PAGE_SHIFT; ++ return drm_bo_ioremap(bo, bus_base, bus_offset, bus_size, map); ++ } ++} ++EXPORT_SYMBOL(drm_bo_kmap); ++ ++void drm_bo_kunmap(struct drm_bo_kmap_obj *map) ++{ ++ if (!map->virtual) ++ return; ++ ++ switch (map->bo_kmap_type) { ++ case bo_map_iomap: ++ iounmap(map->virtual); ++ break; ++ case bo_map_vmap: ++ vunmap(map->virtual); ++ break; ++ case bo_map_kmap: ++ kunmap(map->page); ++ break; ++ case bo_map_premapped: ++ break; ++ default: ++ BUG(); ++ } ++ map->virtual = NULL; ++ map->page = NULL; ++} ++EXPORT_SYMBOL(drm_bo_kunmap); ++ ++int drm_bo_pfn_prot(struct drm_buffer_object *bo, ++ unsigned long dst_offset, ++ unsigned long *pfn, ++ pgprot_t *prot) ++{ ++ struct drm_bo_mem_reg *mem = &bo->mem; ++ struct drm_device *dev = bo->dev; ++ unsigned long bus_offset; ++ unsigned long bus_size; ++ unsigned long bus_base; ++ struct drm_mem_type_manager *man = &dev->bm.man[mem->mem_type]; ++ int ret; ++ ++ ret = drm_bo_pci_offset(dev, mem, &bus_base, &bus_offset, ++ &bus_size); ++ if (ret) ++ return -EINVAL; ++ ++ if (bus_size != 0) ++ *pfn = (bus_base + bus_offset + dst_offset) >> PAGE_SHIFT; ++ else if (!bo->ttm) ++ return -EINVAL; ++ else ++ *pfn = page_to_pfn(drm_ttm_get_page(bo->ttm, dst_offset >> PAGE_SHIFT)); ++ ++ *prot = (mem->flags & DRM_BO_FLAG_CACHED) ? ++ PAGE_KERNEL : drm_kernel_io_prot(man->drm_bus_maptype); ++ ++ return 0; ++} ++EXPORT_SYMBOL(drm_bo_pfn_prot); ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_bufs.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_bufs.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_bufs.c 2009-04-26 02:52:17.130975079 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_bufs.c 2009-04-26 02:54:28.917975163 +0200 +@@ -249,7 +249,7 @@ + map->offset = (unsigned long)map->handle; + if (map->flags & _DRM_CONTAINS_LOCK) { + /* Prevent a 2nd X Server from creating a 2nd lock */ +- if (dev->primary->master->lock.hw_lock != NULL) { ++ if (dev->primary->master->lock.hw_lock != &dev->default_lock) { + vfree(map->handle); + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + return -EBUSY; +@@ -463,8 +463,8 @@ + vfree(map->handle); + if (master) { + if (dev->sigdata.lock == master->lock.hw_lock) +- dev->sigdata.lock = NULL; +- master->lock.hw_lock = NULL; /* SHM removed */ ++ dev->sigdata.lock = &dev->default_lock; ++ master->lock.hw_lock = &dev->default_lock; + master->lock.file_priv = NULL; + wake_up_interruptible_all(&master->lock.lock_queue); + } +@@ -481,6 +481,9 @@ + case _DRM_GEM: + DRM_ERROR("tried to rmmap GEM object\n"); + break; ++ case _DRM_TTM: ++ BUG_ON(1); ++ break; + } + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + +@@ -1580,6 +1583,7 @@ + dev->buf_use++; /* Can't allocate more after this call */ + spin_unlock(&dev->count_lock); + ++ DRM_DEBUG("dma buf count %d, req count %d\n", request->count, dma->buf_count); + if (request->count >= dma->buf_count) { + if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) + || (drm_core_check_feature(dev, DRIVER_SG) +@@ -1590,6 +1594,7 @@ + unsigned long token = dev->agp_buffer_token; + + if (!map) { ++ DRM_DEBUG("No map\n"); + retcode = -EINVAL; + goto done; + } +@@ -1607,6 +1612,7 @@ + up_write(¤t->mm->mmap_sem); + } + if (virtual > -1024UL) { ++ DRM_DEBUG("mmap failed\n"); + /* Real error */ + retcode = (signed long)virtual; + goto done; +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_crtc.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_crtc.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_crtc.c 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_crtc.c 2009-04-26 02:54:38.757983055 +0200 +@@ -1511,7 +1511,7 @@ + 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: +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_crtc_helper.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_crtc_helper.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_crtc_helper.c 2009-04-26 02:52:17.135975757 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_crtc_helper.c 2009-04-26 02:54:45.204725836 +0200 +@@ -552,7 +552,7 @@ + bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, + struct drm_display_mode *mode, + int x, int y, +- struct drm_framebuffer *old_fb) ++ struct drm_framebuffer *old_fb, int conn_changed) + { + struct drm_device *dev = crtc->dev; + struct drm_display_mode *adjusted_mode, saved_mode; +@@ -590,7 +590,7 @@ + crtc->x = x; + crtc->y = y; + +- if (drm_mode_equal(&saved_mode, &crtc->mode)) { ++ if (drm_mode_equal(&saved_mode, &crtc->mode) && !conn_changed) { + if (saved_x != crtc->x || saved_y != crtc->y || + depth_changed || bpp_changed) { + ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, +@@ -848,7 +848,7 @@ + drm_mode_debug_printmodeline(set->mode); + if (!drm_crtc_helper_set_mode(set->crtc, set->mode, + set->x, set->y, +- old_fb)) { ++ old_fb, 1)) { + DRM_ERROR("failed to set mode on crtc %p\n", + set->crtc); + ret = -EINVAL; +@@ -868,6 +868,8 @@ + set->x, set->y, old_fb); + if (ret != 0) + goto fail_set_mode; ++ set->crtc->x = set->x; ++ set->crtc->y = set->y; + } + + kfree(save_encoders); +@@ -999,7 +1001,7 @@ + continue; + + ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, +- crtc->x, crtc->y, crtc->fb); ++ crtc->x, crtc->y, crtc->fb, 1); + + if (ret == false) + DRM_ERROR("failed to set mode on crtc %p\n", crtc); +@@ -1007,3 +1009,30 @@ + return 0; + } + EXPORT_SYMBOL(drm_helper_resume_force_mode); ++ ++void drm_helper_set_connector_dpms(struct drm_connector *connector, ++ int dpms_mode) ++{ ++ int i = 0; ++ struct drm_encoder *encoder; ++ struct drm_encoder_helper_funcs *encoder_funcs; ++ struct drm_mode_object *obj; ++ ++ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { ++ if (connector->encoder_ids[i] == 0) ++ break; ++ ++ obj = drm_mode_object_find(connector->dev, ++ connector->encoder_ids[i], ++ DRM_MODE_OBJECT_ENCODER); ++ if (!obj) ++ continue; ++ ++ encoder = obj_to_encoder(obj); ++ encoder_funcs = encoder->helper_private; ++ if (encoder_funcs->dpms) ++ encoder_funcs->dpms(encoder, dpms_mode); ++ ++ } ++} ++EXPORT_SYMBOL(drm_helper_set_connector_dpms); +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_debugfs.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_debugfs.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_debugfs.c 2009-04-26 02:52:17.136975725 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_debugfs.c 2009-04-26 02:54:52.314726590 +0200 +@@ -48,6 +48,7 @@ + {"bufs", drm_bufs_info, 0}, + {"gem_names", drm_gem_name_info, DRIVER_GEM}, + {"gem_objects", drm_gem_object_info, DRIVER_GEM}, ++ {"page_alloc", drm_page_alloc_info, 0}, + #if DRM_DEBUG_CODE + {"vma", drm_vma_info, 0}, + #endif +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_dma.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_dma.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_dma.c 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_dma.c 2009-04-26 02:54:59.271974876 +0200 +@@ -58,6 +58,7 @@ + + return 0; + } ++EXPORT_SYMBOL(drm_dma_setup); + + /** + * Cleanup the DMA resources. +@@ -120,6 +121,7 @@ + drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER); + dev->dma = NULL; + } ++EXPORT_SYMBOL(drm_dma_takedown); + + /** + * Free a buffer. +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_drv.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_drv.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_drv.c 2009-04-26 02:52:17.137975903 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_drv.c 2009-04-26 02:55:03.586756679 +0200 +@@ -167,8 +167,12 @@ + + if (dev->driver->lastclose) + dev->driver->lastclose(dev); ++ + DRM_DEBUG("driver lastclose completed\n"); + ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_bo_driver_finish(dev); ++ + if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET)) + drm_irq_uninstall(dev); + +@@ -317,9 +321,34 @@ + static int __init drm_core_init(void) + { + int ret = -ENOMEM; ++ struct sysinfo si; ++ unsigned long avail_memctl_mem; ++ unsigned long max_memctl_mem; + + idr_init(&drm_minors_idr); + ++ si_meminfo(&si); ++ ++ /* ++ * AGP only allows low / DMA32 memory ATM. ++ */ ++ ++ avail_memctl_mem = si.totalram - si.totalhigh; ++ ++ /* ++ * Avoid overflows ++ */ ++ ++ max_memctl_mem = 1UL << (32 - PAGE_SHIFT); ++ max_memctl_mem = (max_memctl_mem / si.mem_unit) * PAGE_SIZE; ++ ++ if (avail_memctl_mem >= max_memctl_mem) ++ avail_memctl_mem = max_memctl_mem; ++ ++ drm_init_memctl(avail_memctl_mem/2, avail_memctl_mem*3/4, si.mem_unit); ++ ++ ret = -ENOMEM; ++ + if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) + goto err_p1; + +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_fence.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_fence.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_fence.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_fence.c 2009-04-26 02:58:51.795980205 +0200 +@@ -0,0 +1,540 @@ ++/************************************************************************** ++ * ++ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ **************************************************************************/ ++/* ++ * Authors: Thomas Hellström ++ */ ++ ++#include "drmP.h" ++ ++ ++/* ++ * Convenience function to be called by fence::wait methods that ++ * need polling. ++ */ ++ ++int drm_fence_wait_polling(struct drm_fence_object *fence, int lazy, ++ int interruptible, uint32_t mask, ++ unsigned long end_jiffies) ++{ ++ struct drm_device *dev = fence->dev; ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class]; ++ uint32_t count = 0; ++ int ret; ++ ++ DECLARE_WAITQUEUE(entry, current); ++ add_wait_queue(&fc->fence_queue, &entry); ++ ++ ret = 0; ++ ++ for (;;) { ++ __set_current_state((interruptible) ? ++ TASK_INTERRUPTIBLE : ++ TASK_UNINTERRUPTIBLE); ++ if (drm_fence_object_signaled(fence, mask)) ++ break; ++ if (time_after_eq(jiffies, end_jiffies)) { ++ ret = -EBUSY; ++ break; ++ } ++ if (lazy) ++ schedule_timeout(1); ++ else if ((++count & 0x0F) == 0){ ++ __set_current_state(TASK_RUNNING); ++ schedule(); ++ __set_current_state((interruptible) ? ++ TASK_INTERRUPTIBLE : ++ TASK_UNINTERRUPTIBLE); ++ } ++ if (interruptible && signal_pending(current)) { ++ ret = -EAGAIN; ++ break; ++ } ++ } ++ __set_current_state(TASK_RUNNING); ++ remove_wait_queue(&fc->fence_queue, &entry); ++ return ret; ++} ++EXPORT_SYMBOL(drm_fence_wait_polling); ++ ++/* ++ * Typically called by the IRQ handler. ++ */ ++ ++void drm_fence_handler(struct drm_device *dev, uint32_t fence_class, ++ uint32_t sequence, uint32_t type, uint32_t error) ++{ ++ int wake = 0; ++ uint32_t diff; ++ uint32_t relevant_type; ++ uint32_t new_type; ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_class_manager *fc = &fm->fence_class[fence_class]; ++ struct drm_fence_driver *driver = dev->driver->fence_driver; ++ struct list_head *head; ++ struct drm_fence_object *fence, *next; ++ int found = 0; ++ ++ if (list_empty(&fc->ring)) ++ return; ++ ++ list_for_each_entry(fence, &fc->ring, ring) { ++ diff = (sequence - fence->sequence) & driver->sequence_mask; ++ if (diff > driver->wrap_diff) { ++ found = 1; ++ break; ++ } ++ } ++ ++ fc->waiting_types &= ~type; ++ head = (found) ? &fence->ring : &fc->ring; ++ ++ list_for_each_entry_safe_reverse(fence, next, head, ring) { ++ if (&fence->ring == &fc->ring) ++ break; ++ ++ if (error) { ++ fence->error = error; ++ fence->signaled_types = fence->type; ++ list_del_init(&fence->ring); ++ wake = 1; ++ break; ++ } ++ ++ if (type & DRM_FENCE_TYPE_EXE) ++ type |= fence->native_types; ++ ++ relevant_type = type & fence->type; ++ new_type = (fence->signaled_types | relevant_type) ^ ++ fence->signaled_types; ++ ++ if (new_type) { ++ fence->signaled_types |= new_type; ++ DRM_DEBUG("Fence %p signaled 0x%08x\n", ++ fence, fence->signaled_types); ++ ++ if (driver->needed_flush) ++ fc->pending_flush |= driver->needed_flush(fence); ++ ++ if (new_type & fence->waiting_types) ++ wake = 1; ++ } ++ ++ fc->waiting_types |= fence->waiting_types & ~fence->signaled_types; ++ ++ if (!(fence->type & ~fence->signaled_types)) { ++ DRM_DEBUG("Fence completely signaled %p\n", ++ fence); ++ list_del_init(&fence->ring); ++ } ++ } ++ ++ /* ++ * Reinstate lost waiting types. ++ */ ++ ++ if ((fc->waiting_types & type) != type) { ++ head = head->prev; ++ list_for_each_entry(fence, head, ring) { ++ if (&fence->ring == &fc->ring) ++ break; ++ diff = (fc->highest_waiting_sequence - fence->sequence) & ++ driver->sequence_mask; ++ if (diff > driver->wrap_diff) ++ break; ++ ++ fc->waiting_types |= fence->waiting_types & ~fence->signaled_types; ++ } ++ } ++ ++ if (wake) ++ wake_up_all(&fc->fence_queue); ++} ++EXPORT_SYMBOL(drm_fence_handler); ++ ++static void drm_fence_unring(struct drm_device *dev, struct list_head *ring) ++{ ++ struct drm_fence_manager *fm = &dev->fm; ++ unsigned long flags; ++ ++ write_lock_irqsave(&fm->lock, flags); ++ list_del_init(ring); ++ write_unlock_irqrestore(&fm->lock, flags); ++} ++ ++void drm_fence_usage_deref_locked(struct drm_fence_object **fence) ++{ ++ struct drm_fence_object *tmp_fence = *fence; ++ struct drm_device *dev = tmp_fence->dev; ++ struct drm_fence_manager *fm = &dev->fm; ++ ++ DRM_ASSERT_LOCKED(&dev->struct_mutex); ++ *fence = NULL; ++ if (atomic_dec_and_test(&tmp_fence->usage)) { ++ drm_fence_unring(dev, &tmp_fence->ring); ++ DRM_DEBUG("Destroyed a fence object %p\n", ++ tmp_fence); ++ atomic_dec(&fm->count); ++ drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE); ++ } ++} ++EXPORT_SYMBOL(drm_fence_usage_deref_locked); ++ ++void drm_fence_usage_deref_unlocked(struct drm_fence_object **fence) ++{ ++ struct drm_fence_object *tmp_fence = *fence; ++ struct drm_device *dev = tmp_fence->dev; ++ struct drm_fence_manager *fm = &dev->fm; ++ ++ *fence = NULL; ++ if (atomic_dec_and_test(&tmp_fence->usage)) { ++ mutex_lock(&dev->struct_mutex); ++ if (atomic_read(&tmp_fence->usage) == 0) { ++ drm_fence_unring(dev, &tmp_fence->ring); ++ atomic_dec(&fm->count); ++ drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE); ++ } ++ mutex_unlock(&dev->struct_mutex); ++ } ++} ++EXPORT_SYMBOL(drm_fence_usage_deref_unlocked); ++ ++struct drm_fence_object ++*drm_fence_reference_locked(struct drm_fence_object *src) ++{ ++ DRM_ASSERT_LOCKED(&src->dev->struct_mutex); ++ ++ atomic_inc(&src->usage); ++ return src; ++} ++ ++void drm_fence_reference_unlocked(struct drm_fence_object **dst, ++ struct drm_fence_object *src) ++{ ++ mutex_lock(&src->dev->struct_mutex); ++ *dst = src; ++ atomic_inc(&src->usage); ++ mutex_unlock(&src->dev->struct_mutex); ++} ++EXPORT_SYMBOL(drm_fence_reference_unlocked); ++ ++int drm_fence_object_signaled(struct drm_fence_object *fence, uint32_t mask) ++{ ++ unsigned long flags; ++ int signaled; ++ struct drm_device *dev = fence->dev; ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_driver *driver = dev->driver->fence_driver; ++ ++ mask &= fence->type; ++ read_lock_irqsave(&fm->lock, flags); ++ signaled = (mask & fence->signaled_types) == mask; ++ read_unlock_irqrestore(&fm->lock, flags); ++ if (!signaled && driver->poll) { ++ write_lock_irqsave(&fm->lock, flags); ++ driver->poll(dev, fence->fence_class, mask); ++ signaled = (mask & fence->signaled_types) == mask; ++ write_unlock_irqrestore(&fm->lock, flags); ++ } ++ return signaled; ++} ++EXPORT_SYMBOL(drm_fence_object_signaled); ++ ++ ++int drm_fence_object_flush(struct drm_fence_object *fence, ++ uint32_t type) ++{ ++ struct drm_device *dev = fence->dev; ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class]; ++ struct drm_fence_driver *driver = dev->driver->fence_driver; ++ unsigned long irq_flags; ++ uint32_t saved_pending_flush; ++ uint32_t diff; ++ int call_flush; ++ ++ if (type & ~fence->type) { ++ DRM_ERROR("Flush trying to extend fence type, " ++ "0x%x, 0x%x\n", type, fence->type); ++ return -EINVAL; ++ } ++ ++ write_lock_irqsave(&fm->lock, irq_flags); ++ fence->waiting_types |= type; ++ fc->waiting_types |= fence->waiting_types; ++ diff = (fence->sequence - fc->highest_waiting_sequence) & ++ driver->sequence_mask; ++ ++ if (diff < driver->wrap_diff) ++ fc->highest_waiting_sequence = fence->sequence; ++ ++ /* ++ * fence->waiting_types has changed. Determine whether ++ * we need to initiate some kind of flush as a result of this. ++ */ ++ ++ saved_pending_flush = fc->pending_flush; ++ if (driver->needed_flush) ++ fc->pending_flush |= driver->needed_flush(fence); ++ ++ if (driver->poll) ++ driver->poll(dev, fence->fence_class, fence->waiting_types); ++ ++ call_flush = fc->pending_flush; ++ write_unlock_irqrestore(&fm->lock, irq_flags); ++ ++ if (call_flush && driver->flush) ++ driver->flush(dev, fence->fence_class); ++ ++ return 0; ++} ++EXPORT_SYMBOL(drm_fence_object_flush); ++ ++/* ++ * Make sure old fence objects are signaled before their fence sequences are ++ * wrapped around and reused. ++ */ ++ ++void drm_fence_flush_old(struct drm_device *dev, uint32_t fence_class, ++ uint32_t sequence) ++{ ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_class_manager *fc = &fm->fence_class[fence_class]; ++ struct drm_fence_object *fence; ++ unsigned long irq_flags; ++ struct drm_fence_driver *driver = dev->driver->fence_driver; ++ int call_flush; ++ ++ uint32_t diff; ++ ++ write_lock_irqsave(&fm->lock, irq_flags); ++ ++ list_for_each_entry_reverse(fence, &fc->ring, ring) { ++ diff = (sequence - fence->sequence) & driver->sequence_mask; ++ if (diff <= driver->flush_diff) ++ break; ++ ++ fence->waiting_types = fence->type; ++ fc->waiting_types |= fence->type; ++ ++ if (driver->needed_flush) ++ fc->pending_flush |= driver->needed_flush(fence); ++ } ++ ++ if (driver->poll) ++ driver->poll(dev, fence_class, fc->waiting_types); ++ ++ call_flush = fc->pending_flush; ++ write_unlock_irqrestore(&fm->lock, irq_flags); ++ ++ if (call_flush && driver->flush) ++ driver->flush(dev, fence->fence_class); ++ ++ /* ++ * FIXME: Shold we implement a wait here for really old fences? ++ */ ++ ++} ++EXPORT_SYMBOL(drm_fence_flush_old); ++ ++int drm_fence_object_wait(struct drm_fence_object *fence, ++ int lazy, int ignore_signals, uint32_t mask) ++{ ++ struct drm_device *dev = fence->dev; ++ struct drm_fence_driver *driver = dev->driver->fence_driver; ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class]; ++ int ret = 0; ++ unsigned long _end = 3 * DRM_HZ; ++ ++ if (mask & ~fence->type) { ++ DRM_ERROR("Wait trying to extend fence type" ++ " 0x%08x 0x%08x\n", mask, fence->type); ++ BUG(); ++ return -EINVAL; ++ } ++ ++ if (driver->wait) ++ return driver->wait(fence, lazy, !ignore_signals, mask); ++ ++ drm_fence_object_flush(fence, mask); ++ if (driver->has_irq(dev, fence->fence_class, mask)) { ++ if (!ignore_signals) ++ ret = wait_event_interruptible_timeout ++ (fc->fence_queue, ++ drm_fence_object_signaled(fence, mask), ++ 3 * DRM_HZ); ++ else ++ ret = wait_event_timeout ++ (fc->fence_queue, ++ drm_fence_object_signaled(fence, mask), ++ 3 * DRM_HZ); ++ ++ if (unlikely(ret == -ERESTARTSYS)) ++ return -EAGAIN; ++ ++ if (unlikely(ret == 0)) ++ return -EBUSY; ++ ++ return 0; ++ } ++ ++ return drm_fence_wait_polling(fence, lazy, !ignore_signals, mask, ++ _end); ++} ++EXPORT_SYMBOL(drm_fence_object_wait); ++ ++int drm_fence_object_emit(struct drm_fence_object *fence, uint32_t fence_flags, ++ uint32_t fence_class, uint32_t type) ++{ ++ struct drm_device *dev = fence->dev; ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_driver *driver = dev->driver->fence_driver; ++ struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class]; ++ unsigned long flags; ++ uint32_t sequence; ++ uint32_t native_types; ++ int ret; ++ ++ drm_fence_unring(dev, &fence->ring); ++ ret = driver->emit(dev, fence_class, fence_flags, &sequence, ++ &native_types); ++ if (ret) ++ return ret; ++ ++ write_lock_irqsave(&fm->lock, flags); ++ fence->fence_class = fence_class; ++ fence->type = type; ++ fence->waiting_types = 0; ++ fence->signaled_types = 0; ++ fence->error = 0; ++ fence->sequence = sequence; ++ fence->native_types = native_types; ++ if (list_empty(&fc->ring)) ++ fc->highest_waiting_sequence = sequence - 1; ++ list_add_tail(&fence->ring, &fc->ring); ++ fc->latest_queued_sequence = sequence; ++ write_unlock_irqrestore(&fm->lock, flags); ++ return 0; ++} ++EXPORT_SYMBOL(drm_fence_object_emit); ++ ++static int drm_fence_object_init(struct drm_device *dev, uint32_t fence_class, ++ uint32_t type, ++ uint32_t fence_flags, ++ struct drm_fence_object *fence) ++{ ++ int ret = 0; ++ unsigned long flags; ++ struct drm_fence_manager *fm = &dev->fm; ++ ++ mutex_lock(&dev->struct_mutex); ++ atomic_set(&fence->usage, 1); ++ mutex_unlock(&dev->struct_mutex); ++ ++ write_lock_irqsave(&fm->lock, flags); ++ INIT_LIST_HEAD(&fence->ring); ++ ++ /* ++ * Avoid hitting BUG() for kernel-only fence objects. ++ */ ++ ++ fence->fence_class = fence_class; ++ fence->type = type; ++ fence->signaled_types = 0; ++ fence->waiting_types = 0; ++ fence->sequence = 0; ++ fence->error = 0; ++ fence->dev = dev; ++ write_unlock_irqrestore(&fm->lock, flags); ++ if (fence_flags & DRM_FENCE_FLAG_EMIT) { ++ ret = drm_fence_object_emit(fence, fence_flags, ++ fence->fence_class, type); ++ } ++ return ret; ++} ++ ++int drm_fence_object_create(struct drm_device *dev, uint32_t fence_class, ++ uint32_t type, unsigned flags, ++ struct drm_fence_object **c_fence) ++{ ++ struct drm_fence_object *fence; ++ int ret; ++ struct drm_fence_manager *fm = &dev->fm; ++ ++ fence = drm_ctl_calloc(1, sizeof(*fence), DRM_MEM_FENCE); ++ if (!fence) { ++ DRM_ERROR("Out of memory creating fence object\n"); ++ return -ENOMEM; ++ } ++ ret = drm_fence_object_init(dev, fence_class, type, flags, fence); ++ if (ret) { ++ drm_fence_usage_deref_unlocked(&fence); ++ return ret; ++ } ++ *c_fence = fence; ++ atomic_inc(&fm->count); ++ ++ return 0; ++} ++EXPORT_SYMBOL(drm_fence_object_create); ++ ++void drm_fence_manager_init(struct drm_device *dev) ++{ ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_class_manager *fence_class; ++ struct drm_fence_driver *fed = dev->driver->fence_driver; ++ int i; ++ unsigned long flags; ++ ++ rwlock_init(&fm->lock); ++ write_lock_irqsave(&fm->lock, flags); ++ fm->initialized = 0; ++ if (!fed) ++ goto out_unlock; ++ ++ fm->initialized = 1; ++ fm->num_classes = fed->num_classes; ++ BUG_ON(fm->num_classes > _DRM_FENCE_CLASSES); ++ ++ for (i = 0; i < fm->num_classes; ++i) { ++ fence_class = &fm->fence_class[i]; ++ ++ memset(fence_class, 0, sizeof(*fence_class)); ++ INIT_LIST_HEAD(&fence_class->ring); ++ DRM_INIT_WAITQUEUE(&fence_class->fence_queue); ++ } ++ ++ atomic_set(&fm->count, 0); ++ out_unlock: ++ write_unlock_irqrestore(&fm->lock, flags); ++} ++ ++void drm_fence_manager_takedown(struct drm_device *dev) ++{ ++} ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_fops.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_fops.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_fops.c 2009-04-26 02:52:17.139975280 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_fops.c 2009-04-26 02:55:13.231976636 +0200 +@@ -478,6 +478,10 @@ + } + mutex_unlock(&dev->ctxlist_mutex); + ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_fb_release(file_priv); ++ + mutex_lock(&dev->struct_mutex); + + if (file_priv->is_master) { +@@ -511,6 +515,7 @@ + /* drop the reference held my the file priv */ + drm_master_put(&file_priv->master); + file_priv->is_master = 0; ++ + list_del(&file_priv->lhead); + mutex_unlock(&dev->struct_mutex); + +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_info.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_info.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_info.c 2009-04-26 02:52:17.141975705 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_info.c 2009-04-26 02:55:19.461724709 +0200 +@@ -35,6 +35,7 @@ + + #include + #include "drmP.h" ++#include "drm_page_alloc.h" + + /** + * Called when "/proc/dri/.../name" is read. +@@ -273,6 +274,13 @@ + return 0; + } + ++int drm_page_alloc_info(struct seq_file *m, void *data) ++{ ++ seq_printf(m, "Cached: %d/%d\n", drm_page_alloc_data.cached_pages_in_list, drm_page_alloc_data.total_cached_pages); ++ seq_printf(m, "Uncached: %d/%d\n", drm_page_alloc_data.uncached_pages_in_list, drm_page_alloc_data.total_uncached_pages); ++ return 0; ++} ++ + #if DRM_DEBUG_CODE + + int drm_vma_info(struct seq_file *m, void *data) +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_memory.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_memory.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_memory.c 2009-04-26 02:52:17.143975361 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_memory.c 2009-04-26 02:55:23.293976435 +0200 +@@ -36,6 +36,112 @@ + #include + #include "drmP.h" + ++ ++static struct { ++ spinlock_t lock; ++ uint64_t cur_used; ++ uint64_t emer_used; ++ uint64_t low_threshold; ++ uint64_t high_threshold; ++ uint64_t emer_threshold; ++} drm_memctl = { ++ .lock = SPIN_LOCK_UNLOCKED ++}; ++ ++static inline size_t drm_size_align(size_t size) ++{ ++ size_t tmpSize = 4; ++ if (size > PAGE_SIZE) ++ return PAGE_ALIGN(size); ++ ++ while (tmpSize < size) ++ tmpSize <<= 1; ++ ++ return (size_t) tmpSize; ++} ++ ++int drm_alloc_memctl(size_t size) ++{ ++ int ret = 0; ++ unsigned long a_size = drm_size_align(size); ++ unsigned long new_used; ++ ++ spin_lock(&drm_memctl.lock); ++ new_used = drm_memctl.cur_used + a_size; ++ if (likely(new_used < drm_memctl.high_threshold)) { ++ drm_memctl.cur_used = new_used; ++ goto out; ++ } ++ ++ /* ++ * Allow small allocations from root-only processes to ++ * succeed until the emergency threshold is reached. ++ */ ++ ++ new_used += drm_memctl.emer_used; ++ if (unlikely(!DRM_SUSER(DRM_CURPROC) || ++ (a_size > 16*PAGE_SIZE) || ++ (new_used > drm_memctl.emer_threshold))) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ drm_memctl.cur_used = drm_memctl.high_threshold; ++ drm_memctl.emer_used = new_used - drm_memctl.high_threshold; ++out: ++ spin_unlock(&drm_memctl.lock); ++ return ret; ++} ++EXPORT_SYMBOL(drm_alloc_memctl); ++ ++ ++void drm_free_memctl(size_t size) ++{ ++ unsigned long a_size = drm_size_align(size); ++ ++ spin_lock(&drm_memctl.lock); ++ if (likely(a_size >= drm_memctl.emer_used)) { ++ a_size -= drm_memctl.emer_used; ++ drm_memctl.emer_used = 0; ++ } else { ++ drm_memctl.emer_used -= a_size; ++ a_size = 0; ++ } ++ drm_memctl.cur_used -= a_size; ++ spin_unlock(&drm_memctl.lock); ++} ++EXPORT_SYMBOL(drm_free_memctl); ++ ++void drm_query_memctl(uint64_t *cur_used, ++ uint64_t *emer_used, ++ uint64_t *low_threshold, ++ uint64_t *high_threshold, ++ uint64_t *emer_threshold) ++{ ++ spin_lock(&drm_memctl.lock); ++ *cur_used = drm_memctl.cur_used; ++ *emer_used = drm_memctl.emer_used; ++ *low_threshold = drm_memctl.low_threshold; ++ *high_threshold = drm_memctl.high_threshold; ++ *emer_threshold = drm_memctl.emer_threshold; ++ spin_unlock(&drm_memctl.lock); ++} ++EXPORT_SYMBOL(drm_query_memctl); ++ ++void drm_init_memctl(size_t p_low_threshold, ++ size_t p_high_threshold, ++ size_t unit_size) ++{ ++ spin_lock(&drm_memctl.lock); ++ drm_memctl.emer_used = 0; ++ drm_memctl.cur_used = 0; ++ drm_memctl.low_threshold = p_low_threshold * unit_size; ++ drm_memctl.high_threshold = p_high_threshold * unit_size; ++ drm_memctl.emer_threshold = (drm_memctl.high_threshold >> 4) + ++ drm_memctl.high_threshold; ++ spin_unlock(&drm_memctl.lock); ++} ++ + #ifdef DEBUG_MEMORY + #include "drm_memory_debug.h" + #else +@@ -77,6 +183,7 @@ + } + return pt; + } ++EXPORT_SYMBOL(drm_realloc); + + #if __OS_HAS_AGP + static void *agp_remap(unsigned long offset, unsigned long size, +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_page_alloc.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_page_alloc.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_page_alloc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_page_alloc.c 2009-04-26 02:59:03.682726808 +0200 +@@ -0,0 +1,171 @@ ++/* ++ * Copyright (c) Red Hat Inc. ++ ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sub license, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ */ ++ ++/* simple list based uncached page allocator ++ * - Add chunks of 1MB to the allocator at a time. ++ * - Use page->lru to keep a free list ++ * - doesn't track currently in use pages ++ * ++ * TODO: Add shrinker support ++ */ ++ ++#include "drmP.h" ++#include ++ ++#include "drm_page_alloc.h" ++ ++static struct list_head uncached_free_list; ++static struct list_head cached_free_list; ++ ++static struct mutex page_alloc_mutex; ++static int page_alloc_inited; ++ ++struct drm_page_alloc_usage drm_page_alloc_data; ++ ++/* add 1MB at a time */ ++#define NUM_PAGES_TO_ADD 256 ++ ++static inline void drm_page_put(struct page *page, int cached) ++{ ++ if (!cached) ++ unmap_page_from_agp(page); ++ put_page(page); ++ __free_page(page); ++} ++ ++int drm_add_pages_locked(int num_pages, int cached) ++{ ++ struct page *page; ++ int i; ++ ++ DRM_DEBUG("adding %scached memory %ld\n", cached ? "" : "un", ++ num_pages * PAGE_SIZE); ++ ++ for (i = 0; i < num_pages; i++) { ++ ++ page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32); ++ if (!page) { ++ DRM_ERROR("unable to get page %d\n", i); ++ return i; ++ } ++ ++ get_page(page); ++ if (!cached) { ++#ifdef CONFIG_X86 ++ set_memory_wc((unsigned long)page_address(page), 1); ++#else ++ map_page_into_agp(page); ++#endif ++ list_add(&page->lru, &uncached_free_list); ++ drm_page_alloc_data.total_uncached_pages++; ++ drm_page_alloc_data.uncached_pages_in_list++; ++ } else { ++ list_add(&page->lru, &cached_free_list); ++ drm_page_alloc_data.total_cached_pages++; ++ drm_page_alloc_data.cached_pages_in_list++; ++ } ++ } ++ return i; ++} ++ ++struct page *drm_get_page(int cached) ++{ ++ struct page *page = NULL; ++ int ret; ++ struct list_head *free_list; ++ ++ free_list = cached ? &cached_free_list : &uncached_free_list; ++ ++ mutex_lock(&page_alloc_mutex); ++ if (list_empty(free_list)) { ++ ret = drm_add_pages_locked(NUM_PAGES_TO_ADD, cached); ++ if (ret == 0) ++ return NULL; ++ } ++ ++ page = list_first_entry(free_list, struct page, lru); ++ list_del(&page->lru); ++ if (cached) ++ drm_page_alloc_data.cached_pages_in_list--; ++ else ++ drm_page_alloc_data.uncached_pages_in_list--; ++ ++ mutex_unlock(&page_alloc_mutex); ++ return page; ++} ++ ++void drm_put_page(struct page *page, int cached) ++{ ++ mutex_lock(&page_alloc_mutex); ++ if (cached) { ++ drm_page_alloc_data.cached_pages_in_list++; ++ list_add(&page->lru, &cached_free_list); ++ } else { ++ drm_page_alloc_data.uncached_pages_in_list++; ++ list_add(&page->lru, &uncached_free_list); ++ } ++ mutex_unlock(&page_alloc_mutex); ++} ++ ++void drm_release_all_pages(int cached) ++{ ++ struct page *page, *tmp; ++ struct list_head *free_list; ++ ++ free_list = cached ? &cached_free_list : &uncached_free_list; ++ ++ list_for_each_entry_safe(page, tmp, free_list, lru) { ++ list_del(&page->lru); ++ drm_page_put(page, cached); ++ } ++ drm_page_alloc_data.total_cached_pages = 0; ++ drm_page_alloc_data.total_uncached_pages = 0; ++} ++ ++int drm_page_alloc_init(void) ++{ ++ ++ if (page_alloc_inited) ++ return 0; ++ ++ INIT_LIST_HEAD(&uncached_free_list); ++ INIT_LIST_HEAD(&cached_free_list); ++ ++ mutex_init(&page_alloc_mutex); ++ page_alloc_inited = 1; ++ return 0; ++ ++} ++ ++void drm_page_alloc_fini(void) ++{ ++ if (!page_alloc_inited) ++ return; ++ ++ page_alloc_inited = 0; ++ drm_release_all_pages(0); ++ drm_release_all_pages(1); ++} ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_page_alloc.h linux-2.6.29.1.patch/drivers/gpu/drm/drm_page_alloc.h +--- linux-2.6.29.1/drivers/gpu/drm/drm_page_alloc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_page_alloc.h 2009-04-26 02:59:06.522725339 +0200 +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (c) Red Hat Inc. ++ ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sub license, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ */ ++ ++struct drm_page_alloc_usage { ++ int total_uncached_pages; ++ int total_cached_pages; ++ int cached_pages_in_list; ++ int uncached_pages_in_list; ++}; ++ ++extern struct drm_page_alloc_usage drm_page_alloc_data; +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_stub.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_stub.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_stub.c 2009-04-26 02:52:17.146975474 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_stub.c 2009-04-26 02:55:28.757725673 +0200 +@@ -102,6 +102,7 @@ + drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER); + INIT_LIST_HEAD(&master->magicfree); + master->minor = minor; ++ master->lock.hw_lock = &minor->dev->default_lock; + + list_add_tail(&master->head, &minor->master_list); + +@@ -178,7 +179,7 @@ + int drm_dropmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { +- if (!file_priv->master) ++ if (!file_priv->minor->master) + return -EINVAL; + mutex_lock(&dev->struct_mutex); + drm_master_put(&file_priv->minor->master); +@@ -202,6 +203,7 @@ + init_timer(&dev->timer); + mutex_init(&dev->struct_mutex); + mutex_init(&dev->ctxlist_mutex); ++ mutex_init(&dev->bm.evict_mutex); + + idr_init(&dev->drw_idr); + +@@ -213,7 +215,12 @@ + dev->hose = pdev->sysdata; + #endif + +- if (drm_ht_create(&dev->map_hash, 12)) { ++ if (drm_ht_create(&dev->map_hash, DRM_MAP_HASH_ORDER)) { ++ return -ENOMEM; ++ } ++ if (drm_mm_init(&dev->offset_manager, DRM_FILE_PAGE_OFFSET_START, ++ DRM_FILE_PAGE_OFFSET_SIZE)) { ++ drm_ht_remove(&dev->map_hash); + return -ENOMEM; + } + +@@ -246,7 +253,6 @@ + } + } + +- + retcode = drm_ctxbitmap_init(dev); + if (retcode) { + DRM_ERROR("Cannot allocate memory for context bitmap.\n"); +@@ -262,6 +268,13 @@ + } + } + ++ /* ++ * Set up default lock for DRI2, which doesn't need a lock. ++ * User space will override this in the legacy DRI case. ++ */ ++ dev->sigdata.lock = &dev->default_lock; ++ ++ drm_fence_manager_init(dev); + return 0; + + error_out_unreg: +@@ -451,6 +464,7 @@ + *minor_p = NULL; + return 0; + } ++EXPORT_SYMBOL(drm_put_minor); + + /** + * Called via drm_exit() at module unload time or when pci device is +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_ttm.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_ttm.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_ttm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_ttm.c 2009-04-26 02:59:16.705974931 +0200 +@@ -0,0 +1,469 @@ ++/************************************************************************** ++ * ++ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ **************************************************************************/ ++/* ++ * Authors: Thomas Hellström ++ */ ++ ++#include "drmP.h" ++#include ++ ++/** ++ * Allocates storage for pointers to the pages that back the ttm. ++ * ++ * Uses kmalloc if possible. Otherwise falls back to vmalloc. ++ */ ++static void drm_ttm_alloc_page_directory(struct drm_ttm *ttm) ++{ ++ unsigned long size = ttm->num_pages * sizeof(*ttm->pages); ++ ttm->pages = NULL; ++ ++ if (drm_alloc_memctl(size)) ++ return; ++ ++ if (size <= PAGE_SIZE) ++ ttm->pages = drm_calloc(1, size, DRM_MEM_TTM); ++ ++ if (!ttm->pages) { ++ ttm->pages = vmalloc_user(size); ++ if (ttm->pages) ++ ttm->page_flags |= DRM_TTM_PAGEDIR_VMALLOC; ++ } ++ if (!ttm->pages) ++ drm_free_memctl(size); ++} ++ ++static void drm_ttm_free_page_directory(struct drm_ttm *ttm) ++{ ++ unsigned long size = ttm->num_pages * sizeof(*ttm->pages); ++ ++ if (ttm->page_flags & DRM_TTM_PAGEDIR_VMALLOC) { ++ vfree(ttm->pages); ++ ttm->page_flags &= ~DRM_TTM_PAGEDIR_VMALLOC; ++ } else { ++ drm_free(ttm->pages, size, DRM_MEM_TTM); ++ } ++ drm_free_memctl(size); ++ ttm->pages = NULL; ++} ++ ++static struct page *drm_ttm_alloc_page(struct drm_ttm *ttm, int cached) ++{ ++ struct page *page; ++ ++ if (drm_alloc_memctl(PAGE_SIZE)) ++ return NULL; ++ ++ page = drm_get_page(cached); ++ if (!page) { ++ drm_free_memctl(PAGE_SIZE); ++ return NULL; ++ } ++ return page; ++} ++ ++/* ++ * Change caching policy for the linear kernel map ++ * for range of pages in a ttm. ++ */ ++static int drm_ttm_set_caching(struct drm_ttm *ttm, int noncached) ++{ ++ int i; ++ struct page **cur_page; ++ ++ if ((ttm->page_flags & DRM_TTM_PAGE_UNCACHED) == noncached) ++ return 0; ++ ++ if (noncached) ++ drm_clflush_pages(ttm->pages, ttm->num_pages); ++ ++ for (i = 0; i < ttm->num_pages; ++i) { ++ cur_page = ttm->pages + i; ++ if (*cur_page) { ++ if (!PageHighMem(*cur_page)) { ++ if (noncached) { ++#ifdef CONFIG_X86 ++ set_memory_wc((unsigned long)page_address(*cur_page), 1); ++#else ++ map_page_into_agp(*cur_page); ++#endif ++ } else { ++ unmap_page_from_agp(*cur_page); ++ } ++ } ++ } ++ } ++ ++ DRM_FLAG_MASKED(ttm->page_flags, noncached, DRM_TTM_PAGE_UNCACHED); ++ ++ return 0; ++} ++ ++ ++static void drm_ttm_free_user_pages(struct drm_ttm *ttm) ++{ ++ int write; ++ int dirty; ++ struct page *page; ++ int i; ++ ++ BUG_ON(!(ttm->page_flags & DRM_TTM_PAGE_USER)); ++ write = ((ttm->page_flags & DRM_TTM_PAGE_WRITE) != 0); ++ dirty = ((ttm->page_flags & DRM_TTM_PAGE_USER_DIRTY) != 0); ++ ++ for (i = 0; i < ttm->num_pages; ++i) { ++ page = ttm->pages[i]; ++ if (page == NULL) ++ continue; ++ ++ if (page == ttm->dummy_read_page) { ++ BUG_ON(write); ++ continue; ++ } ++ ++ if (write && dirty && !PageReserved(page)) ++ set_page_dirty_lock(page); ++ ++ ttm->pages[i] = NULL; ++ put_page(page); ++ } ++} ++ ++static void drm_ttm_free_alloced_pages(struct drm_ttm *ttm) ++{ ++ int i; ++ struct drm_buffer_manager *bm = &ttm->dev->bm; ++ struct page **cur_page; ++ int cached = !(ttm->page_flags & DRM_TTM_PAGE_UNCACHED); ++ ++ for (i = 0; i < ttm->num_pages; ++i) { ++ cur_page = ttm->pages + i; ++ if (*cur_page) { ++ drm_put_page(*cur_page, cached); ++ drm_free_memctl(PAGE_SIZE); ++ --bm->cur_pages; ++ } ++ } ++} ++ ++/* ++ * Free all resources associated with a ttm. ++ */ ++ ++int drm_ttm_destroy(struct drm_ttm *ttm) ++{ ++ struct drm_ttm_backend *be; ++ ++ if (!ttm) ++ return 0; ++ ++ be = ttm->be; ++ if (be) { ++ be->func->destroy(be); ++ ttm->be = NULL; ++ } ++ ++ if (ttm->pages) { ++ if (ttm->page_flags & DRM_TTM_PAGE_USER) { ++ if (ttm->page_flags & DRM_TTM_PAGE_UNCACHED) ++ drm_ttm_set_caching(ttm, 0); ++ ++ drm_ttm_free_user_pages(ttm); ++ } else ++ drm_ttm_free_alloced_pages(ttm); ++ ++ drm_ttm_free_page_directory(ttm); ++ } ++ ++ drm_ctl_free(ttm, sizeof(*ttm), DRM_MEM_TTM); ++ return 0; ++} ++ ++struct page *drm_ttm_get_page(struct drm_ttm *ttm, int index) ++{ ++ struct page *p; ++ struct drm_buffer_manager *bm = &ttm->dev->bm; ++ int cached = !(ttm->page_flags & DRM_TTM_PAGE_UNCACHED); ++ ++ while(NULL == (p = ttm->pages[index])) { ++ if (cached) ++ ttm->page_flags |= DRM_TTM_PAGE_ALLOC_CACHED; ++ ++ p = drm_ttm_alloc_page(ttm, cached); ++ if (!p) ++ return NULL; ++ ++ if (PageHighMem(p)) ++ ttm->pages[--ttm->first_himem_page] = p; ++ else ++ ttm->pages[++ttm->last_lomem_page] = p; ++ ++ ++bm->cur_pages; ++ } ++ return p; ++} ++EXPORT_SYMBOL(drm_ttm_get_page); ++ ++/** ++ * drm_ttm_set_user: ++ * ++ * @ttm: the ttm to map pages to. This must always be ++ * a freshly created ttm. ++ * ++ * @tsk: a pointer to the address space from which to map ++ * pages. ++ * ++ * @write: a boolean indicating that write access is desired ++ * ++ * start: the starting address ++ * ++ * Map a range of user addresses to a new ttm object. This ++ * provides access to user memory from the graphics device. ++ */ ++int drm_ttm_set_user(struct drm_ttm *ttm, ++ struct task_struct *tsk, ++ unsigned long start, ++ unsigned long num_pages) ++{ ++ struct mm_struct *mm = tsk->mm; ++ int ret; ++ int write = (ttm->page_flags & DRM_TTM_PAGE_WRITE) != 0; ++ ++ BUG_ON(num_pages != ttm->num_pages); ++ BUG_ON((ttm->page_flags & DRM_TTM_PAGE_USER) == 0); ++ ++ down_read(&mm->mmap_sem); ++ ret = get_user_pages(tsk, mm, start, num_pages, ++ write, 0, ttm->pages, NULL); ++ up_read(&mm->mmap_sem); ++ ++ if (ret != num_pages && write) { ++ drm_ttm_free_user_pages(ttm); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++/** ++ * drm_ttm_populate: ++ * ++ * @ttm: the object to allocate pages for ++ * ++ * Allocate pages for all unset page entries, then ++ * call the backend to create the hardware mappings ++ */ ++int drm_ttm_populate(struct drm_ttm *ttm, int cached) ++{ ++ struct page *page; ++ unsigned long i; ++ struct drm_ttm_backend *be; ++ ++ if (ttm->state != ttm_unpopulated) ++ return 0; ++ ++ be = ttm->be; ++ ++ /* set page flags */ ++ if (cached) ++ ttm->page_flags &= ~DRM_TTM_PAGE_UNCACHED; ++ else ++ ttm->page_flags |= DRM_TTM_PAGE_UNCACHED; ++ ++ for (i = 0; i < ttm->num_pages; ++i) { ++ page = drm_ttm_get_page(ttm, i); ++ if (!page) ++ return -ENOMEM; ++ } ++ ++ be->func->populate(be, ttm->num_pages, ttm->pages, ttm->dummy_read_page); ++ ttm->state = ttm_unbound; ++ return 0; ++} ++ ++/** ++ * drm_ttm_create: ++ * ++ * @dev: the drm_device ++ * ++ * @size: The size (in bytes) of the desired object ++ * ++ * @page_flags: various DRM_TTM_PAGE_* flags. See drm_object.h. ++ * ++ * Allocate and initialize a ttm, leaving it unpopulated at this time ++ */ ++ ++struct drm_ttm *drm_ttm_create(struct drm_device *dev, unsigned long size, ++ uint32_t page_flags, struct page *dummy_read_page) ++{ ++ struct drm_bo_driver *bo_driver = dev->driver->bo_driver; ++ struct drm_ttm *ttm; ++ ++ if (!bo_driver) ++ return NULL; ++ ++ ttm = drm_ctl_calloc(1, sizeof(*ttm), DRM_MEM_TTM); ++ if (!ttm) ++ return NULL; ++ ++ ttm->dev = dev; ++ atomic_set(&ttm->vma_count, 0); ++ ++ ttm->destroy = 0; ++ ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ ttm->first_himem_page = ttm->num_pages; ++ ttm->last_lomem_page = -1; ++ ++ ttm->page_flags = page_flags; ++ ++ ttm->dummy_read_page = dummy_read_page; ++ ++ /* ++ * Account also for AGP module memory usage. ++ */ ++ ++ drm_ttm_alloc_page_directory(ttm); ++ if (!ttm->pages) { ++ drm_ttm_destroy(ttm); ++ DRM_ERROR("Failed allocating page table\n"); ++ return NULL; ++ } ++ ttm->be = bo_driver->create_ttm_backend_entry(dev); ++ if (!ttm->be) { ++ drm_ttm_destroy(ttm); ++ DRM_ERROR("Failed creating ttm backend entry\n"); ++ return NULL; ++ } ++ ttm->state = ttm_unpopulated; ++ return ttm; ++} ++ ++/** ++ * drm_ttm_evict: ++ * ++ * @ttm: the object to be unbound from the aperture. ++ * ++ * Transition a ttm from bound to evicted, where it ++ * isn't present in the aperture, but various caches may ++ * not be consistent. ++ */ ++void drm_ttm_evict(struct drm_ttm *ttm) ++{ ++ struct drm_ttm_backend *be = ttm->be; ++ int ret; ++ ++ if (ttm->state == ttm_bound) { ++ ret = be->func->unbind(be); ++ BUG_ON(ret); ++ } ++ ++ ttm->state = ttm_evicted; ++} ++ ++/** ++ * drm_ttm_fixup_caching: ++ * ++ * @ttm: the object to set unbound ++ * ++ * XXX this function is misnamed. Transition a ttm from evicted to ++ * unbound, flushing caches as appropriate. ++ */ ++void drm_ttm_fixup_caching(struct drm_ttm *ttm) ++{ ++ if (ttm->state == ttm_evicted) { ++ struct drm_ttm_backend *be = ttm->be; ++ if (be->func->needs_ub_cache_adjust(be)) ++ if (ttm->page_flags & DRM_TTM_PAGE_ALLOC_CACHED) ++ drm_ttm_set_caching(ttm, 0); ++ ttm->state = ttm_unbound; ++ } ++} ++ ++/** ++ * drm_ttm_unbind: ++ * ++ * @ttm: the object to unbind from the graphics device ++ * ++ * Unbind an object from the aperture. This removes the mappings ++ * from the graphics device and flushes caches if necessary. ++ */ ++void drm_ttm_unbind(struct drm_ttm *ttm) ++{ ++ if (ttm->state == ttm_bound) ++ drm_ttm_evict(ttm); ++ ++ drm_ttm_fixup_caching(ttm); ++} ++ ++/** ++ * drm_ttm_bind: ++ * ++ * @ttm: the ttm object to bind to the graphics device ++ * ++ * @bo_mem: the aperture memory region which will hold the object ++ * ++ * Bind a ttm object to the aperture. This ensures that the necessary ++ * pages are allocated, flushes CPU caches as needed and marks the ++ * ttm as DRM_TTM_PAGE_USER_DIRTY to indicate that it may have been ++ * modified by the GPU ++ */ ++int drm_ttm_bind(struct drm_ttm *ttm, struct drm_bo_mem_reg *bo_mem) ++{ ++ struct drm_bo_driver *bo_driver = ttm->dev->driver->bo_driver; ++ int ret = 0; ++ struct drm_ttm_backend *be; ++ int cached = (bo_mem->flags & DRM_BO_FLAG_CACHED); ++ ++ if (!ttm) ++ return -EINVAL; ++ if (ttm->state == ttm_bound) ++ return 0; ++ ++ be = ttm->be; ++ ++ if ((ttm->state == ttm_unbound || ttm->state == ttm_unpopulated) && !cached) ++ drm_ttm_set_caching(ttm, DRM_TTM_PAGE_UNCACHED); ++ else if ((bo_mem->flags & DRM_BO_FLAG_CACHED_MAPPED) && ++ bo_driver->ttm_cache_flush) ++ bo_driver->ttm_cache_flush(ttm); ++ ++ ret = drm_ttm_populate(ttm, cached); ++ if (ret) ++ return ret; ++ ++ ret = be->func->bind(be, bo_mem); ++ if (ret) { ++ ttm->state = ttm_evicted; ++ DRM_ERROR("Couldn't bind backend.\n"); ++ return ret; ++ } ++ ++ ttm->state = ttm_bound; ++ if (ttm->page_flags & DRM_TTM_PAGE_USER) ++ ttm->page_flags |= DRM_TTM_PAGE_USER_DIRTY; ++ return 0; ++} ++EXPORT_SYMBOL(drm_ttm_bind); +diff -Naur linux-2.6.29.1/drivers/gpu/drm/drm_vm.c linux-2.6.29.1.patch/drivers/gpu/drm/drm_vm.c +--- linux-2.6.29.1/drivers/gpu/drm/drm_vm.c 2009-04-26 02:52:17.150975346 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/drm_vm.c 2009-04-26 02:55:34.898731104 +0200 +@@ -37,9 +37,15 @@ + #if defined(__ia64__) + #include + #endif ++#if defined(CONFIG_X86) ++#include ++#endif + + static void drm_vm_open(struct vm_area_struct *vma); + static void drm_vm_close(struct vm_area_struct *vma); ++static int drm_bo_mmap_locked(struct vm_area_struct *vma, ++ struct file *filp, ++ drm_local_map_t *map); + + static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) + { +@@ -49,6 +55,14 @@ + if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) { + pgprot_val(tmp) |= _PAGE_PCD; + pgprot_val(tmp) &= ~_PAGE_PWT; ++#if defined(CONFIG_X86_PAT) ++ /* if PAT is enabled and we are mapping a ++ TTM mapping */ ++ if (map_type == _DRM_TTM && pat_enabled) { ++ pgprot_val(tmp) &= ~_PAGE_PCD; ++ pgprot_val(tmp) |= _PAGE_PWT; ++ } ++#endif + } + #elif defined(__powerpc__) + pgprot_val(tmp) |= _PAGE_NO_CACHE; +@@ -272,6 +286,9 @@ + case _DRM_GEM: + DRM_ERROR("tried to rmmap GEM object\n"); + break; ++ case _DRM_TTM: ++ BUG_ON(1); ++ break; + } + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + } +@@ -396,6 +413,8 @@ + .close = drm_vm_close, + }; + ++ ++ + /** + * \c open method for shared virtual memory. + * +@@ -422,6 +441,7 @@ + } + } + ++ + static void drm_vm_open(struct vm_area_struct *vma) + { + struct drm_file *priv = vma->vm_file->private_data; +@@ -572,7 +592,7 @@ + return drm_mmap_dma(filp, vma); + + if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) { +- DRM_ERROR("Could not find map\n"); ++ DRM_ERROR("Could not find map %08x\n", vma->vm_pgoff); + return -EINVAL; + } + +@@ -652,6 +672,8 @@ + vma->vm_flags |= VM_RESERVED; + vma->vm_page_prot = drm_dma_prot(map->type, vma); + break; ++ case _DRM_TTM: ++ return drm_bo_mmap_locked(vma, filp, map); + default: + return -EINVAL; /* This should never happen. */ + } +@@ -676,3 +698,187 @@ + return ret; + } + EXPORT_SYMBOL(drm_mmap); ++ ++static int drm_bo_vm_fault(struct vm_area_struct *vma, ++ struct vm_fault *vmf) ++{ ++ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data; ++ unsigned long page_offset; ++ struct page *page = NULL; ++ struct drm_ttm *ttm; ++ struct drm_device *dev; ++ unsigned long pfn; ++ int err; ++ unsigned long bus_base; ++ unsigned long bus_offset; ++ unsigned long bus_size; ++ unsigned long ret = VM_FAULT_NOPAGE; ++ unsigned long address = (unsigned long)vmf->virtual_address; ++ unsigned long page_last; ++ bool is_iomem; ++ int i; ++ ++ dev = bo->dev; ++ err = mutex_lock_interruptible(&bo->mutex); ++ if (err) { ++ return VM_FAULT_NOPAGE; ++ } ++ ++ err = drm_bo_wait(bo, 0, 1, 0, 1); ++ if (err) { ++ ret = (err != -EAGAIN) ? VM_FAULT_SIGBUS : VM_FAULT_NOPAGE; ++ bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED; ++ goto out_unlock; ++ } ++ ++ bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED; ++ ++ /* ++ * If buffer happens to be in a non-mappable location, ++ * move it to a mappable. ++ */ ++ ++ if (!(bo->mem.flags & DRM_BO_FLAG_MAPPABLE)) { ++ uint32_t new_flags = bo->mem.proposed_flags | ++ DRM_BO_FLAG_MAPPABLE | ++ DRM_BO_FLAG_FORCE_MAPPABLE; ++ err = drm_bo_move_buffer(bo, new_flags, 0, 0); ++ if (err) { ++ ret = (err != -EAGAIN) ? VM_FAULT_SIGBUS : VM_FAULT_NOPAGE; ++ goto out_unlock; ++ } ++ } ++ ++ err = drm_bo_pci_offset(dev, &bo->mem, &bus_base, &bus_offset, ++ &bus_size); ++ ++ if (err) { ++ ret = VM_FAULT_SIGBUS; ++ goto out_unlock; ++ } ++ ++ is_iomem = (bus_size != 0); ++ page_offset = (address - vma->vm_start) >> PAGE_SHIFT; ++ page_last = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; ++ ++ if (is_iomem) { ++ struct drm_mem_type_manager *man = &dev->bm.man[bo->mem.mem_type]; ++ vma->vm_page_prot = drm_io_prot(man->drm_bus_maptype, vma); ++ } else { ++ ttm = bo->ttm; ++ drm_ttm_fixup_caching(ttm); ++ vma->vm_page_prot = (bo->mem.flags & DRM_BO_FLAG_CACHED) ? ++ vm_get_page_prot(vma->vm_flags) : ++ drm_io_prot(_DRM_TTM, vma); ++ } ++#define TTM_BO_VM_NUM_PREFAULT 16 ++ for (i = 0; i < TTM_BO_VM_NUM_PREFAULT; i++) { ++ if (is_iomem) ++ pfn = ((bus_base + bus_offset) >> PAGE_SHIFT) + page_offset; ++ else { ++ ttm = bo->ttm; ++ page = drm_ttm_get_page(ttm, page_offset); ++ if (!page && i == 0) { ++ ret = VM_FAULT_OOM; ++ goto out_unlock; ++ } else if (!page) { ++ break; ++ } ++ pfn = page_to_pfn(page); ++ } ++ ++ err = vm_insert_mixed(vma, address, pfn); ++ if ((err == -EBUSY) || (err != 0 && i > 0)) ++ break; ++ else if (err != 0) { ++ ret = (err != -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS; ++ goto out_unlock; ++ } ++ address += PAGE_SIZE; ++ if (++page_offset >= page_last) ++ break; ++ } ++out_unlock: ++ BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED); ++ mutex_unlock(&bo->mutex); ++ return ret; ++} ++ ++static void drm_bo_vm_open_locked(struct vm_area_struct *vma) ++{ ++ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data; ++ ++ /* clear the clean flags */ ++ bo->mem.flags &= ~DRM_BO_FLAG_CLEAN; ++ bo->mem.proposed_flags &= ~DRM_BO_FLAG_CLEAN; ++ ++ drm_vm_open_locked(vma); ++ atomic_inc(&bo->usage); ++} ++ ++/** ++ * \c vma open method for buffer objects. ++ * ++ * \param vma virtual memory area. ++ */ ++ ++static void drm_bo_vm_open(struct vm_area_struct *vma) ++{ ++ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data; ++ struct drm_device *dev = bo->dev; ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_bo_vm_open_locked(vma); ++ mutex_unlock(&dev->struct_mutex); ++} ++ ++/** ++ * \c vma close method for buffer objects. ++ * ++ * \param vma virtual memory area. ++ */ ++ ++static void drm_bo_vm_close(struct vm_area_struct *vma) ++{ ++ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data; ++ struct drm_device *dev = bo->dev; ++ ++ drm_vm_close(vma); ++ if (bo) { ++ mutex_lock(&dev->struct_mutex); ++ drm_bo_usage_deref_locked((struct drm_buffer_object **) ++ &vma->vm_private_data); ++ mutex_unlock(&dev->struct_mutex); ++ } ++ return; ++} ++ ++ ++static struct vm_operations_struct drm_bo_vm_ops = { ++ .fault = drm_bo_vm_fault, ++ .open = drm_bo_vm_open, ++ .close = drm_bo_vm_close, ++}; ++ ++ ++/** ++ * mmap buffer object memory. ++ * ++ * \param vma virtual memory area. ++ * \param file_priv DRM file private. ++ * \param map The buffer object drm map. ++ * \return zero on success or a negative number on failure. ++ */ ++ ++int drm_bo_mmap_locked(struct vm_area_struct *vma, ++ struct file *filp, ++ drm_local_map_t *map) ++{ ++ vma->vm_ops = &drm_bo_vm_ops; ++ vma->vm_private_data = map->handle; ++ vma->vm_file = filp; ++ vma->vm_flags |= VM_RESERVED | VM_IO; ++ vma->vm_flags |= VM_MIXEDMAP; ++ drm_bo_vm_open_locked(vma); ++ return 0; ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/i915/i915_irq.c linux-2.6.29.1.patch/drivers/gpu/drm/i915/i915_irq.c +--- linux-2.6.29.1/drivers/gpu/drm/i915/i915_irq.c 2009-04-26 02:52:17.187975277 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/i915/i915_irq.c 2009-04-26 02:55:48.101736147 +0200 +@@ -397,7 +397,8 @@ + return ret; + } + +-/* Needs the lock as it touches the ring. ++/* Needs the lock as it touches the ring, though if user space haven't ++ * set up a lock, we expect it to not touch the ring. + */ + int i915_irq_emit(struct drm_device *dev, void *data, + struct drm_file *file_priv) +diff -Naur linux-2.6.29.1/drivers/gpu/drm/i915/intel_display.c linux-2.6.29.1.patch/drivers/gpu/drm/i915/intel_display.c +--- linux-2.6.29.1/drivers/gpu/drm/i915/intel_display.c 2009-04-26 02:52:17.233725521 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/i915/intel_display.c 2009-04-26 02:55:52.239975900 +0200 +@@ -763,12 +763,18 @@ + if (!master_priv->sarea_priv) + return 0; + +- if (pipe) { +- master_priv->sarea_priv->pipeB_x = x; +- master_priv->sarea_priv->pipeB_y = y; +- } else { ++ switch (pipe) { ++ case 0: + master_priv->sarea_priv->pipeA_x = x; + master_priv->sarea_priv->pipeA_y = y; ++ break; ++ case 1: ++ master_priv->sarea_priv->pipeB_x = x; ++ master_priv->sarea_priv->pipeB_y = y; ++ break; ++ default: ++ DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); ++ break; + } + + return 0; +@@ -891,12 +897,12 @@ + + switch (pipe) { + case 0: +- master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0; +- master_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0; ++ master_priv->sarea_priv->planeA_w = enabled ? crtc->mode.hdisplay : 0; ++ master_priv->sarea_priv->planeA_h = enabled ? crtc->mode.vdisplay : 0; + break; + case 1: +- master_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0; +- master_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0; ++ master_priv->sarea_priv->planeB_w = enabled ? crtc->mode.hdisplay : 0; ++ master_priv->sarea_priv->planeB_h = enabled ? crtc->mode.vdisplay : 0; + break; + default: + DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); +@@ -1573,7 +1579,7 @@ + if (!crtc->enabled) { + if (!mode) + mode = &load_detect_mode; +- drm_crtc_helper_set_mode(crtc, mode, 0, 0, crtc->fb); ++ drm_crtc_helper_set_mode(crtc, mode, 0, 0, crtc->fb, 0); + } else { + if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) { + crtc_funcs = crtc->helper_private; +diff -Naur linux-2.6.29.1/drivers/gpu/drm/Kconfig linux-2.6.29.1.patch/drivers/gpu/drm/Kconfig +--- linux-2.6.29.1/drivers/gpu/drm/Kconfig 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/Kconfig 2009-04-26 02:55:56.924008549 +0200 +@@ -35,6 +35,9 @@ + + config DRM_RADEON + tristate "ATI Radeon" ++ select FB_CFB_FILLRECT ++ select FB_CFB_COPYAREA ++ select FB_CFB_IMAGEBLIT + depends on DRM && PCI + help + Choose this option if you have an ATI Radeon graphics card. There +@@ -43,6 +46,14 @@ + + If M is selected, the module will be called radeon. + ++config DRM_RADEON_KMS ++ bool "Enable modesetting on radeon by default" ++ depends on DRM_RADEON ++ help ++ Choose this option if you want kernel modesetting enabled by default, ++ and you have a new enough userspace to support this. Running old ++ userspaces with this enabled will cause pain. ++ + config DRM_I810 + tristate "Intel I810" + depends on DRM && AGP && AGP_INTEL +diff -Naur linux-2.6.29.1/drivers/gpu/drm/Makefile linux-2.6.29.1.patch/drivers/gpu/drm/Makefile +--- linux-2.6.29.1/drivers/gpu/drm/Makefile 2009-04-26 02:52:17.107975258 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/Makefile 2009-04-26 02:56:01.920983544 +0200 +@@ -11,7 +11,8 @@ + drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ + drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ + drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \ +- drm_info.o drm_debugfs.o ++ drm_info.o drm_debugfs.o \ ++ drm_fence.o drm_bo.o drm_ttm.o drm_bo_move.o drm_page_alloc.o + + drm-$(CONFIG_COMPAT) += drm_ioc32.o + +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/atombios_crtc.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atombios_crtc.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/atombios_crtc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atombios_crtc.c 2009-04-26 02:59:35.606976324 +0200 +@@ -0,0 +1,629 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++#include "drm_crtc_helper.h" ++#include "atom.h" ++#include "atom-bits.h" ++ ++#include "radeon_fixed.h" ++ ++static void atombios_lock_crtc(struct drm_crtc *crtc, int lock) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int index = GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters); ++ ENABLE_CRTC_PS_ALLOCATION args; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ args.ucCRTC = radeon_crtc->crtc_id; ++ args.ucEnable = lock; ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++} ++ ++static void atombios_enable_crtc(struct drm_crtc *crtc, int state) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC); ++ ENABLE_CRTC_PS_ALLOCATION args; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ args.ucCRTC = radeon_crtc->crtc_id; ++ args.ucEnable = state; ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++} ++ ++static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq); ++ ENABLE_CRTC_PS_ALLOCATION args; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ args.ucCRTC = radeon_crtc->crtc_id; ++ args.ucEnable = state; ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++} ++ ++static void atombios_blank_crtc(struct drm_crtc *crtc, int state) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC); ++ BLANK_CRTC_PS_ALLOCATION args; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ args.ucCRTC = radeon_crtc->crtc_id; ++ args.ucBlanking = state; ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++} ++ ++void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ ++ switch(mode) { ++ case DRM_MODE_DPMS_ON: ++ case DRM_MODE_DPMS_STANDBY: ++ case DRM_MODE_DPMS_SUSPEND: ++ if (radeon_is_dce3(dev_priv)) ++ atombios_enable_crtc_memreq(crtc, 1); ++ atombios_enable_crtc(crtc, 1); ++ atombios_blank_crtc(crtc, 0); ++ ++ radeon_crtc_load_lut(crtc); ++ break; ++ case DRM_MODE_DPMS_OFF: ++ atombios_blank_crtc(crtc, 1); ++ atombios_enable_crtc(crtc, 0); ++ if (radeon_is_dce3(dev_priv)) ++ atombios_enable_crtc_memreq(crtc, 0); ++ break; ++ } ++} ++ ++static void ++atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, SET_CRTC_USING_DTD_TIMING_PARAMETERS *crtc_param) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param; ++ int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); ++ ++ conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size); ++ conv_param.usH_Blanking_Time = cpu_to_le16(crtc_param->usH_Blanking_Time); ++ conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size); ++ conv_param.usV_Blanking_Time = cpu_to_le16(crtc_param->usV_Blanking_Time); ++ conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset); ++ conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); ++ conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset); ++ conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); ++ conv_param.susModeMiscInfo.usAccess = cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); ++ conv_param.ucCRTC = crtc_param->ucCRTC; ++ ++ printk("executing set crtc dtd timing\n"); ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&conv_param); ++} ++ ++void atombios_crtc_set_timing(struct drm_crtc *crtc, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_param) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param; ++ int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); ++ ++ conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total); ++ conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp); ++ conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart); ++ conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); ++ conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total); ++ conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp); ++ conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart); ++ conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); ++ conv_param.susModeMiscInfo.usAccess = cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); ++ conv_param.ucCRTC = crtc_param->ucCRTC; ++ conv_param.ucOverscanRight = crtc_param->ucOverscanRight; ++ conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft; ++ conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom; ++ conv_param.ucOverscanTop = crtc_param->ucOverscanTop; ++ conv_param.ucReserved = crtc_param->ucReserved; ++ ++ printk("executing set crtc timing\n"); ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&conv_param); ++} ++ ++void ++atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_encoder *encoder = NULL; ++ struct radeon_encoder *radeon_encoder = NULL; ++ uint8_t frev, crev; ++ int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); ++ SET_PIXEL_CLOCK_PS_ALLOCATION args; ++ PIXEL_CLOCK_PARAMETERS *spc1_ptr; ++ PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; ++ PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; ++ uint32_t sclock = mode->clock; ++ uint32_t ref_div = 0, fb_div = 0, post_div = 0; ++ struct radeon_pll *pll; ++ int pll_flags = 0; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ if (radeon_is_avivo(dev_priv)) { ++ uint32_t ss_cntl; ++ ++ if (radeon_is_dce32(dev_priv) && mode->clock > 200000) /* range limits??? */ ++ pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; ++ else ++ pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; ++ ++ /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */ ++ if (radeon_crtc->crtc_id == 0) { ++ ss_cntl = RADEON_READ(AVIVO_P1PLL_INT_SS_CNTL); ++ RADEON_WRITE(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1); ++ } else { ++ ss_cntl = RADEON_READ(AVIVO_P2PLL_INT_SS_CNTL); ++ RADEON_WRITE(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1); ++ } ++ } else { ++ pll_flags |= RADEON_PLL_LEGACY; ++ ++ if (mode->clock > 200000) /* range limits??? */ ++ pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; ++ else ++ pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; ++ ++ } ++ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ if (encoder->crtc == crtc) { ++ if (!radeon_is_avivo(dev_priv)) { ++ if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) ++ pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; ++ if (!radeon_is_avivo(dev_priv) && (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)) ++ pll_flags |= RADEON_PLL_USE_REF_DIV; ++ } ++ radeon_encoder = to_radeon_encoder(encoder); ++ } ++ } ++ ++ if (radeon_crtc->crtc_id == 0) ++ pll = &dev_priv->mode_info.p1pll; ++ else ++ pll = &dev_priv->mode_info.p2pll; ++ ++ radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &ref_div, &post_div, pll_flags); ++ ++ atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev); ++ ++ switch(frev) { ++ case 1: ++ switch(crev) { ++ case 1: ++ spc1_ptr = (PIXEL_CLOCK_PARAMETERS *)&args.sPCLKInput; ++ spc1_ptr->usPixelClock = cpu_to_le16(sclock); ++ spc1_ptr->usRefDiv = cpu_to_le16(ref_div); ++ spc1_ptr->usFbDiv = cpu_to_le16(fb_div); ++ spc1_ptr->ucPostDiv = post_div; ++ spc1_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; ++ spc1_ptr->ucCRTC = radeon_crtc->crtc_id; ++ spc1_ptr->ucRefDivSrc = 1; ++ break; ++ case 2: ++ spc2_ptr = (PIXEL_CLOCK_PARAMETERS_V2 *)&args.sPCLKInput; ++ spc2_ptr->usPixelClock = cpu_to_le16(sclock); ++ spc2_ptr->usRefDiv = cpu_to_le16(ref_div); ++ spc2_ptr->usFbDiv = cpu_to_le16(fb_div); ++ spc2_ptr->ucPostDiv = post_div; ++ spc2_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; ++ spc2_ptr->ucCRTC = radeon_crtc->crtc_id; ++ spc2_ptr->ucRefDivSrc = 1; ++ break; ++ case 3: ++ if (!encoder) ++ return; ++ spc3_ptr = (PIXEL_CLOCK_PARAMETERS_V3 *)&args.sPCLKInput; ++ spc3_ptr->usPixelClock = cpu_to_le16(sclock); ++ spc3_ptr->usRefDiv = cpu_to_le16(ref_div); ++ spc3_ptr->usFbDiv = cpu_to_le16(fb_div); ++ spc3_ptr->ucPostDiv = post_div; ++ spc3_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; ++ spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2); ++ spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id; ++ spc3_ptr->ucEncoderMode = atombios_get_encoder_mode(encoder); ++ break; ++ default: ++ DRM_ERROR("Unknown table version %d %d\n", frev, crev); ++ return; ++ } ++ break; ++ default: ++ DRM_ERROR("Unknown table version %d %d\n", frev, crev); ++ return; ++ } ++ ++ printk("executing set pll\n"); ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++} ++ ++int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_framebuffer *radeon_fb; ++ struct drm_gem_object *obj; ++ struct drm_radeon_gem_object *obj_priv; ++ uint32_t fb_location, fb_format, fb_pitch_pixels; ++ ++ if (!crtc->fb) ++ return -EINVAL; ++ ++ radeon_fb = to_radeon_framebuffer(crtc->fb); ++ ++ obj = radeon_fb->obj; ++ obj_priv = obj->driver_private; ++ ++ if (radeon_gem_object_pin(obj, 0, RADEON_GEM_DOMAIN_VRAM)) ++ return -EINVAL; ++ ++ fb_location = obj_priv->bo->offset + dev_priv->fb_location; ++ ++ switch(crtc->fb->bits_per_pixel) { ++ case 15: ++ fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555; ++ break; ++ case 16: ++ fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | AVIVO_D1GRPH_CONTROL_16BPP_RGB565; ++ break; ++ case 24: ++ case 32: ++ fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888; ++ break; ++ default: ++ DRM_ERROR("Unsupported screen depth %d\n", crtc->fb->bits_per_pixel); ++ return -EINVAL; ++ } ++ ++ /* TODO tiling */ ++ if (radeon_crtc->crtc_id == 0) ++ RADEON_WRITE(AVIVO_D1VGA_CONTROL, 0); ++ else ++ RADEON_WRITE(AVIVO_D2VGA_CONTROL, 0); ++ ++ RADEON_WRITE(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, fb_location); ++ RADEON_WRITE(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, fb_location); ++ RADEON_WRITE(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); ++ ++ RADEON_WRITE(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); ++ RADEON_WRITE(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); ++ RADEON_WRITE(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); ++ RADEON_WRITE(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); ++ RADEON_WRITE(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); ++ RADEON_WRITE(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); ++ ++ fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); ++ RADEON_WRITE(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); ++ RADEON_WRITE(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); ++ ++ RADEON_WRITE(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, ++ crtc->mode.vdisplay); ++ x &= ~3; ++ y &= ~1; ++ RADEON_WRITE(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, (x << 16) | y); ++ RADEON_WRITE(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, ++ (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); ++ ++ if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) ++ RADEON_WRITE(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, ++ AVIVO_D1MODE_INTERLEAVE_EN); ++ else ++ RADEON_WRITE(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); ++ ++ if (old_fb) { ++ radeon_fb = to_radeon_framebuffer(old_fb); ++ radeon_gem_object_unpin(radeon_fb->obj); ++ } ++ return 0; ++} ++ ++int atombios_crtc_mode_set(struct drm_crtc *crtc, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode, ++ int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_encoder *encoder; ++ SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; ++ ++ /* TODO color tiling */ ++ memset(&crtc_timing, 0, sizeof(crtc_timing)); ++ ++ //todo tv ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ ++ } ++ ++ crtc_timing.ucCRTC = radeon_crtc->crtc_id; ++ crtc_timing.usH_Total = adjusted_mode->crtc_htotal; ++ crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; ++ crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; ++ crtc_timing.usH_SyncWidth = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; ++ ++ crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; ++ crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; ++ crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; ++ crtc_timing.usV_SyncWidth = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ++ crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ++ crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) ++ crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ++ crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; ++ ++ atombios_crtc_set_pll(crtc, adjusted_mode); ++ atombios_crtc_set_timing(crtc, &crtc_timing); ++ ++ if (radeon_is_avivo(dev_priv)) ++ atombios_crtc_set_base(crtc, x, y, old_fb); ++ else { ++ if (radeon_crtc->crtc_id == 0) { ++ SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing; ++ memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing)); ++ ++ /* setup FP shadow regs on R4xx */ ++ crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id; ++ crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay; ++ crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay; ++ crtc_dtd_timing.usH_Blanking_Time = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hdisplay; ++ crtc_dtd_timing.usV_Blanking_Time = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vdisplay; ++ crtc_dtd_timing.usH_SyncOffset = adjusted_mode->crtc_hsync_start - adjusted_mode->crtc_hdisplay; ++ crtc_dtd_timing.usV_SyncOffset = adjusted_mode->crtc_vsync_start - adjusted_mode->crtc_vdisplay; ++ crtc_dtd_timing.usH_SyncWidth = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; ++ crtc_dtd_timing.usV_SyncWidth = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; ++ //crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; ++ //crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ++ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ++ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) ++ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ++ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; ++ ++ atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing); ++ } ++ radeon_crtc_set_base(crtc, x, y, old_fb); ++ radeon_legacy_atom_set_surface(crtc); ++ } ++ radeon_init_disp_bandwidth(dev); ++ return 0; ++} ++ ++static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ return true; ++} ++ ++ ++static void atombios_crtc_prepare(struct drm_crtc *crtc) ++{ ++ atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); ++ atombios_lock_crtc(crtc, 1); ++} ++ ++static void atombios_crtc_commit(struct drm_crtc *crtc) ++{ ++ atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); ++ atombios_lock_crtc(crtc, 0); ++} ++ ++static const struct drm_crtc_helper_funcs atombios_helper_funcs = { ++ .dpms = atombios_crtc_dpms, ++ .mode_fixup = atombios_crtc_mode_fixup, ++ .mode_set = atombios_crtc_mode_set, ++ .mode_set_base = atombios_crtc_set_base, ++ .prepare = atombios_crtc_prepare, ++ .commit = atombios_crtc_commit, ++}; ++ ++void radeon_atombios_init_crtc(struct drm_device *dev, ++ struct radeon_crtc *radeon_crtc) ++{ ++ if (radeon_crtc->crtc_id == 1) ++ radeon_crtc->crtc_offset = AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; ++ drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); ++} ++ ++void radeon_init_disp_bw_avivo(struct drm_device *dev, ++ struct drm_display_mode *mode1, ++ uint32_t pixel_bytes1, ++ struct drm_display_mode *mode2, ++ uint32_t pixel_bytes2) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ fixed20_12 min_mem_eff; ++ fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff; ++ fixed20_12 sclk_ff, mclk_ff; ++ uint32_t dc_lb_memory_split, temp; ++ ++ min_mem_eff.full = rfixed_const_8(0); ++ if (dev_priv->disp_priority == 2) { ++ uint32_t mc_init_misc_lat_timer = 0; ++ if (dev_priv->chip_family == CHIP_RV515) ++ mc_init_misc_lat_timer = RADEON_READ_MCIND(dev_priv, RV515_MC_INIT_MISC_LAT_TIMER); ++ else if (dev_priv->chip_family == CHIP_RS690) ++ mc_init_misc_lat_timer = RADEON_READ_MCIND(dev_priv, RS690_MC_INIT_MISC_LAT_TIMER); ++ ++ mc_init_misc_lat_timer &= ~(R300_MC_DISP1R_INIT_LAT_MASK << R300_MC_DISP1R_INIT_LAT_SHIFT); ++ mc_init_misc_lat_timer &= ~(R300_MC_DISP0R_INIT_LAT_MASK << R300_MC_DISP0R_INIT_LAT_SHIFT); ++ ++ if (mode2) ++ mc_init_misc_lat_timer |= (1 << R300_MC_DISP1R_INIT_LAT_SHIFT); ++ if (mode1) ++ mc_init_misc_lat_timer |= (1 << R300_MC_DISP0R_INIT_LAT_SHIFT); ++ ++ if (dev_priv->chip_family == CHIP_RV515) ++ RADEON_WRITE_MCIND(RV515_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer); ++ else if (dev_priv->chip_family == CHIP_RS690) ++ RADEON_WRITE_MCIND(RS690_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer); ++ } ++ ++ /* ++ * determine is there is enough bw for current mode ++ */ ++ temp_ff.full = rfixed_const(100); ++ mclk_ff.full = rfixed_const(dev_priv->mode_info.mclk); ++ mclk_ff.full = rfixed_div(mclk_ff, temp_ff); ++ sclk_ff.full = rfixed_const(dev_priv->mode_info.sclk); ++ sclk_ff.full = rfixed_div(sclk_ff, temp_ff); ++ ++ temp = (dev_priv->ram_width / 8) * (dev_priv->is_ddr ? 2 : 1); ++ temp_ff.full = rfixed_const(temp); ++ mem_bw.full = rfixed_mul(mclk_ff, temp_ff); ++ mem_bw.full = rfixed_mul(mem_bw, min_mem_eff); ++ ++ pix_clk.full = 0; ++ pix_clk2.full = 0; ++ peak_disp_bw.full = 0; ++ if (mode1) { ++ temp_ff.full = rfixed_const(1000); ++ pix_clk.full = rfixed_const(mode1->clock); /* convert to fixed point */ ++ pix_clk.full = rfixed_div(pix_clk, temp_ff); ++ temp_ff.full = rfixed_const(pixel_bytes1); ++ peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff); ++ } ++ if (mode2) { ++ temp_ff.full = rfixed_const(1000); ++ pix_clk2.full = rfixed_const(mode2->clock); /* convert to fixed point */ ++ pix_clk2.full = rfixed_div(pix_clk2, temp_ff); ++ temp_ff.full = rfixed_const(pixel_bytes2); ++ peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff); ++ } ++ ++ if (peak_disp_bw.full >= mem_bw.full) { ++ DRM_ERROR("You may not have enough display bandwidth for current mode\n" ++ "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n"); ++ printk("peak disp bw %d, mem_bw %d\n", rfixed_trunc(peak_disp_bw), ++ rfixed_trunc(mem_bw)); ++ } ++ ++ /* ++ * Line Buffer Setup ++ * There is a single line buffer shared by both display controllers. ++ * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between the display ++ * controllers. The paritioning can either be done manually or via one of four ++ * preset allocations specified in bits 1:0: ++ * 0 - line buffer is divided in half and shared between each display controller ++ * 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4 ++ * 2 - D1 gets the whole buffer ++ * 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4 ++ * Setting bit 2 of DC_LB_MEMORY_SPLIT controls switches to manual allocation mode. ++ * In manual allocation mode, D1 always starts at 0, D1 end/2 is specified in bits ++ * 14:4; D2 allocation follows D1. ++ */ ++ ++ /* is auto or manual better ? */ ++ dc_lb_memory_split = RADEON_READ(AVIVO_DC_LB_MEMORY_SPLIT) & ~AVIVO_DC_LB_MEMORY_SPLIT_MASK; ++ dc_lb_memory_split &= ~AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE; ++#if 1 ++ /* auto */ ++ if (mode1 && mode2) { ++ if (mode1->hdisplay > mode2->hdisplay) { ++ if (mode1->hdisplay > 2560) ++ dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q; ++ else ++ dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; ++ } else if (mode2->hdisplay > mode1->hdisplay) { ++ if (mode2->hdisplay > 2560) ++ dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; ++ else ++ dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; ++ } else ++ dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; ++ } else if (mode1) { ++ dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_ONLY; ++ } else if (mode2) { ++ dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; ++ } ++#else ++ /* manual */ ++ dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE; ++ dc_lb_memory_split &= ~(AVIVO_DC_LB_DISP1_END_ADR_MASK << AVIVO_DC_LB_DISP1_END_ADR_SHIFT); ++ if (mode1) { ++ dc_lb_memory_split |= ((((mode1->hdisplay / 2) + 64 /*???*/) & AVIVO_DC_LB_DISP1_END_ADR_MASK) ++ << AVIVO_DC_LB_DISP1_END_ADR_SHIFT); ++ } else if (mode2) { ++ dc_lb_memory_split |= (0 << AVIVO_DC_LB_DISP1_END_ADR_SHIFT); ++ } ++ ++#endif ++ RADEON_WRITE(AVIVO_DC_LB_MEMORY_SPLIT, dc_lb_memory_split); ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/atombios.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atombios.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/atombios.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atombios.h 2009-04-26 02:59:43.717733542 +0200 +@@ -0,0 +1,5025 @@ ++/* ++ * Copyright 2006-2007 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++ ++/****************************************************************************/ ++/*Portion I: Definitions shared between VBIOS and Driver */ ++/****************************************************************************/ ++ ++ ++#ifndef _ATOMBIOS_H ++#define _ATOMBIOS_H ++ ++#define ATOM_VERSION_MAJOR 0x00020000 ++#define ATOM_VERSION_MINOR 0x00000002 ++ ++#define ATOM_HEADER_VERSION (ATOM_VERSION_MAJOR | ATOM_VERSION_MINOR) ++ ++/* Endianness should be specified before inclusion, ++ * default to little endian ++ */ ++#ifndef ATOM_BIG_ENDIAN ++#error Endian not specified ++#endif ++ ++#ifdef _H2INC ++ #ifndef ULONG ++ typedef unsigned long ULONG; ++ #endif ++ ++ #ifndef UCHAR ++ typedef unsigned char UCHAR; ++ #endif ++ ++ #ifndef USHORT ++ typedef unsigned short USHORT; ++ #endif ++#endif ++ ++#define ATOM_DAC_A 0 ++#define ATOM_DAC_B 1 ++#define ATOM_EXT_DAC 2 ++ ++#define ATOM_CRTC1 0 ++#define ATOM_CRTC2 1 ++ ++#define ATOM_DIGA 0 ++#define ATOM_DIGB 1 ++ ++#define ATOM_PPLL1 0 ++#define ATOM_PPLL2 1 ++ ++#define ATOM_SCALER1 0 ++#define ATOM_SCALER2 1 ++ ++#define ATOM_SCALER_DISABLE 0 ++#define ATOM_SCALER_CENTER 1 ++#define ATOM_SCALER_EXPANSION 2 ++#define ATOM_SCALER_MULTI_EX 3 ++ ++#define ATOM_DISABLE 0 ++#define ATOM_ENABLE 1 ++#define ATOM_LCD_BLOFF (ATOM_DISABLE+2) ++#define ATOM_LCD_BLON (ATOM_ENABLE+2) ++#define ATOM_LCD_BL_BRIGHTNESS_CONTROL (ATOM_ENABLE+3) ++#define ATOM_LCD_SELFTEST_START (ATOM_DISABLE+5) ++#define ATOM_LCD_SELFTEST_STOP (ATOM_ENABLE+5) ++#define ATOM_ENCODER_INIT (ATOM_DISABLE+7) ++ ++#define ATOM_BLANKING 1 ++#define ATOM_BLANKING_OFF 0 ++ ++#define ATOM_CURSOR1 0 ++#define ATOM_CURSOR2 1 ++ ++#define ATOM_ICON1 0 ++#define ATOM_ICON2 1 ++ ++#define ATOM_CRT1 0 ++#define ATOM_CRT2 1 ++ ++#define ATOM_TV_NTSC 1 ++#define ATOM_TV_NTSCJ 2 ++#define ATOM_TV_PAL 3 ++#define ATOM_TV_PALM 4 ++#define ATOM_TV_PALCN 5 ++#define ATOM_TV_PALN 6 ++#define ATOM_TV_PAL60 7 ++#define ATOM_TV_SECAM 8 ++#define ATOM_TV_CV 16 ++ ++#define ATOM_DAC1_PS2 1 ++#define ATOM_DAC1_CV 2 ++#define ATOM_DAC1_NTSC 3 ++#define ATOM_DAC1_PAL 4 ++ ++#define ATOM_DAC2_PS2 ATOM_DAC1_PS2 ++#define ATOM_DAC2_CV ATOM_DAC1_CV ++#define ATOM_DAC2_NTSC ATOM_DAC1_NTSC ++#define ATOM_DAC2_PAL ATOM_DAC1_PAL ++ ++#define ATOM_PM_ON 0 ++#define ATOM_PM_STANDBY 1 ++#define ATOM_PM_SUSPEND 2 ++#define ATOM_PM_OFF 3 ++ ++/* Bit0:{=0:single, =1:dual}, ++ Bit1 {=0:666RGB, =1:888RGB}, ++ Bit2:3:{Grey level} ++ Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888}*/ ++ ++#define ATOM_PANEL_MISC_DUAL 0x00000001 ++#define ATOM_PANEL_MISC_888RGB 0x00000002 ++#define ATOM_PANEL_MISC_GREY_LEVEL 0x0000000C ++#define ATOM_PANEL_MISC_FPDI 0x00000010 ++#define ATOM_PANEL_MISC_GREY_LEVEL_SHIFT 2 ++#define ATOM_PANEL_MISC_SPATIAL 0x00000020 ++#define ATOM_PANEL_MISC_TEMPORAL 0x00000040 ++#define ATOM_PANEL_MISC_API_ENABLED 0x00000080 ++ ++ ++#define MEMTYPE_DDR1 "DDR1" ++#define MEMTYPE_DDR2 "DDR2" ++#define MEMTYPE_DDR3 "DDR3" ++#define MEMTYPE_DDR4 "DDR4" ++ ++#define ASIC_BUS_TYPE_PCI "PCI" ++#define ASIC_BUS_TYPE_AGP "AGP" ++#define ASIC_BUS_TYPE_PCIE "PCI_EXPRESS" ++ ++/* Maximum size of that FireGL flag string */ ++ ++#define ATOM_FIREGL_FLAG_STRING "FGL" //Flag used to enable FireGL Support ++#define ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING 3 //sizeof( ATOM_FIREGL_FLAG_STRING ) ++ ++#define ATOM_FAKE_DESKTOP_STRING "DSK" //Flag used to enable mobile ASIC on Desktop ++#define ATOM_MAX_SIZE_OF_FAKE_DESKTOP_STRING ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING ++ ++#define ATOM_M54T_FLAG_STRING "M54T" //Flag used to enable M54T Support ++#define ATOM_MAX_SIZE_OF_M54T_FLAG_STRING 4 //sizeof( ATOM_M54T_FLAG_STRING ) ++ ++#define HW_ASSISTED_I2C_STATUS_FAILURE 2 ++#define HW_ASSISTED_I2C_STATUS_SUCCESS 1 ++ ++#pragma pack(1) /* BIOS data must use byte aligment */ ++ ++/* Define offset to location of ROM header. */ ++ ++#define OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER 0x00000048L ++#define OFFSET_TO_ATOM_ROM_IMAGE_SIZE 0x00000002L ++ ++#define OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE 0x94 ++#define MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE 20 /* including the terminator 0x0! */ ++#define OFFSET_TO_GET_ATOMBIOS_STRINGS_NUMBER 0x002f ++#define OFFSET_TO_GET_ATOMBIOS_STRINGS_START 0x006e ++ ++/* Common header for all ROM Data tables. ++ Every table pointed _ATOM_MASTER_DATA_TABLE has this common header. ++ And the pointer actually points to this header. */ ++ ++typedef struct _ATOM_COMMON_TABLE_HEADER ++{ ++ USHORT usStructureSize; ++ UCHAR ucTableFormatRevision; /*Change it when the Parser is not backward compatible */ ++ UCHAR ucTableContentRevision; /*Change it only when the table needs to change but the firmware */ ++ /*Image can't be updated, while Driver needs to carry the new table! */ ++}ATOM_COMMON_TABLE_HEADER; ++ ++typedef struct _ATOM_ROM_HEADER ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR uaFirmWareSignature[4]; /*Signature to distinguish between Atombios and non-atombios, ++ atombios should init it as "ATOM", don't change the position */ ++ USHORT usBiosRuntimeSegmentAddress; ++ USHORT usProtectedModeInfoOffset; ++ USHORT usConfigFilenameOffset; ++ USHORT usCRC_BlockOffset; ++ USHORT usBIOS_BootupMessageOffset; ++ USHORT usInt10Offset; ++ USHORT usPciBusDevInitCode; ++ USHORT usIoBaseAddress; ++ USHORT usSubsystemVendorID; ++ USHORT usSubsystemID; ++ USHORT usPCI_InfoOffset; ++ USHORT usMasterCommandTableOffset; /*Offset for SW to get all command table offsets, Don't change the position */ ++ USHORT usMasterDataTableOffset; /*Offset for SW to get all data table offsets, Don't change the position */ ++ UCHAR ucExtendedFunctionCode; ++ UCHAR ucReserved; ++}ATOM_ROM_HEADER; ++ ++/*==============================Command Table Portion==================================== */ ++ ++#ifdef UEFI_BUILD ++ #define UTEMP USHORT ++ #define USHORT void* ++#endif ++ ++typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ ++ USHORT ASIC_Init; //Function Table, used by various SW components,latest version 1.1 ++ USHORT GetDisplaySurfaceSize; //Atomic Table, Used by Bios when enabling HW ICON ++ USHORT ASIC_RegistersInit; //Atomic Table, indirectly used by various SW components,called from ASIC_Init ++ USHORT VRAM_BlockVenderDetection; //Atomic Table, used only by Bios ++ USHORT DIGxEncoderControl; //Only used by Bios ++ USHORT MemoryControllerInit; //Atomic Table, indirectly used by various SW components,called from ASIC_Init ++ USHORT EnableCRTCMemReq; //Function Table,directly used by various SW components,latest version 2.1 ++ USHORT MemoryParamAdjust; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock if needed ++ USHORT DVOEncoderControl; //Function Table,directly used by various SW components,latest version 1.2 ++ USHORT GPIOPinControl; //Atomic Table, only used by Bios ++ USHORT SetEngineClock; //Function Table,directly used by various SW components,latest version 1.1 ++ USHORT SetMemoryClock; //Function Table,directly used by various SW components,latest version 1.1 ++ USHORT SetPixelClock; //Function Table,directly used by various SW components,latest version 1.2 ++ USHORT DynamicClockGating; //Atomic Table, indirectly used by various SW components,called from ASIC_Init ++ USHORT ResetMemoryDLL; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock ++ USHORT ResetMemoryDevice; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock ++ USHORT MemoryPLLInit; ++ USHORT AdjustDisplayPll; //only used by Bios ++ USHORT AdjustMemoryController; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock ++ USHORT EnableASIC_StaticPwrMgt; //Atomic Table, only used by Bios ++ USHORT ASIC_StaticPwrMgtStatusChange; //Obsolete , only used by Bios ++ USHORT DAC_LoadDetection; //Atomic Table, directly used by various SW components,latest version 1.2 ++ USHORT LVTMAEncoderControl; //Atomic Table,directly used by various SW components,latest version 1.3 ++ USHORT LCD1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT DAC1EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT DAC2EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT DVOOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT CV1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT GetConditionalGoldenSetting; //only used by Bios ++ USHORT TVEncoderControl; //Function Table,directly used by various SW components,latest version 1.1 ++ USHORT TMDSAEncoderControl; //Atomic Table, directly used by various SW components,latest version 1.3 ++ USHORT LVDSEncoderControl; //Atomic Table, directly used by various SW components,latest version 1.3 ++ USHORT TV1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT EnableScaler; //Atomic Table, used only by Bios ++ USHORT BlankCRTC; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT EnableCRTC; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT GetPixelClock; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT EnableVGA_Render; //Function Table,directly used by various SW components,latest version 1.1 ++ USHORT EnableVGA_Access; //Obsolete , only used by Bios ++ USHORT SetCRTC_Timing; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT SetCRTC_OverScan; //Atomic Table, used by various SW components,latest version 1.1 ++ USHORT SetCRTC_Replication; //Atomic Table, used only by Bios ++ USHORT SelectCRTC_Source; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT EnableGraphSurfaces; //Atomic Table, used only by Bios ++ USHORT UpdateCRTC_DoubleBufferRegisters; ++ USHORT LUT_AutoFill; //Atomic Table, only used by Bios ++ USHORT EnableHW_IconCursor; //Atomic Table, only used by Bios ++ USHORT GetMemoryClock; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT GetEngineClock; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT SetCRTC_UsingDTDTiming; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT ExternalEncoderControl; //Atomic Table, directly used by various SW components,latest version 2.1 ++ USHORT LVTMAOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT VRAM_BlockDetectionByStrap; //Atomic Table, used only by Bios ++ USHORT MemoryCleanUp; //Atomic Table, only used by Bios ++ USHORT ProcessI2cChannelTransaction; //Function Table,only used by Bios ++ USHORT WriteOneByteToHWAssistedI2C; //Function Table,indirectly used by various SW components ++ USHORT ReadHWAssistedI2CStatus; //Atomic Table, indirectly used by various SW components ++ USHORT SpeedFanControl; //Function Table,indirectly used by various SW components,called from ASIC_Init ++ USHORT PowerConnectorDetection; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT MC_Synchronization; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock ++ USHORT ComputeMemoryEnginePLL; //Atomic Table, indirectly used by various SW components,called from SetMemory/EngineClock ++ USHORT MemoryRefreshConversion; //Atomic Table, indirectly used by various SW components,called from SetMemory or SetEngineClock ++ USHORT VRAM_GetCurrentInfoBlock; //Atomic Table, used only by Bios ++ USHORT DynamicMemorySettings; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock ++ USHORT MemoryTraining; //Atomic Table, used only by Bios ++ USHORT EnableSpreadSpectrumOnPPLL; //Atomic Table, directly used by various SW components,latest version 1.2 ++ USHORT TMDSAOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT SetVoltage; //Function Table,directly and/or indirectly used by various SW components,latest version 1.1 ++ USHORT DAC1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT DAC2OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT SetupHWAssistedI2CStatus; //Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C" ++ USHORT ClockSource; //Atomic Table, indirectly used by various SW components,called from ASIC_Init ++ USHORT MemoryDeviceInit; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock ++ USHORT EnableYUV; //Atomic Table, indirectly used by various SW components,called from EnableVGARender ++ USHORT DIG1EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1 ++ USHORT DIG2EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1 ++ USHORT DIG1TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1 ++ USHORT DIG2TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1 ++ USHORT ProcessAuxChannelTransaction; //Function Table,only used by Bios ++ USHORT DPEncoderService; //Function Table,only used by Bios ++}ATOM_MASTER_LIST_OF_COMMAND_TABLES; ++ ++// For backward compatible ++#define ReadEDIDFromHWAssistedI2C ProcessI2cChannelTransaction ++#define UNIPHYTransmitterControl DIG1TransmitterControl ++#define LVTMATransmitterControl DIG2TransmitterControl ++#define SetCRTC_DPM_State GetConditionalGoldenSetting ++#define SetUniphyInstance ASIC_StaticPwrMgtStatusChange ++ ++typedef struct _ATOM_MASTER_COMMAND_TABLE ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_MASTER_LIST_OF_COMMAND_TABLES ListOfCommandTables; ++}ATOM_MASTER_COMMAND_TABLE; ++ ++/****************************************************************************/ ++// Structures used in every command table ++/****************************************************************************/ ++typedef struct _ATOM_TABLE_ATTRIBUTE ++{ ++#if ATOM_BIG_ENDIAN ++ USHORT UpdatedByUtility:1; //[15]=Table updated by utility flag ++ USHORT PS_SizeInBytes:7; //[14:8]=Size of parameter space in Bytes (multiple of a dword), ++ USHORT WS_SizeInBytes:8; //[7:0]=Size of workspace in Bytes (in multiple of a dword), ++#else ++ USHORT WS_SizeInBytes:8; //[7:0]=Size of workspace in Bytes (in multiple of a dword), ++ USHORT PS_SizeInBytes:7; //[14:8]=Size of parameter space in Bytes (multiple of a dword), ++ USHORT UpdatedByUtility:1; //[15]=Table updated by utility flag ++#endif ++}ATOM_TABLE_ATTRIBUTE; ++ ++typedef union _ATOM_TABLE_ATTRIBUTE_ACCESS ++{ ++ ATOM_TABLE_ATTRIBUTE sbfAccess; ++ USHORT susAccess; ++}ATOM_TABLE_ATTRIBUTE_ACCESS; ++ ++/****************************************************************************/ ++// Common header for all command tables. ++// Every table pointed by _ATOM_MASTER_COMMAND_TABLE has this common header. ++// And the pointer actually points to this header. ++/****************************************************************************/ ++typedef struct _ATOM_COMMON_ROM_COMMAND_TABLE_HEADER ++{ ++ ATOM_COMMON_TABLE_HEADER CommonHeader; ++ ATOM_TABLE_ATTRIBUTE TableAttribute; ++}ATOM_COMMON_ROM_COMMAND_TABLE_HEADER; ++ ++/****************************************************************************/ ++// Structures used by ComputeMemoryEnginePLLTable ++/****************************************************************************/ ++#define COMPUTE_MEMORY_PLL_PARAM 1 ++#define COMPUTE_ENGINE_PLL_PARAM 2 ++ ++typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS ++{ ++ ULONG ulClock; //When returen, it's the re-calculated clock based on given Fb_div Post_Div and ref_div ++ UCHAR ucAction; //0:reserved //1:Memory //2:Engine ++ UCHAR ucReserved; //may expand to return larger Fbdiv later ++ UCHAR ucFbDiv; //return value ++ UCHAR ucPostDiv; //return value ++}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS; ++ ++typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 ++{ ++ ULONG ulClock; //When return, [23:0] return real clock ++ UCHAR ucAction; //0:reserved;COMPUTE_MEMORY_PLL_PARAM:Memory;COMPUTE_ENGINE_PLL_PARAM:Engine. it return ref_div to be written to register ++ USHORT usFbDiv; //return Feedback value to be written to register ++ UCHAR ucPostDiv; //return post div to be written to register ++}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2; ++#define COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS ++ ++ ++#define SET_CLOCK_FREQ_MASK 0x00FFFFFF //Clock change tables only take bit [23:0] as the requested clock value ++#define USE_NON_BUS_CLOCK_MASK 0x01000000 //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) ++#define USE_MEMORY_SELF_REFRESH_MASK 0x02000000 //Only applicable to memory clock change, when set, using memory self refresh during clock transition ++#define SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE 0x04000000 //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change ++#define FIRST_TIME_CHANGE_CLOCK 0x08000000 //Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup ++#define SKIP_SW_PROGRAM_PLL 0x10000000 //Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL ++#define USE_SS_ENABLED_PIXEL_CLOCK USE_NON_BUS_CLOCK_MASK ++ ++#define b3USE_NON_BUS_CLOCK_MASK 0x01 //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) ++#define b3USE_MEMORY_SELF_REFRESH 0x02 //Only applicable to memory clock change, when set, using memory self refresh during clock transition ++#define b3SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE 0x04 //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change ++#define b3FIRST_TIME_CHANGE_CLOCK 0x08 //Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup ++#define b3SKIP_SW_PROGRAM_PLL 0x10 //Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL ++ ++typedef struct _ATOM_COMPUTE_CLOCK_FREQ ++{ ++#if ATOM_BIG_ENDIAN ++ ULONG ulComputeClockFlag:8; // =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM ++ ULONG ulClockFreq:24; // in unit of 10kHz ++#else ++ ULONG ulClockFreq:24; // in unit of 10kHz ++ ULONG ulComputeClockFlag:8; // =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM ++#endif ++}ATOM_COMPUTE_CLOCK_FREQ; ++ ++typedef struct _ATOM_S_MPLL_FB_DIVIDER ++{ ++ USHORT usFbDivFrac; ++ USHORT usFbDiv; ++}ATOM_S_MPLL_FB_DIVIDER; ++ ++typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 ++{ ++ union ++ { ++ ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter ++ ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter ++ }; ++ UCHAR ucRefDiv; //Output Parameter ++ UCHAR ucPostDiv; //Output Parameter ++ UCHAR ucCntlFlag; //Output Parameter ++ UCHAR ucReserved; ++}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3; ++ ++// ucCntlFlag ++#define ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN 1 ++#define ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE 2 ++#define ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE 4 ++ ++typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER ++{ ++ ATOM_COMPUTE_CLOCK_FREQ ulClock; ++ ULONG ulReserved[2]; ++}DYNAMICE_MEMORY_SETTINGS_PARAMETER; ++ ++typedef struct _DYNAMICE_ENGINE_SETTINGS_PARAMETER ++{ ++ ATOM_COMPUTE_CLOCK_FREQ ulClock; ++ ULONG ulMemoryClock; ++ ULONG ulReserved; ++}DYNAMICE_ENGINE_SETTINGS_PARAMETER; ++ ++/****************************************************************************/ ++// Structures used by SetEngineClockTable ++/****************************************************************************/ ++typedef struct _SET_ENGINE_CLOCK_PARAMETERS ++{ ++ ULONG ulTargetEngineClock; //In 10Khz unit ++}SET_ENGINE_CLOCK_PARAMETERS; ++ ++typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION ++{ ++ ULONG ulTargetEngineClock; //In 10Khz unit ++ COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; ++}SET_ENGINE_CLOCK_PS_ALLOCATION; ++ ++/****************************************************************************/ ++// Structures used by SetMemoryClockTable ++/****************************************************************************/ ++typedef struct _SET_MEMORY_CLOCK_PARAMETERS ++{ ++ ULONG ulTargetMemoryClock; //In 10Khz unit ++}SET_MEMORY_CLOCK_PARAMETERS; ++ ++typedef struct _SET_MEMORY_CLOCK_PS_ALLOCATION ++{ ++ ULONG ulTargetMemoryClock; //In 10Khz unit ++ COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; ++}SET_MEMORY_CLOCK_PS_ALLOCATION; ++ ++/****************************************************************************/ ++// Structures used by ASIC_Init.ctb ++/****************************************************************************/ ++typedef struct _ASIC_INIT_PARAMETERS ++{ ++ ULONG ulDefaultEngineClock; //In 10Khz unit ++ ULONG ulDefaultMemoryClock; //In 10Khz unit ++}ASIC_INIT_PARAMETERS; ++ ++typedef struct _ASIC_INIT_PS_ALLOCATION ++{ ++ ASIC_INIT_PARAMETERS sASICInitClocks; ++ SET_ENGINE_CLOCK_PS_ALLOCATION sReserved; //Caller doesn't need to init this structure ++}ASIC_INIT_PS_ALLOCATION; ++ ++/****************************************************************************/ ++// Structure used by DynamicClockGatingTable.ctb ++/****************************************************************************/ ++typedef struct _DYNAMIC_CLOCK_GATING_PARAMETERS ++{ ++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE ++ UCHAR ucPadding[3]; ++}DYNAMIC_CLOCK_GATING_PARAMETERS; ++#define DYNAMIC_CLOCK_GATING_PS_ALLOCATION DYNAMIC_CLOCK_GATING_PARAMETERS ++ ++/****************************************************************************/ ++// Structure used by EnableASIC_StaticPwrMgtTable.ctb ++/****************************************************************************/ ++typedef struct _ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS ++{ ++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE ++ UCHAR ucPadding[3]; ++}ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS; ++#define ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by DAC_LoadDetectionTable.ctb ++/****************************************************************************/ ++typedef struct _DAC_LOAD_DETECTION_PARAMETERS ++{ ++ USHORT usDeviceID; //{ATOM_DEVICE_CRTx_SUPPORT,ATOM_DEVICE_TVx_SUPPORT,ATOM_DEVICE_CVx_SUPPORT} ++ UCHAR ucDacType; //{ATOM_DAC_A,ATOM_DAC_B, ATOM_EXT_DAC} ++ UCHAR ucMisc; //Valid only when table revision =1.3 and above ++}DAC_LOAD_DETECTION_PARAMETERS; ++ ++// DAC_LOAD_DETECTION_PARAMETERS.ucMisc ++#define DAC_LOAD_MISC_YPrPb 0x01 ++ ++typedef struct _DAC_LOAD_DETECTION_PS_ALLOCATION ++{ ++ DAC_LOAD_DETECTION_PARAMETERS sDacload; ++ ULONG Reserved[2];// Don't set this one, allocation for EXT DAC ++}DAC_LOAD_DETECTION_PS_ALLOCATION; ++ ++/****************************************************************************/ ++// Structures used by DAC1EncoderControlTable.ctb and DAC2EncoderControlTable.ctb ++/****************************************************************************/ ++typedef struct _DAC_ENCODER_CONTROL_PARAMETERS ++{ ++ USHORT usPixelClock; // in 10KHz; for bios convenient ++ UCHAR ucDacStandard; // See definition of ATOM_DACx_xxx, For DEC3.0, bit 7 used as internal flag to indicate DAC2 (==1) or DAC1 (==0) ++ UCHAR ucAction; // 0: turn off encoder ++ // 1: setup and turn on encoder ++ // 7: ATOM_ENCODER_INIT Initialize DAC ++}DAC_ENCODER_CONTROL_PARAMETERS; ++ ++#define DAC_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by DIG1EncoderControlTable ++// DIG2EncoderControlTable ++// ExternalEncoderControlTable ++/****************************************************************************/ ++typedef struct _DIG_ENCODER_CONTROL_PARAMETERS ++{ ++ USHORT usPixelClock; // in 10KHz; for bios convenient ++ UCHAR ucConfig; ++ // [2] Link Select: ++ // =0: PHY linkA if bfLane<3 ++ // =1: PHY linkB if bfLanes<3 ++ // =0: PHY linkA+B if bfLanes=3 ++ // [3] Transmitter Sel ++ // =0: UNIPHY or PCIEPHY ++ // =1: LVTMA ++ UCHAR ucAction; // =0: turn off encoder ++ // =1: turn on encoder ++ UCHAR ucEncoderMode; ++ // =0: DP encoder ++ // =1: LVDS encoder ++ // =2: DVI encoder ++ // =3: HDMI encoder ++ // =4: SDVO encoder ++ UCHAR ucLaneNum; // how many lanes to enable ++ UCHAR ucReserved[2]; ++}DIG_ENCODER_CONTROL_PARAMETERS; ++#define DIG_ENCODER_CONTROL_PS_ALLOCATION DIG_ENCODER_CONTROL_PARAMETERS ++#define EXTERNAL_ENCODER_CONTROL_PARAMETER DIG_ENCODER_CONTROL_PARAMETERS ++ ++//ucConfig ++#define ATOM_ENCODER_CONFIG_DPLINKRATE_MASK 0x01 ++#define ATOM_ENCODER_CONFIG_DPLINKRATE_1_62GHZ 0x00 ++#define ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ 0x01 ++#define ATOM_ENCODER_CONFIG_LINK_SEL_MASK 0x04 ++#define ATOM_ENCODER_CONFIG_LINKA 0x00 ++#define ATOM_ENCODER_CONFIG_LINKB 0x04 ++#define ATOM_ENCODER_CONFIG_LINKA_B ATOM_TRANSMITTER_CONFIG_LINKA ++#define ATOM_ENCODER_CONFIG_LINKB_A ATOM_ENCODER_CONFIG_LINKB ++#define ATOM_ENCODER_CONFIG_TRANSMITTER_SEL_MASK 0x08 ++#define ATOM_ENCODER_CONFIG_UNIPHY 0x00 ++#define ATOM_ENCODER_CONFIG_LVTMA 0x08 ++#define ATOM_ENCODER_CONFIG_TRANSMITTER1 0x00 ++#define ATOM_ENCODER_CONFIG_TRANSMITTER2 0x08 ++#define ATOM_ENCODER_CONFIG_DIGB 0x80 // VBIOS Internal use, outside SW should set this bit=0 ++// ucAction ++// ATOM_ENABLE: Enable Encoder ++// ATOM_DISABLE: Disable Encoder ++ ++//ucEncoderMode ++#define ATOM_ENCODER_MODE_DP 0 ++#define ATOM_ENCODER_MODE_LVDS 1 ++#define ATOM_ENCODER_MODE_DVI 2 ++#define ATOM_ENCODER_MODE_HDMI 3 ++#define ATOM_ENCODER_MODE_SDVO 4 ++#define ATOM_ENCODER_MODE_TV 13 ++#define ATOM_ENCODER_MODE_CV 14 ++#define ATOM_ENCODER_MODE_CRT 15 ++ ++typedef struct _ATOM_DIG_ENCODER_CONFIG_V2 ++{ ++#if ATOM_BIG_ENDIAN ++ UCHAR ucReserved1:2; ++ UCHAR ucTransmitterSel:2; // =0: UniphyAB, =1: UniphyCD =2: UniphyEF ++ UCHAR ucLinkSel:1; // =0: linkA/C/E =1: linkB/D/F ++ UCHAR ucReserved:1; ++ UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz ++#else ++ UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz ++ UCHAR ucReserved:1; ++ UCHAR ucLinkSel:1; // =0: linkA/C/E =1: linkB/D/F ++ UCHAR ucTransmitterSel:2; // =0: UniphyAB, =1: UniphyCD =2: UniphyEF ++ UCHAR ucReserved1:2; ++#endif ++}ATOM_DIG_ENCODER_CONFIG_V2; ++ ++ ++typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 ++{ ++ USHORT usPixelClock; // in 10KHz; for bios convenient ++ ATOM_DIG_ENCODER_CONFIG_V2 acConfig; ++ UCHAR ucAction; ++ UCHAR ucEncoderMode; ++ // =0: DP encoder ++ // =1: LVDS encoder ++ // =2: DVI encoder ++ // =3: HDMI encoder ++ // =4: SDVO encoder ++ UCHAR ucLaneNum; // how many lanes to enable ++ UCHAR ucReserved[2]; ++}DIG_ENCODER_CONTROL_PARAMETERS_V2; ++ ++//ucConfig ++#define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_MASK 0x01 ++#define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_1_62GHZ 0x00 ++#define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_2_70GHZ 0x01 ++#define ATOM_ENCODER_CONFIG_V2_LINK_SEL_MASK 0x04 ++#define ATOM_ENCODER_CONFIG_V2_LINKA 0x00 ++#define ATOM_ENCODER_CONFIG_V2_LINKB 0x04 ++#define ATOM_ENCODER_CONFIG_V2_TRANSMITTER_SEL_MASK 0x18 ++#define ATOM_ENCODER_CONFIG_V2_TRANSMITTER1 0x00 ++#define ATOM_ENCODER_CONFIG_V2_TRANSMITTER2 0x08 ++#define ATOM_ENCODER_CONFIG_V2_TRANSMITTER3 0x10 ++ ++/****************************************************************************/ ++// Structures used by UNIPHYTransmitterControlTable ++// LVTMATransmitterControlTable ++// DVOOutputControlTable ++/****************************************************************************/ ++typedef struct _ATOM_DP_VS_MODE ++{ ++ UCHAR ucLaneSel; ++ UCHAR ucLaneSet; ++}ATOM_DP_VS_MODE; ++ ++typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS ++{ ++ union ++ { ++ USHORT usPixelClock; // in 10KHz; for bios convenient ++ USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h ++ ATOM_DP_VS_MODE asMode; // DP Voltage swing mode ++ }; ++ UCHAR ucConfig; ++ // [0]=0: 4 lane Link, ++ // =1: 8 lane Link ( Dual Links TMDS ) ++ // [1]=0: InCoherent mode ++ // =1: Coherent Mode ++ // [2] Link Select: ++ // =0: PHY linkA if bfLane<3 ++ // =1: PHY linkB if bfLanes<3 ++ // =0: PHY linkA+B if bfLanes=3 ++ // [5:4]PCIE lane Sel ++ // =0: lane 0~3 or 0~7 ++ // =1: lane 4~7 ++ // =2: lane 8~11 or 8~15 ++ // =3: lane 12~15 ++ UCHAR ucAction; // =0: turn off encoder ++ // =1: turn on encoder ++ UCHAR ucReserved[4]; ++}DIG_TRANSMITTER_CONTROL_PARAMETERS; ++ ++#define DIG_TRANSMITTER_CONTROL_PS_ALLOCATION DIG_TRANSMITTER_CONTROL_PARAMETERS ++ ++//ucInitInfo ++#define ATOM_TRAMITTER_INITINFO_CONNECTOR_MASK 0x00ff ++ ++//ucConfig ++#define ATOM_TRANSMITTER_CONFIG_8LANE_LINK 0x01 ++#define ATOM_TRANSMITTER_CONFIG_COHERENT 0x02 ++#define ATOM_TRANSMITTER_CONFIG_LINK_SEL_MASK 0x04 ++#define ATOM_TRANSMITTER_CONFIG_LINKA 0x00 ++#define ATOM_TRANSMITTER_CONFIG_LINKB 0x04 ++#define ATOM_TRANSMITTER_CONFIG_LINKA_B 0x00 ++#define ATOM_TRANSMITTER_CONFIG_LINKB_A 0x04 ++ ++#define ATOM_TRANSMITTER_CONFIG_ENCODER_SEL_MASK 0x08 // only used when ATOM_TRANSMITTER_ACTION_ENABLE ++#define ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER 0x00 // only used when ATOM_TRANSMITTER_ACTION_ENABLE ++#define ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER 0x08 // only used when ATOM_TRANSMITTER_ACTION_ENABLE ++ ++#define ATOM_TRANSMITTER_CONFIG_CLKSRC_MASK 0x30 ++#define ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL 0x00 ++#define ATOM_TRANSMITTER_CONFIG_CLKSRC_PCIE 0x20 ++#define ATOM_TRANSMITTER_CONFIG_CLKSRC_XTALIN 0x30 ++#define ATOM_TRANSMITTER_CONFIG_LANE_SEL_MASK 0xc0 ++#define ATOM_TRANSMITTER_CONFIG_LANE_0_3 0x00 ++#define ATOM_TRANSMITTER_CONFIG_LANE_0_7 0x00 ++#define ATOM_TRANSMITTER_CONFIG_LANE_4_7 0x40 ++#define ATOM_TRANSMITTER_CONFIG_LANE_8_11 0x80 ++#define ATOM_TRANSMITTER_CONFIG_LANE_8_15 0x80 ++#define ATOM_TRANSMITTER_CONFIG_LANE_12_15 0xc0 ++ ++//ucAction ++#define ATOM_TRANSMITTER_ACTION_DISABLE 0 ++#define ATOM_TRANSMITTER_ACTION_ENABLE 1 ++#define ATOM_TRANSMITTER_ACTION_LCD_BLOFF 2 ++#define ATOM_TRANSMITTER_ACTION_LCD_BLON 3 ++#define ATOM_TRANSMITTER_ACTION_BL_BRIGHTNESS_CONTROL 4 ++#define ATOM_TRANSMITTER_ACTION_LCD_SELFTEST_START 5 ++#define ATOM_TRANSMITTER_ACTION_LCD_SELFTEST_STOP 6 ++#define ATOM_TRANSMITTER_ACTION_INIT 7 ++#define ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT 8 ++#define ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT 9 ++#define ATOM_TRANSMITTER_ACTION_SETUP 10 ++#define ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH 11 ++ ++ ++// Following are used for DigTransmitterControlTable ver1.2 ++typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V2 ++{ ++#if ATOM_BIG_ENDIAN ++ UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) ++ // =1 Dig Transmitter 2 ( Uniphy CD ) ++ // =2 Dig Transmitter 3 ( Uniphy EF ) ++ UCHAR ucReserved:1; ++ UCHAR fDPConnector:1; //bit4=0: DP connector =1: None DP connector ++ UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) ++ UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E ++ // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F ++ ++ UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) ++ UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector ++#else ++ UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector ++ UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) ++ UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E ++ // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F ++ UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) ++ UCHAR fDPConnector:1; //bit4=0: DP connector =1: None DP connector ++ UCHAR ucReserved:1; ++ UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) ++ // =1 Dig Transmitter 2 ( Uniphy CD ) ++ // =2 Dig Transmitter 3 ( Uniphy EF ) ++#endif ++}ATOM_DIG_TRANSMITTER_CONFIG_V2; ++ ++//ucConfig ++//Bit0 ++#define ATOM_TRANSMITTER_CONFIG_V2_DUAL_LINK_CONNECTOR 0x01 ++ ++//Bit1 ++#define ATOM_TRANSMITTER_CONFIG_V2_COHERENT 0x02 ++ ++//Bit2 ++#define ATOM_TRANSMITTER_CONFIG_V2_LINK_SEL_MASK 0x04 ++#define ATOM_TRANSMITTER_CONFIG_V2_LINKA 0x00 ++#define ATOM_TRANSMITTER_CONFIG_V2_LINKB 0x04 ++ ++// Bit3 ++#define ATOM_TRANSMITTER_CONFIG_V2_ENCODER_SEL_MASK 0x08 ++#define ATOM_TRANSMITTER_CONFIG_V2_DIG1_ENCODER 0x00 // only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP ++#define ATOM_TRANSMITTER_CONFIG_V2_DIG2_ENCODER 0x08 // only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP ++ ++// Bit4 ++#define ATOM_TRASMITTER_CONFIG_V2_DP_CONNECTOR 0x10 ++ ++// Bit7:6 ++#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER_SEL_MASK 0xC0 ++#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER1 0x00 //AB ++#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER2 0x40 //CD ++#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER3 0x80 //EF ++ ++typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 ++{ ++ union ++ { ++ USHORT usPixelClock; // in 10KHz; for bios convenient ++ USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h ++ ATOM_DP_VS_MODE asMode; // DP Voltage swing mode ++ }; ++ ATOM_DIG_TRANSMITTER_CONFIG_V2 acConfig; ++ UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_XXX ++ UCHAR ucReserved[4]; ++}DIG_TRANSMITTER_CONTROL_PARAMETERS_V2; ++ ++ ++/****************************************************************************/ ++// Structures used by DAC1OuputControlTable ++// DAC2OuputControlTable ++// LVTMAOutputControlTable (Before DEC30) ++// TMDSAOutputControlTable (Before DEC30) ++/****************************************************************************/ ++typedef struct _DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++{ ++ UCHAR ucAction; // Possible input:ATOM_ENABLE||ATOMDISABLE ++ // When the display is LCD, in addition to above: ++ // ATOM_LCD_BLOFF|| ATOM_LCD_BLON ||ATOM_LCD_BL_BRIGHTNESS_CONTROL||ATOM_LCD_SELFTEST_START|| ++ // ATOM_LCD_SELFTEST_STOP ++ ++ UCHAR aucPadding[3]; // padding to DWORD aligned ++}DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS; ++ ++#define DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++ ++ ++#define CRT1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++#define CRT1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION ++ ++#define CRT2_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++#define CRT2_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION ++ ++#define CV1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++#define CV1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION ++ ++#define TV1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++#define TV1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION ++ ++#define DFP1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++#define DFP1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION ++ ++#define DFP2_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++#define DFP2_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION ++ ++#define LCD1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++#define LCD1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION ++ ++#define DVO_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS ++#define DVO_OUTPUT_CONTROL_PS_ALLOCATION DIG_TRANSMITTER_CONTROL_PS_ALLOCATION ++#define DVO_OUTPUT_CONTROL_PARAMETERS_V3 DIG_TRANSMITTER_CONTROL_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by BlankCRTCTable ++/****************************************************************************/ ++typedef struct _BLANK_CRTC_PARAMETERS ++{ ++ UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 ++ UCHAR ucBlanking; // ATOM_BLANKING or ATOM_BLANKINGOFF ++ USHORT usBlackColorRCr; ++ USHORT usBlackColorGY; ++ USHORT usBlackColorBCb; ++}BLANK_CRTC_PARAMETERS; ++#define BLANK_CRTC_PS_ALLOCATION BLANK_CRTC_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by EnableCRTCTable ++// EnableCRTCMemReqTable ++// UpdateCRTC_DoubleBufferRegistersTable ++/****************************************************************************/ ++typedef struct _ENABLE_CRTC_PARAMETERS ++{ ++ UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 ++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE ++ UCHAR ucPadding[2]; ++}ENABLE_CRTC_PARAMETERS; ++#define ENABLE_CRTC_PS_ALLOCATION ENABLE_CRTC_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by SetCRTC_OverScanTable ++/****************************************************************************/ ++typedef struct _SET_CRTC_OVERSCAN_PARAMETERS ++{ ++ USHORT usOverscanRight; // right ++ USHORT usOverscanLeft; // left ++ USHORT usOverscanBottom; // bottom ++ USHORT usOverscanTop; // top ++ UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 ++ UCHAR ucPadding[3]; ++}SET_CRTC_OVERSCAN_PARAMETERS; ++#define SET_CRTC_OVERSCAN_PS_ALLOCATION SET_CRTC_OVERSCAN_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by SetCRTC_ReplicationTable ++/****************************************************************************/ ++typedef struct _SET_CRTC_REPLICATION_PARAMETERS ++{ ++ UCHAR ucH_Replication; // horizontal replication ++ UCHAR ucV_Replication; // vertical replication ++ UCHAR usCRTC; // ATOM_CRTC1 or ATOM_CRTC2 ++ UCHAR ucPadding; ++}SET_CRTC_REPLICATION_PARAMETERS; ++#define SET_CRTC_REPLICATION_PS_ALLOCATION SET_CRTC_REPLICATION_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by SelectCRTC_SourceTable ++/****************************************************************************/ ++typedef struct _SELECT_CRTC_SOURCE_PARAMETERS ++{ ++ UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 ++ UCHAR ucDevice; // ATOM_DEVICE_CRT1|ATOM_DEVICE_CRT2|.... ++ UCHAR ucPadding[2]; ++}SELECT_CRTC_SOURCE_PARAMETERS; ++#define SELECT_CRTC_SOURCE_PS_ALLOCATION SELECT_CRTC_SOURCE_PARAMETERS ++ ++typedef struct _SELECT_CRTC_SOURCE_PARAMETERS_V2 ++{ ++ UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 ++ UCHAR ucEncoderID; // DAC1/DAC2/TVOUT/DIG1/DIG2/DVO ++ UCHAR ucEncodeMode; // Encoding mode, only valid when using DIG1/DIG2/DVO ++ UCHAR ucPadding; ++}SELECT_CRTC_SOURCE_PARAMETERS_V2; ++ ++//ucEncoderID ++//#define ASIC_INT_DAC1_ENCODER_ID 0x00 ++//#define ASIC_INT_TV_ENCODER_ID 0x02 ++//#define ASIC_INT_DIG1_ENCODER_ID 0x03 ++//#define ASIC_INT_DAC2_ENCODER_ID 0x04 ++//#define ASIC_EXT_TV_ENCODER_ID 0x06 ++//#define ASIC_INT_DVO_ENCODER_ID 0x07 ++//#define ASIC_INT_DIG2_ENCODER_ID 0x09 ++//#define ASIC_EXT_DIG_ENCODER_ID 0x05 ++ ++//ucEncodeMode ++//#define ATOM_ENCODER_MODE_DP 0 ++//#define ATOM_ENCODER_MODE_LVDS 1 ++//#define ATOM_ENCODER_MODE_DVI 2 ++//#define ATOM_ENCODER_MODE_HDMI 3 ++//#define ATOM_ENCODER_MODE_SDVO 4 ++//#define ATOM_ENCODER_MODE_TV 13 ++//#define ATOM_ENCODER_MODE_CV 14 ++//#define ATOM_ENCODER_MODE_CRT 15 ++ ++/****************************************************************************/ ++// Structures used by SetPixelClockTable ++// GetPixelClockTable ++/****************************************************************************/ ++//Major revision=1., Minor revision=1 ++typedef struct _PIXEL_CLOCK_PARAMETERS ++{ ++ USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) ++ // 0 means disable PPLL ++ USHORT usRefDiv; // Reference divider ++ USHORT usFbDiv; // feedback divider ++ UCHAR ucPostDiv; // post divider ++ UCHAR ucFracFbDiv; // fractional feedback divider ++ UCHAR ucPpll; // ATOM_PPLL1 or ATOM_PPL2 ++ UCHAR ucRefDivSrc; // ATOM_PJITTER or ATO_NONPJITTER ++ UCHAR ucCRTC; // Which CRTC uses this Ppll ++ UCHAR ucPadding; ++}PIXEL_CLOCK_PARAMETERS; ++ ++//Major revision=1., Minor revision=2, add ucMiscIfno ++//ucMiscInfo: ++#define MISC_FORCE_REPROG_PIXEL_CLOCK 0x1 ++#define MISC_DEVICE_INDEX_MASK 0xF0 ++#define MISC_DEVICE_INDEX_SHIFT 4 ++ ++typedef struct _PIXEL_CLOCK_PARAMETERS_V2 ++{ ++ USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) ++ // 0 means disable PPLL ++ USHORT usRefDiv; // Reference divider ++ USHORT usFbDiv; // feedback divider ++ UCHAR ucPostDiv; // post divider ++ UCHAR ucFracFbDiv; // fractional feedback divider ++ UCHAR ucPpll; // ATOM_PPLL1 or ATOM_PPL2 ++ UCHAR ucRefDivSrc; // ATOM_PJITTER or ATO_NONPJITTER ++ UCHAR ucCRTC; // Which CRTC uses this Ppll ++ UCHAR ucMiscInfo; // Different bits for different purpose, bit [7:4] as device index, bit[0]=Force prog ++}PIXEL_CLOCK_PARAMETERS_V2; ++ ++//Major revision=1., Minor revision=3, structure/definition change ++//ucEncoderMode: ++//ATOM_ENCODER_MODE_DP ++//ATOM_ENOCDER_MODE_LVDS ++//ATOM_ENOCDER_MODE_DVI ++//ATOM_ENOCDER_MODE_HDMI ++//ATOM_ENOCDER_MODE_SDVO ++//ATOM_ENCODER_MODE_TV 13 ++//ATOM_ENCODER_MODE_CV 14 ++//ATOM_ENCODER_MODE_CRT 15 ++ ++//ucDVOConfig ++//#define DVO_ENCODER_CONFIG_RATE_SEL 0x01 ++//#define DVO_ENCODER_CONFIG_DDR_SPEED 0x00 ++//#define DVO_ENCODER_CONFIG_SDR_SPEED 0x01 ++//#define DVO_ENCODER_CONFIG_OUTPUT_SEL 0x0c ++//#define DVO_ENCODER_CONFIG_LOW12BIT 0x00 ++//#define DVO_ENCODER_CONFIG_UPPER12BIT 0x04 ++//#define DVO_ENCODER_CONFIG_24BIT 0x08 ++ ++//ucMiscInfo: also changed, see below ++#define PIXEL_CLOCK_MISC_FORCE_PROG_PPLL 0x01 ++#define PIXEL_CLOCK_MISC_VGA_MODE 0x02 ++#define PIXEL_CLOCK_MISC_CRTC_SEL_MASK 0x04 ++#define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1 0x00 ++#define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2 0x04 ++#define PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK 0x08 ++ ++typedef struct _PIXEL_CLOCK_PARAMETERS_V3 ++{ ++ USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) ++ // 0 means disable PPLL. For VGA PPLL,make sure this value is not 0. ++ USHORT usRefDiv; // Reference divider ++ USHORT usFbDiv; // feedback divider ++ UCHAR ucPostDiv; // post divider ++ UCHAR ucFracFbDiv; // fractional feedback divider ++ UCHAR ucPpll; // ATOM_PPLL1 or ATOM_PPL2 ++ UCHAR ucTransmitterId; // graphic encoder id defined in objectId.h ++ union ++ { ++ UCHAR ucEncoderMode; // encoder type defined as ATOM_ENCODER_MODE_DP/DVI/HDMI/ ++ UCHAR ucDVOConfig; // when use DVO, need to know SDR/DDR, 12bit or 24bit ++ }; ++ UCHAR ucMiscInfo; // bit[0]=Force program, bit[1]= set pclk for VGA, b[2]= CRTC sel ++ // bit[3]=0:use PPLL for dispclk source, =1: use engine clock for dispclock source ++}PIXEL_CLOCK_PARAMETERS_V3; ++ ++#define PIXEL_CLOCK_PARAMETERS_LAST PIXEL_CLOCK_PARAMETERS_V2 ++#define GET_PIXEL_CLOCK_PS_ALLOCATION PIXEL_CLOCK_PARAMETERS_LAST ++ ++/****************************************************************************/ ++// Structures used by AdjustDisplayPllTable ++/****************************************************************************/ ++typedef struct _ADJUST_DISPLAY_PLL_PARAMETERS ++{ ++ USHORT usPixelClock; ++ UCHAR ucTransmitterID; ++ UCHAR ucEncodeMode; ++ union ++ { ++ UCHAR ucDVOConfig; //if DVO, need passing link rate and output 12bitlow or 24bit ++ UCHAR ucConfig; //if none DVO, not defined yet ++ }; ++ UCHAR ucReserved[3]; ++}ADJUST_DISPLAY_PLL_PARAMETERS; ++ ++#define ADJUST_DISPLAY_CONFIG_SS_ENABLE 0x10 ++ ++#define ADJUST_DISPLAY_PLL_PS_ALLOCATION ADJUST_DISPLAY_PLL_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by EnableYUVTable ++/****************************************************************************/ ++typedef struct _ENABLE_YUV_PARAMETERS ++{ ++ UCHAR ucEnable; // ATOM_ENABLE:Enable YUV or ATOM_DISABLE:Disable YUV (RGB) ++ UCHAR ucCRTC; // Which CRTC needs this YUV or RGB format ++ UCHAR ucPadding[2]; ++}ENABLE_YUV_PARAMETERS; ++#define ENABLE_YUV_PS_ALLOCATION ENABLE_YUV_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by GetMemoryClockTable ++/****************************************************************************/ ++typedef struct _GET_MEMORY_CLOCK_PARAMETERS ++{ ++ ULONG ulReturnMemoryClock; // current memory speed in 10KHz unit ++} GET_MEMORY_CLOCK_PARAMETERS; ++#define GET_MEMORY_CLOCK_PS_ALLOCATION GET_MEMORY_CLOCK_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by GetEngineClockTable ++/****************************************************************************/ ++typedef struct _GET_ENGINE_CLOCK_PARAMETERS ++{ ++ ULONG ulReturnEngineClock; // current engine speed in 10KHz unit ++} GET_ENGINE_CLOCK_PARAMETERS; ++#define GET_ENGINE_CLOCK_PS_ALLOCATION GET_ENGINE_CLOCK_PARAMETERS ++ ++/****************************************************************************/ ++// Following Structures and constant may be obsolete ++/****************************************************************************/ ++//Maxium 8 bytes,the data read in will be placed in the parameter space. ++//Read operaion successeful when the paramter space is non-zero, otherwise read operation failed ++typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS ++{ ++ USHORT usPrescale; //Ratio between Engine clock and I2C clock ++ USHORT usVRAMAddress; //Adress in Frame Buffer where to pace raw EDID ++ USHORT usStatus; //When use output: lower byte EDID checksum, high byte hardware status ++ //WHen use input: lower byte as 'byte to read':currently limited to 128byte or 1byte ++ UCHAR ucSlaveAddr; //Read from which slave ++ UCHAR ucLineNumber; //Read from which HW assisted line ++}READ_EDID_FROM_HW_I2C_DATA_PARAMETERS; ++#define READ_EDID_FROM_HW_I2C_DATA_PS_ALLOCATION READ_EDID_FROM_HW_I2C_DATA_PARAMETERS ++ ++ ++#define ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSDATABYTE 0 ++#define ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSTWODATABYTES 1 ++#define ATOM_WRITE_I2C_FORMAT_PSCOUNTER_PSOFFSET_IDDATABLOCK 2 ++#define ATOM_WRITE_I2C_FORMAT_PSCOUNTER_IDOFFSET_PLUS_IDDATABLOCK 3 ++#define ATOM_WRITE_I2C_FORMAT_IDCOUNTER_IDOFFSET_IDDATABLOCK 4 ++ ++typedef struct _WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS ++{ ++ USHORT usPrescale; //Ratio between Engine clock and I2C clock ++ USHORT usByteOffset; //Write to which byte ++ //Upper portion of usByteOffset is Format of data ++ //1bytePS+offsetPS ++ //2bytesPS+offsetPS ++ //blockID+offsetPS ++ //blockID+offsetID ++ //blockID+counterID+offsetID ++ UCHAR ucData; //PS data1 ++ UCHAR ucStatus; //Status byte 1=success, 2=failure, Also is used as PS data2 ++ UCHAR ucSlaveAddr; //Write to which slave ++ UCHAR ucLineNumber; //Write from which HW assisted line ++}WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS; ++ ++#define WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS ++ ++typedef struct _SET_UP_HW_I2C_DATA_PARAMETERS ++{ ++ USHORT usPrescale; //Ratio between Engine clock and I2C clock ++ UCHAR ucSlaveAddr; //Write to which slave ++ UCHAR ucLineNumber; //Write from which HW assisted line ++}SET_UP_HW_I2C_DATA_PARAMETERS; ++ ++ ++/**************************************************************************/ ++#define SPEED_FAN_CONTROL_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS ++ ++/****************************************************************************/ ++// Structures used by PowerConnectorDetectionTable ++/****************************************************************************/ ++typedef struct _POWER_CONNECTOR_DETECTION_PARAMETERS ++{ ++ UCHAR ucPowerConnectorStatus; //Used for return value 0: detected, 1:not detected ++ UCHAR ucPwrBehaviorId; ++ USHORT usPwrBudget; //how much power currently boot to in unit of watt ++}POWER_CONNECTOR_DETECTION_PARAMETERS; ++ ++typedef struct POWER_CONNECTOR_DETECTION_PS_ALLOCATION ++{ ++ UCHAR ucPowerConnectorStatus; //Used for return value 0: detected, 1:not detected ++ UCHAR ucReserved; ++ USHORT usPwrBudget; //how much power currently boot to in unit of watt ++ WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; ++}POWER_CONNECTOR_DETECTION_PS_ALLOCATION; ++ ++/****************************LVDS SS Command Table Definitions**********************/ ++ ++/****************************************************************************/ ++// Structures used by EnableSpreadSpectrumOnPPLLTable ++/****************************************************************************/ ++typedef struct _ENABLE_LVDS_SS_PARAMETERS ++{ ++ USHORT usSpreadSpectrumPercentage; ++ UCHAR ucSpreadSpectrumType; //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD ++ UCHAR ucSpreadSpectrumStepSize_Delay; //bits3:2 SS_STEP_SIZE; bit 6:4 SS_DELAY ++ UCHAR ucEnable; //ATOM_ENABLE or ATOM_DISABLE ++ UCHAR ucPadding[3]; ++}ENABLE_LVDS_SS_PARAMETERS; ++ ++//ucTableFormatRevision=1,ucTableContentRevision=2 ++typedef struct _ENABLE_LVDS_SS_PARAMETERS_V2 ++{ ++ USHORT usSpreadSpectrumPercentage; ++ UCHAR ucSpreadSpectrumType; //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD ++ UCHAR ucSpreadSpectrumStep; // ++ UCHAR ucEnable; //ATOM_ENABLE or ATOM_DISABLE ++ UCHAR ucSpreadSpectrumDelay; ++ UCHAR ucSpreadSpectrumRange; ++ UCHAR ucPadding; ++}ENABLE_LVDS_SS_PARAMETERS_V2; ++ ++//This new structure is based on ENABLE_LVDS_SS_PARAMETERS but expands to SS on PPLL, so other devices can use SS. ++typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL ++{ ++ USHORT usSpreadSpectrumPercentage; ++ UCHAR ucSpreadSpectrumType; // Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD ++ UCHAR ucSpreadSpectrumStep; // ++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE ++ UCHAR ucSpreadSpectrumDelay; ++ UCHAR ucSpreadSpectrumRange; ++ UCHAR ucPpll; // ATOM_PPLL1/ATOM_PPLL2 ++}ENABLE_SPREAD_SPECTRUM_ON_PPLL; ++ ++#define ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION ENABLE_SPREAD_SPECTRUM_ON_PPLL ++ ++/**************************************************************************/ ++ ++typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION ++{ ++ PIXEL_CLOCK_PARAMETERS sPCLKInput; ++ ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;//Caller doesn't need to init this portion ++}SET_PIXEL_CLOCK_PS_ALLOCATION; ++ ++#define ENABLE_VGA_RENDER_PS_ALLOCATION SET_PIXEL_CLOCK_PS_ALLOCATION ++ ++/****************************************************************************/ ++// Structures used by ### ++/****************************************************************************/ ++typedef struct _MEMORY_TRAINING_PARAMETERS ++{ ++ ULONG ulTargetMemoryClock; //In 10Khz unit ++}MEMORY_TRAINING_PARAMETERS; ++#define MEMORY_TRAINING_PS_ALLOCATION MEMORY_TRAINING_PARAMETERS ++ ++ ++/****************************LVDS and other encoder command table definitions **********************/ ++ ++ ++/****************************************************************************/ ++// Structures used by LVDSEncoderControlTable (Before DCE30) ++// LVTMAEncoderControlTable (Before DCE30) ++// TMDSAEncoderControlTable (Before DCE30) ++/****************************************************************************/ ++typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS ++{ ++ USHORT usPixelClock; // in 10KHz; for bios convenient ++ UCHAR ucMisc; // bit0=0: Enable single link ++ // =1: Enable dual link ++ // Bit1=0: 666RGB ++ // =1: 888RGB ++ UCHAR ucAction; // 0: turn off encoder ++ // 1: setup and turn on encoder ++}LVDS_ENCODER_CONTROL_PARAMETERS; ++ ++#define LVDS_ENCODER_CONTROL_PS_ALLOCATION LVDS_ENCODER_CONTROL_PARAMETERS ++ ++#define TMDS1_ENCODER_CONTROL_PARAMETERS LVDS_ENCODER_CONTROL_PARAMETERS ++#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION TMDS1_ENCODER_CONTROL_PARAMETERS ++ ++#define TMDS2_ENCODER_CONTROL_PARAMETERS TMDS1_ENCODER_CONTROL_PARAMETERS ++#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION TMDS2_ENCODER_CONTROL_PARAMETERS ++ ++ ++//ucTableFormatRevision=1,ucTableContentRevision=2 ++typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 ++{ ++ USHORT usPixelClock; // in 10KHz; for bios convenient ++ UCHAR ucMisc; // see PANEL_ENCODER_MISC_xx defintions below ++ UCHAR ucAction; // 0: turn off encoder ++ // 1: setup and turn on encoder ++ UCHAR ucTruncate; // bit0=0: Disable truncate ++ // =1: Enable truncate ++ // bit4=0: 666RGB ++ // =1: 888RGB ++ UCHAR ucSpatial; // bit0=0: Disable spatial dithering ++ // =1: Enable spatial dithering ++ // bit4=0: 666RGB ++ // =1: 888RGB ++ UCHAR ucTemporal; // bit0=0: Disable temporal dithering ++ // =1: Enable temporal dithering ++ // bit4=0: 666RGB ++ // =1: 888RGB ++ // bit5=0: Gray level 2 ++ // =1: Gray level 4 ++ UCHAR ucFRC; // bit4=0: 25FRC_SEL pattern E ++ // =1: 25FRC_SEL pattern F ++ // bit6:5=0: 50FRC_SEL pattern A ++ // =1: 50FRC_SEL pattern B ++ // =2: 50FRC_SEL pattern C ++ // =3: 50FRC_SEL pattern D ++ // bit7=0: 75FRC_SEL pattern E ++ // =1: 75FRC_SEL pattern F ++}LVDS_ENCODER_CONTROL_PARAMETERS_V2; ++ ++#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 LVDS_ENCODER_CONTROL_PARAMETERS_V2 ++ ++#define TMDS1_ENCODER_CONTROL_PARAMETERS_V2 LVDS_ENCODER_CONTROL_PARAMETERS_V2 ++#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_V2 TMDS1_ENCODER_CONTROL_PARAMETERS_V2 ++ ++#define TMDS2_ENCODER_CONTROL_PARAMETERS_V2 TMDS1_ENCODER_CONTROL_PARAMETERS_V2 ++#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_V2 TMDS2_ENCODER_CONTROL_PARAMETERS_V2 ++ ++#define LVDS_ENCODER_CONTROL_PARAMETERS_V3 LVDS_ENCODER_CONTROL_PARAMETERS_V2 ++#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_V3 LVDS_ENCODER_CONTROL_PARAMETERS_V3 ++ ++#define TMDS1_ENCODER_CONTROL_PARAMETERS_V3 LVDS_ENCODER_CONTROL_PARAMETERS_V3 ++#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_V3 TMDS1_ENCODER_CONTROL_PARAMETERS_V3 ++ ++#define TMDS2_ENCODER_CONTROL_PARAMETERS_V3 LVDS_ENCODER_CONTROL_PARAMETERS_V3 ++#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_V3 TMDS2_ENCODER_CONTROL_PARAMETERS_V3 ++ ++/****************************************************************************/ ++// Structures used by ### ++/****************************************************************************/ ++typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS ++{ ++ UCHAR ucEnable; // Enable or Disable External TMDS encoder ++ UCHAR ucMisc; // Bit0=0:Enable Single link;=1:Enable Dual link;Bit1 {=0:666RGB, =1:888RGB} ++ UCHAR ucPadding[2]; ++}ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS; ++ ++typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ++{ ++ ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS sXTmdsEncoder; ++ WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; //Caller doesn't need to init this portion ++}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION; ++ ++#define ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2 LVDS_ENCODER_CONTROL_PARAMETERS_V2 ++ ++typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2 ++{ ++ ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2 sXTmdsEncoder; ++ WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; //Caller doesn't need to init this portion ++}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2; ++ ++typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION ++{ ++ DIG_ENCODER_CONTROL_PARAMETERS sDigEncoder; ++ WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; ++}EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION; ++ ++/****************************************************************************/ ++// Structures used by DVOEncoderControlTable ++/****************************************************************************/ ++//ucTableFormatRevision=1,ucTableContentRevision=3 ++ ++//ucDVOConfig: ++#define DVO_ENCODER_CONFIG_RATE_SEL 0x01 ++#define DVO_ENCODER_CONFIG_DDR_SPEED 0x00 ++#define DVO_ENCODER_CONFIG_SDR_SPEED 0x01 ++#define DVO_ENCODER_CONFIG_OUTPUT_SEL 0x0c ++#define DVO_ENCODER_CONFIG_LOW12BIT 0x00 ++#define DVO_ENCODER_CONFIG_UPPER12BIT 0x04 ++#define DVO_ENCODER_CONFIG_24BIT 0x08 ++ ++typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3 ++{ ++ USHORT usPixelClock; ++ UCHAR ucDVOConfig; ++ UCHAR ucAction; //ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT ++ UCHAR ucReseved[4]; ++}DVO_ENCODER_CONTROL_PARAMETERS_V3; ++#define DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 DVO_ENCODER_CONTROL_PARAMETERS_V3 ++ ++//ucTableFormatRevision=1 ++//ucTableContentRevision=3 structure is not changed but usMisc add bit 1 as another input for ++// bit1=0: non-coherent mode ++// =1: coherent mode ++ ++//========================================================================================== ++//Only change is here next time when changing encoder parameter definitions again! ++#define LVDS_ENCODER_CONTROL_PARAMETERS_LAST LVDS_ENCODER_CONTROL_PARAMETERS_V3 ++#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_LAST LVDS_ENCODER_CONTROL_PARAMETERS_LAST ++ ++#define TMDS1_ENCODER_CONTROL_PARAMETERS_LAST LVDS_ENCODER_CONTROL_PARAMETERS_V3 ++#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_LAST TMDS1_ENCODER_CONTROL_PARAMETERS_LAST ++ ++#define TMDS2_ENCODER_CONTROL_PARAMETERS_LAST LVDS_ENCODER_CONTROL_PARAMETERS_V3 ++#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_LAST TMDS2_ENCODER_CONTROL_PARAMETERS_LAST ++ ++#define DVO_ENCODER_CONTROL_PARAMETERS_LAST DVO_ENCODER_CONTROL_PARAMETERS ++#define DVO_ENCODER_CONTROL_PS_ALLOCATION_LAST DVO_ENCODER_CONTROL_PS_ALLOCATION ++ ++//========================================================================================== ++#define PANEL_ENCODER_MISC_DUAL 0x01 ++#define PANEL_ENCODER_MISC_COHERENT 0x02 ++#define PANEL_ENCODER_MISC_TMDS_LINKB 0x04 ++#define PANEL_ENCODER_MISC_HDMI_TYPE 0x08 ++ ++#define PANEL_ENCODER_ACTION_DISABLE ATOM_DISABLE ++#define PANEL_ENCODER_ACTION_ENABLE ATOM_ENABLE ++#define PANEL_ENCODER_ACTION_COHERENTSEQ (ATOM_ENABLE+1) ++ ++#define PANEL_ENCODER_TRUNCATE_EN 0x01 ++#define PANEL_ENCODER_TRUNCATE_DEPTH 0x10 ++#define PANEL_ENCODER_SPATIAL_DITHER_EN 0x01 ++#define PANEL_ENCODER_SPATIAL_DITHER_DEPTH 0x10 ++#define PANEL_ENCODER_TEMPORAL_DITHER_EN 0x01 ++#define PANEL_ENCODER_TEMPORAL_DITHER_DEPTH 0x10 ++#define PANEL_ENCODER_TEMPORAL_LEVEL_4 0x20 ++#define PANEL_ENCODER_25FRC_MASK 0x10 ++#define PANEL_ENCODER_25FRC_E 0x00 ++#define PANEL_ENCODER_25FRC_F 0x10 ++#define PANEL_ENCODER_50FRC_MASK 0x60 ++#define PANEL_ENCODER_50FRC_A 0x00 ++#define PANEL_ENCODER_50FRC_B 0x20 ++#define PANEL_ENCODER_50FRC_C 0x40 ++#define PANEL_ENCODER_50FRC_D 0x60 ++#define PANEL_ENCODER_75FRC_MASK 0x80 ++#define PANEL_ENCODER_75FRC_E 0x00 ++#define PANEL_ENCODER_75FRC_F 0x80 ++ ++/****************************************************************************/ ++// Structures used by SetVoltageTable ++/****************************************************************************/ ++#define SET_VOLTAGE_TYPE_ASIC_VDDC 1 ++#define SET_VOLTAGE_TYPE_ASIC_MVDDC 2 ++#define SET_VOLTAGE_TYPE_ASIC_MVDDQ 3 ++#define SET_VOLTAGE_TYPE_ASIC_VDDCI 4 ++#define SET_VOLTAGE_INIT_MODE 5 ++#define SET_VOLTAGE_GET_MAX_VOLTAGE 6 //Gets the Max. voltage for the soldered Asic ++ ++#define SET_ASIC_VOLTAGE_MODE_ALL_SOURCE 0x1 ++#define SET_ASIC_VOLTAGE_MODE_SOURCE_A 0x2 ++#define SET_ASIC_VOLTAGE_MODE_SOURCE_B 0x4 ++ ++#define SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE 0x0 ++#define SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL 0x1 ++#define SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK 0x2 ++ ++typedef struct _SET_VOLTAGE_PARAMETERS ++{ ++ UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ ++ UCHAR ucVoltageMode; // To set all, to set source A or source B or ... ++ UCHAR ucVoltageIndex; // An index to tell which voltage level ++ UCHAR ucReserved; ++}SET_VOLTAGE_PARAMETERS; ++ ++typedef struct _SET_VOLTAGE_PARAMETERS_V2 ++{ ++ UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ ++ UCHAR ucVoltageMode; // Not used, maybe use for state machine for differen power mode ++ USHORT usVoltageLevel; // real voltage level ++}SET_VOLTAGE_PARAMETERS_V2; ++ ++typedef struct _SET_VOLTAGE_PS_ALLOCATION ++{ ++ SET_VOLTAGE_PARAMETERS sASICSetVoltage; ++ WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; ++}SET_VOLTAGE_PS_ALLOCATION; ++ ++/****************************************************************************/ ++// Structures used by TVEncoderControlTable ++/****************************************************************************/ ++typedef struct _TV_ENCODER_CONTROL_PARAMETERS ++{ ++ USHORT usPixelClock; // in 10KHz; for bios convenient ++ UCHAR ucTvStandard; // See definition "ATOM_TV_NTSC ..." ++ UCHAR ucAction; // 0: turn off encoder ++ // 1: setup and turn on encoder ++}TV_ENCODER_CONTROL_PARAMETERS; ++ ++typedef struct _TV_ENCODER_CONTROL_PS_ALLOCATION ++{ ++ TV_ENCODER_CONTROL_PARAMETERS sTVEncoder; ++ WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; // Don't set this one ++}TV_ENCODER_CONTROL_PS_ALLOCATION; ++ ++//==============================Data Table Portion==================================== ++ ++#ifdef UEFI_BUILD ++ #define UTEMP USHORT ++ #define USHORT void* ++#endif ++ ++/****************************************************************************/ ++// Structure used in Data.mtb ++/****************************************************************************/ ++typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES ++{ ++ USHORT UtilityPipeLine; // Offest for the utility to get parser info,Don't change this position! ++ USHORT MultimediaCapabilityInfo; // Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios ++ USHORT MultimediaConfigInfo; // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios ++ USHORT StandardVESA_Timing; // Only used by Bios ++ USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4 ++ USHORT DAC_Info; // Will be obsolete from R600 ++ USHORT LVDS_Info; // Shared by various SW components,latest version 1.1 ++ USHORT TMDS_Info; // Will be obsolete from R600 ++ USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1 ++ USHORT SupportedDevicesInfo; // Will be obsolete from R600 ++ USHORT GPIO_I2C_Info; // Shared by various SW components,latest version 1.2 will be used from R600 ++ USHORT VRAM_UsageByFirmware; // Shared by various SW components,latest version 1.3 will be used from R600 ++ USHORT GPIO_Pin_LUT; // Shared by various SW components,latest version 1.1 ++ USHORT VESA_ToInternalModeLUT; // Only used by Bios ++ USHORT ComponentVideoInfo; // Shared by various SW components,latest version 2.1 will be used from R600 ++ USHORT PowerPlayInfo; // Shared by various SW components,latest version 2.1,new design from R600 ++ USHORT CompassionateData; // Will be obsolete from R600 ++ USHORT SaveRestoreInfo; // Only used by Bios ++ USHORT PPLL_SS_Info; // Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info ++ USHORT OemInfo; // Defined and used by external SW, should be obsolete soon ++ USHORT XTMDS_Info; // Will be obsolete from R600 ++ USHORT MclkSS_Info; // Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used ++ USHORT Object_Header; // Shared by various SW components,latest version 1.1 ++ USHORT IndirectIOAccess; // Only used by Bios,this table position can't change at all!! ++ USHORT MC_InitParameter; // Only used by command table ++ USHORT ASIC_VDDC_Info; // Will be obsolete from R600 ++ USHORT ASIC_InternalSS_Info; // New tabel name from R600, used to be called "ASIC_MVDDC_Info" ++ USHORT TV_VideoMode; // Only used by command table ++ USHORT VRAM_Info; // Only used by command table, latest version 1.3 ++ USHORT MemoryTrainingInfo; // Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1 ++ USHORT IntegratedSystemInfo; // Shared by various SW components ++ USHORT ASIC_ProfilingInfo; // New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600 ++ USHORT VoltageObjectInfo; // Shared by various SW components, latest version 1.1 ++ USHORT PowerSourceInfo; // Shared by various SW components, latest versoin 1.1 ++}ATOM_MASTER_LIST_OF_DATA_TABLES; ++ ++#ifdef UEFI_BUILD ++ #define USHORT UTEMP ++#endif ++ ++typedef struct _ATOM_MASTER_DATA_TABLE ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables; ++}ATOM_MASTER_DATA_TABLE; ++ ++/****************************************************************************/ ++// Structure used in MultimediaCapabilityInfoTable ++/****************************************************************************/ ++typedef struct _ATOM_MULTIMEDIA_CAPABILITY_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ULONG ulSignature; // HW info table signature string "$ATI" ++ UCHAR ucI2C_Type; // I2C type (normal GP_IO, ImpactTV GP_IO, Dedicated I2C pin, etc) ++ UCHAR ucTV_OutInfo; // Type of TV out supported (3:0) and video out crystal frequency (6:4) and TV data port (7) ++ UCHAR ucVideoPortInfo; // Provides the video port capabilities ++ UCHAR ucHostPortInfo; // Provides host port configuration information ++}ATOM_MULTIMEDIA_CAPABILITY_INFO; ++ ++/****************************************************************************/ ++// Structure used in MultimediaConfigInfoTable ++/****************************************************************************/ ++typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ULONG ulSignature; // MM info table signature sting "$MMT" ++ UCHAR ucTunerInfo; // Type of tuner installed on the adapter (4:0) and video input for tuner (7:5) ++ UCHAR ucAudioChipInfo; // List the audio chip type (3:0) product type (4) and OEM revision (7:5) ++ UCHAR ucProductID; // Defines as OEM ID or ATI board ID dependent on product type setting ++ UCHAR ucMiscInfo1; // Tuner voltage (1:0) HW teletext support (3:2) FM audio decoder (5:4) reserved (6) audio scrambling (7) ++ UCHAR ucMiscInfo2; // I2S input config (0) I2S output config (1) I2S Audio Chip (4:2) SPDIF Output Config (5) reserved (7:6) ++ UCHAR ucMiscInfo3; // Video Decoder Type (3:0) Video In Standard/Crystal (7:4) ++ UCHAR ucMiscInfo4; // Video Decoder Host Config (2:0) reserved (7:3) ++ UCHAR ucVideoInput0Info;// Video Input 0 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) ++ UCHAR ucVideoInput1Info;// Video Input 1 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) ++ UCHAR ucVideoInput2Info;// Video Input 2 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) ++ UCHAR ucVideoInput3Info;// Video Input 3 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) ++ UCHAR ucVideoInput4Info;// Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) ++}ATOM_MULTIMEDIA_CONFIG_INFO; ++ ++/****************************************************************************/ ++// Structures used in FirmwareInfoTable ++/****************************************************************************/ ++ ++// usBIOSCapability Defintion: ++// Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; ++// Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; ++// Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; ++// Others: Reserved ++#define ATOM_BIOS_INFO_ATOM_FIRMWARE_POSTED 0x0001 ++#define ATOM_BIOS_INFO_DUAL_CRTC_SUPPORT 0x0002 ++#define ATOM_BIOS_INFO_EXTENDED_DESKTOP_SUPPORT 0x0004 ++#define ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT 0x0008 ++#define ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT 0x0010 ++#define ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU 0x0020 ++#define ATOM_BIOS_INFO_WMI_SUPPORT 0x0040 ++#define ATOM_BIOS_INFO_PPMODE_ASSIGNGED_BY_SYSTEM 0x0080 ++#define ATOM_BIOS_INFO_HYPERMEMORY_SUPPORT 0x0100 ++#define ATOM_BIOS_INFO_HYPERMEMORY_SIZE_MASK 0x1E00 ++#define ATOM_BIOS_INFO_VPOST_WITHOUT_FIRST_MODE_SET 0x2000 ++#define ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE 0x4000 ++ ++ ++#ifndef _H2INC ++ ++//Please don't add or expand this bitfield structure below, this one will retire soon.! ++typedef struct _ATOM_FIRMWARE_CAPABILITY ++{ ++#if ATOM_BIG_ENDIAN ++ USHORT Reserved:3; ++ USHORT HyperMemory_Size:4; ++ USHORT HyperMemory_Support:1; ++ USHORT PPMode_Assigned:1; ++ USHORT WMI_SUPPORT:1; ++ USHORT GPUControlsBL:1; ++ USHORT EngineClockSS_Support:1; ++ USHORT MemoryClockSS_Support:1; ++ USHORT ExtendedDesktopSupport:1; ++ USHORT DualCRTC_Support:1; ++ USHORT FirmwarePosted:1; ++#else ++ USHORT FirmwarePosted:1; ++ USHORT DualCRTC_Support:1; ++ USHORT ExtendedDesktopSupport:1; ++ USHORT MemoryClockSS_Support:1; ++ USHORT EngineClockSS_Support:1; ++ USHORT GPUControlsBL:1; ++ USHORT WMI_SUPPORT:1; ++ USHORT PPMode_Assigned:1; ++ USHORT HyperMemory_Support:1; ++ USHORT HyperMemory_Size:4; ++ USHORT Reserved:3; ++#endif ++}ATOM_FIRMWARE_CAPABILITY; ++ ++typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS ++{ ++ ATOM_FIRMWARE_CAPABILITY sbfAccess; ++ USHORT susAccess; ++}ATOM_FIRMWARE_CAPABILITY_ACCESS; ++ ++#else ++ ++typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS ++{ ++ USHORT susAccess; ++}ATOM_FIRMWARE_CAPABILITY_ACCESS; ++ ++#endif ++ ++typedef struct _ATOM_FIRMWARE_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ULONG ulFirmwareRevision; ++ ULONG ulDefaultEngineClock; //In 10Khz unit ++ ULONG ulDefaultMemoryClock; //In 10Khz unit ++ ULONG ulDriverTargetEngineClock; //In 10Khz unit ++ ULONG ulDriverTargetMemoryClock; //In 10Khz unit ++ ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit ++ ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit ++ ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit ++ ULONG ulASICMaxEngineClock; //In 10Khz unit ++ ULONG ulASICMaxMemoryClock; //In 10Khz unit ++ UCHAR ucASICMaxTemperature; ++ UCHAR ucPadding[3]; //Don't use them ++ ULONG aulReservedForBIOS[3]; //Don't use them ++ USHORT usMinEngineClockPLL_Input; //In 10Khz unit ++ USHORT usMaxEngineClockPLL_Input; //In 10Khz unit ++ USHORT usMinEngineClockPLL_Output; //In 10Khz unit ++ USHORT usMinMemoryClockPLL_Input; //In 10Khz unit ++ USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit ++ USHORT usMinMemoryClockPLL_Output; //In 10Khz unit ++ USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk ++ USHORT usMinPixelClockPLL_Input; //In 10Khz unit ++ USHORT usMaxPixelClockPLL_Input; //In 10Khz unit ++ USHORT usMinPixelClockPLL_Output; //In 10Khz unit, the definitions above can't change!!! ++ ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; ++ USHORT usReferenceClock; //In 10Khz unit ++ USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit ++ UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit ++ UCHAR ucDesign_ID; //Indicate what is the board design ++ UCHAR ucMemoryModule_ID; //Indicate what is the board design ++}ATOM_FIRMWARE_INFO; ++ ++typedef struct _ATOM_FIRMWARE_INFO_V1_2 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ULONG ulFirmwareRevision; ++ ULONG ulDefaultEngineClock; //In 10Khz unit ++ ULONG ulDefaultMemoryClock; //In 10Khz unit ++ ULONG ulDriverTargetEngineClock; //In 10Khz unit ++ ULONG ulDriverTargetMemoryClock; //In 10Khz unit ++ ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit ++ ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit ++ ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit ++ ULONG ulASICMaxEngineClock; //In 10Khz unit ++ ULONG ulASICMaxMemoryClock; //In 10Khz unit ++ UCHAR ucASICMaxTemperature; ++ UCHAR ucMinAllowedBL_Level; ++ UCHAR ucPadding[2]; //Don't use them ++ ULONG aulReservedForBIOS[2]; //Don't use them ++ ULONG ulMinPixelClockPLL_Output; //In 10Khz unit ++ USHORT usMinEngineClockPLL_Input; //In 10Khz unit ++ USHORT usMaxEngineClockPLL_Input; //In 10Khz unit ++ USHORT usMinEngineClockPLL_Output; //In 10Khz unit ++ USHORT usMinMemoryClockPLL_Input; //In 10Khz unit ++ USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit ++ USHORT usMinMemoryClockPLL_Output; //In 10Khz unit ++ USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk ++ USHORT usMinPixelClockPLL_Input; //In 10Khz unit ++ USHORT usMaxPixelClockPLL_Input; //In 10Khz unit ++ USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output ++ ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; ++ USHORT usReferenceClock; //In 10Khz unit ++ USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit ++ UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit ++ UCHAR ucDesign_ID; //Indicate what is the board design ++ UCHAR ucMemoryModule_ID; //Indicate what is the board design ++}ATOM_FIRMWARE_INFO_V1_2; ++ ++typedef struct _ATOM_FIRMWARE_INFO_V1_3 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ULONG ulFirmwareRevision; ++ ULONG ulDefaultEngineClock; //In 10Khz unit ++ ULONG ulDefaultMemoryClock; //In 10Khz unit ++ ULONG ulDriverTargetEngineClock; //In 10Khz unit ++ ULONG ulDriverTargetMemoryClock; //In 10Khz unit ++ ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit ++ ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit ++ ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit ++ ULONG ulASICMaxEngineClock; //In 10Khz unit ++ ULONG ulASICMaxMemoryClock; //In 10Khz unit ++ UCHAR ucASICMaxTemperature; ++ UCHAR ucMinAllowedBL_Level; ++ UCHAR ucPadding[2]; //Don't use them ++ ULONG aulReservedForBIOS; //Don't use them ++ ULONG ul3DAccelerationEngineClock;//In 10Khz unit ++ ULONG ulMinPixelClockPLL_Output; //In 10Khz unit ++ USHORT usMinEngineClockPLL_Input; //In 10Khz unit ++ USHORT usMaxEngineClockPLL_Input; //In 10Khz unit ++ USHORT usMinEngineClockPLL_Output; //In 10Khz unit ++ USHORT usMinMemoryClockPLL_Input; //In 10Khz unit ++ USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit ++ USHORT usMinMemoryClockPLL_Output; //In 10Khz unit ++ USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk ++ USHORT usMinPixelClockPLL_Input; //In 10Khz unit ++ USHORT usMaxPixelClockPLL_Input; //In 10Khz unit ++ USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output ++ ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; ++ USHORT usReferenceClock; //In 10Khz unit ++ USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit ++ UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit ++ UCHAR ucDesign_ID; //Indicate what is the board design ++ UCHAR ucMemoryModule_ID; //Indicate what is the board design ++}ATOM_FIRMWARE_INFO_V1_3; ++ ++typedef struct _ATOM_FIRMWARE_INFO_V1_4 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ULONG ulFirmwareRevision; ++ ULONG ulDefaultEngineClock; //In 10Khz unit ++ ULONG ulDefaultMemoryClock; //In 10Khz unit ++ ULONG ulDriverTargetEngineClock; //In 10Khz unit ++ ULONG ulDriverTargetMemoryClock; //In 10Khz unit ++ ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit ++ ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit ++ ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit ++ ULONG ulASICMaxEngineClock; //In 10Khz unit ++ ULONG ulASICMaxMemoryClock; //In 10Khz unit ++ UCHAR ucASICMaxTemperature; ++ UCHAR ucMinAllowedBL_Level; ++ USHORT usBootUpVDDCVoltage; //In MV unit ++ USHORT usLcdMinPixelClockPLL_Output; // In MHz unit ++ USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit ++ ULONG ul3DAccelerationEngineClock;//In 10Khz unit ++ ULONG ulMinPixelClockPLL_Output; //In 10Khz unit ++ USHORT usMinEngineClockPLL_Input; //In 10Khz unit ++ USHORT usMaxEngineClockPLL_Input; //In 10Khz unit ++ USHORT usMinEngineClockPLL_Output; //In 10Khz unit ++ USHORT usMinMemoryClockPLL_Input; //In 10Khz unit ++ USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit ++ USHORT usMinMemoryClockPLL_Output; //In 10Khz unit ++ USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk ++ USHORT usMinPixelClockPLL_Input; //In 10Khz unit ++ USHORT usMaxPixelClockPLL_Input; //In 10Khz unit ++ USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output ++ ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; ++ USHORT usReferenceClock; //In 10Khz unit ++ USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit ++ UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit ++ UCHAR ucDesign_ID; //Indicate what is the board design ++ UCHAR ucMemoryModule_ID; //Indicate what is the board design ++}ATOM_FIRMWARE_INFO_V1_4; ++ ++#define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V1_4 ++ ++/****************************************************************************/ ++// Structures used in IntegratedSystemInfoTable ++/****************************************************************************/ ++#define IGP_CAP_FLAG_DYNAMIC_CLOCK_EN 0x2 ++#define IGP_CAP_FLAG_AC_CARD 0x4 ++#define IGP_CAP_FLAG_SDVO_CARD 0x8 ++#define IGP_CAP_FLAG_POSTDIV_BY_2_MODE 0x10 ++ ++typedef struct _ATOM_INTEGRATED_SYSTEM_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ULONG ulBootUpEngineClock; //in 10kHz unit ++ ULONG ulBootUpMemoryClock; //in 10kHz unit ++ ULONG ulMaxSystemMemoryClock; //in 10kHz unit ++ ULONG ulMinSystemMemoryClock; //in 10kHz unit ++ UCHAR ucNumberOfCyclesInPeriodHi; ++ UCHAR ucLCDTimingSel; //=0:not valid.!=0 sel this timing descriptor from LCD EDID. ++ USHORT usReserved1; ++ USHORT usInterNBVoltageLow; //An intermidiate PMW value to set the voltage ++ USHORT usInterNBVoltageHigh; //Another intermidiate PMW value to set the voltage ++ ULONG ulReserved[2]; ++ ++ USHORT usFSBClock; //In MHz unit ++ USHORT usCapabilityFlag; //Bit0=1 indicates the fake HDMI support,Bit1=0/1 for Dynamic clocking dis/enable ++ //Bit[3:2]== 0:No PCIE card, 1:AC card, 2:SDVO card ++ //Bit[4]==1: P/2 mode, ==0: P/1 mode ++ USHORT usPCIENBCfgReg7; //bit[7:0]=MUX_Sel, bit[9:8]=MUX_SEL_LEVEL2, bit[10]=Lane_Reversal ++ USHORT usK8MemoryClock; //in MHz unit ++ USHORT usK8SyncStartDelay; //in 0.01 us unit ++ USHORT usK8DataReturnTime; //in 0.01 us unit ++ UCHAR ucMaxNBVoltage; ++ UCHAR ucMinNBVoltage; ++ UCHAR ucMemoryType; //[7:4]=1:DDR1;=2:DDR2;=3:DDR3.[3:0] is reserved ++ UCHAR ucNumberOfCyclesInPeriod; //CG.FVTHROT_PWM_CTRL_REG0.NumberOfCyclesInPeriod ++ UCHAR ucStartingPWM_HighTime; //CG.FVTHROT_PWM_CTRL_REG0.StartingPWM_HighTime ++ UCHAR ucHTLinkWidth; //16 bit vs. 8 bit ++ UCHAR ucMaxNBVoltageHigh; ++ UCHAR ucMinNBVoltageHigh; ++}ATOM_INTEGRATED_SYSTEM_INFO; ++ ++/* Explanation on entries in ATOM_INTEGRATED_SYSTEM_INFO ++ulBootUpMemoryClock: For Intel IGP,it's the UMA system memory clock ++ For AMD IGP,it's 0 if no SidePort memory installed or it's the boot-up SidePort memory clock ++ulMaxSystemMemoryClock: For Intel IGP,it's the Max freq from memory SPD if memory runs in ASYNC mode or otherwise (SYNC mode) it's 0 ++ For AMD IGP,for now this can be 0 ++ulMinSystemMemoryClock: For Intel IGP,it's 133MHz if memory runs in ASYNC mode or otherwise (SYNC mode) it's 0 ++ For AMD IGP,for now this can be 0 ++ ++usFSBClock: For Intel IGP,it's FSB Freq ++ For AMD IGP,it's HT Link Speed ++ ++usK8MemoryClock: For AMD IGP only. For RevF CPU, set it to 200 ++usK8SyncStartDelay: For AMD IGP only. Memory access latency in K8, required for watermark calculation ++usK8DataReturnTime: For AMD IGP only. Memory access latency in K8, required for watermark calculation ++ ++VC:Voltage Control ++ucMaxNBVoltage: Voltage regulator dependent PWM value. Low 8 bits of the value for the max voltage.Set this one to 0xFF if VC without PWM. Set this to 0x0 if no VC at all. ++ucMinNBVoltage: Voltage regulator dependent PWM value. Low 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all. ++ ++ucNumberOfCyclesInPeriod: Indicate how many cycles when PWM duty is 100%. low 8 bits of the value. ++ucNumberOfCyclesInPeriodHi: Indicate how many cycles when PWM duty is 100%. high 8 bits of the value.If the PWM has an inverter,set bit [7]==1,otherwise set it 0 ++ ++ucMaxNBVoltageHigh: Voltage regulator dependent PWM value. High 8 bits of the value for the max voltage.Set this one to 0xFF if VC without PWM. Set this to 0x0 if no VC at all. ++ucMinNBVoltageHigh: Voltage regulator dependent PWM value. High 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all. ++ ++ ++usInterNBVoltageLow: Voltage regulator dependent PWM value. The value makes the the voltage >=Min NB voltage but <=InterNBVoltageHigh. Set this to 0x0000 if VC without PWM or no VC at all. ++usInterNBVoltageHigh: Voltage regulator dependent PWM value. The value makes the the voltage >=InterNBVoltageLow but <=Max NB voltage.Set this to 0x0000 if VC without PWM or no VC at all. ++*/ ++ ++ ++/* ++The following IGP table is introduced from RS780, which is supposed to be put by SBIOS in FB before IGP VBIOS starts VPOST; ++Then VBIOS will copy the whole structure to its image so all GPU SW components can access this data structure to get whatever they need. ++The enough reservation should allow us to never change table revisions. Whenever needed, a GPU SW component can use reserved portion for new data entries. ++ ++SW components can access the IGP system infor structure in the same way as before ++*/ ++ ++ ++typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ULONG ulBootUpEngineClock; //in 10kHz unit ++ ULONG ulReserved1[2]; //must be 0x0 for the reserved ++ ULONG ulBootUpUMAClock; //in 10kHz unit ++ ULONG ulBootUpSidePortClock; //in 10kHz unit ++ ULONG ulMinSidePortClock; //in 10kHz unit ++ ULONG ulReserved2[6]; //must be 0x0 for the reserved ++ ULONG ulSystemConfig; //see explanation below ++ ULONG ulBootUpReqDisplayVector; ++ ULONG ulOtherDisplayMisc; ++ ULONG ulDDISlot1Config; ++ ULONG ulDDISlot2Config; ++ UCHAR ucMemoryType; //[3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved ++ UCHAR ucUMAChannelNumber; ++ UCHAR ucDockingPinBit; ++ UCHAR ucDockingPinPolarity; ++ ULONG ulDockingPinCFGInfo; ++ ULONG ulCPUCapInfo; ++ USHORT usNumberOfCyclesInPeriod; ++ USHORT usMaxNBVoltage; ++ USHORT usMinNBVoltage; ++ USHORT usBootUpNBVoltage; ++ ULONG ulHTLinkFreq; //in 10Khz ++ USHORT usMinHTLinkWidth; ++ USHORT usMaxHTLinkWidth; ++ USHORT usUMASyncStartDelay; ++ USHORT usUMADataReturnTime; ++ USHORT usLinkStatusZeroTime; ++ USHORT usReserved; ++ ULONG ulHighVoltageHTLinkFreq; // in 10Khz ++ ULONG ulLowVoltageHTLinkFreq; // in 10Khz ++ USHORT usMaxUpStreamHTLinkWidth; ++ USHORT usMaxDownStreamHTLinkWidth; ++ USHORT usMinUpStreamHTLinkWidth; ++ USHORT usMinDownStreamHTLinkWidth; ++ ULONG ulReserved3[97]; //must be 0x0 ++}ATOM_INTEGRATED_SYSTEM_INFO_V2; ++ ++/* ++ulBootUpEngineClock: Boot-up Engine Clock in 10Khz; ++ulBootUpUMAClock: Boot-up UMA Clock in 10Khz; it must be 0x0 when UMA is not present ++ulBootUpSidePortClock: Boot-up SidePort Clock in 10Khz; it must be 0x0 when SidePort Memory is not present,this could be equal to or less than maximum supported Sideport memory clock ++ ++ulSystemConfig: ++Bit[0]=1: PowerExpress mode =0 Non-PowerExpress mode; ++Bit[1]=1: system boots up at AMD overdrived state or user customized mode. In this case, driver will just stick to this boot-up mode. No other PowerPlay state ++ =0: system boots up at driver control state. Power state depends on PowerPlay table. ++Bit[2]=1: PWM method is used on NB voltage control. =0: GPIO method is used. ++Bit[3]=1: Only one power state(Performance) will be supported. ++ =0: Multiple power states supported from PowerPlay table. ++Bit[4]=1: CLMC is supported and enabled on current system. ++ =0: CLMC is not supported or enabled on current system. SBIOS need to support HT link/freq change through ATIF interface. ++Bit[5]=1: Enable CDLW for all driver control power states. Max HT width is from SBIOS, while Min HT width is determined by display requirement. ++ =0: CDLW is disabled. If CLMC is enabled case, Min HT width will be set equal to Max HT width. If CLMC disabled case, Max HT width will be applied. ++Bit[6]=1: High Voltage requested for all power states. In this case, voltage will be forced at 1.1v and powerplay table voltage drop/throttling request will be ignored. ++ =0: Voltage settings is determined by powerplay table. ++Bit[7]=1: Enable CLMC as hybrid Mode. CDLD and CILR will be disabled in this case and we're using legacy C1E. This is workaround for CPU(Griffin) performance issue. ++ =0: Enable CLMC as regular mode, CDLD and CILR will be enabled. ++ ++ulBootUpReqDisplayVector: This dword is a bit vector indicates what display devices are requested during boot-up. Refer to ATOM_DEVICE_xxx_SUPPORT for the bit vector definitions. ++ ++ulOtherDisplayMisc: [15:8]- Bootup LCD Expansion selection; 0-center, 1-full panel size expansion; ++ [7:0] - BootupTV standard selection; This is a bit vector to indicate what TV standards are supported by the system. Refer to ucTVSuppportedStd definition; ++ ++ulDDISlot1Config: Describes the PCIE lane configuration on this DDI PCIE slot (ADD2 card) or connector (Mobile design). ++ [3:0] - Bit vector to indicate PCIE lane config of the DDI slot/connector on chassis (bit 0=1 lane 3:0; bit 1=1 lane 7:4; bit 2=1 lane 11:8; bit 3=1 lane 15:12) ++ [7:4] - Bit vector to indicate PCIE lane config of the same DDI slot/connector on docking station (bit 0=1 lane 3:0; bit 1=1 lane 7:4; bit 2=1 lane 11:8; bit 3=1 lane 15:12) ++ [15:8] - Lane configuration attribute; ++ [23:16]- Connector type, possible value: ++ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D ++ CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D ++ CONNECTOR_OBJECT_ID_HDMI_TYPE_A ++ CONNECTOR_OBJECT_ID_DISPLAYPORT ++ [31:24]- Reserved ++ ++ulDDISlot2Config: Same as Slot1. ++ucMemoryType: SidePort memory type, set it to 0x0 when Sideport memory is not installed. Driver needs this info to change sideport memory clock. Not for display in CCC. ++For IGP, Hypermemory is the only memory type showed in CCC. ++ ++ucUMAChannelNumber: how many channels for the UMA; ++ ++ulDockingPinCFGInfo: [15:0]-Bus/Device/Function # to CFG to read this Docking Pin; [31:16]-reg offset in CFG to read this pin ++ucDockingPinBit: which bit in this register to read the pin status; ++ucDockingPinPolarity:Polarity of the pin when docked; ++ ++ulCPUCapInfo: [7:0]=1:Griffin;[7:0]=2:Greyhound;[7:0]=3:K8, other bits reserved for now and must be 0x0 ++ ++usNumberOfCyclesInPeriod:Indicate how many cycles when PWM duty is 100%. ++usMaxNBVoltage:Max. voltage control value in either PWM or GPIO mode. ++usMinNBVoltage:Min. voltage control value in either PWM or GPIO mode. ++ GPIO mode: both usMaxNBVoltage & usMinNBVoltage have a valid value ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE=0 ++ PWM mode: both usMaxNBVoltage & usMinNBVoltage have a valid value ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE=1 ++ GPU SW don't control mode: usMaxNBVoltage & usMinNBVoltage=0 and no care about ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE ++usBootUpNBVoltage:Boot-up voltage regulator dependent PWM value. ++ ++ulHTLinkFreq: Bootup HT link Frequency in 10Khz. ++usMinHTLinkWidth: Bootup minimum HT link width. If CDLW disabled, this is equal to usMaxHTLinkWidth. ++ If CDLW enabled, both upstream and downstream width should be the same during bootup. ++usMaxHTLinkWidth: Bootup maximum HT link width. If CDLW disabled, this is equal to usMinHTLinkWidth. ++ If CDLW enabled, both upstream and downstream width should be the same during bootup. ++ ++usUMASyncStartDelay: Memory access latency, required for watermark calculation ++usUMADataReturnTime: Memory access latency, required for watermark calculation ++usLinkStatusZeroTime:Memory access latency required for watermark calculation, set this to 0x0 for K8 CPU, set a proper value in 0.01 the unit of us ++for Griffin or Greyhound. SBIOS needs to convert to actual time by: ++ if T0Ttime [5:4]=00b, then usLinkStatusZeroTime=T0Ttime [3:0]*0.1us (0.0 to 1.5us) ++ if T0Ttime [5:4]=01b, then usLinkStatusZeroTime=T0Ttime [3:0]*0.5us (0.0 to 7.5us) ++ if T0Ttime [5:4]=10b, then usLinkStatusZeroTime=T0Ttime [3:0]*2.0us (0.0 to 30us) ++ if T0Ttime [5:4]=11b, and T0Ttime [3:0]=0x0 to 0xa, then usLinkStatusZeroTime=T0Ttime [3:0]*20us (0.0 to 200us) ++ ++ulHighVoltageHTLinkFreq: HT link frequency for power state with low voltage. If boot up runs in HT1, this must be 0. ++ This must be less than or equal to ulHTLinkFreq(bootup frequency). ++ulLowVoltageHTLinkFreq: HT link frequency for power state with low voltage or voltage scaling 1.0v~1.1v. If boot up runs in HT1, this must be 0. ++ This must be less than or equal to ulHighVoltageHTLinkFreq. ++ ++usMaxUpStreamHTLinkWidth: Asymmetric link width support in the future, to replace usMaxHTLinkWidth. Not used for now. ++usMaxDownStreamHTLinkWidth: same as above. ++usMinUpStreamHTLinkWidth: Asymmetric link width support in the future, to replace usMinHTLinkWidth. Not used for now. ++usMinDownStreamHTLinkWidth: same as above. ++*/ ++ ++ ++#define SYSTEM_CONFIG_POWEREXPRESS_ENABLE 0x00000001 ++#define SYSTEM_CONFIG_RUN_AT_OVERDRIVE_ENGINE 0x00000002 ++#define SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE 0x00000004 ++#define SYSTEM_CONFIG_PERFORMANCE_POWERSTATE_ONLY 0x00000008 ++#define SYSTEM_CONFIG_CLMC_ENABLED 0x00000010 ++#define SYSTEM_CONFIG_CDLW_ENABLED 0x00000020 ++#define SYSTEM_CONFIG_HIGH_VOLTAGE_REQUESTED 0x00000040 ++#define SYSTEM_CONFIG_CLMC_HYBRID_MODE_ENABLED 0x00000080 ++ ++#define IGP_DDI_SLOT_LANE_CONFIG_MASK 0x000000FF ++ ++#define b0IGP_DDI_SLOT_LANE_MAP_MASK 0x0F ++#define b0IGP_DDI_SLOT_DOCKING_LANE_MAP_MASK 0xF0 ++#define b0IGP_DDI_SLOT_CONFIG_LANE_0_3 0x01 ++#define b0IGP_DDI_SLOT_CONFIG_LANE_4_7 0x02 ++#define b0IGP_DDI_SLOT_CONFIG_LANE_8_11 0x04 ++#define b0IGP_DDI_SLOT_CONFIG_LANE_12_15 0x08 ++ ++#define IGP_DDI_SLOT_ATTRIBUTE_MASK 0x0000FF00 ++#define IGP_DDI_SLOT_CONFIG_REVERSED 0x00000100 ++#define b1IGP_DDI_SLOT_CONFIG_REVERSED 0x01 ++ ++#define IGP_DDI_SLOT_CONNECTOR_TYPE_MASK 0x00FF0000 ++ ++#define ATOM_CRT_INT_ENCODER1_INDEX 0x00000000 ++#define ATOM_LCD_INT_ENCODER1_INDEX 0x00000001 ++#define ATOM_TV_INT_ENCODER1_INDEX 0x00000002 ++#define ATOM_DFP_INT_ENCODER1_INDEX 0x00000003 ++#define ATOM_CRT_INT_ENCODER2_INDEX 0x00000004 ++#define ATOM_LCD_EXT_ENCODER1_INDEX 0x00000005 ++#define ATOM_TV_EXT_ENCODER1_INDEX 0x00000006 ++#define ATOM_DFP_EXT_ENCODER1_INDEX 0x00000007 ++#define ATOM_CV_INT_ENCODER1_INDEX 0x00000008 ++#define ATOM_DFP_INT_ENCODER2_INDEX 0x00000009 ++#define ATOM_CRT_EXT_ENCODER1_INDEX 0x0000000A ++#define ATOM_CV_EXT_ENCODER1_INDEX 0x0000000B ++#define ATOM_DFP_INT_ENCODER3_INDEX 0x0000000C ++#define ATOM_DFP_INT_ENCODER4_INDEX 0x0000000D ++ ++// define ASIC internal encoder id ( bit vector ) ++#define ASIC_INT_DAC1_ENCODER_ID 0x00 ++#define ASIC_INT_TV_ENCODER_ID 0x02 ++#define ASIC_INT_DIG1_ENCODER_ID 0x03 ++#define ASIC_INT_DAC2_ENCODER_ID 0x04 ++#define ASIC_EXT_TV_ENCODER_ID 0x06 ++#define ASIC_INT_DVO_ENCODER_ID 0x07 ++#define ASIC_INT_DIG2_ENCODER_ID 0x09 ++#define ASIC_EXT_DIG_ENCODER_ID 0x05 ++ ++//define Encoder attribute ++#define ATOM_ANALOG_ENCODER 0 ++#define ATOM_DIGITAL_ENCODER 1 ++ ++#define ATOM_DEVICE_CRT1_INDEX 0x00000000 ++#define ATOM_DEVICE_LCD1_INDEX 0x00000001 ++#define ATOM_DEVICE_TV1_INDEX 0x00000002 ++#define ATOM_DEVICE_DFP1_INDEX 0x00000003 ++#define ATOM_DEVICE_CRT2_INDEX 0x00000004 ++#define ATOM_DEVICE_LCD2_INDEX 0x00000005 ++#define ATOM_DEVICE_TV2_INDEX 0x00000006 ++#define ATOM_DEVICE_DFP2_INDEX 0x00000007 ++#define ATOM_DEVICE_CV_INDEX 0x00000008 ++#define ATOM_DEVICE_DFP3_INDEX 0x00000009 ++#define ATOM_DEVICE_DFP4_INDEX 0x0000000A ++#define ATOM_DEVICE_DFP5_INDEX 0x0000000B ++#define ATOM_DEVICE_RESERVEDC_INDEX 0x0000000C ++#define ATOM_DEVICE_RESERVEDD_INDEX 0x0000000D ++#define ATOM_DEVICE_RESERVEDE_INDEX 0x0000000E ++#define ATOM_DEVICE_RESERVEDF_INDEX 0x0000000F ++#define ATOM_MAX_SUPPORTED_DEVICE_INFO (ATOM_DEVICE_DFP3_INDEX+1) ++#define ATOM_MAX_SUPPORTED_DEVICE_INFO_2 ATOM_MAX_SUPPORTED_DEVICE_INFO ++#define ATOM_MAX_SUPPORTED_DEVICE_INFO_3 (ATOM_DEVICE_DFP5_INDEX + 1 ) ++ ++#define ATOM_MAX_SUPPORTED_DEVICE (ATOM_DEVICE_RESERVEDF_INDEX+1) ++ ++#define ATOM_DEVICE_CRT1_SUPPORT (0x1L << ATOM_DEVICE_CRT1_INDEX ) ++#define ATOM_DEVICE_LCD1_SUPPORT (0x1L << ATOM_DEVICE_LCD1_INDEX ) ++#define ATOM_DEVICE_TV1_SUPPORT (0x1L << ATOM_DEVICE_TV1_INDEX ) ++#define ATOM_DEVICE_DFP1_SUPPORT (0x1L << ATOM_DEVICE_DFP1_INDEX) ++#define ATOM_DEVICE_CRT2_SUPPORT (0x1L << ATOM_DEVICE_CRT2_INDEX ) ++#define ATOM_DEVICE_LCD2_SUPPORT (0x1L << ATOM_DEVICE_LCD2_INDEX ) ++#define ATOM_DEVICE_TV2_SUPPORT (0x1L << ATOM_DEVICE_TV2_INDEX ) ++#define ATOM_DEVICE_DFP2_SUPPORT (0x1L << ATOM_DEVICE_DFP2_INDEX) ++#define ATOM_DEVICE_CV_SUPPORT (0x1L << ATOM_DEVICE_CV_INDEX ) ++#define ATOM_DEVICE_DFP3_SUPPORT (0x1L << ATOM_DEVICE_DFP3_INDEX ) ++#define ATOM_DEVICE_DFP4_SUPPORT (0x1L << ATOM_DEVICE_DFP4_INDEX ) ++#define ATOM_DEVICE_DFP5_SUPPORT (0x1L << ATOM_DEVICE_DFP5_INDEX ) ++ ++#define ATOM_DEVICE_CRT_SUPPORT ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT ++#define ATOM_DEVICE_DFP_SUPPORT ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT | ATOM_DEVICE_DFP3_SUPPORT | ATOM_DEVICE_DFP4_SUPPORT | ATOM_DEVICE_DFP5_SUPPORT ++#define ATOM_DEVICE_TV_SUPPORT ATOM_DEVICE_TV1_SUPPORT | ATOM_DEVICE_TV2_SUPPORT ++#define ATOM_DEVICE_LCD_SUPPORT ATOM_DEVICE_LCD1_SUPPORT | ATOM_DEVICE_LCD2_SUPPORT ++ ++#define ATOM_DEVICE_CONNECTOR_TYPE_MASK 0x000000F0 ++#define ATOM_DEVICE_CONNECTOR_TYPE_SHIFT 0x00000004 ++#define ATOM_DEVICE_CONNECTOR_VGA 0x00000001 ++#define ATOM_DEVICE_CONNECTOR_DVI_I 0x00000002 ++#define ATOM_DEVICE_CONNECTOR_DVI_D 0x00000003 ++#define ATOM_DEVICE_CONNECTOR_DVI_A 0x00000004 ++#define ATOM_DEVICE_CONNECTOR_SVIDEO 0x00000005 ++#define ATOM_DEVICE_CONNECTOR_COMPOSITE 0x00000006 ++#define ATOM_DEVICE_CONNECTOR_LVDS 0x00000007 ++#define ATOM_DEVICE_CONNECTOR_DIGI_LINK 0x00000008 ++#define ATOM_DEVICE_CONNECTOR_SCART 0x00000009 ++#define ATOM_DEVICE_CONNECTOR_HDMI_TYPE_A 0x0000000A ++#define ATOM_DEVICE_CONNECTOR_HDMI_TYPE_B 0x0000000B ++#define ATOM_DEVICE_CONNECTOR_CASE_1 0x0000000E ++#define ATOM_DEVICE_CONNECTOR_DISPLAYPORT 0x0000000F ++ ++ ++#define ATOM_DEVICE_DAC_INFO_MASK 0x0000000F ++#define ATOM_DEVICE_DAC_INFO_SHIFT 0x00000000 ++#define ATOM_DEVICE_DAC_INFO_NODAC 0x00000000 ++#define ATOM_DEVICE_DAC_INFO_DACA 0x00000001 ++#define ATOM_DEVICE_DAC_INFO_DACB 0x00000002 ++#define ATOM_DEVICE_DAC_INFO_EXDAC 0x00000003 ++ ++#define ATOM_DEVICE_I2C_ID_NOI2C 0x00000000 ++ ++#define ATOM_DEVICE_I2C_LINEMUX_MASK 0x0000000F ++#define ATOM_DEVICE_I2C_LINEMUX_SHIFT 0x00000000 ++ ++#define ATOM_DEVICE_I2C_ID_MASK 0x00000070 ++#define ATOM_DEVICE_I2C_ID_SHIFT 0x00000004 ++#define ATOM_DEVICE_I2C_ID_IS_FOR_NON_MM_USE 0x00000001 ++#define ATOM_DEVICE_I2C_ID_IS_FOR_MM_USE 0x00000002 ++#define ATOM_DEVICE_I2C_ID_IS_FOR_SDVO_USE 0x00000003 //For IGP RS600 ++#define ATOM_DEVICE_I2C_ID_IS_FOR_DAC_SCL 0x00000004 //For IGP RS690 ++ ++#define ATOM_DEVICE_I2C_HARDWARE_CAP_MASK 0x00000080 ++#define ATOM_DEVICE_I2C_HARDWARE_CAP_SHIFT 0x00000007 ++#define ATOM_DEVICE_USES_SOFTWARE_ASSISTED_I2C 0x00000000 ++#define ATOM_DEVICE_USES_HARDWARE_ASSISTED_I2C 0x00000001 ++ ++// usDeviceSupport: ++// Bits0 = 0 - no CRT1 support= 1- CRT1 is supported ++// Bit 1 = 0 - no LCD1 support= 1- LCD1 is supported ++// Bit 2 = 0 - no TV1 support= 1- TV1 is supported ++// Bit 3 = 0 - no DFP1 support= 1- DFP1 is supported ++// Bit 4 = 0 - no CRT2 support= 1- CRT2 is supported ++// Bit 5 = 0 - no LCD2 support= 1- LCD2 is supported ++// Bit 6 = 0 - no TV2 support= 1- TV2 is supported ++// Bit 7 = 0 - no DFP2 support= 1- DFP2 is supported ++// Bit 8 = 0 - no CV support= 1- CV is supported ++// Bit 9 = 0 - no DFP3 support= 1- DFP3 is supported ++// Byte1 (Supported Device Info) ++// Bit 0 = = 0 - no CV support= 1- CV is supported ++// ++// ++ ++// ucI2C_ConfigID ++// [7:0] - I2C LINE Associate ID ++// = 0 - no I2C ++// [7] - HW_Cap = 1, [6:0]=HW assisted I2C ID(HW line selection) ++// = 0, [6:0]=SW assisted I2C ID ++// [6-4] - HW_ENGINE_ID = 1, HW engine for NON multimedia use ++// = 2, HW engine for Multimedia use ++// = 3-7 Reserved for future I2C engines ++// [3-0] - I2C_LINE_MUX = A Mux number when it's HW assisted I2C or GPIO ID when it's SW I2C ++ ++typedef struct _ATOM_I2C_ID_CONFIG ++{ ++#if ATOM_BIG_ENDIAN ++ UCHAR bfHW_Capable:1; ++ UCHAR bfHW_EngineID:3; ++ UCHAR bfI2C_LineMux:4; ++#else ++ UCHAR bfI2C_LineMux:4; ++ UCHAR bfHW_EngineID:3; ++ UCHAR bfHW_Capable:1; ++#endif ++}ATOM_I2C_ID_CONFIG; ++ ++typedef union _ATOM_I2C_ID_CONFIG_ACCESS ++{ ++ ATOM_I2C_ID_CONFIG sbfAccess; ++ UCHAR ucAccess; ++}ATOM_I2C_ID_CONFIG_ACCESS; ++ ++ ++/****************************************************************************/ ++// Structure used in GPIO_I2C_InfoTable ++/****************************************************************************/ ++typedef struct _ATOM_GPIO_I2C_ASSIGMENT ++{ ++ USHORT usClkMaskRegisterIndex; ++ USHORT usClkEnRegisterIndex; ++ USHORT usClkY_RegisterIndex; ++ USHORT usClkA_RegisterIndex; ++ USHORT usDataMaskRegisterIndex; ++ USHORT usDataEnRegisterIndex; ++ USHORT usDataY_RegisterIndex; ++ USHORT usDataA_RegisterIndex; ++ ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; ++ UCHAR ucClkMaskShift; ++ UCHAR ucClkEnShift; ++ UCHAR ucClkY_Shift; ++ UCHAR ucClkA_Shift; ++ UCHAR ucDataMaskShift; ++ UCHAR ucDataEnShift; ++ UCHAR ucDataY_Shift; ++ UCHAR ucDataA_Shift; ++ UCHAR ucReserved1; ++ UCHAR ucReserved2; ++}ATOM_GPIO_I2C_ASSIGMENT; ++ ++typedef struct _ATOM_GPIO_I2C_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_GPIO_I2C_ASSIGMENT asGPIO_Info[ATOM_MAX_SUPPORTED_DEVICE]; ++}ATOM_GPIO_I2C_INFO; ++ ++/****************************************************************************/ ++// Common Structure used in other structures ++/****************************************************************************/ ++ ++#ifndef _H2INC ++ ++//Please don't add or expand this bitfield structure below, this one will retire soon.! ++typedef struct _ATOM_MODE_MISC_INFO ++{ ++#if ATOM_BIG_ENDIAN ++ USHORT Reserved:6; ++ USHORT RGB888:1; ++ USHORT DoubleClock:1; ++ USHORT Interlace:1; ++ USHORT CompositeSync:1; ++ USHORT V_ReplicationBy2:1; ++ USHORT H_ReplicationBy2:1; ++ USHORT VerticalCutOff:1; ++ USHORT VSyncPolarity:1; //0=Active High, 1=Active Low ++ USHORT HSyncPolarity:1; //0=Active High, 1=Active Low ++ USHORT HorizontalCutOff:1; ++#else ++ USHORT HorizontalCutOff:1; ++ USHORT HSyncPolarity:1; //0=Active High, 1=Active Low ++ USHORT VSyncPolarity:1; //0=Active High, 1=Active Low ++ USHORT VerticalCutOff:1; ++ USHORT H_ReplicationBy2:1; ++ USHORT V_ReplicationBy2:1; ++ USHORT CompositeSync:1; ++ USHORT Interlace:1; ++ USHORT DoubleClock:1; ++ USHORT RGB888:1; ++ USHORT Reserved:6; ++#endif ++}ATOM_MODE_MISC_INFO; ++ ++typedef union _ATOM_MODE_MISC_INFO_ACCESS ++{ ++ ATOM_MODE_MISC_INFO sbfAccess; ++ USHORT usAccess; ++}ATOM_MODE_MISC_INFO_ACCESS; ++ ++#else ++ ++typedef union _ATOM_MODE_MISC_INFO_ACCESS ++{ ++ USHORT usAccess; ++}ATOM_MODE_MISC_INFO_ACCESS; ++ ++#endif ++ ++// usModeMiscInfo- ++#define ATOM_H_CUTOFF 0x01 ++#define ATOM_HSYNC_POLARITY 0x02 //0=Active High, 1=Active Low ++#define ATOM_VSYNC_POLARITY 0x04 //0=Active High, 1=Active Low ++#define ATOM_V_CUTOFF 0x08 ++#define ATOM_H_REPLICATIONBY2 0x10 ++#define ATOM_V_REPLICATIONBY2 0x20 ++#define ATOM_COMPOSITESYNC 0x40 ++#define ATOM_INTERLACE 0x80 ++#define ATOM_DOUBLE_CLOCK_MODE 0x100 ++#define ATOM_RGB888_MODE 0x200 ++ ++//usRefreshRate- ++#define ATOM_REFRESH_43 43 ++#define ATOM_REFRESH_47 47 ++#define ATOM_REFRESH_56 56 ++#define ATOM_REFRESH_60 60 ++#define ATOM_REFRESH_65 65 ++#define ATOM_REFRESH_70 70 ++#define ATOM_REFRESH_72 72 ++#define ATOM_REFRESH_75 75 ++#define ATOM_REFRESH_85 85 ++ ++// ATOM_MODE_TIMING data are exactly the same as VESA timing data. ++// Translation from EDID to ATOM_MODE_TIMING, use the following formula. ++// ++// VESA_HTOTAL = VESA_ACTIVE + 2* VESA_BORDER + VESA_BLANK ++// = EDID_HA + EDID_HBL ++// VESA_HDISP = VESA_ACTIVE = EDID_HA ++// VESA_HSYNC_START = VESA_ACTIVE + VESA_BORDER + VESA_FRONT_PORCH ++// = EDID_HA + EDID_HSO ++// VESA_HSYNC_WIDTH = VESA_HSYNC_TIME = EDID_HSPW ++// VESA_BORDER = EDID_BORDER ++ ++/****************************************************************************/ ++// Structure used in SetCRTC_UsingDTDTimingTable ++/****************************************************************************/ ++typedef struct _SET_CRTC_USING_DTD_TIMING_PARAMETERS ++{ ++ USHORT usH_Size; ++ USHORT usH_Blanking_Time; ++ USHORT usV_Size; ++ USHORT usV_Blanking_Time; ++ USHORT usH_SyncOffset; ++ USHORT usH_SyncWidth; ++ USHORT usV_SyncOffset; ++ USHORT usV_SyncWidth; ++ ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; ++ UCHAR ucH_Border; // From DFP EDID ++ UCHAR ucV_Border; ++ UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 ++ UCHAR ucPadding[3]; ++}SET_CRTC_USING_DTD_TIMING_PARAMETERS; ++ ++/****************************************************************************/ ++// Structure used in SetCRTC_TimingTable ++/****************************************************************************/ ++typedef struct _SET_CRTC_TIMING_PARAMETERS ++{ ++ USHORT usH_Total; // horizontal total ++ USHORT usH_Disp; // horizontal display ++ USHORT usH_SyncStart; // horozontal Sync start ++ USHORT usH_SyncWidth; // horizontal Sync width ++ USHORT usV_Total; // vertical total ++ USHORT usV_Disp; // vertical display ++ USHORT usV_SyncStart; // vertical Sync start ++ USHORT usV_SyncWidth; // vertical Sync width ++ ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; ++ UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 ++ UCHAR ucOverscanRight; // right ++ UCHAR ucOverscanLeft; // left ++ UCHAR ucOverscanBottom; // bottom ++ UCHAR ucOverscanTop; // top ++ UCHAR ucReserved; ++}SET_CRTC_TIMING_PARAMETERS; ++#define SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION SET_CRTC_TIMING_PARAMETERS ++ ++/****************************************************************************/ ++// Structure used in StandardVESA_TimingTable ++// AnalogTV_InfoTable ++// ComponentVideoInfoTable ++/****************************************************************************/ ++typedef struct _ATOM_MODE_TIMING ++{ ++ USHORT usCRTC_H_Total; ++ USHORT usCRTC_H_Disp; ++ USHORT usCRTC_H_SyncStart; ++ USHORT usCRTC_H_SyncWidth; ++ USHORT usCRTC_V_Total; ++ USHORT usCRTC_V_Disp; ++ USHORT usCRTC_V_SyncStart; ++ USHORT usCRTC_V_SyncWidth; ++ USHORT usPixelClock; //in 10Khz unit ++ ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; ++ USHORT usCRTC_OverscanRight; ++ USHORT usCRTC_OverscanLeft; ++ USHORT usCRTC_OverscanBottom; ++ USHORT usCRTC_OverscanTop; ++ USHORT usReserve; ++ UCHAR ucInternalModeNumber; ++ UCHAR ucRefreshRate; ++}ATOM_MODE_TIMING; ++ ++typedef struct _ATOM_DTD_FORMAT ++{ ++ USHORT usPixClk; ++ USHORT usHActive; ++ USHORT usHBlanking_Time; ++ USHORT usVActive; ++ USHORT usVBlanking_Time; ++ USHORT usHSyncOffset; ++ USHORT usHSyncWidth; ++ USHORT usVSyncOffset; ++ USHORT usVSyncWidth; ++ USHORT usImageHSize; ++ USHORT usImageVSize; ++ UCHAR ucHBorder; ++ UCHAR ucVBorder; ++ ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; ++ UCHAR ucInternalModeNumber; ++ UCHAR ucRefreshRate; ++}ATOM_DTD_FORMAT; ++ ++/****************************************************************************/ ++// Structure used in LVDS_InfoTable ++// * Need a document to describe this table ++/****************************************************************************/ ++#define SUPPORTED_LCD_REFRESHRATE_30Hz 0x0004 ++#define SUPPORTED_LCD_REFRESHRATE_40Hz 0x0008 ++#define SUPPORTED_LCD_REFRESHRATE_50Hz 0x0010 ++#define SUPPORTED_LCD_REFRESHRATE_60Hz 0x0020 ++ ++//Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12. ++//Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL ++#define LCDPANEL_CAP_READ_EDID 0x1 ++ ++//ucTableFormatRevision=1 ++//ucTableContentRevision=1 ++typedef struct _ATOM_LVDS_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_DTD_FORMAT sLCDTiming; ++ USHORT usModePatchTableOffset; ++ USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. ++ USHORT usOffDelayInMs; ++ UCHAR ucPowerSequenceDigOntoDEin10Ms; ++ UCHAR ucPowerSequenceDEtoBLOnin10Ms; ++ UCHAR ucLVDS_Misc; // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} ++ // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} ++ // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} ++ // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} ++ UCHAR ucPanelDefaultRefreshRate; ++ UCHAR ucPanelIdentification; ++ UCHAR ucSS_Id; ++}ATOM_LVDS_INFO; ++ ++//ucTableFormatRevision=1 ++//ucTableContentRevision=2 ++typedef struct _ATOM_LVDS_INFO_V12 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_DTD_FORMAT sLCDTiming; ++ USHORT usExtInfoTableOffset; ++ USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. ++ USHORT usOffDelayInMs; ++ UCHAR ucPowerSequenceDigOntoDEin10Ms; ++ UCHAR ucPowerSequenceDEtoBLOnin10Ms; ++ UCHAR ucLVDS_Misc; // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} ++ // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} ++ // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} ++ // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} ++ UCHAR ucPanelDefaultRefreshRate; ++ UCHAR ucPanelIdentification; ++ UCHAR ucSS_Id; ++ USHORT usLCDVenderID; ++ USHORT usLCDProductID; ++ UCHAR ucLCDPanel_SpecialHandlingCap; ++ UCHAR ucPanelInfoSize; // start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable ++ UCHAR ucReserved[2]; ++}ATOM_LVDS_INFO_V12; ++ ++#define ATOM_LVDS_INFO_LAST ATOM_LVDS_INFO_V12 ++ ++typedef struct _ATOM_PATCH_RECORD_MODE ++{ ++ UCHAR ucRecordType; ++ USHORT usHDisp; ++ USHORT usVDisp; ++}ATOM_PATCH_RECORD_MODE; ++ ++typedef struct _ATOM_LCD_RTS_RECORD ++{ ++ UCHAR ucRecordType; ++ UCHAR ucRTSValue; ++}ATOM_LCD_RTS_RECORD; ++ ++//!! If the record below exits, it shoud always be the first record for easy use in command table!!! ++typedef struct _ATOM_LCD_MODE_CONTROL_CAP ++{ ++ UCHAR ucRecordType; ++ USHORT usLCDCap; ++}ATOM_LCD_MODE_CONTROL_CAP; ++ ++#define LCD_MODE_CAP_BL_OFF 1 ++#define LCD_MODE_CAP_CRTC_OFF 2 ++#define LCD_MODE_CAP_PANEL_OFF 4 ++ ++typedef struct _ATOM_FAKE_EDID_PATCH_RECORD ++{ ++ UCHAR ucRecordType; ++ UCHAR ucFakeEDIDLength; ++ UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. ++} ATOM_FAKE_EDID_PATCH_RECORD; ++ ++typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD ++{ ++ UCHAR ucRecordType; ++ USHORT usHSize; ++ USHORT usVSize; ++}ATOM_PANEL_RESOLUTION_PATCH_RECORD; ++ ++#define LCD_MODE_PATCH_RECORD_MODE_TYPE 1 ++#define LCD_RTS_RECORD_TYPE 2 ++#define LCD_CAP_RECORD_TYPE 3 ++#define LCD_FAKE_EDID_PATCH_RECORD_TYPE 4 ++#define LCD_PANEL_RESOLUTION_RECORD_TYPE 5 ++#define ATOM_RECORD_END_TYPE 0xFF ++ ++/****************************Spread Spectrum Info Table Definitions **********************/ ++ ++//ucTableFormatRevision=1 ++//ucTableContentRevision=2 ++typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT ++{ ++ USHORT usSpreadSpectrumPercentage; ++ UCHAR ucSpreadSpectrumType; //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD ++ UCHAR ucSS_Step; ++ UCHAR ucSS_Delay; ++ UCHAR ucSS_Id; ++ UCHAR ucRecommandedRef_Div; ++ UCHAR ucSS_Range; //it was reserved for V11 ++}ATOM_SPREAD_SPECTRUM_ASSIGNMENT; ++ ++#define ATOM_MAX_SS_ENTRY 16 ++#define ATOM_DP_SS_ID1 0x0f1 // SS modulation freq=30k ++#define ATOM_DP_SS_ID2 0x0f2 // SS modulation freq=33k ++ ++ ++#define ATOM_SS_DOWN_SPREAD_MODE_MASK 0x00000000 ++#define ATOM_SS_DOWN_SPREAD_MODE 0x00000000 ++#define ATOM_SS_CENTRE_SPREAD_MODE_MASK 0x00000001 ++#define ATOM_SS_CENTRE_SPREAD_MODE 0x00000001 ++#define ATOM_INTERNAL_SS_MASK 0x00000000 ++#define ATOM_EXTERNAL_SS_MASK 0x00000002 ++#define EXEC_SS_STEP_SIZE_SHIFT 2 ++#define EXEC_SS_DELAY_SHIFT 4 ++#define ACTIVEDATA_TO_BLON_DELAY_SHIFT 4 ++ ++typedef struct _ATOM_SPREAD_SPECTRUM_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_SPREAD_SPECTRUM_ASSIGNMENT asSS_Info[ATOM_MAX_SS_ENTRY]; ++}ATOM_SPREAD_SPECTRUM_INFO; ++ ++/****************************************************************************/ ++// Structure used in AnalogTV_InfoTable (Top level) ++/****************************************************************************/ ++//ucTVBootUpDefaultStd definiton: ++ ++//ATOM_TV_NTSC 1 ++//ATOM_TV_NTSCJ 2 ++//ATOM_TV_PAL 3 ++//ATOM_TV_PALM 4 ++//ATOM_TV_PALCN 5 ++//ATOM_TV_PALN 6 ++//ATOM_TV_PAL60 7 ++//ATOM_TV_SECAM 8 ++ ++//ucTVSuppportedStd definition: ++#define NTSC_SUPPORT 0x1 ++#define NTSCJ_SUPPORT 0x2 ++ ++#define PAL_SUPPORT 0x4 ++#define PALM_SUPPORT 0x8 ++#define PALCN_SUPPORT 0x10 ++#define PALN_SUPPORT 0x20 ++#define PAL60_SUPPORT 0x40 ++#define SECAM_SUPPORT 0x80 ++ ++#define MAX_SUPPORTED_TV_TIMING 2 ++ ++typedef struct _ATOM_ANALOG_TV_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR ucTV_SupportedStandard; ++ UCHAR ucTV_BootUpDefaultStandard; ++ UCHAR ucExt_TV_ASIC_ID; ++ UCHAR ucExt_TV_ASIC_SlaveAddr; ++ /*ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING];*/ ++ ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING]; ++}ATOM_ANALOG_TV_INFO; ++ ++ ++/**************************************************************************/ ++// VRAM usage and their defintions ++ ++// One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. ++// Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. ++// All the addresses below are the offsets from the frame buffer start.They all MUST be Dword aligned! ++// To driver: The physical address of this memory portion=mmFB_START(4K aligned)+ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR ++// To Bios: ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR->MM_INDEX ++ ++#ifndef VESA_MEMORY_IN_64K_BLOCK ++#define VESA_MEMORY_IN_64K_BLOCK 0x100 //256*64K=16Mb (Max. VESA memory is 16Mb!) ++#endif ++ ++#define ATOM_EDID_RAW_DATASIZE 256 //In Bytes ++#define ATOM_HWICON_SURFACE_SIZE 4096 //In Bytes ++#define ATOM_HWICON_INFOTABLE_SIZE 32 ++#define MAX_DTD_MODE_IN_VRAM 6 ++#define ATOM_DTD_MODE_SUPPORT_TBL_SIZE (MAX_DTD_MODE_IN_VRAM*28) //28= (SIZEOF ATOM_DTD_FORMAT) ++#define ATOM_STD_MODE_SUPPORT_TBL_SIZE 32*8 //32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT) ++#define DFP_ENCODER_TYPE_OFFSET 0x80 ++#define DP_ENCODER_LANE_NUM_OFFSET 0x84 ++#define DP_ENCODER_LINK_RATE_OFFSET 0x88 ++ ++#define ATOM_HWICON1_SURFACE_ADDR 0 ++#define ATOM_HWICON2_SURFACE_ADDR (ATOM_HWICON1_SURFACE_ADDR + ATOM_HWICON_SURFACE_SIZE) ++#define ATOM_HWICON_INFOTABLE_ADDR (ATOM_HWICON2_SURFACE_ADDR + ATOM_HWICON_SURFACE_SIZE) ++#define ATOM_CRT1_EDID_ADDR (ATOM_HWICON_INFOTABLE_ADDR + ATOM_HWICON_INFOTABLE_SIZE) ++#define ATOM_CRT1_DTD_MODE_TBL_ADDR (ATOM_CRT1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_CRT1_STD_MODE_TBL_ADDR (ATOM_CRT1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_LCD1_EDID_ADDR (ATOM_CRT1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_LCD1_DTD_MODE_TBL_ADDR (ATOM_LCD1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_LCD1_STD_MODE_TBL_ADDR (ATOM_LCD1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_TV1_DTD_MODE_TBL_ADDR (ATOM_LCD1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_DFP1_EDID_ADDR (ATOM_TV1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_DFP1_DTD_MODE_TBL_ADDR (ATOM_DFP1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_DFP1_STD_MODE_TBL_ADDR (ATOM_DFP1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_CRT2_EDID_ADDR (ATOM_DFP1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_CRT2_DTD_MODE_TBL_ADDR (ATOM_CRT2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_CRT2_STD_MODE_TBL_ADDR (ATOM_CRT2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_LCD2_EDID_ADDR (ATOM_CRT2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_LCD2_DTD_MODE_TBL_ADDR (ATOM_LCD2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_LCD2_STD_MODE_TBL_ADDR (ATOM_LCD2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_TV2_EDID_ADDR (ATOM_LCD2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_TV2_DTD_MODE_TBL_ADDR (ATOM_TV2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_TV2_STD_MODE_TBL_ADDR (ATOM_TV2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_DFP2_EDID_ADDR (ATOM_TV2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_DFP2_DTD_MODE_TBL_ADDR (ATOM_DFP2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_DFP2_STD_MODE_TBL_ADDR (ATOM_DFP2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_CV_EDID_ADDR (ATOM_DFP2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_CV_DTD_MODE_TBL_ADDR (ATOM_CV_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_CV_STD_MODE_TBL_ADDR (ATOM_CV_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_DFP3_EDID_ADDR (ATOM_CV_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_DFP3_DTD_MODE_TBL_ADDR (ATOM_DFP3_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_DFP3_STD_MODE_TBL_ADDR (ATOM_DFP3_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_DFP4_EDID_ADDR (ATOM_DFP3_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_DFP4_DTD_MODE_TBL_ADDR (ATOM_DFP4_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_DFP4_STD_MODE_TBL_ADDR (ATOM_DFP4_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_DFP5_EDID_ADDR (ATOM_DFP4_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++#define ATOM_DFP5_DTD_MODE_TBL_ADDR (ATOM_DFP5_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) ++#define ATOM_DFP5_STD_MODE_TBL_ADDR (ATOM_DFP5_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_DP_TRAINING_TBL_ADDR (ATOM_DFP5_STD_MODE_TBL_ADDR+ATOM_STD_MODE_SUPPORT_TBL_SIZE) ++ ++#define ATOM_STACK_STORAGE_START (ATOM_DP_TRAINING_TBL_ADDR+256) ++#define ATOM_STACK_STORAGE_END ATOM_STACK_STORAGE_START+512 ++ ++//The size below is in Kb! ++#define ATOM_VRAM_RESERVE_SIZE ((((ATOM_STACK_STORAGE_END - ATOM_HWICON1_SURFACE_ADDR)>>10)+4)&0xFFFC) ++ ++#define ATOM_VRAM_OPERATION_FLAGS_MASK 0xC0000000L ++#define ATOM_VRAM_OPERATION_FLAGS_SHIFT 30 ++#define ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION 0x1 ++#define ATOM_VRAM_BLOCK_NEEDS_RESERVATION 0x0 ++ ++/***********************************************************************************/ ++// Structure used in VRAM_UsageByFirmwareTable ++// Note1: This table is filled by SetBiosReservationStartInFB in CoreCommSubs.asm ++// at running time. ++// note2: From RV770, the memory is more than 32bit addressable, so we will change ++// ucTableFormatRevision=1,ucTableContentRevision=4, the strcuture remains ++// exactly same as 1.1 and 1.2 (1.3 is never in use), but ulStartAddrUsedByFirmware ++// (in offset to start of memory address) is KB aligned instead of byte aligend. ++/***********************************************************************************/ ++#define ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO 1 ++ ++typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO ++{ ++ ULONG ulStartAddrUsedByFirmware; ++ USHORT usFirmwareUseInKb; ++ USHORT usReserved; ++}ATOM_FIRMWARE_VRAM_RESERVE_INFO; ++ ++typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_FIRMWARE_VRAM_RESERVE_INFO asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO]; ++}ATOM_VRAM_USAGE_BY_FIRMWARE; ++ ++/****************************************************************************/ ++// Structure used in GPIO_Pin_LUTTable ++/****************************************************************************/ ++typedef struct _ATOM_GPIO_PIN_ASSIGNMENT ++{ ++ USHORT usGpioPin_AIndex; ++ UCHAR ucGpioPinBitShift; ++ UCHAR ucGPIO_ID; ++}ATOM_GPIO_PIN_ASSIGNMENT; ++ ++typedef struct _ATOM_GPIO_PIN_LUT ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_GPIO_PIN_ASSIGNMENT asGPIO_Pin[1]; ++}ATOM_GPIO_PIN_LUT; ++ ++/****************************************************************************/ ++// Structure used in ComponentVideoInfoTable ++/****************************************************************************/ ++#define GPIO_PIN_ACTIVE_HIGH 0x1 ++ ++#define MAX_SUPPORTED_CV_STANDARDS 5 ++ ++// definitions for ATOM_D_INFO.ucSettings ++#define ATOM_GPIO_SETTINGS_BITSHIFT_MASK 0x1F // [4:0] ++#define ATOM_GPIO_SETTINGS_RESERVED_MASK 0x60 // [6:5] = must be zeroed out ++#define ATOM_GPIO_SETTINGS_ACTIVE_MASK 0x80 // [7] ++ ++typedef struct _ATOM_GPIO_INFO ++{ ++ USHORT usAOffset; ++ UCHAR ucSettings; ++ UCHAR ucReserved; ++}ATOM_GPIO_INFO; ++ ++// definitions for ATOM_COMPONENT_VIDEO_INFO.ucMiscInfo (bit vector) ++#define ATOM_CV_RESTRICT_FORMAT_SELECTION 0x2 ++ ++// definitions for ATOM_COMPONENT_VIDEO_INFO.uc480i/uc480p/uc720p/uc1080i ++#define ATOM_GPIO_DEFAULT_MODE_EN 0x80 //[7]; ++#define ATOM_GPIO_SETTING_PERMODE_MASK 0x7F //[6:0] ++ ++// definitions for ATOM_COMPONENT_VIDEO_INFO.ucLetterBoxMode ++//Line 3 out put 5V. ++#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_A 0x01 //represent gpio 3 state for 16:9 ++#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_B 0x02 //represent gpio 4 state for 16:9 ++#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_SHIFT 0x0 ++ ++//Line 3 out put 2.2V ++#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_A 0x04 //represent gpio 3 state for 4:3 Letter box ++#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_B 0x08 //represent gpio 4 state for 4:3 Letter box ++#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_SHIFT 0x2 ++ ++//Line 3 out put 0V ++#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_A 0x10 //represent gpio 3 state for 4:3 ++#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_B 0x20 //represent gpio 4 state for 4:3 ++#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_SHIFT 0x4 ++ ++#define ATOM_CV_LINE3_ASPECTRATIO_MASK 0x3F // bit [5:0] ++ ++#define ATOM_CV_LINE3_ASPECTRATIO_EXIST 0x80 //bit 7 ++ ++//GPIO bit index in gpio setting per mode value, also represend the block no. in gpio blocks. ++#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_A 3 //bit 3 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. ++#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_B 4 //bit 4 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. ++ ++ ++typedef struct _ATOM_COMPONENT_VIDEO_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usMask_PinRegisterIndex; ++ USHORT usEN_PinRegisterIndex; ++ USHORT usY_PinRegisterIndex; ++ USHORT usA_PinRegisterIndex; ++ UCHAR ucBitShift; ++ UCHAR ucPinActiveState; //ucPinActiveState: Bit0=1 active high, =0 active low ++ ATOM_DTD_FORMAT sReserved; // must be zeroed out ++ UCHAR ucMiscInfo; ++ UCHAR uc480i; ++ UCHAR uc480p; ++ UCHAR uc720p; ++ UCHAR uc1080i; ++ UCHAR ucLetterBoxMode; ++ UCHAR ucReserved[3]; ++ UCHAR ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector ++ ATOM_GPIO_INFO aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS]; ++ ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_CV_STANDARDS]; ++}ATOM_COMPONENT_VIDEO_INFO; ++ ++//ucTableFormatRevision=2 ++//ucTableContentRevision=1 ++typedef struct _ATOM_COMPONENT_VIDEO_INFO_V21 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR ucMiscInfo; ++ UCHAR uc480i; ++ UCHAR uc480p; ++ UCHAR uc720p; ++ UCHAR uc1080i; ++ UCHAR ucReserved; ++ UCHAR ucLetterBoxMode; ++ UCHAR ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector ++ ATOM_GPIO_INFO aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS]; ++ ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_CV_STANDARDS]; ++}ATOM_COMPONENT_VIDEO_INFO_V21; ++ ++#define ATOM_COMPONENT_VIDEO_INFO_LAST ATOM_COMPONENT_VIDEO_INFO_V21 ++ ++/****************************************************************************/ ++// Structure used in object_InfoTable ++/****************************************************************************/ ++typedef struct _ATOM_OBJECT_HEADER ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usDeviceSupport; ++ USHORT usConnectorObjectTableOffset; ++ USHORT usRouterObjectTableOffset; ++ USHORT usEncoderObjectTableOffset; ++ USHORT usProtectionObjectTableOffset; //only available when Protection block is independent. ++ USHORT usDisplayPathTableOffset; ++}ATOM_OBJECT_HEADER; ++ ++ ++typedef struct _ATOM_DISPLAY_OBJECT_PATH ++{ ++ USHORT usDeviceTag; //supported device ++ USHORT usSize; //the size of ATOM_DISPLAY_OBJECT_PATH ++ USHORT usConnObjectId; //Connector Object ID ++ USHORT usGPUObjectId; //GPU ID ++ USHORT usGraphicObjIds[1]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. ++}ATOM_DISPLAY_OBJECT_PATH; ++ ++typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE ++{ ++ UCHAR ucNumOfDispPath; ++ UCHAR ucVersion; ++ UCHAR ucPadding[2]; ++ ATOM_DISPLAY_OBJECT_PATH asDispPath[1]; ++}ATOM_DISPLAY_OBJECT_PATH_TABLE; ++ ++ ++typedef struct _ATOM_OBJECT //each object has this structure ++{ ++ USHORT usObjectID; ++ USHORT usSrcDstTableOffset; ++ USHORT usRecordOffset; //this pointing to a bunch of records defined below ++ USHORT usReserved; ++}ATOM_OBJECT; ++ ++typedef struct _ATOM_OBJECT_TABLE //Above 4 object table offset pointing to a bunch of objects all have this structure ++{ ++ UCHAR ucNumberOfObjects; ++ UCHAR ucPadding[3]; ++ ATOM_OBJECT asObjects[1]; ++}ATOM_OBJECT_TABLE; ++ ++typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset pointing to this structure ++{ ++ UCHAR ucNumberOfSrc; ++ USHORT usSrcObjectID[1]; ++ UCHAR ucNumberOfDst; ++ USHORT usDstObjectID[1]; ++}ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT; ++ ++ ++//Related definitions, all records are differnt but they have a commond header ++typedef struct _ATOM_COMMON_RECORD_HEADER ++{ ++ UCHAR ucRecordType; //An emun to indicate the record type ++ UCHAR ucRecordSize; //The size of the whole record in byte ++}ATOM_COMMON_RECORD_HEADER; ++ ++ ++#define ATOM_I2C_RECORD_TYPE 1 ++#define ATOM_HPD_INT_RECORD_TYPE 2 ++#define ATOM_OUTPUT_PROTECTION_RECORD_TYPE 3 ++#define ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE 4 ++#define ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD_TYPE 5 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE ++#define ATOM_ENCODER_FPGA_CONTROL_RECORD_TYPE 6 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE ++#define ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD_TYPE 7 ++#define ATOM_JTAG_RECORD_TYPE 8 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE ++#define ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE 9 ++#define ATOM_ENCODER_DVO_CF_RECORD_TYPE 10 ++#define ATOM_CONNECTOR_CF_RECORD_TYPE 11 ++#define ATOM_CONNECTOR_HARDCODE_DTD_RECORD_TYPE 12 ++#define ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE 13 ++#define ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE 14 ++#define ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE 15 ++ ++//Must be updated when new record type is added,equal to that record definition! ++#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_CONNECTOR_CF_RECORD_TYPE ++ ++typedef struct _ATOM_I2C_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ ATOM_I2C_ID_CONFIG sucI2cId; ++ UCHAR ucI2CAddr; //The slave address, it's 0 when the record is attached to connector for DDC ++}ATOM_I2C_RECORD; ++ ++typedef struct _ATOM_HPD_INT_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucHPDIntGPIOID; //Corresponding block in GPIO_PIN_INFO table gives the pin info ++ UCHAR ucPluggged_PinState; ++}ATOM_HPD_INT_RECORD; ++ ++ ++typedef struct _ATOM_OUTPUT_PROTECTION_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucProtectionFlag; ++ UCHAR ucReserved; ++}ATOM_OUTPUT_PROTECTION_RECORD; ++ ++typedef struct _ATOM_CONNECTOR_DEVICE_TAG ++{ ++ ULONG ulACPIDeviceEnum; //Reserved for now ++ USHORT usDeviceID; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT" ++ USHORT usPadding; ++}ATOM_CONNECTOR_DEVICE_TAG; ++ ++typedef struct _ATOM_CONNECTOR_DEVICE_TAG_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucNumberOfDevice; ++ UCHAR ucReserved; ++ ATOM_CONNECTOR_DEVICE_TAG asDeviceTag[1]; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation ++}ATOM_CONNECTOR_DEVICE_TAG_RECORD; ++ ++ ++typedef struct _ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucConfigGPIOID; ++ UCHAR ucConfigGPIOState; //Set to 1 when it's active high to enable external flow in ++ UCHAR ucFlowinGPIPID; ++ UCHAR ucExtInGPIPID; ++}ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD; ++ ++typedef struct _ATOM_ENCODER_FPGA_CONTROL_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucCTL1GPIO_ID; ++ UCHAR ucCTL1GPIOState; //Set to 1 when it's active high ++ UCHAR ucCTL2GPIO_ID; ++ UCHAR ucCTL2GPIOState; //Set to 1 when it's active high ++ UCHAR ucCTL3GPIO_ID; ++ UCHAR ucCTL3GPIOState; //Set to 1 when it's active high ++ UCHAR ucCTLFPGA_IN_ID; ++ UCHAR ucPadding[3]; ++}ATOM_ENCODER_FPGA_CONTROL_RECORD; ++ ++typedef struct _ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucGPIOID; //Corresponding block in GPIO_PIN_INFO table gives the pin info ++ UCHAR ucTVActiveState; //Indicating when the pin==0 or 1 when TV is connected ++}ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD; ++ ++typedef struct _ATOM_JTAG_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucTMSGPIO_ID; ++ UCHAR ucTMSGPIOState; //Set to 1 when it's active high ++ UCHAR ucTCKGPIO_ID; ++ UCHAR ucTCKGPIOState; //Set to 1 when it's active high ++ UCHAR ucTDOGPIO_ID; ++ UCHAR ucTDOGPIOState; //Set to 1 when it's active high ++ UCHAR ucTDIGPIO_ID; ++ UCHAR ucTDIGPIOState; //Set to 1 when it's active high ++ UCHAR ucPadding[2]; ++}ATOM_JTAG_RECORD; ++ ++ ++//The following generic object gpio pin control record type will replace JTAG_RECORD/FPGA_CONTROL_RECORD/DVI_EXT_INPUT_RECORD above gradually ++typedef struct _ATOM_GPIO_PIN_CONTROL_PAIR ++{ ++ UCHAR ucGPIOID; // GPIO_ID, find the corresponding ID in GPIO_LUT table ++ UCHAR ucGPIO_PinState; // Pin state showing how to set-up the pin ++}ATOM_GPIO_PIN_CONTROL_PAIR; ++ ++typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucFlags; // Future expnadibility ++ UCHAR ucNumberOfPins; // Number of GPIO pins used to control the object ++ ATOM_GPIO_PIN_CONTROL_PAIR asGpio[1]; // the real gpio pin pair determined by number of pins ucNumberOfPins ++}ATOM_OBJECT_GPIO_CNTL_RECORD; ++ ++//Definitions for GPIO pin state ++#define GPIO_PIN_TYPE_INPUT 0x00 ++#define GPIO_PIN_TYPE_OUTPUT 0x10 ++#define GPIO_PIN_TYPE_HW_CONTROL 0x20 ++ ++//For GPIO_PIN_TYPE_OUTPUT the following is defined ++#define GPIO_PIN_OUTPUT_STATE_MASK 0x01 ++#define GPIO_PIN_OUTPUT_STATE_SHIFT 0 ++#define GPIO_PIN_STATE_ACTIVE_LOW 0x0 ++#define GPIO_PIN_STATE_ACTIVE_HIGH 0x1 ++ ++typedef struct _ATOM_ENCODER_DVO_CF_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ ULONG ulStrengthControl; // DVOA strength control for CF ++ UCHAR ucPadding[2]; ++}ATOM_ENCODER_DVO_CF_RECORD; ++ ++// value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle ++#define ATOM_CONNECTOR_CF_RECORD_CONNECTED_UPPER12BITBUNDLEA 1 ++#define ATOM_CONNECTOR_CF_RECORD_CONNECTED_LOWER12BITBUNDLEB 2 ++ ++typedef struct _ATOM_CONNECTOR_CF_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ USHORT usMaxPixClk; ++ UCHAR ucFlowCntlGpioId; ++ UCHAR ucSwapCntlGpioId; ++ UCHAR ucConnectedDvoBundle; ++ UCHAR ucPadding; ++}ATOM_CONNECTOR_CF_RECORD; ++ ++typedef struct _ATOM_CONNECTOR_HARDCODE_DTD_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ ATOM_DTD_FORMAT asTiming; ++}ATOM_CONNECTOR_HARDCODE_DTD_RECORD; ++ ++typedef struct _ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; //ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE ++ UCHAR ucSubConnectorType; //CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D|X_ID_DUAL_LINK_DVI_D|HDMI_TYPE_A ++ UCHAR ucReserved; ++}ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD; ++ ++ ++typedef struct _ATOM_ROUTER_DDC_PATH_SELECT_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucMuxType; //decide the number of ucMuxState, =0, no pin state, =1: single state with complement, >1: multiple state ++ UCHAR ucMuxControlPin; ++ UCHAR ucMuxState[2]; //for alligment purpose ++}ATOM_ROUTER_DDC_PATH_SELECT_RECORD; ++ ++typedef struct _ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD ++{ ++ ATOM_COMMON_RECORD_HEADER sheader; ++ UCHAR ucMuxType; ++ UCHAR ucMuxControlPin; ++ UCHAR ucMuxState[2]; //for alligment purpose ++}ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD; ++ ++// define ucMuxType ++#define ATOM_ROUTER_MUX_PIN_STATE_MASK 0x0f ++#define ATOM_ROUTER_MUX_PIN_SINGLE_STATE_COMPLEMENT 0x01 ++ ++/****************************************************************************/ ++// ASIC voltage data table ++/****************************************************************************/ ++typedef struct _ATOM_VOLTAGE_INFO_HEADER ++{ ++ USHORT usVDDCBaseLevel; //In number of 50mv unit ++ USHORT usReserved; //For possible extension table offset ++ UCHAR ucNumOfVoltageEntries; ++ UCHAR ucBytesPerVoltageEntry; ++ UCHAR ucVoltageStep; //Indicating in how many mv increament is one step, 0.5mv unit ++ UCHAR ucDefaultVoltageEntry; ++ UCHAR ucVoltageControlI2cLine; ++ UCHAR ucVoltageControlAddress; ++ UCHAR ucVoltageControlOffset; ++}ATOM_VOLTAGE_INFO_HEADER; ++ ++typedef struct _ATOM_VOLTAGE_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_VOLTAGE_INFO_HEADER viHeader; ++ UCHAR ucVoltageEntries[64]; //64 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries*ucBytesPerVoltageEntry ++}ATOM_VOLTAGE_INFO; ++ ++ ++typedef struct _ATOM_VOLTAGE_FORMULA ++{ ++ USHORT usVoltageBaseLevel; // In number of 1mv unit ++ USHORT usVoltageStep; // Indicating in how many mv increament is one step, 1mv unit ++ UCHAR ucNumOfVoltageEntries; // Number of Voltage Entry, which indicate max Voltage ++ UCHAR ucFlag; // bit0=0 :step is 1mv =1 0.5mv ++ UCHAR ucBaseVID; // if there is no lookup table, VID= BaseVID + ( Vol - BaseLevle ) /VoltageStep ++ UCHAR ucReserved; ++ UCHAR ucVIDAdjustEntries[32]; // 32 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries ++}ATOM_VOLTAGE_FORMULA; ++ ++typedef struct _ATOM_VOLTAGE_CONTROL ++{ ++ UCHAR ucVoltageControlId; //Indicate it is controlled by I2C or GPIO or HW state machine ++ UCHAR ucVoltageControlI2cLine; ++ UCHAR ucVoltageControlAddress; ++ UCHAR ucVoltageControlOffset; ++ USHORT usGpioPin_AIndex; //GPIO_PAD register index ++ UCHAR ucGpioPinBitShift[9]; //at most 8 pin support 255 VIDs, termintate with 0xff ++ UCHAR ucReserved; ++}ATOM_VOLTAGE_CONTROL; ++ ++// Define ucVoltageControlId ++#define VOLTAGE_CONTROLLED_BY_HW 0x00 ++#define VOLTAGE_CONTROLLED_BY_I2C_MASK 0x7F ++#define VOLTAGE_CONTROLLED_BY_GPIO 0x80 ++#define VOLTAGE_CONTROL_ID_LM64 0x01 //I2C control, used for R5xx Core Voltage ++#define VOLTAGE_CONTROL_ID_DAC 0x02 //I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI ++#define VOLTAGE_CONTROL_ID_VT116xM 0x03 //I2C control, used for R6xx Core Voltage ++#define VOLTAGE_CONTROL_ID_DS4402 0x04 ++ ++typedef struct _ATOM_VOLTAGE_OBJECT ++{ ++ UCHAR ucVoltageType; //Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI ++ UCHAR ucSize; //Size of Object ++ ATOM_VOLTAGE_CONTROL asControl; //describ how to control ++ ATOM_VOLTAGE_FORMULA asFormula; //Indicate How to convert real Voltage to VID ++}ATOM_VOLTAGE_OBJECT; ++ ++typedef struct _ATOM_VOLTAGE_OBJECT_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_VOLTAGE_OBJECT asVoltageObj[3]; //Info for Voltage control ++}ATOM_VOLTAGE_OBJECT_INFO; ++ ++typedef struct _ATOM_LEAKID_VOLTAGE ++{ ++ UCHAR ucLeakageId; ++ UCHAR ucReserved; ++ USHORT usVoltage; ++}ATOM_LEAKID_VOLTAGE; ++ ++typedef struct _ATOM_ASIC_PROFILE_VOLTAGE ++{ ++ UCHAR ucProfileId; ++ UCHAR ucReserved; ++ USHORT usSize; ++ USHORT usEfuseSpareStartAddr; ++ USHORT usFuseIndex[8]; //from LSB to MSB, Max 8bit,end of 0xffff if less than 8 efuse id, ++ ATOM_LEAKID_VOLTAGE asLeakVol[2]; //Leakid and relatd voltage ++}ATOM_ASIC_PROFILE_VOLTAGE; ++ ++//ucProfileId ++#define ATOM_ASIC_PROFILE_ID_EFUSE_VOLTAGE 1 ++#define ATOM_ASIC_PROFILE_ID_EFUSE_PERFORMANCE_VOLTAGE 1 ++#define ATOM_ASIC_PROFILE_ID_EFUSE_THERMAL_VOLTAGE 2 ++ ++typedef struct _ATOM_ASIC_PROFILING_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER asHeader; ++ ATOM_ASIC_PROFILE_VOLTAGE asVoltage; ++}ATOM_ASIC_PROFILING_INFO; ++ ++typedef struct _ATOM_POWER_SOURCE_OBJECT ++{ ++ UCHAR ucPwrSrcId; // Power source ++ UCHAR ucPwrSensorType; // GPIO, I2C or none ++ UCHAR ucPwrSensId; // if GPIO detect, it is GPIO id, if I2C detect, it is I2C id ++ UCHAR ucPwrSensSlaveAddr; // Slave address if I2C detect ++ UCHAR ucPwrSensRegIndex; // I2C register Index if I2C detect ++ UCHAR ucPwrSensRegBitMask; // detect which bit is used if I2C detect ++ UCHAR ucPwrSensActiveState; // high active or low active ++ UCHAR ucReserve[3]; // reserve ++ USHORT usSensPwr; // in unit of watt ++}ATOM_POWER_SOURCE_OBJECT; ++ ++typedef struct _ATOM_POWER_SOURCE_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER asHeader; ++ UCHAR asPwrbehave[16]; ++ ATOM_POWER_SOURCE_OBJECT asPwrObj[1]; ++}ATOM_POWER_SOURCE_INFO; ++ ++ ++//Define ucPwrSrcId ++#define POWERSOURCE_PCIE_ID1 0x00 ++#define POWERSOURCE_6PIN_CONNECTOR_ID1 0x01 ++#define POWERSOURCE_8PIN_CONNECTOR_ID1 0x02 ++#define POWERSOURCE_6PIN_CONNECTOR_ID2 0x04 ++#define POWERSOURCE_8PIN_CONNECTOR_ID2 0x08 ++ ++//define ucPwrSensorId ++#define POWER_SENSOR_ALWAYS 0x00 ++#define POWER_SENSOR_GPIO 0x01 ++#define POWER_SENSOR_I2C 0x02 ++ ++/**************************************************************************/ ++// This portion is only used when ext thermal chip or engine/memory clock SS chip is populated on a design ++//Memory SS Info Table ++//Define Memory Clock SS chip ID ++#define ICS91719 1 ++#define ICS91720 2 ++ ++//Define one structure to inform SW a "block of data" writing to external SS chip via I2C protocol ++typedef struct _ATOM_I2C_DATA_RECORD ++{ ++ UCHAR ucNunberOfBytes; //Indicates how many bytes SW needs to write to the external ASIC for one block, besides to "Start" and "Stop" ++ UCHAR ucI2CData[1]; //I2C data in bytes, should be less than 16 bytes usually ++}ATOM_I2C_DATA_RECORD; ++ ++ ++//Define one structure to inform SW how many blocks of data writing to external SS chip via I2C protocol, in addition to other information ++typedef struct _ATOM_I2C_DEVICE_SETUP_INFO ++{ ++ ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; //I2C line and HW/SW assisted cap. ++ UCHAR ucSSChipID; //SS chip being used ++ UCHAR ucSSChipSlaveAddr; //Slave Address to set up this SS chip ++ UCHAR ucNumOfI2CDataRecords; //number of data block ++ ATOM_I2C_DATA_RECORD asI2CData[1]; ++}ATOM_I2C_DEVICE_SETUP_INFO; ++ ++//========================================================================================== ++typedef struct _ATOM_ASIC_MVDD_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_I2C_DEVICE_SETUP_INFO asI2CSetup[1]; ++}ATOM_ASIC_MVDD_INFO; ++ ++//========================================================================================== ++#define ATOM_MCLK_SS_INFO ATOM_ASIC_MVDD_INFO ++ ++//========================================================================================== ++/**************************************************************************/ ++ ++typedef struct _ATOM_ASIC_SS_ASSIGNMENT ++{ ++ ULONG ulTargetClockRange; //Clock Out frequence (VCO ), in unit of 10Khz ++ USHORT usSpreadSpectrumPercentage; //in unit of 0.01% ++ USHORT usSpreadRateInKhz; //in unit of kHz, modulation freq ++ UCHAR ucClockIndication; //Indicate which clock source needs SS ++ UCHAR ucSpreadSpectrumMode; //Bit1=0 Down Spread,=1 Center Spread. ++ UCHAR ucReserved[2]; ++}ATOM_ASIC_SS_ASSIGNMENT; ++ ++//Define ucSpreadSpectrumType ++#define ASIC_INTERNAL_MEMORY_SS 1 ++#define ASIC_INTERNAL_ENGINE_SS 2 ++#define ASIC_INTERNAL_UVD_SS 3 ++ ++typedef struct _ATOM_ASIC_INTERNAL_SS_INFO{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_ASIC_SS_ASSIGNMENT asSpreadSpectrum[4]; ++}ATOM_ASIC_INTERNAL_SS_INFO; ++ ++//==============================Scratch Pad Definition Portion=============================== ++#define ATOM_DEVICE_CONNECT_INFO_DEF 0 ++#define ATOM_ROM_LOCATION_DEF 1 ++#define ATOM_TV_STANDARD_DEF 2 ++#define ATOM_ACTIVE_INFO_DEF 3 ++#define ATOM_LCD_INFO_DEF 4 ++#define ATOM_DOS_REQ_INFO_DEF 5 ++#define ATOM_ACC_CHANGE_INFO_DEF 6 ++#define ATOM_DOS_MODE_INFO_DEF 7 ++#define ATOM_I2C_CHANNEL_STATUS_DEF 8 ++#define ATOM_I2C_CHANNEL_STATUS1_DEF 9 ++ ++ ++// BIOS_0_SCRATCH Definition ++#define ATOM_S0_CRT1_MONO 0x00000001L ++#define ATOM_S0_CRT1_COLOR 0x00000002L ++#define ATOM_S0_CRT1_MASK (ATOM_S0_CRT1_MONO+ATOM_S0_CRT1_COLOR) ++ ++#define ATOM_S0_TV1_COMPOSITE_A 0x00000004L ++#define ATOM_S0_TV1_SVIDEO_A 0x00000008L ++#define ATOM_S0_TV1_MASK_A (ATOM_S0_TV1_COMPOSITE_A+ATOM_S0_TV1_SVIDEO_A) ++ ++#define ATOM_S0_CV_A 0x00000010L ++#define ATOM_S0_CV_DIN_A 0x00000020L ++#define ATOM_S0_CV_MASK_A (ATOM_S0_CV_A+ATOM_S0_CV_DIN_A) ++ ++ ++#define ATOM_S0_CRT2_MONO 0x00000100L ++#define ATOM_S0_CRT2_COLOR 0x00000200L ++#define ATOM_S0_CRT2_MASK (ATOM_S0_CRT2_MONO+ATOM_S0_CRT2_COLOR) ++ ++#define ATOM_S0_TV1_COMPOSITE 0x00000400L ++#define ATOM_S0_TV1_SVIDEO 0x00000800L ++#define ATOM_S0_TV1_SCART 0x00004000L ++#define ATOM_S0_TV1_MASK (ATOM_S0_TV1_COMPOSITE+ATOM_S0_TV1_SVIDEO+ATOM_S0_TV1_SCART) ++ ++#define ATOM_S0_CV 0x00001000L ++#define ATOM_S0_CV_DIN 0x00002000L ++#define ATOM_S0_CV_MASK (ATOM_S0_CV+ATOM_S0_CV_DIN) ++ ++#define ATOM_S0_DFP1 0x00010000L ++#define ATOM_S0_DFP2 0x00020000L ++#define ATOM_S0_LCD1 0x00040000L ++#define ATOM_S0_LCD2 0x00080000L ++#define ATOM_S0_TV2 0x00100000L ++#define ATOM_S0_DFP3 0x00200000L ++#define ATOM_S0_DFP4 0x00400000L ++#define ATOM_S0_DFP5 0x00800000L ++ ++#define ATOM_S0_DFP_MASK ATOM_S0_DFP1 | ATOM_S0_DFP2 | ATOM_S0_DFP3 | ATOM_S0_DFP4 | ATOM_S0_DFP5 ++ ++#define ATOM_S0_FAD_REGISTER_BUG 0x02000000L // If set, indicates we are running a PCIE asic with ++ // the FAD/HDP reg access bug. Bit is read by DAL ++ ++#define ATOM_S0_THERMAL_STATE_MASK 0x1C000000L ++#define ATOM_S0_THERMAL_STATE_SHIFT 26 ++ ++#define ATOM_S0_SYSTEM_POWER_STATE_MASK 0xE0000000L ++#define ATOM_S0_SYSTEM_POWER_STATE_SHIFT 29 ++ ++#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_AC 1 ++#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 ++#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 ++ ++//Byte aligned defintion for BIOS usage ++#define ATOM_S0_CRT1_MONOb0 0x01 ++#define ATOM_S0_CRT1_COLORb0 0x02 ++#define ATOM_S0_CRT1_MASKb0 (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0) ++ ++#define ATOM_S0_TV1_COMPOSITEb0 0x04 ++#define ATOM_S0_TV1_SVIDEOb0 0x08 ++#define ATOM_S0_TV1_MASKb0 (ATOM_S0_TV1_COMPOSITEb0+ATOM_S0_TV1_SVIDEOb0) ++ ++#define ATOM_S0_CVb0 0x10 ++#define ATOM_S0_CV_DINb0 0x20 ++#define ATOM_S0_CV_MASKb0 (ATOM_S0_CVb0+ATOM_S0_CV_DINb0) ++ ++#define ATOM_S0_CRT2_MONOb1 0x01 ++#define ATOM_S0_CRT2_COLORb1 0x02 ++#define ATOM_S0_CRT2_MASKb1 (ATOM_S0_CRT2_MONOb1+ATOM_S0_CRT2_COLORb1) ++ ++#define ATOM_S0_TV1_COMPOSITEb1 0x04 ++#define ATOM_S0_TV1_SVIDEOb1 0x08 ++#define ATOM_S0_TV1_SCARTb1 0x40 ++#define ATOM_S0_TV1_MASKb1 (ATOM_S0_TV1_COMPOSITEb1+ATOM_S0_TV1_SVIDEOb1+ATOM_S0_TV1_SCARTb1) ++ ++#define ATOM_S0_CVb1 0x10 ++#define ATOM_S0_CV_DINb1 0x20 ++#define ATOM_S0_CV_MASKb1 (ATOM_S0_CVb1+ATOM_S0_CV_DINb1) ++ ++#define ATOM_S0_DFP1b2 0x01 ++#define ATOM_S0_DFP2b2 0x02 ++#define ATOM_S0_LCD1b2 0x04 ++#define ATOM_S0_LCD2b2 0x08 ++#define ATOM_S0_TV2b2 0x10 ++#define ATOM_S0_DFP3b2 0x20 ++ ++#define ATOM_S0_THERMAL_STATE_MASKb3 0x1C ++#define ATOM_S0_THERMAL_STATE_SHIFTb3 2 ++ ++#define ATOM_S0_SYSTEM_POWER_STATE_MASKb3 0xE0 ++#define ATOM_S0_LCD1_SHIFT 18 ++ ++// BIOS_1_SCRATCH Definition ++#define ATOM_S1_ROM_LOCATION_MASK 0x0000FFFFL ++#define ATOM_S1_PCI_BUS_DEV_MASK 0xFFFF0000L ++ ++// BIOS_2_SCRATCH Definition ++#define ATOM_S2_TV1_STANDARD_MASK 0x0000000FL ++#define ATOM_S2_CURRENT_BL_LEVEL_MASK 0x0000FF00L ++#define ATOM_S2_CURRENT_BL_LEVEL_SHIFT 8 ++ ++#define ATOM_S2_CRT1_DPMS_STATE 0x00010000L ++#define ATOM_S2_LCD1_DPMS_STATE 0x00020000L ++#define ATOM_S2_TV1_DPMS_STATE 0x00040000L ++#define ATOM_S2_DFP1_DPMS_STATE 0x00080000L ++#define ATOM_S2_CRT2_DPMS_STATE 0x00100000L ++#define ATOM_S2_LCD2_DPMS_STATE 0x00200000L ++#define ATOM_S2_TV2_DPMS_STATE 0x00400000L ++#define ATOM_S2_DFP2_DPMS_STATE 0x00800000L ++#define ATOM_S2_CV_DPMS_STATE 0x01000000L ++#define ATOM_S2_DFP3_DPMS_STATE 0x02000000L ++#define ATOM_S2_DFP4_DPMS_STATE 0x04000000L ++#define ATOM_S2_DFP5_DPMS_STATE 0x08000000L ++ ++#define ATOM_S2_DFP_DPM_STATE ATOM_S2_DFP1_DPMS_STATE | ATOM_S2_DFP2_DPMS_STATE | ATOM_S2_DFP3_DPMS_STATE | ATOM_S2_DFP4_DPMS_STATE | ATOM_S2_DFP5_DPMS_STATE ++ ++#define ATOM_S2_DEVICE_DPMS_STATE (ATOM_S2_CRT1_DPMS_STATE+ATOM_S2_LCD1_DPMS_STATE+ATOM_S2_TV1_DPMS_STATE+\ ++ ATOM_S2_DFP_DPMS_STATE+ATOM_S2_CRT2_DPMS_STATE+ATOM_S2_LCD2_DPMS_STATE+\ ++ ATOM_S2_TV2_DPMS_STATE+ATOM_S2_CV_DPMS_STATE ++ ++#define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK 0x0C000000L ++#define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK_SHIFT 26 ++#define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGE 0x10000000L ++ ++#define ATOM_S2_VRI_BRIGHT_ENABLE 0x20000000L ++ ++#define ATOM_S2_DISPLAY_ROTATION_0_DEGREE 0x0 ++#define ATOM_S2_DISPLAY_ROTATION_90_DEGREE 0x1 ++#define ATOM_S2_DISPLAY_ROTATION_180_DEGREE 0x2 ++#define ATOM_S2_DISPLAY_ROTATION_270_DEGREE 0x3 ++#define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30 ++#define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK 0xC0000000L ++ ++ ++//Byte aligned defintion for BIOS usage ++#define ATOM_S2_TV1_STANDARD_MASKb0 0x0F ++#define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF ++#define ATOM_S2_CRT1_DPMS_STATEb2 0x01 ++#define ATOM_S2_LCD1_DPMS_STATEb2 0x02 ++#define ATOM_S2_TV1_DPMS_STATEb2 0x04 ++#define ATOM_S2_DFP1_DPMS_STATEb2 0x08 ++#define ATOM_S2_CRT2_DPMS_STATEb2 0x10 ++#define ATOM_S2_LCD2_DPMS_STATEb2 0x20 ++#define ATOM_S2_TV2_DPMS_STATEb2 0x40 ++#define ATOM_S2_DFP2_DPMS_STATEb2 0x80 ++#define ATOM_S2_CV_DPMS_STATEb3 0x01 ++#define ATOM_S2_DFP3_DPMS_STATEb3 0x02 ++#define ATOM_S2_DFP4_DPMS_STATEb3 0x04 ++#define ATOM_S2_DFP5_DPMS_STATEb3 0x08 ++ ++#define ATOM_S2_DEVICE_DPMS_MASKw1 0x3FF ++#define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASKb3 0x0C ++#define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGEb3 0x10 ++#define ATOM_S2_VRI_BRIGHT_ENABLEb3 0x20 ++#define ATOM_S2_ROTATION_STATE_MASKb3 0xC0 ++ ++ ++// BIOS_3_SCRATCH Definition ++#define ATOM_S3_CRT1_ACTIVE 0x00000001L ++#define ATOM_S3_LCD1_ACTIVE 0x00000002L ++#define ATOM_S3_TV1_ACTIVE 0x00000004L ++#define ATOM_S3_DFP1_ACTIVE 0x00000008L ++#define ATOM_S3_CRT2_ACTIVE 0x00000010L ++#define ATOM_S3_LCD2_ACTIVE 0x00000020L ++#define ATOM_S3_TV2_ACTIVE 0x00000040L ++#define ATOM_S3_DFP2_ACTIVE 0x00000080L ++#define ATOM_S3_CV_ACTIVE 0x00000100L ++#define ATOM_S3_DFP3_ACTIVE 0x00000200L ++#define ATOM_S3_DFP4_ACTIVE 0x00000400L ++#define ATOM_S3_DFP5_ACTIVE 0x00000800L ++ ++#define ATOM_S3_DEVICE_ACTIVE_MASK 0x000003FFL ++ ++#define ATOM_S3_LCD_FULLEXPANSION_ACTIVE 0x00001000L ++#define ATOM_S3_LCD_EXPANSION_ASPEC_RATIO_ACTIVE 0x00002000L ++ ++#define ATOM_S3_CRT1_CRTC_ACTIVE 0x00010000L ++#define ATOM_S3_LCD1_CRTC_ACTIVE 0x00020000L ++#define ATOM_S3_TV1_CRTC_ACTIVE 0x00040000L ++#define ATOM_S3_DFP1_CRTC_ACTIVE 0x00080000L ++#define ATOM_S3_CRT2_CRTC_ACTIVE 0x00100000L ++#define ATOM_S3_LCD2_CRTC_ACTIVE 0x00200000L ++#define ATOM_S3_TV2_CRTC_ACTIVE 0x00400000L ++#define ATOM_S3_DFP2_CRTC_ACTIVE 0x00800000L ++#define ATOM_S3_CV_CRTC_ACTIVE 0x01000000L ++#define ATOM_S3_DFP3_CRTC_ACTIVE 0x02000000L ++#define ATOM_S3_DFP4_CRTC_ACTIVE 0x04000000L ++#define ATOM_S3_DFP5_CRTC_ACTIVE 0x08000000L ++ ++#define ATOM_S3_DEVICE_CRTC_ACTIVE_MASK 0x0FFF0000L ++#define ATOM_S3_ASIC_GUI_ENGINE_HUNG 0x20000000L ++#define ATOM_S3_ALLOW_FAST_PWR_SWITCH 0x40000000L ++#define ATOM_S3_RQST_GPU_USE_MIN_PWR 0x80000000L ++ ++//Byte aligned defintion for BIOS usage ++#define ATOM_S3_CRT1_ACTIVEb0 0x01 ++#define ATOM_S3_LCD1_ACTIVEb0 0x02 ++#define ATOM_S3_TV1_ACTIVEb0 0x04 ++#define ATOM_S3_DFP1_ACTIVEb0 0x08 ++#define ATOM_S3_CRT2_ACTIVEb0 0x10 ++#define ATOM_S3_LCD2_ACTIVEb0 0x20 ++#define ATOM_S3_TV2_ACTIVEb0 0x40 ++#define ATOM_S3_DFP2_ACTIVEb0 0x80 ++#define ATOM_S3_CV_ACTIVEb1 0x01 ++#define ATOM_S3_DFP3_ACTIVEb1 0x02 ++#define ATOM_S3_DFP4_ACTIVEb1 0x04 ++#define ATOM_S3_DFP5_ACTIVEb1 0x08 ++ ++#define ATOM_S3_ACTIVE_CRTC1w0 0xFFF ++ ++#define ATOM_S3_CRT1_CRTC_ACTIVEb2 0x01 ++#define ATOM_S3_LCD1_CRTC_ACTIVEb2 0x02 ++#define ATOM_S3_TV1_CRTC_ACTIVEb2 0x04 ++#define ATOM_S3_DFP1_CRTC_ACTIVEb2 0x08 ++#define ATOM_S3_CRT2_CRTC_ACTIVEb2 0x10 ++#define ATOM_S3_LCD2_CRTC_ACTIVEb2 0x20 ++#define ATOM_S3_TV2_CRTC_ACTIVEb2 0x40 ++#define ATOM_S3_DFP2_CRTC_ACTIVEb2 0x80 ++#define ATOM_S3_CV_CRTC_ACTIVEb3 0x01 ++#define ATOM_S3_DFP3_CRTC_ACTIVEb3 0x02 ++#define ATOM_S3_DFP4_CRTC_ACTIVEb3 0x04 ++#define ATOM_S3_DFP5_CRTC_ACTIVEb3 0x08 ++ ++#define ATOM_S3_ACTIVE_CRTC2w1 0xFFF ++ ++#define ATOM_S3_ASIC_GUI_ENGINE_HUNGb3 0x20 ++#define ATOM_S3_ALLOW_FAST_PWR_SWITCHb3 0x40 ++#define ATOM_S3_RQST_GPU_USE_MIN_PWRb3 0x80 ++ ++// BIOS_4_SCRATCH Definition ++#define ATOM_S4_LCD1_PANEL_ID_MASK 0x000000FFL ++#define ATOM_S4_LCD1_REFRESH_MASK 0x0000FF00L ++#define ATOM_S4_LCD1_REFRESH_SHIFT 8 ++ ++//Byte aligned defintion for BIOS usage ++#define ATOM_S4_LCD1_PANEL_ID_MASKb0 0x0FF ++#define ATOM_S4_LCD1_REFRESH_MASKb1 ATOM_S4_LCD1_PANEL_ID_MASKb0 ++#define ATOM_S4_VRAM_INFO_MASKb2 ATOM_S4_LCD1_PANEL_ID_MASKb0 ++ ++// BIOS_5_SCRATCH Definition, BIOS_5_SCRATCH is used by Firmware only !!!! ++#define ATOM_S5_DOS_REQ_CRT1b0 0x01 ++#define ATOM_S5_DOS_REQ_LCD1b0 0x02 ++#define ATOM_S5_DOS_REQ_TV1b0 0x04 ++#define ATOM_S5_DOS_REQ_DFP1b0 0x08 ++#define ATOM_S5_DOS_REQ_CRT2b0 0x10 ++#define ATOM_S5_DOS_REQ_LCD2b0 0x20 ++#define ATOM_S5_DOS_REQ_TV2b0 0x40 ++#define ATOM_S5_DOS_REQ_DFP2b0 0x80 ++#define ATOM_S5_DOS_REQ_CVb1 0x01 ++#define ATOM_S5_DOS_REQ_DFP3b1 0x02 ++#define ATOM_S5_DOS_REQ_DFP4b1 0x04 ++#define ATOM_S5_DOS_REQ_DFP5b1 0x08 ++ ++#define ATOM_S5_DOS_REQ_DEVICEw0 0x03FF ++ ++#define ATOM_S5_DOS_REQ_CRT1 0x0001 ++#define ATOM_S5_DOS_REQ_LCD1 0x0002 ++#define ATOM_S5_DOS_REQ_TV1 0x0004 ++#define ATOM_S5_DOS_REQ_DFP1 0x0008 ++#define ATOM_S5_DOS_REQ_CRT2 0x0010 ++#define ATOM_S5_DOS_REQ_LCD2 0x0020 ++#define ATOM_S5_DOS_REQ_TV2 0x0040 ++#define ATOM_S5_DOS_REQ_DFP2 0x0080 ++#define ATOM_S5_DOS_REQ_CV 0x0100 ++#define ATOM_S5_DOS_REQ_DFP3 0x0200 ++#define ATOM_S5_DOS_REQ_DFP4 0x0400 ++#define ATOM_S5_DOS_REQ_DFP5 0x0800 ++ ++#define ATOM_S5_DOS_FORCE_CRT1b2 ATOM_S5_DOS_REQ_CRT1b0 ++#define ATOM_S5_DOS_FORCE_TV1b2 ATOM_S5_DOS_REQ_TV1b0 ++#define ATOM_S5_DOS_FORCE_CRT2b2 ATOM_S5_DOS_REQ_CRT2b0 ++#define ATOM_S5_DOS_FORCE_CVb3 ATOM_S5_DOS_REQ_CVb1 ++#define ATOM_S5_DOS_FORCE_DEVICEw1 (ATOM_S5_DOS_FORCE_CRT1b2+ATOM_S5_DOS_FORCE_TV1b2+ATOM_S5_DOS_FORCE_CRT2b2+\ ++ (ATOM_S5_DOS_FORCE_CVb3<<8)) ++ ++// BIOS_6_SCRATCH Definition ++#define ATOM_S6_DEVICE_CHANGE 0x00000001L ++#define ATOM_S6_SCALER_CHANGE 0x00000002L ++#define ATOM_S6_LID_CHANGE 0x00000004L ++#define ATOM_S6_DOCKING_CHANGE 0x00000008L ++#define ATOM_S6_ACC_MODE 0x00000010L ++#define ATOM_S6_EXT_DESKTOP_MODE 0x00000020L ++#define ATOM_S6_LID_STATE 0x00000040L ++#define ATOM_S6_DOCK_STATE 0x00000080L ++#define ATOM_S6_CRITICAL_STATE 0x00000100L ++#define ATOM_S6_HW_I2C_BUSY_STATE 0x00000200L ++#define ATOM_S6_THERMAL_STATE_CHANGE 0x00000400L ++#define ATOM_S6_INTERRUPT_SET_BY_BIOS 0x00000800L ++#define ATOM_S6_REQ_LCD_EXPANSION_FULL 0x00001000L //Normal expansion Request bit for LCD ++#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO 0x00002000L //Aspect ratio expansion Request bit for LCD ++ ++#define ATOM_S6_DISPLAY_STATE_CHANGE 0x00004000L //This bit is recycled when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_H_expansion ++#define ATOM_S6_I2C_STATE_CHANGE 0x00008000L //This bit is recycled,when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_V_expansion ++ ++#define ATOM_S6_ACC_REQ_CRT1 0x00010000L ++#define ATOM_S6_ACC_REQ_LCD1 0x00020000L ++#define ATOM_S6_ACC_REQ_TV1 0x00040000L ++#define ATOM_S6_ACC_REQ_DFP1 0x00080000L ++#define ATOM_S6_ACC_REQ_CRT2 0x00100000L ++#define ATOM_S6_ACC_REQ_LCD2 0x00200000L ++#define ATOM_S6_ACC_REQ_TV2 0x00400000L ++#define ATOM_S6_ACC_REQ_DFP2 0x00800000L ++#define ATOM_S6_ACC_REQ_CV 0x01000000L ++#define ATOM_S6_ACC_REQ_DFP3 0x02000000L ++#define ATOM_S6_ACC_REQ_DFP4 0x04000000L ++#define ATOM_S6_ACC_REQ_DFP5 0x08000000L ++ ++#define ATOM_S6_ACC_REQ_MASK 0x0FFF0000L ++#define ATOM_S6_SYSTEM_POWER_MODE_CHANGE 0x10000000L ++#define ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH 0x20000000L ++#define ATOM_S6_VRI_BRIGHTNESS_CHANGE 0x40000000L ++#define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK 0x80000000L ++ ++//Byte aligned defintion for BIOS usage ++#define ATOM_S6_DEVICE_CHANGEb0 0x01 ++#define ATOM_S6_SCALER_CHANGEb0 0x02 ++#define ATOM_S6_LID_CHANGEb0 0x04 ++#define ATOM_S6_DOCKING_CHANGEb0 0x08 ++#define ATOM_S6_ACC_MODEb0 0x10 ++#define ATOM_S6_EXT_DESKTOP_MODEb0 0x20 ++#define ATOM_S6_LID_STATEb0 0x40 ++#define ATOM_S6_DOCK_STATEb0 0x80 ++#define ATOM_S6_CRITICAL_STATEb1 0x01 ++#define ATOM_S6_HW_I2C_BUSY_STATEb1 0x02 ++#define ATOM_S6_THERMAL_STATE_CHANGEb1 0x04 ++#define ATOM_S6_INTERRUPT_SET_BY_BIOSb1 0x08 ++#define ATOM_S6_REQ_LCD_EXPANSION_FULLb1 0x10 ++#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIOb1 0x20 ++ ++#define ATOM_S6_ACC_REQ_CRT1b2 0x01 ++#define ATOM_S6_ACC_REQ_LCD1b2 0x02 ++#define ATOM_S6_ACC_REQ_TV1b2 0x04 ++#define ATOM_S6_ACC_REQ_DFP1b2 0x08 ++#define ATOM_S6_ACC_REQ_CRT2b2 0x10 ++#define ATOM_S6_ACC_REQ_LCD2b2 0x20 ++#define ATOM_S6_ACC_REQ_TV2b2 0x40 ++#define ATOM_S6_ACC_REQ_DFP2b2 0x80 ++#define ATOM_S6_ACC_REQ_CVb3 0x01 ++#define ATOM_S6_ACC_REQ_DFP3b3 0x02 ++#define ATOM_S6_ACC_REQ_DFP4b3 0x04 ++#define ATOM_S6_ACC_REQ_DFP5b3 0x08 ++ ++#define ATOM_S6_ACC_REQ_DEVICEw1 ATOM_S5_DOS_REQ_DEVICEw0 ++#define ATOM_S6_SYSTEM_POWER_MODE_CHANGEb3 0x10 ++#define ATOM_S6_ACC_BLOCK_DISPLAY_SWITCHb3 0x20 ++#define ATOM_S6_VRI_BRIGHTNESS_CHANGEb3 0x40 ++#define ATOM_S6_CONFIG_DISPLAY_CHANGEb3 0x80 ++ ++#define ATOM_S6_DEVICE_CHANGE_SHIFT 0 ++#define ATOM_S6_SCALER_CHANGE_SHIFT 1 ++#define ATOM_S6_LID_CHANGE_SHIFT 2 ++#define ATOM_S6_DOCKING_CHANGE_SHIFT 3 ++#define ATOM_S6_ACC_MODE_SHIFT 4 ++#define ATOM_S6_EXT_DESKTOP_MODE_SHIFT 5 ++#define ATOM_S6_LID_STATE_SHIFT 6 ++#define ATOM_S6_DOCK_STATE_SHIFT 7 ++#define ATOM_S6_CRITICAL_STATE_SHIFT 8 ++#define ATOM_S6_HW_I2C_BUSY_STATE_SHIFT 9 ++#define ATOM_S6_THERMAL_STATE_CHANGE_SHIFT 10 ++#define ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT 11 ++#define ATOM_S6_REQ_SCALER_SHIFT 12 ++#define ATOM_S6_REQ_SCALER_ARATIO_SHIFT 13 ++#define ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT 14 ++#define ATOM_S6_I2C_STATE_CHANGE_SHIFT 15 ++#define ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT 28 ++#define ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH_SHIFT 29 ++#define ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT 30 ++#define ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT 31 ++ ++// BIOS_7_SCRATCH Definition, BIOS_7_SCRATCH is used by Firmware only !!!! ++#define ATOM_S7_DOS_MODE_TYPEb0 0x03 ++#define ATOM_S7_DOS_MODE_VGAb0 0x00 ++#define ATOM_S7_DOS_MODE_VESAb0 0x01 ++#define ATOM_S7_DOS_MODE_EXTb0 0x02 ++#define ATOM_S7_DOS_MODE_PIXEL_DEPTHb0 0x0C ++#define ATOM_S7_DOS_MODE_PIXEL_FORMATb0 0xF0 ++#define ATOM_S7_DOS_8BIT_DAC_ENb1 0x01 ++#define ATOM_S7_DOS_MODE_NUMBERw1 0x0FFFF ++ ++#define ATOM_S7_DOS_8BIT_DAC_EN_SHIFT 8 ++ ++// BIOS_8_SCRATCH Definition ++#define ATOM_S8_I2C_CHANNEL_BUSY_MASK 0x00000FFFF ++#define ATOM_S8_I2C_HW_ENGINE_BUSY_MASK 0x0FFFF0000 ++ ++#define ATOM_S8_I2C_CHANNEL_BUSY_SHIFT 0 ++#define ATOM_S8_I2C_ENGINE_BUSY_SHIFT 16 ++ ++// BIOS_9_SCRATCH Definition ++#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_MASK ++#define ATOM_S9_I2C_CHANNEL_COMPLETED_MASK 0x0000FFFF ++#endif ++#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_MASK ++#define ATOM_S9_I2C_CHANNEL_ABORTED_MASK 0xFFFF0000 ++#endif ++#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_SHIFT ++#define ATOM_S9_I2C_CHANNEL_COMPLETED_SHIFT 0 ++#endif ++#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT ++#define ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT 16 ++#endif ++ ++ ++#define ATOM_FLAG_SET 0x20 ++#define ATOM_FLAG_CLEAR 0 ++#define CLEAR_ATOM_S6_ACC_MODE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_ACC_MODE_SHIFT | ATOM_FLAG_CLEAR) ++#define SET_ATOM_S6_DEVICE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DEVICE_CHANGE_SHIFT | ATOM_FLAG_SET) ++#define SET_ATOM_S6_VRI_BRIGHTNESS_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT | ATOM_FLAG_SET) ++#define SET_ATOM_S6_SCALER_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SCALER_CHANGE_SHIFT | ATOM_FLAG_SET) ++#define SET_ATOM_S6_LID_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_CHANGE_SHIFT | ATOM_FLAG_SET) ++ ++#define SET_ATOM_S6_LID_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_SET) ++#define CLEAR_ATOM_S6_LID_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_CLEAR) ++ ++#define SET_ATOM_S6_DOCK_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCKING_CHANGE_SHIFT | ATOM_FLAG_SET) ++#define SET_ATOM_S6_DOCK_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_SET) ++#define CLEAR_ATOM_S6_DOCK_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_CLEAR) ++ ++#define SET_ATOM_S6_THERMAL_STATE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_THERMAL_STATE_CHANGE_SHIFT | ATOM_FLAG_SET) ++#define SET_ATOM_S6_SYSTEM_POWER_MODE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT | ATOM_FLAG_SET) ++#define SET_ATOM_S6_INTERRUPT_SET_BY_BIOS ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT | ATOM_FLAG_SET) ++ ++#define SET_ATOM_S6_CRITICAL_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_SET) ++#define CLEAR_ATOM_S6_CRITICAL_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_CLEAR) ++ ++#define SET_ATOM_S6_REQ_SCALER ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_SET) ++#define CLEAR_ATOM_S6_REQ_SCALER ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_CLEAR ) ++ ++#define SET_ATOM_S6_REQ_SCALER_ARATIO ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_SET ) ++#define CLEAR_ATOM_S6_REQ_SCALER_ARATIO ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_CLEAR ) ++ ++#define SET_ATOM_S6_I2C_STATE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_I2C_STATE_CHANGE_SHIFT | ATOM_FLAG_SET ) ++ ++#define SET_ATOM_S6_DISPLAY_STATE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT | ATOM_FLAG_SET ) ++ ++#define SET_ATOM_S6_DEVICE_RECONFIG ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT | ATOM_FLAG_SET) ++#define CLEAR_ATOM_S0_LCD1 ((ATOM_DEVICE_CONNECT_INFO_DEF << 8 )| ATOM_S0_LCD1_SHIFT | ATOM_FLAG_CLEAR ) ++#define SET_ATOM_S7_DOS_8BIT_DAC_EN ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_SET ) ++#define CLEAR_ATOM_S7_DOS_8BIT_DAC_EN ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_CLEAR ) ++ ++/****************************************************************************/ ++//Portion II: Definitinos only used in Driver ++/****************************************************************************/ ++ ++// Macros used by driver ++ ++#define GetIndexIntoMasterTable(MasterOrData, FieldName) (((char*)(&((ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES*)0)->FieldName)-(char*)0)/sizeof(USHORT)) ++ ++#define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableFormatRevision)&0x3F) ++#define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableContentRevision)&0x3F) ++ ++#define GET_DATA_TABLE_MAJOR_REVISION GET_COMMAND_TABLE_COMMANDSET_REVISION ++#define GET_DATA_TABLE_MINOR_REVISION GET_COMMAND_TABLE_PARAMETER_REVISION ++ ++/****************************************************************************/ ++//Portion III: Definitinos only used in VBIOS ++/****************************************************************************/ ++#define ATOM_DAC_SRC 0x80 ++#define ATOM_SRC_DAC1 0 ++#define ATOM_SRC_DAC2 0x80 ++ ++ ++#ifdef UEFI_BUILD ++ #define USHORT UTEMP ++#endif ++ ++typedef struct _MEMORY_PLLINIT_PARAMETERS ++{ ++ ULONG ulTargetMemoryClock; //In 10Khz unit ++ UCHAR ucAction; //not define yet ++ UCHAR ucFbDiv_Hi; //Fbdiv Hi byte ++ UCHAR ucFbDiv; //FB value ++ UCHAR ucPostDiv; //Post div ++}MEMORY_PLLINIT_PARAMETERS; ++ ++#define MEMORY_PLLINIT_PS_ALLOCATION MEMORY_PLLINIT_PARAMETERS ++ ++ ++#define GPIO_PIN_WRITE 0x01 ++#define GPIO_PIN_READ 0x00 ++ ++typedef struct _GPIO_PIN_CONTROL_PARAMETERS ++{ ++ UCHAR ucGPIO_ID; //return value, read from GPIO pins ++ UCHAR ucGPIOBitShift; //define which bit in uGPIOBitVal need to be update ++ UCHAR ucGPIOBitVal; //Set/Reset corresponding bit defined in ucGPIOBitMask ++ UCHAR ucAction; //=GPIO_PIN_WRITE: Read; =GPIO_PIN_READ: Write ++}GPIO_PIN_CONTROL_PARAMETERS; ++ ++typedef struct _ENABLE_SCALER_PARAMETERS ++{ ++ UCHAR ucScaler; // ATOM_SCALER1, ATOM_SCALER2 ++ UCHAR ucEnable; // ATOM_SCALER_DISABLE or ATOM_SCALER_CENTER or ATOM_SCALER_EXPANSION ++ UCHAR ucTVStandard; // ++ UCHAR ucPadding[1]; ++}ENABLE_SCALER_PARAMETERS; ++#define ENABLE_SCALER_PS_ALLOCATION ENABLE_SCALER_PARAMETERS ++ ++//ucEnable: ++#define SCALER_BYPASS_AUTO_CENTER_NO_REPLICATION 0 ++#define SCALER_BYPASS_AUTO_CENTER_AUTO_REPLICATION 1 ++#define SCALER_ENABLE_2TAP_ALPHA_MODE 2 ++#define SCALER_ENABLE_MULTITAP_MODE 3 ++ ++typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS ++{ ++ ULONG usHWIconHorzVertPosn; // Hardware Icon Vertical position ++ UCHAR ucHWIconVertOffset; // Hardware Icon Vertical offset ++ UCHAR ucHWIconHorzOffset; // Hardware Icon Horizontal offset ++ UCHAR ucSelection; // ATOM_CURSOR1 or ATOM_ICON1 or ATOM_CURSOR2 or ATOM_ICON2 ++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE ++}ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS; ++ ++typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION ++{ ++ ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS sEnableIcon; ++ ENABLE_CRTC_PARAMETERS sReserved; ++}ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION; ++ ++typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS ++{ ++ USHORT usHight; // Image Hight ++ USHORT usWidth; // Image Width ++ UCHAR ucSurface; // Surface 1 or 2 ++ UCHAR ucPadding[3]; ++}ENABLE_GRAPH_SURFACE_PARAMETERS; ++ ++typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2 ++{ ++ USHORT usHight; // Image Hight ++ USHORT usWidth; // Image Width ++ UCHAR ucSurface; // Surface 1 or 2 ++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE ++ UCHAR ucPadding[2]; ++}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2; ++ ++typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION ++{ ++ ENABLE_GRAPH_SURFACE_PARAMETERS sSetSurface; ++ ENABLE_YUV_PS_ALLOCATION sReserved; // Don't set this one ++}ENABLE_GRAPH_SURFACE_PS_ALLOCATION; ++ ++typedef struct _MEMORY_CLEAN_UP_PARAMETERS ++{ ++ USHORT usMemoryStart; //in 8Kb boundry, offset from memory base address ++ USHORT usMemorySize; //8Kb blocks aligned ++}MEMORY_CLEAN_UP_PARAMETERS; ++#define MEMORY_CLEAN_UP_PS_ALLOCATION MEMORY_CLEAN_UP_PARAMETERS ++ ++typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS ++{ ++ USHORT usX_Size; //When use as input parameter, usX_Size indicates which CRTC ++ USHORT usY_Size; ++}GET_DISPLAY_SURFACE_SIZE_PARAMETERS; ++ ++typedef struct _INDIRECT_IO_ACCESS ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR IOAccessSequence[256]; ++} INDIRECT_IO_ACCESS; ++ ++#define INDIRECT_READ 0x00 ++#define INDIRECT_WRITE 0x80 ++ ++#define INDIRECT_IO_MM 0 ++#define INDIRECT_IO_PLL 1 ++#define INDIRECT_IO_MC 2 ++#define INDIRECT_IO_PCIE 3 ++#define INDIRECT_IO_PCIEP 4 ++#define INDIRECT_IO_NBMISC 5 ++ ++#define INDIRECT_IO_PLL_READ INDIRECT_IO_PLL | INDIRECT_READ ++#define INDIRECT_IO_PLL_WRITE INDIRECT_IO_PLL | INDIRECT_WRITE ++#define INDIRECT_IO_MC_READ INDIRECT_IO_MC | INDIRECT_READ ++#define INDIRECT_IO_MC_WRITE INDIRECT_IO_MC | INDIRECT_WRITE ++#define INDIRECT_IO_PCIE_READ INDIRECT_IO_PCIE | INDIRECT_READ ++#define INDIRECT_IO_PCIE_WRITE INDIRECT_IO_PCIE | INDIRECT_WRITE ++#define INDIRECT_IO_PCIEP_READ INDIRECT_IO_PCIEP | INDIRECT_READ ++#define INDIRECT_IO_PCIEP_WRITE INDIRECT_IO_PCIEP | INDIRECT_WRITE ++#define INDIRECT_IO_NBMISC_READ INDIRECT_IO_NBMISC | INDIRECT_READ ++#define INDIRECT_IO_NBMISC_WRITE INDIRECT_IO_NBMISC | INDIRECT_WRITE ++ ++typedef struct _ATOM_OEM_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; ++}ATOM_OEM_INFO; ++ ++typedef struct _ATOM_TV_MODE ++{ ++ UCHAR ucVMode_Num; //Video mode number ++ UCHAR ucTV_Mode_Num; //Internal TV mode number ++}ATOM_TV_MODE; ++ ++typedef struct _ATOM_BIOS_INT_TVSTD_MODE ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usTV_Mode_LUT_Offset; // Pointer to standard to internal number conversion table ++ USHORT usTV_FIFO_Offset; // Pointer to FIFO entry table ++ USHORT usNTSC_Tbl_Offset; // Pointer to SDTV_Mode_NTSC table ++ USHORT usPAL_Tbl_Offset; // Pointer to SDTV_Mode_PAL table ++ USHORT usCV_Tbl_Offset; // Pointer to SDTV_Mode_PAL table ++}ATOM_BIOS_INT_TVSTD_MODE; ++ ++ ++typedef struct _ATOM_TV_MODE_SCALER_PTR ++{ ++ USHORT ucFilter0_Offset; //Pointer to filter format 0 coefficients ++ USHORT usFilter1_Offset; //Pointer to filter format 0 coefficients ++ UCHAR ucTV_Mode_Num; ++}ATOM_TV_MODE_SCALER_PTR; ++ ++typedef struct _ATOM_STANDARD_VESA_TIMING ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_DTD_FORMAT aModeTimings[16]; // 16 is not the real array number, just for initial allocation ++}ATOM_STANDARD_VESA_TIMING; ++ ++ ++typedef struct _ATOM_STD_FORMAT ++{ ++ USHORT usSTD_HDisp; ++ USHORT usSTD_VDisp; ++ USHORT usSTD_RefreshRate; ++ USHORT usReserved; ++}ATOM_STD_FORMAT; ++ ++typedef struct _ATOM_VESA_TO_EXTENDED_MODE ++{ ++ USHORT usVESA_ModeNumber; ++ USHORT usExtendedModeNumber; ++}ATOM_VESA_TO_EXTENDED_MODE; ++ ++typedef struct _ATOM_VESA_TO_INTENAL_MODE_LUT ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_VESA_TO_EXTENDED_MODE asVESA_ToExtendedModeInfo[76]; ++}ATOM_VESA_TO_INTENAL_MODE_LUT; ++ ++/*************** ATOM Memory Related Data Structure ***********************/ ++typedef struct _ATOM_MEMORY_VENDOR_BLOCK{ ++ UCHAR ucMemoryType; ++ UCHAR ucMemoryVendor; ++ UCHAR ucAdjMCId; ++ UCHAR ucDynClkId; ++ ULONG ulDllResetClkRange; ++}ATOM_MEMORY_VENDOR_BLOCK; ++ ++ ++typedef struct _ATOM_MEMORY_SETTING_ID_CONFIG{ ++#if ATOM_BIG_ENDIAN ++ ULONG ucMemBlkId:8; ++ ULONG ulMemClockRange:24; ++#else ++ ULONG ulMemClockRange:24; ++ ULONG ucMemBlkId:8; ++#endif ++}ATOM_MEMORY_SETTING_ID_CONFIG; ++ ++typedef union _ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS ++{ ++ ATOM_MEMORY_SETTING_ID_CONFIG slAccess; ++ ULONG ulAccess; ++}ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS; ++ ++ ++typedef struct _ATOM_MEMORY_SETTING_DATA_BLOCK{ ++ ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS ulMemoryID; ++ ULONG aulMemData[1]; ++}ATOM_MEMORY_SETTING_DATA_BLOCK; ++ ++ ++typedef struct _ATOM_INIT_REG_INDEX_FORMAT{ ++ USHORT usRegIndex; // MC register index ++ UCHAR ucPreRegDataLength; // offset in ATOM_INIT_REG_DATA_BLOCK.saRegDataBuf ++}ATOM_INIT_REG_INDEX_FORMAT; ++ ++ ++typedef struct _ATOM_INIT_REG_BLOCK{ ++ USHORT usRegIndexTblSize; //size of asRegIndexBuf ++ USHORT usRegDataBlkSize; //size of ATOM_MEMORY_SETTING_DATA_BLOCK ++ ATOM_INIT_REG_INDEX_FORMAT asRegIndexBuf[1]; ++ ATOM_MEMORY_SETTING_DATA_BLOCK asRegDataBuf[1]; ++}ATOM_INIT_REG_BLOCK; ++ ++#define END_OF_REG_INDEX_BLOCK 0x0ffff ++#define END_OF_REG_DATA_BLOCK 0x00000000 ++#define ATOM_INIT_REG_MASK_FLAG 0x80 ++#define CLOCK_RANGE_HIGHEST 0x00ffffff ++ ++#define VALUE_DWORD SIZEOF ULONG ++#define VALUE_SAME_AS_ABOVE 0 ++#define VALUE_MASK_DWORD 0x84 ++ ++#define INDEX_ACCESS_RANGE_BEGIN (VALUE_DWORD + 1) ++#define INDEX_ACCESS_RANGE_END (INDEX_ACCESS_RANGE_BEGIN + 1) ++#define VALUE_INDEX_ACCESS_SINGLE (INDEX_ACCESS_RANGE_END + 1) ++ ++ ++typedef struct _ATOM_MC_INIT_PARAM_TABLE ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usAdjustARB_SEQDataOffset; ++ USHORT usMCInitMemTypeTblOffset; ++ USHORT usMCInitCommonTblOffset; ++ USHORT usMCInitPowerDownTblOffset; ++ ULONG ulARB_SEQDataBuf[32]; ++ ATOM_INIT_REG_BLOCK asMCInitMemType; ++ ATOM_INIT_REG_BLOCK asMCInitCommon; ++}ATOM_MC_INIT_PARAM_TABLE; ++ ++ ++#define _4Mx16 0x2 ++#define _4Mx32 0x3 ++#define _8Mx16 0x12 ++#define _8Mx32 0x13 ++#define _16Mx16 0x22 ++#define _16Mx32 0x23 ++#define _32Mx16 0x32 ++#define _32Mx32 0x33 ++#define _64Mx8 0x41 ++#define _64Mx16 0x42 ++ ++#define SAMSUNG 0x1 ++#define INFINEON 0x2 ++#define ELPIDA 0x3 ++#define ETRON 0x4 ++#define NANYA 0x5 ++#define HYNIX 0x6 ++#define MOSEL 0x7 ++#define WINBOND 0x8 ++#define ESMT 0x9 ++#define MICRON 0xF ++ ++#define QIMONDA INFINEON ++#define PROMOS MOSEL ++ ++/////////////Support for GDDR5 MC uCode to reside in upper 64K of ROM///////////// ++ ++#define UCODE_ROM_START_ADDRESS 0x1c000 ++#define UCODE_SIGNATURE 0x4375434d // 'MCuC' - MC uCode ++ ++//uCode block header for reference ++ ++typedef struct _MCuCodeHeader ++{ ++ ULONG ulSignature; ++ UCHAR ucRevision; ++ UCHAR ucChecksum; ++ UCHAR ucReserved1; ++ UCHAR ucReserved2; ++ USHORT usParametersLength; ++ USHORT usUCodeLength; ++ USHORT usReserved1; ++ USHORT usReserved2; ++} MCuCodeHeader; ++ ++////////////////////////////////////////////////////////////////////////////////// ++ ++#define ATOM_MAX_NUMBER_OF_VRAM_MODULE 16 ++ ++#define ATOM_VRAM_MODULE_MEMORY_VENDOR_ID_MASK 0xF ++typedef struct _ATOM_VRAM_MODULE_V1 ++{ ++ ULONG ulReserved; ++ USHORT usEMRSValue; ++ USHORT usMRSValue; ++ USHORT usReserved; ++ UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module ++ UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] reserved; ++ UCHAR ucMemoryVenderID; // Predefined,never change across designs or memory type/vender ++ UCHAR ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... ++ UCHAR ucRow; // Number of Row,in power of 2; ++ UCHAR ucColumn; // Number of Column,in power of 2; ++ UCHAR ucBank; // Nunber of Bank; ++ UCHAR ucRank; // Number of Rank, in power of 2 ++ UCHAR ucChannelNum; // Number of channel; ++ UCHAR ucChannelConfig; // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 ++ UCHAR ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; ++ UCHAR ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; ++ UCHAR ucReserved[2]; ++}ATOM_VRAM_MODULE_V1; ++ ++ ++typedef struct _ATOM_VRAM_MODULE_V2 ++{ ++ ULONG ulReserved; ++ ULONG ulFlags; // To enable/disable functionalities based on memory type ++ ULONG ulEngineClock; // Override of default engine clock for particular memory type ++ ULONG ulMemoryClock; // Override of default memory clock for particular memory type ++ USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type ++ USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type ++ USHORT usEMRSValue; ++ USHORT usMRSValue; ++ USHORT usReserved; ++ UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module ++ UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; ++ UCHAR ucMemoryVenderID; // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed ++ UCHAR ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... ++ UCHAR ucRow; // Number of Row,in power of 2; ++ UCHAR ucColumn; // Number of Column,in power of 2; ++ UCHAR ucBank; // Nunber of Bank; ++ UCHAR ucRank; // Number of Rank, in power of 2 ++ UCHAR ucChannelNum; // Number of channel; ++ UCHAR ucChannelConfig; // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 ++ UCHAR ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; ++ UCHAR ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; ++ UCHAR ucRefreshRateFactor; ++ UCHAR ucReserved[3]; ++}ATOM_VRAM_MODULE_V2; ++ ++ ++typedef struct _ATOM_MEMORY_TIMING_FORMAT ++{ ++ ULONG ulClkRange; // memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing ++ union{ ++ USHORT usMRS; // mode register ++ USHORT usDDR3_MR0; ++ }; ++ union{ ++ USHORT usEMRS; // extended mode register ++ USHORT usDDR3_MR1; ++ }; ++ UCHAR ucCL; // CAS latency ++ UCHAR ucWL; // WRITE Latency ++ UCHAR uctRAS; // tRAS ++ UCHAR uctRC; // tRC ++ UCHAR uctRFC; // tRFC ++ UCHAR uctRCDR; // tRCDR ++ UCHAR uctRCDW; // tRCDW ++ UCHAR uctRP; // tRP ++ UCHAR uctRRD; // tRRD ++ UCHAR uctWR; // tWR ++ UCHAR uctWTR; // tWTR ++ UCHAR uctPDIX; // tPDIX ++ UCHAR uctFAW; // tFAW ++ UCHAR uctAOND; // tAOND ++ union ++ { ++ struct { ++ UCHAR ucflag; // flag to control memory timing calculation. bit0= control EMRS2 Infineon ++ UCHAR ucReserved; ++ }; ++ USHORT usDDR3_MR2; ++ }; ++}ATOM_MEMORY_TIMING_FORMAT; ++ ++ ++typedef struct _ATOM_MEMORY_TIMING_FORMAT_V1 ++{ ++ ULONG ulClkRange; // memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing ++ USHORT usMRS; // mode register ++ USHORT usEMRS; // extended mode register ++ UCHAR ucCL; // CAS latency ++ UCHAR ucWL; // WRITE Latency ++ UCHAR uctRAS; // tRAS ++ UCHAR uctRC; // tRC ++ UCHAR uctRFC; // tRFC ++ UCHAR uctRCDR; // tRCDR ++ UCHAR uctRCDW; // tRCDW ++ UCHAR uctRP; // tRP ++ UCHAR uctRRD; // tRRD ++ UCHAR uctWR; // tWR ++ UCHAR uctWTR; // tWTR ++ UCHAR uctPDIX; // tPDIX ++ UCHAR uctFAW; // tFAW ++ UCHAR uctAOND; // tAOND ++ UCHAR ucflag; // flag to control memory timing calculation. bit0= control EMRS2 Infineon ++////////////////////////////////////GDDR parameters/////////////////////////////////// ++ UCHAR uctCCDL; // ++ UCHAR uctCRCRL; // ++ UCHAR uctCRCWL; // ++ UCHAR uctCKE; // ++ UCHAR uctCKRSE; // ++ UCHAR uctCKRSX; // ++ UCHAR uctFAW32; // ++ UCHAR ucReserved1; // ++ UCHAR ucReserved2; // ++ UCHAR ucTerminator; ++}ATOM_MEMORY_TIMING_FORMAT_V1; ++ ++ ++typedef struct _ATOM_MEMORY_FORMAT ++{ ++ ULONG ulDllDisClock; // memory DLL will be disable when target memory clock is below this clock ++ union{ ++ USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type ++ USHORT usDDR3_Reserved; // Not used for DDR3 memory ++ }; ++ union{ ++ USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type ++ USHORT usDDR3_MR3; // Used for DDR3 memory ++ }; ++ UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; ++ UCHAR ucMemoryVenderID; // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed ++ UCHAR ucRow; // Number of Row,in power of 2; ++ UCHAR ucColumn; // Number of Column,in power of 2; ++ UCHAR ucBank; // Nunber of Bank; ++ UCHAR ucRank; // Number of Rank, in power of 2 ++ UCHAR ucBurstSize; // burst size, 0= burst size=4 1= burst size=8 ++ UCHAR ucDllDisBit; // position of DLL Enable/Disable bit in EMRS ( Extended Mode Register ) ++ UCHAR ucRefreshRateFactor; // memory refresh rate in unit of ms ++ UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 ++ UCHAR ucPreamble; //[7:4] Write Preamble, [3:0] Read Preamble ++ UCHAR ucMemAttrib; // Memory Device Addribute, like RDBI/WDBI etc ++ ATOM_MEMORY_TIMING_FORMAT asMemTiming[5]; //Memory Timing block sort from lower clock to higher clock ++}ATOM_MEMORY_FORMAT; ++ ++ ++typedef struct _ATOM_VRAM_MODULE_V3 ++{ ++ ULONG ulChannelMapCfg; // board dependent paramenter:Channel combination ++ USHORT usSize; // size of ATOM_VRAM_MODULE_V3 ++ USHORT usDefaultMVDDQ; // board dependent parameter:Default Memory Core Voltage ++ USHORT usDefaultMVDDC; // board dependent parameter:Default Memory IO Voltage ++ UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module ++ UCHAR ucChannelNum; // board dependent parameter:Number of channel; ++ UCHAR ucChannelSize; // board dependent parameter:32bit or 64bit ++ UCHAR ucVREFI; // board dependnt parameter: EXT or INT +160mv to -140mv ++ UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters ++ UCHAR ucFlag; // To enable/disable functionalities based on memory type ++ ATOM_MEMORY_FORMAT asMemory; // describ all of video memory parameters from memory spec ++}ATOM_VRAM_MODULE_V3; ++ ++ ++//ATOM_VRAM_MODULE_V3.ucNPL_RT ++#define NPL_RT_MASK 0x0f ++#define BATTERY_ODT_MASK 0xc0 ++ ++#define ATOM_VRAM_MODULE ATOM_VRAM_MODULE_V3 ++ ++typedef struct _ATOM_VRAM_MODULE_V4 ++{ ++ ULONG ulChannelMapCfg; // board dependent parameter: Channel combination ++ USHORT usModuleSize; // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE ++ USHORT usPrivateReserved; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! ++ // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) ++ USHORT usReserved; ++ UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module ++ UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; ++ UCHAR ucChannelNum; // Number of channels present in this module config ++ UCHAR ucChannelWidth; // 0 - 32 bits; 1 - 64 bits ++ UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 ++ UCHAR ucFlag; // To enable/disable functionalities based on memory type ++ UCHAR ucMisc; // bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 ++ UCHAR ucVREFI; // board dependent parameter ++ UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters ++ UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble ++ UCHAR ucMemorySize; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! ++ // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros ++ UCHAR ucReserved[3]; ++ ++//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level ++ union{ ++ USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type ++ USHORT usDDR3_Reserved; ++ }; ++ union{ ++ USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type ++ USHORT usDDR3_MR3; // Used for DDR3 memory ++ }; ++ UCHAR ucMemoryVenderID; // Predefined, If not predefined, vendor detection table gets executed ++ UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) ++ UCHAR ucReserved2[2]; ++ ATOM_MEMORY_TIMING_FORMAT asMemTiming[5];//Memory Timing block sort from lower clock to higher clock ++}ATOM_VRAM_MODULE_V4; ++ ++#define VRAM_MODULE_V4_MISC_RANK_MASK 0x3 ++#define VRAM_MODULE_V4_MISC_DUAL_RANK 0x1 ++#define VRAM_MODULE_V4_MISC_BL_MASK 0x4 ++#define VRAM_MODULE_V4_MISC_BL8 0x4 ++#define VRAM_MODULE_V4_MISC_DUAL_CS 0x10 ++ ++typedef struct _ATOM_VRAM_MODULE_V5 ++{ ++ ULONG ulChannelMapCfg; // board dependent parameter: Channel combination ++ USHORT usModuleSize; // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE ++ USHORT usPrivateReserved; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! ++ // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) ++ USHORT usReserved; ++ UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module ++ UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; ++ UCHAR ucChannelNum; // Number of channels present in this module config ++ UCHAR ucChannelWidth; // 0 - 32 bits; 1 - 64 bits ++ UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 ++ UCHAR ucFlag; // To enable/disable functionalities based on memory type ++ UCHAR ucMisc; // bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 ++ UCHAR ucVREFI; // board dependent parameter ++ UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters ++ UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble ++ UCHAR ucMemorySize; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! ++ // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros ++ UCHAR ucReserved[3]; ++ ++//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level ++ USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type ++ USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type ++ UCHAR ucMemoryVenderID; // Predefined, If not predefined, vendor detection table gets executed ++ UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) ++ UCHAR ucFIFODepth; // FIFO depth supposes to be detected during vendor detection, but if we dont do vendor detection we have to hardcode FIFO Depth ++ UCHAR ucCDR_Bandwidth; // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth ++ ATOM_MEMORY_TIMING_FORMAT_V1 asMemTiming[5];//Memory Timing block sort from lower clock to higher clock ++}ATOM_VRAM_MODULE_V5; ++ ++typedef struct _ATOM_VRAM_INFO_V2 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR ucNumOfVRAMModule; ++ ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; ++}ATOM_VRAM_INFO_V2; ++ ++typedef struct _ATOM_VRAM_INFO_V3 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting ++ USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting ++ USHORT usRerseved; ++ UCHAR aVID_PinsShift[9]; // 8 bit strap maximum+terminator ++ UCHAR ucNumOfVRAMModule; ++ ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; ++ ATOM_INIT_REG_BLOCK asMemPatch; // for allocation ++ // ATOM_INIT_REG_BLOCK aMemAdjust; ++}ATOM_VRAM_INFO_V3; ++ ++#define ATOM_VRAM_INFO_LAST ATOM_VRAM_INFO_V3 ++ ++typedef struct _ATOM_VRAM_INFO_V4 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting ++ USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting ++ USHORT usRerseved; ++ UCHAR ucMemDQ7_0ByteRemap; // DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3 ++ ULONG ulMemDQ7_0BitRemap; // each DQ line ( 7~0) use 3bits, like: DQ0=Bit[2:0], DQ1:[5:3], ... DQ7:[23:21] ++ UCHAR ucReservde[4]; ++ UCHAR ucNumOfVRAMModule; ++ ATOM_VRAM_MODULE_V4 aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; ++ ATOM_INIT_REG_BLOCK asMemPatch; // for allocation ++ // ATOM_INIT_REG_BLOCK aMemAdjust; ++}ATOM_VRAM_INFO_V4; ++ ++typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR aVID_PinsShift[9]; //8 bit strap maximum+terminator ++}ATOM_VRAM_GPIO_DETECTION_INFO; ++ ++ ++typedef struct _ATOM_MEMORY_TRAINING_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR ucTrainingLoop; ++ UCHAR ucReserved[3]; ++ ATOM_INIT_REG_BLOCK asMemTrainingSetting; ++}ATOM_MEMORY_TRAINING_INFO; ++ ++ ++typedef struct SW_I2C_CNTL_DATA_PARAMETERS ++{ ++ UCHAR ucControl; ++ UCHAR ucData; ++ UCHAR ucSatus; ++ UCHAR ucTemp; ++} SW_I2C_CNTL_DATA_PARAMETERS; ++ ++#define SW_I2C_CNTL_DATA_PS_ALLOCATION SW_I2C_CNTL_DATA_PARAMETERS ++ ++typedef struct _SW_I2C_IO_DATA_PARAMETERS ++{ ++ USHORT GPIO_Info; ++ UCHAR ucAct; ++ UCHAR ucData; ++ } SW_I2C_IO_DATA_PARAMETERS; ++ ++#define SW_I2C_IO_DATA_PS_ALLOCATION SW_I2C_IO_DATA_PARAMETERS ++ ++/****************************SW I2C CNTL DEFINITIONS**********************/ ++#define SW_I2C_IO_RESET 0 ++#define SW_I2C_IO_GET 1 ++#define SW_I2C_IO_DRIVE 2 ++#define SW_I2C_IO_SET 3 ++#define SW_I2C_IO_START 4 ++ ++#define SW_I2C_IO_CLOCK 0 ++#define SW_I2C_IO_DATA 0x80 ++ ++#define SW_I2C_IO_ZERO 0 ++#define SW_I2C_IO_ONE 0x100 ++ ++#define SW_I2C_CNTL_READ 0 ++#define SW_I2C_CNTL_WRITE 1 ++#define SW_I2C_CNTL_START 2 ++#define SW_I2C_CNTL_STOP 3 ++#define SW_I2C_CNTL_OPEN 4 ++#define SW_I2C_CNTL_CLOSE 5 ++#define SW_I2C_CNTL_WRITE1BIT 6 ++ ++//==============================VESA definition Portion=============================== ++#define VESA_OEM_PRODUCT_REV '01.00' ++#define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support ++#define VESA_MODE_WIN_ATTRIBUTE 7 ++#define VESA_WIN_SIZE 64 ++ ++typedef struct _PTR_32_BIT_STRUCTURE ++{ ++ USHORT Offset16; ++ USHORT Segment16; ++} PTR_32_BIT_STRUCTURE; ++ ++typedef union _PTR_32_BIT_UNION ++{ ++ PTR_32_BIT_STRUCTURE SegmentOffset; ++ ULONG Ptr32_Bit; ++} PTR_32_BIT_UNION; ++ ++typedef struct _VBE_1_2_INFO_BLOCK_UPDATABLE ++{ ++ UCHAR VbeSignature[4]; ++ USHORT VbeVersion; ++ PTR_32_BIT_UNION OemStringPtr; ++ UCHAR Capabilities[4]; ++ PTR_32_BIT_UNION VideoModePtr; ++ USHORT TotalMemory; ++} VBE_1_2_INFO_BLOCK_UPDATABLE; ++ ++ ++typedef struct _VBE_2_0_INFO_BLOCK_UPDATABLE ++{ ++ VBE_1_2_INFO_BLOCK_UPDATABLE CommonBlock; ++ USHORT OemSoftRev; ++ PTR_32_BIT_UNION OemVendorNamePtr; ++ PTR_32_BIT_UNION OemProductNamePtr; ++ PTR_32_BIT_UNION OemProductRevPtr; ++} VBE_2_0_INFO_BLOCK_UPDATABLE; ++ ++typedef union _VBE_VERSION_UNION ++{ ++ VBE_2_0_INFO_BLOCK_UPDATABLE VBE_2_0_InfoBlock; ++ VBE_1_2_INFO_BLOCK_UPDATABLE VBE_1_2_InfoBlock; ++} VBE_VERSION_UNION; ++ ++typedef struct _VBE_INFO_BLOCK ++{ ++ VBE_VERSION_UNION UpdatableVBE_Info; ++ UCHAR Reserved[222]; ++ UCHAR OemData[256]; ++} VBE_INFO_BLOCK; ++ ++typedef struct _VBE_FP_INFO ++{ ++ USHORT HSize; ++ USHORT VSize; ++ USHORT FPType; ++ UCHAR RedBPP; ++ UCHAR GreenBPP; ++ UCHAR BlueBPP; ++ UCHAR ReservedBPP; ++ ULONG RsvdOffScrnMemSize; ++ ULONG RsvdOffScrnMEmPtr; ++ UCHAR Reserved[14]; ++} VBE_FP_INFO; ++ ++typedef struct _VESA_MODE_INFO_BLOCK ++{ ++// Mandatory information for all VBE revisions ++ USHORT ModeAttributes; // dw ? ; mode attributes ++ UCHAR WinAAttributes; // db ? ; window A attributes ++ UCHAR WinBAttributes; // db ? ; window B attributes ++ USHORT WinGranularity; // dw ? ; window granularity ++ USHORT WinSize; // dw ? ; window size ++ USHORT WinASegment; // dw ? ; window A start segment ++ USHORT WinBSegment; // dw ? ; window B start segment ++ ULONG WinFuncPtr; // dd ? ; real mode pointer to window function ++ USHORT BytesPerScanLine;// dw ? ; bytes per scan line ++ ++//; Mandatory information for VBE 1.2 and above ++ USHORT XResolution; // dw ? ; horizontal resolution in pixels or characters ++ USHORT YResolution; // dw ? ; vertical resolution in pixels or characters ++ UCHAR XCharSize; // db ? ; character cell width in pixels ++ UCHAR YCharSize; // db ? ; character cell height in pixels ++ UCHAR NumberOfPlanes; // db ? ; number of memory planes ++ UCHAR BitsPerPixel; // db ? ; bits per pixel ++ UCHAR NumberOfBanks; // db ? ; number of banks ++ UCHAR MemoryModel; // db ? ; memory model type ++ UCHAR BankSize; // db ? ; bank size in KB ++ UCHAR NumberOfImagePages;// db ? ; number of images ++ UCHAR ReservedForPageFunction;//db 1 ; reserved for page function ++ ++//; Direct Color fields(required for direct/6 and YUV/7 memory models) ++ UCHAR RedMaskSize; // db ? ; size of direct color red mask in bits ++ UCHAR RedFieldPosition; // db ? ; bit position of lsb of red mask ++ UCHAR GreenMaskSize; // db ? ; size of direct color green mask in bits ++ UCHAR GreenFieldPosition; // db ? ; bit position of lsb of green mask ++ UCHAR BlueMaskSize; // db ? ; size of direct color blue mask in bits ++ UCHAR BlueFieldPosition; // db ? ; bit position of lsb of blue mask ++ UCHAR RsvdMaskSize; // db ? ; size of direct color reserved mask in bits ++ UCHAR RsvdFieldPosition; // db ? ; bit position of lsb of reserved mask ++ UCHAR DirectColorModeInfo;// db ? ; direct color mode attributes ++ ++//; Mandatory information for VBE 2.0 and above ++ ULONG PhysBasePtr; // dd ? ; physical address for flat memory frame buffer ++ ULONG Reserved_1; // dd 0 ; reserved - always set to 0 ++ USHORT Reserved_2; // dw 0 ; reserved - always set to 0 ++ ++//; Mandatory information for VBE 3.0 and above ++ USHORT LinBytesPerScanLine; // dw ? ; bytes per scan line for linear modes ++ UCHAR BnkNumberOfImagePages;// db ? ; number of images for banked modes ++ UCHAR LinNumberOfImagPages; // db ? ; number of images for linear modes ++ UCHAR LinRedMaskSize; // db ? ; size of direct color red mask(linear modes) ++ UCHAR LinRedFieldPosition; // db ? ; bit position of lsb of red mask(linear modes) ++ UCHAR LinGreenMaskSize; // db ? ; size of direct color green mask(linear modes) ++ UCHAR LinGreenFieldPosition;// db ? ; bit position of lsb of green mask(linear modes) ++ UCHAR LinBlueMaskSize; // db ? ; size of direct color blue mask(linear modes) ++ UCHAR LinBlueFieldPosition; // db ? ; bit position of lsb of blue mask(linear modes) ++ UCHAR LinRsvdMaskSize; // db ? ; size of direct color reserved mask(linear modes) ++ UCHAR LinRsvdFieldPosition; // db ? ; bit position of lsb of reserved mask(linear modes) ++ ULONG MaxPixelClock; // dd ? ; maximum pixel clock(in Hz) for graphics mode ++ UCHAR Reserved; // db 190 dup (0) ++} VESA_MODE_INFO_BLOCK; ++ ++// BIOS function CALLS ++#define ATOM_BIOS_EXTENDED_FUNCTION_CODE 0xA0 // ATI Extended Function code ++#define ATOM_BIOS_FUNCTION_COP_MODE 0x00 ++#define ATOM_BIOS_FUNCTION_SHORT_QUERY1 0x04 ++#define ATOM_BIOS_FUNCTION_SHORT_QUERY2 0x05 ++#define ATOM_BIOS_FUNCTION_SHORT_QUERY3 0x06 ++#define ATOM_BIOS_FUNCTION_GET_DDC 0x0B ++#define ATOM_BIOS_FUNCTION_ASIC_DSTATE 0x0E ++#define ATOM_BIOS_FUNCTION_DEBUG_PLAY 0x0F ++#define ATOM_BIOS_FUNCTION_STV_STD 0x16 ++#define ATOM_BIOS_FUNCTION_DEVICE_DET 0x17 ++#define ATOM_BIOS_FUNCTION_DEVICE_SWITCH 0x18 ++ ++#define ATOM_BIOS_FUNCTION_PANEL_CONTROL 0x82 ++#define ATOM_BIOS_FUNCTION_OLD_DEVICE_DET 0x83 ++#define ATOM_BIOS_FUNCTION_OLD_DEVICE_SWITCH 0x84 ++#define ATOM_BIOS_FUNCTION_HW_ICON 0x8A ++#define ATOM_BIOS_FUNCTION_SET_CMOS 0x8B ++#define SUB_FUNCTION_UPDATE_DISPLAY_INFO 0x8000 // Sub function 80 ++#define SUB_FUNCTION_UPDATE_EXPANSION_INFO 0x8100 // Sub function 80 ++ ++#define ATOM_BIOS_FUNCTION_DISPLAY_INFO 0x8D ++#define ATOM_BIOS_FUNCTION_DEVICE_ON_OFF 0x8E ++#define ATOM_BIOS_FUNCTION_VIDEO_STATE 0x8F ++#define ATOM_SUB_FUNCTION_GET_CRITICAL_STATE 0x0300 // Sub function 03 ++#define ATOM_SUB_FUNCTION_GET_LIDSTATE 0x0700 // Sub function 7 ++#define ATOM_SUB_FUNCTION_THERMAL_STATE_NOTICE 0x1400 // Notify caller the current thermal state ++#define ATOM_SUB_FUNCTION_CRITICAL_STATE_NOTICE 0x8300 // Notify caller the current critical state ++#define ATOM_SUB_FUNCTION_SET_LIDSTATE 0x8500 // Sub function 85 ++#define ATOM_SUB_FUNCTION_GET_REQ_DISPLAY_FROM_SBIOS_MODE 0x8900// Sub function 89 ++#define ATOM_SUB_FUNCTION_INFORM_ADC_SUPPORT 0x9400 // Notify caller that ADC is supported ++ ++ ++#define ATOM_BIOS_FUNCTION_VESA_DPMS 0x4F10 // Set DPMS ++#define ATOM_SUB_FUNCTION_SET_DPMS 0x0001 // BL: Sub function 01 ++#define ATOM_SUB_FUNCTION_GET_DPMS 0x0002 // BL: Sub function 02 ++#define ATOM_PARAMETER_VESA_DPMS_ON 0x0000 // BH Parameter for DPMS ON. ++#define ATOM_PARAMETER_VESA_DPMS_STANDBY 0x0100 // BH Parameter for DPMS STANDBY ++#define ATOM_PARAMETER_VESA_DPMS_SUSPEND 0x0200 // BH Parameter for DPMS SUSPEND ++#define ATOM_PARAMETER_VESA_DPMS_OFF 0x0400 // BH Parameter for DPMS OFF ++#define ATOM_PARAMETER_VESA_DPMS_REDUCE_ON 0x0800 // BH Parameter for DPMS REDUCE ON (NOT SUPPORTED) ++ ++#define ATOM_BIOS_RETURN_CODE_MASK 0x0000FF00L ++#define ATOM_BIOS_REG_HIGH_MASK 0x0000FF00L ++#define ATOM_BIOS_REG_LOW_MASK 0x000000FFL ++ ++// structure used for VBIOS only ++ ++//DispOutInfoTable ++typedef struct _ASIC_TRANSMITTER_INFO ++{ ++ USHORT usTransmitterObjId; ++ USHORT usSupportDevice; ++ UCHAR ucTransmitterCmdTblId; ++ UCHAR ucConfig; ++ UCHAR ucEncoderID; //available 1st encoder ( default ) ++ UCHAR ucOptionEncoderID; //available 2nd encoder ( optional ) ++ UCHAR uc2ndEncoderID; ++ UCHAR ucReserved; ++}ASIC_TRANSMITTER_INFO; ++ ++typedef struct _ASIC_ENCODER_INFO ++{ ++ UCHAR ucEncoderID; ++ UCHAR ucEncoderConfig; ++ USHORT usEncoderCmdTblId; ++}ASIC_ENCODER_INFO; ++ ++typedef struct _ATOM_DISP_OUT_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT ptrTransmitterInfo; ++ USHORT ptrEncoderInfo; ++ ASIC_TRANSMITTER_INFO asTransmitterInfo[1]; ++ ASIC_ENCODER_INFO asEncoderInfo[1]; ++}ATOM_DISP_OUT_INFO; ++ ++// DispDevicePriorityInfo ++typedef struct _ATOM_DISPLAY_DEVICE_PRIORITY_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT asDevicePriority[16]; ++}ATOM_DISPLAY_DEVICE_PRIORITY_INFO; ++ ++//ProcessAuxChannelTransactionTable ++typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS ++{ ++ USHORT lpAuxRequest; ++ USHORT lpDataOut; ++ UCHAR ucChannelID; ++ union ++ { ++ UCHAR ucReplyStatus; ++ UCHAR ucDelay; ++ }; ++ UCHAR ucDataOutLen; ++ UCHAR ucReserved; ++}PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS; ++ ++#define PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS ++ ++//GetSinkType ++ ++typedef struct _DP_ENCODER_SERVICE_PARAMETERS ++{ ++ USHORT ucLinkClock; ++ union ++ { ++ UCHAR ucConfig; // for DP training command ++ UCHAR ucI2cId; // use for GET_SINK_TYPE command ++ }; ++ UCHAR ucAction; ++ UCHAR ucStatus; ++ UCHAR ucLaneNum; ++ UCHAR ucReserved[2]; ++}DP_ENCODER_SERVICE_PARAMETERS; ++ ++// ucAction ++#define ATOM_DP_ACTION_GET_SINK_TYPE 0x01 ++#define ATOM_DP_ACTION_TRAINING_START 0x02 ++#define ATOM_DP_ACTION_TRAINING_COMPLETE 0x03 ++#define ATOM_DP_ACTION_TRAINING_PATTERN_SEL 0x04 ++#define ATOM_DP_ACTION_SET_VSWING_PREEMP 0x05 ++#define ATOM_DP_ACTION_GET_VSWING_PREEMP 0x06 ++#define ATOM_DP_ACTION_BLANKING 0x07 ++ ++// ucConfig ++#define ATOM_DP_CONFIG_ENCODER_SEL_MASK 0x03 ++#define ATOM_DP_CONFIG_DIG1_ENCODER 0x00 ++#define ATOM_DP_CONFIG_DIG2_ENCODER 0x01 ++#define ATOM_DP_CONFIG_EXTERNAL_ENCODER 0x02 ++#define ATOM_DP_CONFIG_LINK_SEL_MASK 0x04 ++#define ATOM_DP_CONFIG_LINK_A 0x00 ++#define ATOM_DP_CONFIG_LINK_B 0x04 ++ ++#define DP_ENCODER_SERVICE_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS ++ ++// DP_TRAINING_TABLE ++#define DPCD_SET_LINKRATE_LANENUM_PATTERN1_TBL_ADDR ATOM_DP_TRAINING_TBL_ADDR ++#define DPCD_SET_SS_CNTL_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 8 ) ++#define DPCD_SET_LANE_VSWING_PREEMP_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 16 ) ++#define DPCD_SET_TRAINING_PATTERN0_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 24 ) ++#define DPCD_SET_TRAINING_PATTERN2_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 32) ++#define DPCD_GET_LINKRATE_LANENUM_SS_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 40) ++#define DPCD_GET_LANE_STATUS_ADJUST_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 48) ++#define DP_I2C_AUX_DDC_WRITE_START_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 60) ++#define DP_I2C_AUX_DDC_WRITE_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 64) ++#define DP_I2C_AUX_DDC_READ_START_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 72) ++#define DP_I2C_AUX_DDC_READ_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 76) ++#define DP_I2C_AUX_DDC_READ_END_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 80) ++ ++ ++typedef struct _PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS ++{ ++ UCHAR ucI2CSpeed; ++ union ++ { ++ UCHAR ucRegIndex; ++ UCHAR ucStatus; ++ }; ++ USHORT lpI2CDataOut; ++ UCHAR ucFlag; ++ UCHAR ucTransBytes; ++ UCHAR ucSlaveAddr; ++ UCHAR ucLineNumber; ++}PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS; ++ ++#define PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS ++ ++//ucFlag ++#define HW_I2C_WRITE 1 ++#define HW_I2C_READ 0 ++ ++ ++/****************************************************************************/ ++//Portion VI: Definitinos being oboselete ++/****************************************************************************/ ++ ++//========================================================================================== ++//Remove the definitions below when driver is ready! ++typedef struct _ATOM_DAC_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usMaxFrequency; // in 10kHz unit ++ USHORT usReserved; ++}ATOM_DAC_INFO; ++ ++ ++typedef struct _COMPASSIONATE_DATA ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ++ //============================== DAC1 portion ++ UCHAR ucDAC1_BG_Adjustment; ++ UCHAR ucDAC1_DAC_Adjustment; ++ USHORT usDAC1_FORCE_Data; ++ //============================== DAC2 portion ++ UCHAR ucDAC2_CRT2_BG_Adjustment; ++ UCHAR ucDAC2_CRT2_DAC_Adjustment; ++ USHORT usDAC2_CRT2_FORCE_Data; ++ USHORT usDAC2_CRT2_MUX_RegisterIndex; ++ UCHAR ucDAC2_CRT2_MUX_RegisterInfo; //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low ++ UCHAR ucDAC2_NTSC_BG_Adjustment; ++ UCHAR ucDAC2_NTSC_DAC_Adjustment; ++ USHORT usDAC2_TV1_FORCE_Data; ++ USHORT usDAC2_TV1_MUX_RegisterIndex; ++ UCHAR ucDAC2_TV1_MUX_RegisterInfo; //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low ++ UCHAR ucDAC2_CV_BG_Adjustment; ++ UCHAR ucDAC2_CV_DAC_Adjustment; ++ USHORT usDAC2_CV_FORCE_Data; ++ USHORT usDAC2_CV_MUX_RegisterIndex; ++ UCHAR ucDAC2_CV_MUX_RegisterInfo; //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low ++ UCHAR ucDAC2_PAL_BG_Adjustment; ++ UCHAR ucDAC2_PAL_DAC_Adjustment; ++ USHORT usDAC2_TV2_FORCE_Data; ++}COMPASSIONATE_DATA; ++ ++/****************************Supported Device Info Table Definitions**********************/ ++// ucConnectInfo: ++// [7:4] - connector type ++// = 1 - VGA connector ++// = 2 - DVI-I ++// = 3 - DVI-D ++// = 4 - DVI-A ++// = 5 - SVIDEO ++// = 6 - COMPOSITE ++// = 7 - LVDS ++// = 8 - DIGITAL LINK ++// = 9 - SCART ++// = 0xA - HDMI_type A ++// = 0xB - HDMI_type B ++// = 0xE - Special case1 (DVI+DIN) ++// Others=TBD ++// [3:0] - DAC Associated ++// = 0 - no DAC ++// = 1 - DACA ++// = 2 - DACB ++// = 3 - External DAC ++// Others=TBD ++// ++ ++typedef struct _ATOM_CONNECTOR_INFO ++{ ++#if ATOM_BIG_ENDIAN ++ UCHAR bfConnectorType:4; ++ UCHAR bfAssociatedDAC:4; ++#else ++ UCHAR bfAssociatedDAC:4; ++ UCHAR bfConnectorType:4; ++#endif ++}ATOM_CONNECTOR_INFO; ++ ++typedef union _ATOM_CONNECTOR_INFO_ACCESS ++{ ++ ATOM_CONNECTOR_INFO sbfAccess; ++ UCHAR ucAccess; ++}ATOM_CONNECTOR_INFO_ACCESS; ++ ++typedef struct _ATOM_CONNECTOR_INFO_I2C ++{ ++ ATOM_CONNECTOR_INFO_ACCESS sucConnectorInfo; ++ ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; ++}ATOM_CONNECTOR_INFO_I2C; ++ ++ ++typedef struct _ATOM_SUPPORTED_DEVICES_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usDeviceSupport; ++ ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO]; ++}ATOM_SUPPORTED_DEVICES_INFO; ++ ++#define NO_INT_SRC_MAPPED 0xFF ++ ++typedef struct _ATOM_CONNECTOR_INC_SRC_BITMAP ++{ ++ UCHAR ucIntSrcBitmap; ++}ATOM_CONNECTOR_INC_SRC_BITMAP; ++ ++typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usDeviceSupport; ++ ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2]; ++ ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2]; ++}ATOM_SUPPORTED_DEVICES_INFO_2; ++ ++typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usDeviceSupport; ++ ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE]; ++ ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE]; ++}ATOM_SUPPORTED_DEVICES_INFO_2d1; ++ ++#define ATOM_SUPPORTED_DEVICES_INFO_LAST ATOM_SUPPORTED_DEVICES_INFO_2d1 ++ ++ ++ ++typedef struct _ATOM_MISC_CONTROL_INFO ++{ ++ USHORT usFrequency; ++ UCHAR ucPLL_ChargePump; // PLL charge-pump gain control ++ UCHAR ucPLL_DutyCycle; // PLL duty cycle control ++ UCHAR ucPLL_VCO_Gain; // PLL VCO gain control ++ UCHAR ucPLL_VoltageSwing; // PLL driver voltage swing control ++}ATOM_MISC_CONTROL_INFO; ++ ++ ++#define ATOM_MAX_MISC_INFO 4 ++ ++typedef struct _ATOM_TMDS_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usMaxFrequency; // in 10Khz ++ ATOM_MISC_CONTROL_INFO asMiscInfo[ATOM_MAX_MISC_INFO]; ++}ATOM_TMDS_INFO; ++ ++ ++typedef struct _ATOM_ENCODER_ANALOG_ATTRIBUTE ++{ ++ UCHAR ucTVStandard; //Same as TV standards defined above, ++ UCHAR ucPadding[1]; ++}ATOM_ENCODER_ANALOG_ATTRIBUTE; ++ ++typedef struct _ATOM_ENCODER_DIGITAL_ATTRIBUTE ++{ ++ UCHAR ucAttribute; //Same as other digital encoder attributes defined above ++ UCHAR ucPadding[1]; ++}ATOM_ENCODER_DIGITAL_ATTRIBUTE; ++ ++typedef union _ATOM_ENCODER_ATTRIBUTE ++{ ++ ATOM_ENCODER_ANALOG_ATTRIBUTE sAlgAttrib; ++ ATOM_ENCODER_DIGITAL_ATTRIBUTE sDigAttrib; ++}ATOM_ENCODER_ATTRIBUTE; ++ ++ ++typedef struct _DVO_ENCODER_CONTROL_PARAMETERS ++{ ++ USHORT usPixelClock; ++ USHORT usEncoderID; ++ UCHAR ucDeviceType; //Use ATOM_DEVICE_xxx1_Index to indicate device type only. ++ UCHAR ucAction; //ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT ++ ATOM_ENCODER_ATTRIBUTE usDevAttr; ++}DVO_ENCODER_CONTROL_PARAMETERS; ++ ++typedef struct _DVO_ENCODER_CONTROL_PS_ALLOCATION ++{ ++ DVO_ENCODER_CONTROL_PARAMETERS sDVOEncoder; ++ WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; //Caller doesn't need to init this portion ++}DVO_ENCODER_CONTROL_PS_ALLOCATION; ++ ++ ++#define ATOM_XTMDS_ASIC_SI164_ID 1 ++#define ATOM_XTMDS_ASIC_SI178_ID 2 ++#define ATOM_XTMDS_ASIC_TFP513_ID 3 ++#define ATOM_XTMDS_SUPPORTED_SINGLELINK 0x00000001 ++#define ATOM_XTMDS_SUPPORTED_DUALLINK 0x00000002 ++#define ATOM_XTMDS_MVPU_FPGA 0x00000004 ++ ++ ++typedef struct _ATOM_XTMDS_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usSingleLinkMaxFrequency; ++ ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; //Point the ID on which I2C is used to control external chip ++ UCHAR ucXtransimitterID; ++ UCHAR ucSupportedLink; // Bit field, bit0=1, single link supported;bit1=1,dual link supported ++ UCHAR ucSequnceAlterID; // Even with the same external TMDS asic, it's possible that the program seqence alters ++ // due to design. This ID is used to alert driver that the sequence is not "standard"! ++ UCHAR ucMasterAddress; // Address to control Master xTMDS Chip ++ UCHAR ucSlaveAddress; // Address to control Slave xTMDS Chip ++}ATOM_XTMDS_INFO; ++ ++typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS ++{ ++ UCHAR ucEnable; // ATOM_ENABLE=On or ATOM_DISABLE=Off ++ UCHAR ucDevice; // ATOM_DEVICE_DFP1_INDEX.... ++ UCHAR ucPadding[2]; ++}DFP_DPMS_STATUS_CHANGE_PARAMETERS; ++ ++/****************************Legacy Power Play Table Definitions **********************/ ++ ++//Definitions for ulPowerPlayMiscInfo ++#define ATOM_PM_MISCINFO_SPLIT_CLOCK 0x00000000L ++#define ATOM_PM_MISCINFO_USING_MCLK_SRC 0x00000001L ++#define ATOM_PM_MISCINFO_USING_SCLK_SRC 0x00000002L ++ ++#define ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT 0x00000004L ++#define ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH 0x00000008L ++ ++#define ATOM_PM_MISCINFO_LOAD_PERFORMANCE_EN 0x00000010L ++ ++#define ATOM_PM_MISCINFO_ENGINE_CLOCK_CONTRL_EN 0x00000020L ++#define ATOM_PM_MISCINFO_MEMORY_CLOCK_CONTRL_EN 0x00000040L ++#define ATOM_PM_MISCINFO_PROGRAM_VOLTAGE 0x00000080L //When this bit set, ucVoltageDropIndex is not an index for GPIO pin, but a voltage ID that SW needs program ++ ++#define ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN 0x00000100L ++#define ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN 0x00000200L ++#define ATOM_PM_MISCINFO_ASIC_SLEEP_MODE_EN 0x00000400L ++#define ATOM_PM_MISCINFO_LOAD_BALANCE_EN 0x00000800L ++#define ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE 0x00001000L ++#define ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE 0x00002000L ++#define ATOM_PM_MISCINFO_LOW_LCD_REFRESH_RATE 0x00004000L ++ ++#define ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE 0x00008000L ++#define ATOM_PM_MISCINFO_OVER_CLOCK_MODE 0x00010000L ++#define ATOM_PM_MISCINFO_OVER_DRIVE_MODE 0x00020000L ++#define ATOM_PM_MISCINFO_POWER_SAVING_MODE 0x00040000L ++#define ATOM_PM_MISCINFO_THERMAL_DIODE_MODE 0x00080000L ++ ++#define ATOM_PM_MISCINFO_FRAME_MODULATION_MASK 0x00300000L //0-FM Disable, 1-2 level FM, 2-4 level FM, 3-Reserved ++#define ATOM_PM_MISCINFO_FRAME_MODULATION_SHIFT 20 ++ ++#define ATOM_PM_MISCINFO_DYN_CLK_3D_IDLE 0x00400000L ++#define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2 0x00800000L ++#define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4 0x01000000L ++#define ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN 0x02000000L //When set, Dynamic ++#define ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN 0x04000000L //When set, Dynamic ++#define ATOM_PM_MISCINFO_3D_ACCELERATION_EN 0x08000000L //When set, This mode is for acceleated 3D mode ++ ++#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_MASK 0x70000000L //1-Optimal Battery Life Group, 2-High Battery, 3-Balanced, 4-High Performance, 5- Optimal Performance (Default state with Default clocks) ++#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_SHIFT 28 ++#define ATOM_PM_MISCINFO_ENABLE_BACK_BIAS 0x80000000L ++ ++#define ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE 0x00000001L ++#define ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT 0x00000002L ++#define ATOM_PM_MISCINFO2_DYNAMIC_BACK_BIAS_EN 0x00000004L ++#define ATOM_PM_MISCINFO2_FS3D_OVERDRIVE_INFO 0x00000008L ++#define ATOM_PM_MISCINFO2_FORCEDLOWPWR_MODE 0x00000010L ++#define ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN 0x00000020L ++#define ATOM_PM_MISCINFO2_VIDEO_PLAYBACK_CAPABLE 0x00000040L //If this bit is set in multi-pp mode, then driver will pack up one with the minior power consumption. ++ //If it's not set in any pp mode, driver will use its default logic to pick a pp mode in video playback ++#define ATOM_PM_MISCINFO2_NOT_VALID_ON_DC 0x00000080L ++#define ATOM_PM_MISCINFO2_STUTTER_MODE_EN 0x00000100L ++#define ATOM_PM_MISCINFO2_UVD_SUPPORT_MODE 0x00000200L ++ ++//ucTableFormatRevision=1 ++//ucTableContentRevision=1 ++typedef struct _ATOM_POWERMODE_INFO ++{ ++ ULONG ulMiscInfo; //The power level should be arranged in ascending order ++ ULONG ulReserved1; // must set to 0 ++ ULONG ulReserved2; // must set to 0 ++ USHORT usEngineClock; ++ USHORT usMemoryClock; ++ UCHAR ucVoltageDropIndex; // index to GPIO table ++ UCHAR ucSelectedPanel_RefreshRate;// panel refresh rate ++ UCHAR ucMinTemperature; ++ UCHAR ucMaxTemperature; ++ UCHAR ucNumPciELanes; // number of PCIE lanes ++}ATOM_POWERMODE_INFO; ++ ++//ucTableFormatRevision=2 ++//ucTableContentRevision=1 ++typedef struct _ATOM_POWERMODE_INFO_V2 ++{ ++ ULONG ulMiscInfo; //The power level should be arranged in ascending order ++ ULONG ulMiscInfo2; ++ ULONG ulEngineClock; ++ ULONG ulMemoryClock; ++ UCHAR ucVoltageDropIndex; // index to GPIO table ++ UCHAR ucSelectedPanel_RefreshRate;// panel refresh rate ++ UCHAR ucMinTemperature; ++ UCHAR ucMaxTemperature; ++ UCHAR ucNumPciELanes; // number of PCIE lanes ++}ATOM_POWERMODE_INFO_V2; ++ ++//ucTableFormatRevision=2 ++//ucTableContentRevision=2 ++typedef struct _ATOM_POWERMODE_INFO_V3 ++{ ++ ULONG ulMiscInfo; //The power level should be arranged in ascending order ++ ULONG ulMiscInfo2; ++ ULONG ulEngineClock; ++ ULONG ulMemoryClock; ++ UCHAR ucVoltageDropIndex; // index to Core (VDDC) votage table ++ UCHAR ucSelectedPanel_RefreshRate;// panel refresh rate ++ UCHAR ucMinTemperature; ++ UCHAR ucMaxTemperature; ++ UCHAR ucNumPciELanes; // number of PCIE lanes ++ UCHAR ucVDDCI_VoltageDropIndex; // index to VDDCI votage table ++}ATOM_POWERMODE_INFO_V3; ++ ++ ++#define ATOM_MAX_NUMBEROF_POWER_BLOCK 8 ++ ++#define ATOM_PP_OVERDRIVE_INTBITMAP_AUXWIN 0x01 ++#define ATOM_PP_OVERDRIVE_INTBITMAP_OVERDRIVE 0x02 ++ ++#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_LM63 0x01 ++#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ADM1032 0x02 ++#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ADM1030 0x03 ++#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_MUA6649 0x04 ++#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_LM64 0x05 ++#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_F75375 0x06 ++#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ASC7512 0x07 // Andigilog ++ ++ ++typedef struct _ATOM_POWERPLAY_INFO ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR ucOverdriveThermalController; ++ UCHAR ucOverdriveI2cLine; ++ UCHAR ucOverdriveIntBitmap; ++ UCHAR ucOverdriveControllerAddress; ++ UCHAR ucSizeOfPowerModeEntry; ++ UCHAR ucNumOfPowerModeEntries; ++ ATOM_POWERMODE_INFO asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; ++}ATOM_POWERPLAY_INFO; ++ ++typedef struct _ATOM_POWERPLAY_INFO_V2 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR ucOverdriveThermalController; ++ UCHAR ucOverdriveI2cLine; ++ UCHAR ucOverdriveIntBitmap; ++ UCHAR ucOverdriveControllerAddress; ++ UCHAR ucSizeOfPowerModeEntry; ++ UCHAR ucNumOfPowerModeEntries; ++ ATOM_POWERMODE_INFO_V2 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; ++}ATOM_POWERPLAY_INFO_V2; ++ ++typedef struct _ATOM_POWERPLAY_INFO_V3 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ UCHAR ucOverdriveThermalController; ++ UCHAR ucOverdriveI2cLine; ++ UCHAR ucOverdriveIntBitmap; ++ UCHAR ucOverdriveControllerAddress; ++ UCHAR ucSizeOfPowerModeEntry; ++ UCHAR ucNumOfPowerModeEntries; ++ ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; ++}ATOM_POWERPLAY_INFO_V3; ++ ++ ++ ++/**************************************************************************/ ++ ++ ++// Following definitions are for compatiblity issue in different SW components. ++#define ATOM_MASTER_DATA_TABLE_REVISION 0x01 ++#define Object_Info Object_Header ++#define AdjustARB_SEQ MC_InitParameter ++#define VRAM_GPIO_DetectionInfo VoltageObjectInfo ++#define ASIC_VDDCI_Info ASIC_ProfilingInfo ++#define ASIC_MVDDQ_Info MemoryTrainingInfo ++#define SS_Info PPLL_SS_Info ++#define ASIC_MVDDC_Info ASIC_InternalSS_Info ++#define DispDevicePriorityInfo SaveRestoreInfo ++#define DispOutInfo TV_VideoMode ++ ++ ++#define ATOM_ENCODER_OBJECT_TABLE ATOM_OBJECT_TABLE ++#define ATOM_CONNECTOR_OBJECT_TABLE ATOM_OBJECT_TABLE ++ ++//New device naming, remove them when both DAL/VBIOS is ready ++#define DFP2I_OUTPUT_CONTROL_PARAMETERS CRT1_OUTPUT_CONTROL_PARAMETERS ++#define DFP2I_OUTPUT_CONTROL_PS_ALLOCATION DFP2I_OUTPUT_CONTROL_PARAMETERS ++ ++#define DFP1X_OUTPUT_CONTROL_PARAMETERS CRT1_OUTPUT_CONTROL_PARAMETERS ++#define DFP1X_OUTPUT_CONTROL_PS_ALLOCATION DFP1X_OUTPUT_CONTROL_PARAMETERS ++ ++#define DFP1I_OUTPUT_CONTROL_PARAMETERS DFP1_OUTPUT_CONTROL_PARAMETERS ++#define DFP1I_OUTPUT_CONTROL_PS_ALLOCATION DFP1_OUTPUT_CONTROL_PS_ALLOCATION ++ ++#define ATOM_DEVICE_DFP1I_SUPPORT ATOM_DEVICE_DFP1_SUPPORT ++#define ATOM_DEVICE_DFP1X_SUPPORT ATOM_DEVICE_DFP2_SUPPORT ++ ++#define ATOM_DEVICE_DFP1I_INDEX ATOM_DEVICE_DFP1_INDEX ++#define ATOM_DEVICE_DFP1X_INDEX ATOM_DEVICE_DFP2_INDEX ++ ++#define ATOM_DEVICE_DFP2I_INDEX 0x00000009 ++#define ATOM_DEVICE_DFP2I_SUPPORT (0x1L << ATOM_DEVICE_DFP2I_INDEX) ++ ++#define ATOM_S0_DFP1I ATOM_S0_DFP1 ++#define ATOM_S0_DFP1X ATOM_S0_DFP2 ++ ++#define ATOM_S0_DFP2I 0x00200000L ++#define ATOM_S0_DFP2Ib2 0x20 ++ ++#define ATOM_S2_DFP1I_DPMS_STATE ATOM_S2_DFP1_DPMS_STATE ++#define ATOM_S2_DFP1X_DPMS_STATE ATOM_S2_DFP2_DPMS_STATE ++ ++#define ATOM_S2_DFP2I_DPMS_STATE 0x02000000L ++#define ATOM_S2_DFP2I_DPMS_STATEb3 0x02 ++ ++#define ATOM_S3_DFP2I_ACTIVEb1 0x02 ++ ++#define ATOM_S3_DFP1I_ACTIVE ATOM_S3_DFP1_ACTIVE ++#define ATOM_S3_DFP1X_ACTIVE ATOM_S3_DFP2_ACTIVE ++ ++#define ATOM_S3_DFP2I_ACTIVE 0x00000200L ++ ++#define ATOM_S3_DFP1I_CRTC_ACTIVE ATOM_S3_DFP1_CRTC_ACTIVE ++#define ATOM_S3_DFP1X_CRTC_ACTIVE ATOM_S3_DFP2_CRTC_ACTIVE ++#define ATOM_S3_DFP2I_CRTC_ACTIVE 0x02000000L ++ ++#define ATOM_S3_DFP2I_CRTC_ACTIVEb3 0x02 ++#define ATOM_S5_DOS_REQ_DFP2Ib1 0x02 ++ ++#define ATOM_S5_DOS_REQ_DFP2I 0x0200 ++#define ATOM_S6_ACC_REQ_DFP1I ATOM_S6_ACC_REQ_DFP1 ++#define ATOM_S6_ACC_REQ_DFP1X ATOM_S6_ACC_REQ_DFP2 ++ ++#define ATOM_S6_ACC_REQ_DFP2Ib3 0x02 ++#define ATOM_S6_ACC_REQ_DFP2I 0x02000000L ++ ++#define TMDS1XEncoderControl DVOEncoderControl ++#define DFP1XOutputControl DVOOutputControl ++ ++#define ExternalDFPOutputControl DFP1XOutputControl ++#define EnableExternalTMDS_Encoder TMDS1XEncoderControl ++ ++#define DFP1IOutputControl TMDSAOutputControl ++#define DFP2IOutputControl LVTMAOutputControl ++ ++#define DAC1_ENCODER_CONTROL_PARAMETERS DAC_ENCODER_CONTROL_PARAMETERS ++#define DAC1_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PS_ALLOCATION ++ ++#define DAC2_ENCODER_CONTROL_PARAMETERS DAC_ENCODER_CONTROL_PARAMETERS ++#define DAC2_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PS_ALLOCATION ++ ++#define ucDac1Standard ucDacStandard ++#define ucDac2Standard ucDacStandard ++ ++#define TMDS1EncoderControl TMDSAEncoderControl ++#define TMDS2EncoderControl LVTMAEncoderControl ++ ++#define DFP1OutputControl TMDSAOutputControl ++#define DFP2OutputControl LVTMAOutputControl ++#define CRT1OutputControl DAC1OutputControl ++#define CRT2OutputControl DAC2OutputControl ++ ++//These two lines will be removed for sure in a few days, will follow up with Michael V. ++#define EnableLVDS_SS EnableSpreadSpectrumOnPPLL ++#define ENABLE_LVDS_SS_PARAMETERS_V3 ENABLE_SPREAD_SPECTRUM_ON_PPLL ++ ++/*********************************************************************************/ ++ ++#pragma pack() // BIOS data must use byte aligment ++ ++#endif /* _ATOMBIOS_H */ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/atom-bits.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom-bits.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/atom-bits.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom-bits.h 2009-04-26 02:59:53.402975571 +0200 +@@ -0,0 +1,48 @@ ++/* ++ * Copyright 2008 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Author: Stanislaw Skowronek ++ */ ++ ++#ifndef ATOM_BITS_H ++#define ATOM_BITS_H ++ ++static inline uint8_t get_u8(void *bios, int ptr) ++{ ++ return ((unsigned char *)bios)[ptr]; ++} ++#define U8(ptr) get_u8(ctx->ctx->bios,(ptr)) ++#define CU8(ptr) get_u8(ctx->bios,(ptr)) ++static inline uint16_t get_u16(void *bios, int ptr) ++{ ++ return get_u8(bios,ptr)|(((uint16_t)get_u8(bios,ptr+1))<<8); ++} ++#define U16(ptr) get_u16(ctx->ctx->bios,(ptr)) ++#define CU16(ptr) get_u16(ctx->bios,(ptr)) ++static inline uint32_t get_u32(void *bios, int ptr) ++{ ++ return get_u16(bios,ptr)|(((uint32_t)get_u16(bios,ptr+2))<<16); ++} ++#define U32(ptr) get_u32(ctx->ctx->bios,(ptr)) ++#define CU32(ptr) get_u32(ctx->bios,(ptr)) ++#define CSTR(ptr) (((char *)(ctx->bios))+(ptr)) ++ ++#endif +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/atom.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/atom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom.c 2009-04-26 02:59:59.886725135 +0200 +@@ -0,0 +1,1141 @@ ++/* ++ * Copyright 2008 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Author: Stanislaw Skowronek ++ */ ++ ++#include ++#include ++ ++#define ATOM_DEBUG ++ ++#include "atom.h" ++#include "atom-names.h" ++#include "atom-bits.h" ++ ++#define ATOM_COND_ABOVE 0 ++#define ATOM_COND_ABOVEOREQUAL 1 ++#define ATOM_COND_ALWAYS 2 ++#define ATOM_COND_BELOW 3 ++#define ATOM_COND_BELOWOREQUAL 4 ++#define ATOM_COND_EQUAL 5 ++#define ATOM_COND_NOTEQUAL 6 ++ ++#define ATOM_PORT_ATI 0 ++#define ATOM_PORT_PCI 1 ++#define ATOM_PORT_SYSIO 2 ++ ++#define ATOM_UNIT_MICROSEC 0 ++#define ATOM_UNIT_MILLISEC 1 ++ ++#define PLL_INDEX 2 ++#define PLL_DATA 3 ++ ++typedef struct { ++ struct atom_context *ctx; ++ ++ uint32_t *ps, *ws; ++ int ps_shift; ++ uint16_t start; ++} atom_exec_context; ++ ++int atom_debug = 0; ++void atom_execute_table(struct atom_context *ctx, int index, uint32_t *params); ++ ++static uint32_t atom_arg_mask[8] = {0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, 0xFF000000}; ++static int atom_arg_shift[8] = {0, 0, 8, 16, 0, 8, 16, 24}; ++static int atom_dst_to_src[8][4] = { // translate destination alignment field to the source alignment encoding ++ { 0, 0, 0, 0 }, ++ { 1, 2, 3, 0 }, ++ { 1, 2, 3, 0 }, ++ { 1, 2, 3, 0 }, ++ { 4, 5, 6, 7 }, ++ { 4, 5, 6, 7 }, ++ { 4, 5, 6, 7 }, ++ { 4, 5, 6, 7 }, ++}; ++static int atom_def_dst[8] = { 0, 0, 1, 2, 0, 1, 2, 3 }; ++ ++static int debug_depth = 0; ++#ifdef ATOM_DEBUG ++static void debug_print_spaces(int n) ++{ ++ while(n--) ++ printk(" "); ++} ++#define DEBUG(...) do if(atom_debug) { printk(KERN_DEBUG __VA_ARGS__); } while(0) ++#define SDEBUG(...) do if(atom_debug) { printk(KERN_DEBUG); debug_print_spaces(debug_depth); printk(__VA_ARGS__); } while(0) ++#else ++#define DEBUG(...) do { } while(0) ++#define SDEBUG(...) do { } while(0) ++#endif ++ ++static uint32_t atom_iio_execute(struct atom_context *ctx, int base, uint32_t index, uint32_t data) ++{ ++ uint32_t temp = 0xCDCDCDCD; ++ while(1) ++ switch(CU8(base)) { ++ case ATOM_IIO_NOP: ++ base++; ++ break; ++ case ATOM_IIO_READ: ++ temp = ctx->card->reg_read(ctx->card, CU16(base+1)); ++ base+=3; ++ break; ++ case ATOM_IIO_WRITE: ++ ctx->card->reg_write(ctx->card, CU16(base+1), temp); ++ base+=3; ++ break; ++ case ATOM_IIO_CLEAR: ++ temp &= ~((0xFFFFFFFF >> (32-CU8(base+1))) << CU8(base+2)); ++ base+=3; ++ break; ++ case ATOM_IIO_SET: ++ temp |= (0xFFFFFFFF >> (32-CU8(base+1))) << CU8(base+2); ++ base+=3; ++ break; ++ case ATOM_IIO_MOVE_INDEX: ++ temp &= ~((0xFFFFFFFF >> (32-CU8(base+1))) << CU8(base+2)); ++ temp |= ((index >> CU8(base+2)) & (0xFFFFFFFF >> (32-CU8(base+1)))) << CU8(base+3); ++ base+=4; ++ break; ++ case ATOM_IIO_MOVE_DATA: ++ temp &= ~((0xFFFFFFFF >> (32-CU8(base+1))) << CU8(base+2)); ++ temp |= ((data >> CU8(base+2)) & (0xFFFFFFFF >> (32-CU8(base+1)))) << CU8(base+3); ++ base+=4; ++ break; ++ case ATOM_IIO_MOVE_ATTR: ++ temp &= ~((0xFFFFFFFF >> (32-CU8(base+1))) << CU8(base+2)); ++ temp |= ((ctx->io_attr >> CU8(base+2)) & (0xFFFFFFFF >> (32-CU8(base+1)))) << CU8(base+3); ++ base+=4; ++ break; ++ case ATOM_IIO_END: ++ return temp; ++ default: ++ printk(KERN_INFO "Unknown IIO opcode.\n"); ++ return 0; ++ } ++} ++ ++static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, int *ptr, uint32_t *saved, int print) ++{ ++ uint32_t idx, val = 0xCDCDCDCD, align, arg; ++ struct atom_context *gctx = ctx->ctx; ++ arg = attr & 7; ++ align = (attr >> 3) & 7; ++ switch(arg) { ++ case ATOM_ARG_REG: ++ idx = U16(*ptr); ++ (*ptr)+=2; ++ if(print) ++ DEBUG("REG[0x%04X]", idx); ++ idx += gctx->reg_block; ++ switch(gctx->io_mode) { ++ case ATOM_IO_MM: ++ val = gctx->card->reg_read(gctx->card, idx); ++ break; ++ case ATOM_IO_PCI: ++ printk(KERN_INFO "PCI registers are not implemented.\n"); ++ return 0; ++ case ATOM_IO_SYSIO: ++ printk(KERN_INFO "SYSIO registers are not implemented.\n"); ++ return 0; ++ default: ++ if(!(gctx->io_mode&0x80)) { ++ printk(KERN_INFO "Bad IO mode.\n"); ++ return 0; ++ } ++ if(!gctx->iio[gctx->io_mode&0x7F]) { ++ printk(KERN_INFO "Undefined indirect IO read method %d.\n", gctx->io_mode&0x7F); ++ return 0; ++ } ++ val = atom_iio_execute(gctx, gctx->iio[gctx->io_mode&0x7F], idx, 0); ++ } ++ break; ++ case ATOM_ARG_PS: ++ idx = U8(*ptr); ++ (*ptr)++; ++ val = le32_to_cpu(ctx->ps[idx]); ++ if(print) ++ DEBUG("PS[0x%02X,0x%04X]", idx, val); ++ break; ++ case ATOM_ARG_WS: ++ idx = U8(*ptr); ++ (*ptr)++; ++ if(print) ++ DEBUG("WS[0x%02X]", idx); ++ switch(idx) { ++ case ATOM_WS_QUOTIENT: ++ val = gctx->divmul[0]; ++ break; ++ case ATOM_WS_REMAINDER: ++ val = gctx->divmul[1]; ++ break; ++ case ATOM_WS_DATAPTR: ++ val = gctx->data_block; ++ break; ++ case ATOM_WS_SHIFT: ++ val = gctx->shift; ++ break; ++ case ATOM_WS_OR_MASK: ++ val = 1<shift; ++ break; ++ case ATOM_WS_AND_MASK: ++ val = ~(1<shift); ++ break; ++ case ATOM_WS_FB_WINDOW: ++ val = gctx->fb_base; ++ break; ++ case ATOM_WS_ATTRIBUTES: ++ val = gctx->io_attr; ++ break; ++ default: ++ val = ctx->ws[idx]; ++ } ++ break; ++ case ATOM_ARG_ID: ++ idx = U16(*ptr); ++ (*ptr)+=2; ++ if(print) { ++ if(gctx->data_block) ++ DEBUG("ID[0x%04X+%04X]", idx, gctx->data_block); ++ else ++ DEBUG("ID[0x%04X]", idx); ++ } ++ val = U32(idx + gctx->data_block); ++ break; ++ case ATOM_ARG_FB: ++ idx = U8(*ptr); ++ (*ptr)++; ++ if(print) ++ DEBUG("FB[0x%02X]", idx); ++ printk(KERN_INFO "FB access is not implemented.\n"); ++ return 0; ++ case ATOM_ARG_IMM: ++ switch(align) { ++ case ATOM_SRC_DWORD: ++ val = U32(*ptr); ++ (*ptr)+=4; ++ if(print) ++ DEBUG("IMM 0x%08X\n", val); ++ return val; ++ case ATOM_SRC_WORD0: ++ case ATOM_SRC_WORD8: ++ case ATOM_SRC_WORD16: ++ val = U16(*ptr); ++ (*ptr)+=2; ++ if(print) ++ DEBUG("IMM 0x%04X\n", val); ++ return val; ++ case ATOM_SRC_BYTE0: ++ case ATOM_SRC_BYTE8: ++ case ATOM_SRC_BYTE16: ++ case ATOM_SRC_BYTE24: ++ val = U8(*ptr); ++ (*ptr)++; ++ if(print) ++ DEBUG("IMM 0x%02X\n", val); ++ return val; ++ } ++ return 0; ++ case ATOM_ARG_PLL: ++ idx = U8(*ptr); ++ (*ptr)++; ++ if(print) ++ DEBUG("PLL[0x%02X]", idx); ++ val = gctx->card->pll_read(gctx->card, idx); ++ break; ++ case ATOM_ARG_MC: ++ idx = U8(*ptr); ++ (*ptr)++; ++ if(print) ++ DEBUG("MC[0x%02X]", idx); ++ val = gctx->card->mc_read(gctx->card, idx); ++ break; ++ } ++ if(saved) ++ *saved = val; ++ val &= atom_arg_mask[align]; ++ val >>= atom_arg_shift[align]; ++ if(print) ++ switch(align) { ++ case ATOM_SRC_DWORD: ++ DEBUG(".[31:0] -> 0x%08X\n", val); ++ break; ++ case ATOM_SRC_WORD0: ++ DEBUG(".[15:0] -> 0x%04X\n", val); ++ break; ++ case ATOM_SRC_WORD8: ++ DEBUG(".[23:8] -> 0x%04X\n", val); ++ break; ++ case ATOM_SRC_WORD16: ++ DEBUG(".[31:16] -> 0x%04X\n", val); ++ break; ++ case ATOM_SRC_BYTE0: ++ DEBUG(".[7:0] -> 0x%02X\n", val); ++ break; ++ case ATOM_SRC_BYTE8: ++ DEBUG(".[15:8] -> 0x%02X\n", val); ++ break; ++ case ATOM_SRC_BYTE16: ++ DEBUG(".[23:16] -> 0x%02X\n", val); ++ break; ++ case ATOM_SRC_BYTE24: ++ DEBUG(".[31:24] -> 0x%02X\n", val); ++ break; ++ } ++ return val; ++} ++ ++static void atom_skip_src_int(atom_exec_context *ctx, uint8_t attr, int *ptr) ++{ ++ uint32_t align = (attr >> 3) & 7, arg = attr & 7; ++ switch(arg) { ++ case ATOM_ARG_REG: ++ case ATOM_ARG_ID: ++ (*ptr)+=2; ++ break; ++ case ATOM_ARG_PLL: ++ case ATOM_ARG_MC: ++ case ATOM_ARG_PS: ++ case ATOM_ARG_WS: ++ case ATOM_ARG_FB: ++ (*ptr)++; ++ break; ++ case ATOM_ARG_IMM: ++ switch(align) { ++ case ATOM_SRC_DWORD: ++ (*ptr)+=4; ++ return; ++ case ATOM_SRC_WORD0: ++ case ATOM_SRC_WORD8: ++ case ATOM_SRC_WORD16: ++ (*ptr)+=2; ++ return; ++ case ATOM_SRC_BYTE0: ++ case ATOM_SRC_BYTE8: ++ case ATOM_SRC_BYTE16: ++ case ATOM_SRC_BYTE24: ++ (*ptr)++; ++ return; ++ } ++ return; ++ } ++} ++ ++static uint32_t atom_get_src(atom_exec_context *ctx, uint8_t attr, int *ptr) ++{ ++ return atom_get_src_int(ctx, attr, ptr, NULL, 1); ++} ++ ++static uint32_t atom_get_dst(atom_exec_context *ctx, int arg, uint8_t attr, int *ptr, uint32_t *saved, int print) ++{ ++ return atom_get_src_int(ctx, arg|atom_dst_to_src[(attr>>3)&7][(attr>>6)&3]<<3, ptr, saved, print); ++} ++ ++static void atom_skip_dst(atom_exec_context *ctx, int arg, uint8_t attr, int *ptr) ++{ ++ atom_skip_src_int(ctx, arg|atom_dst_to_src[(attr>>3)&7][(attr>>6)&3]<<3, ptr); ++} ++ ++static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, int *ptr, uint32_t val, uint32_t saved) ++{ ++ uint32_t align = atom_dst_to_src[(attr>>3)&7][(attr>>6)&3], old_val = val, idx; ++ struct atom_context *gctx = ctx->ctx; ++ old_val &= atom_arg_mask[align] >> atom_arg_shift[align]; ++ val <<= atom_arg_shift[align]; ++ val &= atom_arg_mask[align]; ++ saved &= ~atom_arg_mask[align]; ++ val |= saved; ++ switch(arg) { ++ case ATOM_ARG_REG: ++ idx = U16(*ptr); ++ (*ptr)+=2; ++ DEBUG("REG[0x%04X]", idx); ++ idx += gctx->reg_block; ++ switch(gctx->io_mode) { ++ case ATOM_IO_MM: ++ if(idx == 0) ++ gctx->card->reg_write(gctx->card, idx, val<<2); ++ else ++ gctx->card->reg_write(gctx->card, idx, val); ++ break; ++ case ATOM_IO_PCI: ++ printk(KERN_INFO "PCI registers are not implemented.\n"); ++ return; ++ case ATOM_IO_SYSIO: ++ printk(KERN_INFO "SYSIO registers are not implemented.\n"); ++ return; ++ default: ++ if(!(gctx->io_mode&0x80)) { ++ printk(KERN_INFO "Bad IO mode.\n"); ++ return; ++ } ++ if(!gctx->iio[gctx->io_mode&0xFF]) { ++ printk(KERN_INFO "Undefined indirect IO write method %d.\n", gctx->io_mode&0x7F); ++ return; ++ } ++ atom_iio_execute(gctx, gctx->iio[gctx->io_mode&0xFF], idx, val); ++ } ++ break; ++ case ATOM_ARG_PS: ++ idx = U8(*ptr); ++ (*ptr)++; ++ DEBUG("PS[0x%02X]", idx); ++ ctx->ps[idx] = cpu_to_le32(val); ++ break; ++ case ATOM_ARG_WS: ++ idx = U8(*ptr); ++ (*ptr)++; ++ DEBUG("WS[0x%02X]", idx); ++ switch(idx) { ++ case ATOM_WS_QUOTIENT: ++ gctx->divmul[0] = val; ++ break; ++ case ATOM_WS_REMAINDER: ++ gctx->divmul[1] = val; ++ break; ++ case ATOM_WS_DATAPTR: ++ gctx->data_block = val; ++ break; ++ case ATOM_WS_SHIFT: ++ gctx->shift = val; ++ break; ++ case ATOM_WS_OR_MASK: ++ case ATOM_WS_AND_MASK: ++ break; ++ case ATOM_WS_FB_WINDOW: ++ gctx->fb_base = val; ++ break; ++ case ATOM_WS_ATTRIBUTES: ++ gctx->io_attr = val; ++ break; ++ default: ++ ctx->ws[idx] = val; ++ } ++ break; ++ case ATOM_ARG_FB: ++ idx = U8(*ptr); ++ (*ptr)++; ++ DEBUG("FB[0x%02X]", idx); ++ printk(KERN_INFO "FB access is not implemented.\n"); ++ return; ++ case ATOM_ARG_PLL: ++ idx = U8(*ptr); ++ (*ptr)++; ++ DEBUG("PLL[0x%02X]", idx); ++ gctx->card->pll_write(gctx->card, idx, val); ++ break; ++ case ATOM_ARG_MC: ++ idx = U8(*ptr); ++ (*ptr)++; ++ DEBUG("MC[0x%02X]", idx); ++ gctx->card->mc_write(gctx->card, idx, val); ++ return; ++ } ++ switch(align) { ++ case ATOM_SRC_DWORD: ++ DEBUG(".[31:0] <- 0x%08X\n", old_val); ++ break; ++ case ATOM_SRC_WORD0: ++ DEBUG(".[15:0] <- 0x%04X\n", old_val); ++ break; ++ case ATOM_SRC_WORD8: ++ DEBUG(".[23:8] <- 0x%04X\n", old_val); ++ break; ++ case ATOM_SRC_WORD16: ++ DEBUG(".[31:16] <- 0x%04X\n", old_val); ++ break; ++ case ATOM_SRC_BYTE0: ++ DEBUG(".[7:0] <- 0x%02X\n", old_val); ++ break; ++ case ATOM_SRC_BYTE8: ++ DEBUG(".[15:8] <- 0x%02X\n", old_val); ++ break; ++ case ATOM_SRC_BYTE16: ++ DEBUG(".[23:16] <- 0x%02X\n", old_val); ++ break; ++ case ATOM_SRC_BYTE24: ++ DEBUG(".[31:24] <- 0x%02X\n", old_val); ++ break; ++ } ++} ++ ++static void atom_op_add(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src, saved; ++ int dptr = *ptr; ++ SDEBUG(" dst: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); ++ SDEBUG(" src: "); ++ src = atom_get_src(ctx, attr, ptr); ++ dst += src; ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, dst, saved); ++} ++ ++static void atom_op_and(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src, saved; ++ int dptr = *ptr; ++ SDEBUG(" dst: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); ++ SDEBUG(" src: "); ++ src = atom_get_src(ctx, attr, ptr); ++ dst &= src; ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, dst, saved); ++} ++ ++static void atom_op_beep(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ printk("ATOM BIOS beeped!\n"); ++} ++ ++static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ int idx = U8((*ptr)++); ++ if(idx < ATOM_TABLE_NAMES_CNT) ++ SDEBUG(" table: %d (%s)\n", idx, atom_table_names[idx]); ++ else ++ SDEBUG(" table: %d\n", idx); ++ if(U16(ctx->ctx->cmd_table + 4 + 2*idx)) ++ atom_execute_table(ctx->ctx, idx, ctx->ps+ctx->ps_shift); ++} ++ ++static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t saved; ++ int dptr = *ptr; ++ attr &= 0x38; ++ attr |= atom_def_dst[attr>>3]<<6; ++ atom_get_dst(ctx, arg, attr, ptr, &saved, 0); ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, 0, saved); ++} ++ ++static void atom_op_compare(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src; ++ SDEBUG(" src1: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1); ++ SDEBUG(" src2: "); ++ src = atom_get_src(ctx, attr, ptr); ++ ctx->ctx->cs_equal = (dst == src); ++ ctx->ctx->cs_above = (dst > src); ++ SDEBUG(" result: %s %s\n", ctx->ctx->cs_equal?"EQ":"NE", ctx->ctx->cs_above?"GT":"LE"); ++} ++ ++static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t count = U8((*ptr)++); ++ SDEBUG(" count: %d\n", count); ++ if(arg == ATOM_UNIT_MICROSEC) ++ schedule_timeout_uninterruptible(usecs_to_jiffies(count)); ++ else ++ schedule_timeout_uninterruptible(msecs_to_jiffies(count)); ++} ++ ++static void atom_op_div(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src; ++ SDEBUG(" src1: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1); ++ SDEBUG(" src2: "); ++ src = atom_get_src(ctx, attr, ptr); ++ if(src != 0) { ++ ctx->ctx->divmul[0] = dst/src; ++ ctx->ctx->divmul[1] = dst%src; ++ } else { ++ ctx->ctx->divmul[0] = 0; ++ ctx->ctx->divmul[1] = 0; ++ } ++} ++ ++static void atom_op_eot(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ /* functionally, a nop */ ++} ++ ++static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ int execute = 0, target = U16(*ptr); ++ (*ptr)+=2; ++ switch(arg) { ++ case ATOM_COND_ABOVE: ++ execute = ctx->ctx->cs_above; ++ break; ++ case ATOM_COND_ABOVEOREQUAL: ++ execute = ctx->ctx->cs_above || ctx->ctx->cs_equal; ++ break; ++ case ATOM_COND_ALWAYS: ++ execute = 1; ++ break; ++ case ATOM_COND_BELOW: ++ execute = !(ctx->ctx->cs_above || ctx->ctx->cs_equal); ++ break; ++ case ATOM_COND_BELOWOREQUAL: ++ execute = !ctx->ctx->cs_above; ++ break; ++ case ATOM_COND_EQUAL: ++ execute = ctx->ctx->cs_equal; ++ break; ++ case ATOM_COND_NOTEQUAL: ++ execute = !ctx->ctx->cs_equal; ++ break; ++ } ++ if(arg != ATOM_COND_ALWAYS) ++ SDEBUG(" taken: %s\n", execute?"yes":"no"); ++ SDEBUG(" target: 0x%04X\n", target); ++ if(execute) ++ *ptr = ctx->start+target; ++} ++ ++static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src1, src2, saved; ++ int dptr = *ptr; ++ SDEBUG(" dst: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); ++ SDEBUG(" src1: "); ++ src1 = atom_get_src(ctx, attr, ptr); ++ SDEBUG(" src2: "); ++ src2 = atom_get_src(ctx, attr, ptr); ++ dst &= src1; ++ dst |= src2; ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, dst, saved); ++} ++ ++static void atom_op_move(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t src, saved; ++ int dptr = *ptr; ++ if(((attr>>3)&7) != ATOM_SRC_DWORD) ++ atom_get_dst(ctx, arg, attr, ptr, &saved, 0); ++ else { ++ atom_skip_dst(ctx, arg, attr, ptr); ++ saved = 0xCDCDCDCD; ++ } ++ SDEBUG(" src: "); ++ src = atom_get_src(ctx, attr, ptr); ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, src, saved); ++} ++ ++static void atom_op_mul(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src; ++ SDEBUG(" src1: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1); ++ SDEBUG(" src2: "); ++ src = atom_get_src(ctx, attr, ptr); ++ ctx->ctx->divmul[0] = dst*src; ++} ++ ++static void atom_op_nop(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ /* nothing */ ++} ++ ++static void atom_op_or(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src, saved; ++ int dptr = *ptr; ++ SDEBUG(" dst: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); ++ SDEBUG(" src: "); ++ src = atom_get_src(ctx, attr, ptr); ++ dst |= src; ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, dst, saved); ++} ++ ++static void atom_op_postcard(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t val = U8((*ptr)++); ++ SDEBUG("POST card output: 0x%02X\n", val); ++} ++ ++static void atom_op_repeat(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ printk(KERN_INFO "unimplemented!\n"); ++} ++ ++static void atom_op_restorereg(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ printk(KERN_INFO "unimplemented!\n"); ++} ++ ++static void atom_op_savereg(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ printk(KERN_INFO "unimplemented!\n"); ++} ++ ++static void atom_op_setdatablock(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ int idx = U8(*ptr); ++ (*ptr)++; ++ SDEBUG(" block: %d\n", idx); ++ if(!idx) ++ ctx->ctx->data_block = 0; ++ else if(idx==255) ++ ctx->ctx->data_block = ctx->start; ++ else ++ ctx->ctx->data_block = U16(ctx->ctx->data_table + 4 + 2*idx); ++ SDEBUG(" base: 0x%04X\n", ctx->ctx->data_block); ++} ++ ++static void atom_op_setfbbase(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ SDEBUG(" fb_base: "); ++ ctx->ctx->fb_base = atom_get_src(ctx, attr, ptr); ++} ++ ++static void atom_op_setport(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ int port; ++ switch(arg) { ++ case ATOM_PORT_ATI: ++ port = U16(*ptr); ++ if(port < ATOM_IO_NAMES_CNT) ++ SDEBUG(" port: %d (%s)\n", port, atom_io_names[port]); ++ else ++ SDEBUG(" port: %d\n", port); ++ if(!port) ++ ctx->ctx->io_mode = ATOM_IO_MM; ++ else ++ ctx->ctx->io_mode = ATOM_IO_IIO|port; ++ (*ptr)+=2; ++ break; ++ case ATOM_PORT_PCI: ++ ctx->ctx->io_mode = ATOM_IO_PCI; ++ (*ptr)++; ++ break; ++ case ATOM_PORT_SYSIO: ++ ctx->ctx->io_mode = ATOM_IO_SYSIO; ++ (*ptr)++; ++ break; ++ } ++} ++ ++static void atom_op_setregblock(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ ctx->ctx->reg_block = U16(*ptr); ++ (*ptr)+=2; ++ SDEBUG(" base: 0x%04X\n", ctx->ctx->reg_block); ++} ++ ++static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++), shift; ++ uint32_t saved, dst; ++ int dptr = *ptr; ++ attr &= 0x38; ++ attr |= atom_def_dst[attr>>3]<<6; ++ SDEBUG(" dst: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); ++ shift = U8((*ptr)++); ++ SDEBUG(" shift: %d\n", shift); ++ dst <<= shift; ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, dst, saved); ++} ++ ++static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++), shift; ++ uint32_t saved, dst; ++ int dptr = *ptr; ++ attr &= 0x38; ++ attr |= atom_def_dst[attr>>3]<<6; ++ SDEBUG(" dst: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); ++ shift = U8((*ptr)++); ++ SDEBUG(" shift: %d\n", shift); ++ dst >>= shift; ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, dst, saved); ++} ++ ++static void atom_op_sub(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src, saved; ++ int dptr = *ptr; ++ SDEBUG(" dst: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); ++ SDEBUG(" src: "); ++ src = atom_get_src(ctx, attr, ptr); ++ dst -= src; ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, dst, saved); ++} ++ ++static void atom_op_switch(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t src, val, target; ++ SDEBUG(" switch: "); ++ src = atom_get_src(ctx, attr, ptr); ++ while(U16(*ptr) != ATOM_CASE_END) ++ if(U8(*ptr) == ATOM_CASE_MAGIC) { ++ (*ptr)++; ++ SDEBUG(" case: "); ++ val = atom_get_src(ctx, (attr&0x38)|ATOM_ARG_IMM, ptr); ++ target = U16(*ptr); ++ if(val == src) { ++ SDEBUG(" target: %04X\n", target); ++ *ptr = ctx->start+target; ++ return; ++ } ++ (*ptr) += 2; ++ } else { ++ printk(KERN_INFO "Bad case.\n"); ++ return; ++ } ++ (*ptr) += 2; ++} ++ ++static void atom_op_test(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src; ++ SDEBUG(" src1: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1); ++ SDEBUG(" src2: "); ++ src = atom_get_src(ctx, attr, ptr); ++ ctx->ctx->cs_equal = ((dst & src) == 0); ++ SDEBUG(" result: %s\n", ctx->ctx->cs_equal?"EQ":"NE"); ++} ++ ++static void atom_op_xor(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ uint8_t attr = U8((*ptr)++); ++ uint32_t dst, src, saved; ++ int dptr = *ptr; ++ SDEBUG(" dst: "); ++ dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); ++ SDEBUG(" src: "); ++ src = atom_get_src(ctx, attr, ptr); ++ dst ^= src; ++ SDEBUG(" dst: "); ++ atom_put_dst(ctx, arg, attr, &dptr, dst, saved); ++} ++ ++static void atom_op_debug(atom_exec_context *ctx, int *ptr, int arg) ++{ ++ printk(KERN_INFO "unimplemented!\n"); ++} ++ ++static struct { ++ void (*func)(atom_exec_context *, int *, int); ++ int arg; ++} opcode_table[ATOM_OP_CNT] = { ++ { NULL, 0 }, ++ { atom_op_move, ATOM_ARG_REG }, ++ { atom_op_move, ATOM_ARG_PS }, ++ { atom_op_move, ATOM_ARG_WS }, ++ { atom_op_move, ATOM_ARG_FB }, ++ { atom_op_move, ATOM_ARG_PLL }, ++ { atom_op_move, ATOM_ARG_MC }, ++ { atom_op_and, ATOM_ARG_REG }, ++ { atom_op_and, ATOM_ARG_PS }, ++ { atom_op_and, ATOM_ARG_WS }, ++ { atom_op_and, ATOM_ARG_FB }, ++ { atom_op_and, ATOM_ARG_PLL }, ++ { atom_op_and, ATOM_ARG_MC }, ++ { atom_op_or, ATOM_ARG_REG }, ++ { atom_op_or, ATOM_ARG_PS }, ++ { atom_op_or, ATOM_ARG_WS }, ++ { atom_op_or, ATOM_ARG_FB }, ++ { atom_op_or, ATOM_ARG_PLL }, ++ { atom_op_or, ATOM_ARG_MC }, ++ { atom_op_shl, ATOM_ARG_REG }, ++ { atom_op_shl, ATOM_ARG_PS }, ++ { atom_op_shl, ATOM_ARG_WS }, ++ { atom_op_shl, ATOM_ARG_FB }, ++ { atom_op_shl, ATOM_ARG_PLL }, ++ { atom_op_shl, ATOM_ARG_MC }, ++ { atom_op_shr, ATOM_ARG_REG }, ++ { atom_op_shr, ATOM_ARG_PS }, ++ { atom_op_shr, ATOM_ARG_WS }, ++ { atom_op_shr, ATOM_ARG_FB }, ++ { atom_op_shr, ATOM_ARG_PLL }, ++ { atom_op_shr, ATOM_ARG_MC }, ++ { atom_op_mul, ATOM_ARG_REG }, ++ { atom_op_mul, ATOM_ARG_PS }, ++ { atom_op_mul, ATOM_ARG_WS }, ++ { atom_op_mul, ATOM_ARG_FB }, ++ { atom_op_mul, ATOM_ARG_PLL }, ++ { atom_op_mul, ATOM_ARG_MC }, ++ { atom_op_div, ATOM_ARG_REG }, ++ { atom_op_div, ATOM_ARG_PS }, ++ { atom_op_div, ATOM_ARG_WS }, ++ { atom_op_div, ATOM_ARG_FB }, ++ { atom_op_div, ATOM_ARG_PLL }, ++ { atom_op_div, ATOM_ARG_MC }, ++ { atom_op_add, ATOM_ARG_REG }, ++ { atom_op_add, ATOM_ARG_PS }, ++ { atom_op_add, ATOM_ARG_WS }, ++ { atom_op_add, ATOM_ARG_FB }, ++ { atom_op_add, ATOM_ARG_PLL }, ++ { atom_op_add, ATOM_ARG_MC }, ++ { atom_op_sub, ATOM_ARG_REG }, ++ { atom_op_sub, ATOM_ARG_PS }, ++ { atom_op_sub, ATOM_ARG_WS }, ++ { atom_op_sub, ATOM_ARG_FB }, ++ { atom_op_sub, ATOM_ARG_PLL }, ++ { atom_op_sub, ATOM_ARG_MC }, ++ { atom_op_setport, ATOM_PORT_ATI }, ++ { atom_op_setport, ATOM_PORT_PCI }, ++ { atom_op_setport, ATOM_PORT_SYSIO }, ++ { atom_op_setregblock, 0 }, ++ { atom_op_setfbbase, 0 }, ++ { atom_op_compare, ATOM_ARG_REG }, ++ { atom_op_compare, ATOM_ARG_PS }, ++ { atom_op_compare, ATOM_ARG_WS }, ++ { atom_op_compare, ATOM_ARG_FB }, ++ { atom_op_compare, ATOM_ARG_PLL }, ++ { atom_op_compare, ATOM_ARG_MC }, ++ { atom_op_switch, 0 }, ++ { atom_op_jump, ATOM_COND_ALWAYS }, ++ { atom_op_jump, ATOM_COND_EQUAL }, ++ { atom_op_jump, ATOM_COND_BELOW }, ++ { atom_op_jump, ATOM_COND_ABOVE }, ++ { atom_op_jump, ATOM_COND_BELOWOREQUAL }, ++ { atom_op_jump, ATOM_COND_ABOVEOREQUAL }, ++ { atom_op_jump, ATOM_COND_NOTEQUAL }, ++ { atom_op_test, ATOM_ARG_REG }, ++ { atom_op_test, ATOM_ARG_PS }, ++ { atom_op_test, ATOM_ARG_WS }, ++ { atom_op_test, ATOM_ARG_FB }, ++ { atom_op_test, ATOM_ARG_PLL }, ++ { atom_op_test, ATOM_ARG_MC }, ++ { atom_op_delay, ATOM_UNIT_MILLISEC }, ++ { atom_op_delay, ATOM_UNIT_MICROSEC }, ++ { atom_op_calltable, 0 }, ++ { atom_op_repeat, 0 }, ++ { atom_op_clear, ATOM_ARG_REG }, ++ { atom_op_clear, ATOM_ARG_PS }, ++ { atom_op_clear, ATOM_ARG_WS }, ++ { atom_op_clear, ATOM_ARG_FB }, ++ { atom_op_clear, ATOM_ARG_PLL }, ++ { atom_op_clear, ATOM_ARG_MC }, ++ { atom_op_nop, 0 }, ++ { atom_op_eot, 0 }, ++ { atom_op_mask, ATOM_ARG_REG }, ++ { atom_op_mask, ATOM_ARG_PS }, ++ { atom_op_mask, ATOM_ARG_WS }, ++ { atom_op_mask, ATOM_ARG_FB }, ++ { atom_op_mask, ATOM_ARG_PLL }, ++ { atom_op_mask, ATOM_ARG_MC }, ++ { atom_op_postcard, 0 }, ++ { atom_op_beep, 0 }, ++ { atom_op_savereg, 0 }, ++ { atom_op_restorereg, 0 }, ++ { atom_op_setdatablock, 0 }, ++ { atom_op_xor, ATOM_ARG_REG }, ++ { atom_op_xor, ATOM_ARG_PS }, ++ { atom_op_xor, ATOM_ARG_WS }, ++ { atom_op_xor, ATOM_ARG_FB }, ++ { atom_op_xor, ATOM_ARG_PLL }, ++ { atom_op_xor, ATOM_ARG_MC }, ++ { atom_op_shl, ATOM_ARG_REG }, ++ { atom_op_shl, ATOM_ARG_PS }, ++ { atom_op_shl, ATOM_ARG_WS }, ++ { atom_op_shl, ATOM_ARG_FB }, ++ { atom_op_shl, ATOM_ARG_PLL }, ++ { atom_op_shl, ATOM_ARG_MC }, ++ { atom_op_shr, ATOM_ARG_REG }, ++ { atom_op_shr, ATOM_ARG_PS }, ++ { atom_op_shr, ATOM_ARG_WS }, ++ { atom_op_shr, ATOM_ARG_FB }, ++ { atom_op_shr, ATOM_ARG_PLL }, ++ { atom_op_shr, ATOM_ARG_MC }, ++ { atom_op_debug, 0 }, ++}; ++ ++void atom_execute_table(struct atom_context *ctx, int index, uint32_t *params) ++{ ++ int base = CU16(ctx->cmd_table+4+2*index); ++ int len, ws, ps, ptr; ++ unsigned char op; ++ atom_exec_context ectx; ++ ++ if(!base) ++ return; ++ ++ len = CU16(base+ATOM_CT_SIZE_PTR); ++ ws = CU8(base+ATOM_CT_WS_PTR); ++ ps = CU8(base+ATOM_CT_PS_PTR) & ATOM_CT_PS_MASK; ++ ptr = base+ATOM_CT_CODE_PTR; ++ ++ SDEBUG(">> execute %04X (len %d, WS %d, PS %d)\n", base, len, ws, ps); ++ ++ /* reset reg block */ ++ ctx->reg_block = 0; ++ ectx.ctx = ctx; ++ ectx.ps_shift = ps/4; ++ ectx.start = base; ++ ectx.ps = params; ++ if(ws) ++ ectx.ws = kzalloc(4*ws, GFP_KERNEL); ++ else ++ ectx.ws = NULL; ++ ++ debug_depth++; ++ while(1) { ++ op = CU8(ptr++); ++ if(op0) ++ opcode_table[op].func(&ectx, &ptr, opcode_table[op].arg); ++ else ++ break; ++ ++ if(op == ATOM_OP_EOT) ++ break; ++ } ++ debug_depth--; ++ SDEBUG("<<\n"); ++ ++ if(ws) ++ kfree(ectx.ws); ++} ++ ++static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; ++static void atom_index_iio(struct atom_context *ctx, int base) ++{ ++ ctx->iio = kzalloc(2*256, GFP_KERNEL); ++ while(CU8(base) == ATOM_IIO_START) { ++ ctx->iio[CU8(base+1)] = base+2; ++ base += 2; ++ while(CU8(base) != ATOM_IIO_END) ++ base += atom_iio_len[CU8(base)]; ++ base += 3; ++ } ++} ++ ++struct atom_context *atom_parse(struct card_info *card, void *bios) ++{ ++ int base; ++ struct atom_context *ctx = kzalloc(sizeof(struct atom_context), GFP_KERNEL); ++ char *str; ++ ++ ctx->card = card; ++ ctx->bios = bios; ++ ++ if(CU16(0) != ATOM_BIOS_MAGIC) { ++ printk(KERN_INFO "Invalid BIOS magic.\n"); ++ kfree(ctx); ++ return NULL; ++ } ++ if(strncmp(CSTR(ATOM_ATI_MAGIC_PTR), ATOM_ATI_MAGIC, strlen(ATOM_ATI_MAGIC))) { ++ printk(KERN_INFO "Invalid ATI magic.\n"); ++ kfree(ctx); ++ return NULL; ++ } ++ ++ base = CU16(ATOM_ROM_TABLE_PTR); ++ if(strncmp(CSTR(base+ATOM_ROM_MAGIC_PTR), ATOM_ROM_MAGIC, strlen(ATOM_ROM_MAGIC))) { ++ printk(KERN_INFO "Invalid ATOM magic.\n"); ++ kfree(ctx); ++ return NULL; ++ } ++ ++ ctx->cmd_table = CU16(base+ATOM_ROM_CMD_PTR); ++ ctx->data_table = CU16(base+ATOM_ROM_DATA_PTR); ++ atom_index_iio(ctx, CU16(ctx->data_table+ATOM_DATA_IIO_PTR)+4); ++ ++ str = CSTR(CU16(base+ATOM_ROM_MSG_PTR)); ++ while(*str && ((*str == '\n') || (*str == '\r'))) ++ str++; ++ printk(KERN_INFO "ATOM BIOS: %s", str); ++ ++ return ctx; ++} ++ ++int atom_asic_init(struct atom_context *ctx) ++{ ++ int hwi = CU16(ctx->data_table + ATOM_DATA_FWI_PTR); ++ uint32_t ps[16]; ++ memset(ps, 0, 64); ++ ++ ps[0] = cpu_to_le32(CU32(hwi + ATOM_FWI_DEFSCLK_PTR)); ++ ps[1] = cpu_to_le32(CU32(hwi + ATOM_FWI_DEFMCLK_PTR)); ++ if(!ps[0] || !ps[1]) ++ return 1; ++ ++ if(!CU16(ctx->cmd_table+4+2*ATOM_CMD_INIT)) ++ return 1; ++ atom_execute_table(ctx, ATOM_CMD_INIT, ps); ++ ++ return 0; ++} ++ ++void atom_destroy(struct atom_context *ctx) ++{ ++ if(ctx->iio) ++ kfree(ctx->iio); ++ kfree(ctx); ++} ++ ++ ++void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start) ++{ ++ int offset = index * 2 + 4; ++ int idx = CU16(ctx->data_table + offset); ++ ++ if (size) ++ *size = CU16(idx); ++ if (frev) ++ *frev = CU8(idx + 2); ++ if (crev) ++ *crev = CU8(idx + 3); ++ *data_start = idx; ++ return; ++} ++ ++void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev) ++{ ++ int offset = index * 2 + 4; ++ int idx = CU16(ctx->cmd_table + offset); ++ ++ if (frev) ++ *frev = CU8(idx + 2); ++ if (crev) ++ *crev = CU8(idx + 3); ++ return; ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/atom.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/atom.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom.h 2009-04-26 03:00:03.718729462 +0200 +@@ -0,0 +1,150 @@ ++/* ++ * Copyright 2008 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Author: Stanislaw Skowronek ++ */ ++ ++#ifndef ATOM_H ++#define ATOM_H ++ ++#include ++#include "drmP.h" ++ ++#define ATOM_BIOS_MAGIC 0xAA55 ++#define ATOM_ATI_MAGIC_PTR 0x30 ++#define ATOM_ATI_MAGIC " 761295520" ++#define ATOM_ROM_TABLE_PTR 0x48 ++ ++#define ATOM_ROM_MAGIC "ATOM" ++#define ATOM_ROM_MAGIC_PTR 4 ++ ++#define ATOM_ROM_MSG_PTR 0x10 ++#define ATOM_ROM_CMD_PTR 0x1E ++#define ATOM_ROM_DATA_PTR 0x20 ++ ++#define ATOM_CMD_INIT 0 ++#define ATOM_CMD_SETSCLK 0x0A ++#define ATOM_CMD_SETMCLK 0x0B ++#define ATOM_CMD_SETPCLK 0x0C ++ ++#define ATOM_DATA_FWI_PTR 0xC ++#define ATOM_DATA_IIO_PTR 0x32 ++ ++#define ATOM_FWI_DEFSCLK_PTR 8 ++#define ATOM_FWI_DEFMCLK_PTR 0xC ++#define ATOM_FWI_MAXSCLK_PTR 0x24 ++#define ATOM_FWI_MAXMCLK_PTR 0x28 ++ ++#define ATOM_CT_SIZE_PTR 0 ++#define ATOM_CT_WS_PTR 4 ++#define ATOM_CT_PS_PTR 5 ++#define ATOM_CT_PS_MASK 0x7F ++#define ATOM_CT_CODE_PTR 6 ++ ++#define ATOM_OP_CNT 123 ++#define ATOM_OP_EOT 91 ++ ++#define ATOM_CASE_MAGIC 0x63 ++#define ATOM_CASE_END 0x5A5A ++ ++#define ATOM_ARG_REG 0 ++#define ATOM_ARG_PS 1 ++#define ATOM_ARG_WS 2 ++#define ATOM_ARG_FB 3 ++#define ATOM_ARG_ID 4 ++#define ATOM_ARG_IMM 5 ++#define ATOM_ARG_PLL 6 ++#define ATOM_ARG_MC 7 ++ ++#define ATOM_SRC_DWORD 0 ++#define ATOM_SRC_WORD0 1 ++#define ATOM_SRC_WORD8 2 ++#define ATOM_SRC_WORD16 3 ++#define ATOM_SRC_BYTE0 4 ++#define ATOM_SRC_BYTE8 5 ++#define ATOM_SRC_BYTE16 6 ++#define ATOM_SRC_BYTE24 7 ++ ++#define ATOM_WS_QUOTIENT 0x40 ++#define ATOM_WS_REMAINDER 0x41 ++#define ATOM_WS_DATAPTR 0x42 ++#define ATOM_WS_SHIFT 0x43 ++#define ATOM_WS_OR_MASK 0x44 ++#define ATOM_WS_AND_MASK 0x45 ++#define ATOM_WS_FB_WINDOW 0x46 ++#define ATOM_WS_ATTRIBUTES 0x47 ++ ++#define ATOM_IIO_NOP 0 ++#define ATOM_IIO_START 1 ++#define ATOM_IIO_READ 2 ++#define ATOM_IIO_WRITE 3 ++#define ATOM_IIO_CLEAR 4 ++#define ATOM_IIO_SET 5 ++#define ATOM_IIO_MOVE_INDEX 6 ++#define ATOM_IIO_MOVE_ATTR 7 ++#define ATOM_IIO_MOVE_DATA 8 ++#define ATOM_IIO_END 9 ++ ++#define ATOM_IO_MM 0 ++#define ATOM_IO_PCI 1 ++#define ATOM_IO_SYSIO 2 ++#define ATOM_IO_IIO 0x80 ++ ++struct card_info { ++ struct drm_device *dev; ++ void (* reg_write)(struct card_info *, uint32_t, uint32_t); // filled by driver ++ uint32_t (* reg_read)(struct card_info *, uint32_t); // filled by driver ++ void (* mc_write)(struct card_info *, uint32_t, uint32_t); // filled by driver ++ uint32_t (* mc_read)(struct card_info *, uint32_t); // filled by driver ++ void (* pll_write)(struct card_info *, uint32_t, uint32_t); // filled by driver ++ uint32_t (* pll_read)(struct card_info *, uint32_t); // filled by driver ++// int (* read_rom)(struct card_info *, uint8_t *); // filled by driver ++}; ++ ++struct atom_context { ++ struct card_info *card; ++ void *bios; ++ uint32_t cmd_table, data_table; ++ uint16_t *iio; ++ ++ uint16_t data_block; ++ uint32_t fb_base; ++ uint32_t divmul[2]; ++ uint16_t io_attr; ++ uint16_t reg_block; ++ uint8_t shift; ++ int cs_equal, cs_above; ++ int io_mode; ++}; ++ ++extern int atom_debug; ++ ++struct atom_context *atom_parse(struct card_info *, void *); ++void atom_execute_table(struct atom_context *, int, uint32_t *); ++int atom_asic_init(struct atom_context *); ++void atom_destroy(struct atom_context *); ++void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); ++void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); ++#include "atom-types.h" ++#include "atombios.h" ++#include "ObjectID.h" ++ ++#endif +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/atom-names.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom-names.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/atom-names.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom-names.h 2009-04-26 03:00:11.950975372 +0200 +@@ -0,0 +1,100 @@ ++/* ++ * Copyright 2008 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Author: Stanislaw Skowronek ++ */ ++ ++#ifndef ATOM_NAMES_H ++#define ATOM_NAMES_H ++ ++#include "atom.h" ++ ++#ifdef ATOM_DEBUG ++ ++#define ATOM_OP_NAMES_CNT 123 ++static char *atom_op_names[ATOM_OP_NAMES_CNT]={ ++"RESERVED", "MOVE_REG", "MOVE_PS", "MOVE_WS", "MOVE_FB", "MOVE_PLL", ++"MOVE_MC", "AND_REG", "AND_PS", "AND_WS", "AND_FB", "AND_PLL", "AND_MC", ++"OR_REG", "OR_PS", "OR_WS", "OR_FB", "OR_PLL", "OR_MC", "SHIFT_LEFT_REG", ++"SHIFT_LEFT_PS", "SHIFT_LEFT_WS", "SHIFT_LEFT_FB", "SHIFT_LEFT_PLL", ++"SHIFT_LEFT_MC", "SHIFT_RIGHT_REG", "SHIFT_RIGHT_PS", "SHIFT_RIGHT_WS", ++"SHIFT_RIGHT_FB", "SHIFT_RIGHT_PLL", "SHIFT_RIGHT_MC", "MUL_REG", ++"MUL_PS", "MUL_WS", "MUL_FB", "MUL_PLL", "MUL_MC", "DIV_REG", "DIV_PS", ++"DIV_WS", "DIV_FB", "DIV_PLL", "DIV_MC", "ADD_REG", "ADD_PS", "ADD_WS", ++"ADD_FB", "ADD_PLL", "ADD_MC", "SUB_REG", "SUB_PS", "SUB_WS", "SUB_FB", ++"SUB_PLL", "SUB_MC", "SET_ATI_PORT", "SET_PCI_PORT", "SET_SYS_IO_PORT", ++"SET_REG_BLOCK", "SET_FB_BASE", "COMPARE_REG", "COMPARE_PS", ++"COMPARE_WS", "COMPARE_FB", "COMPARE_PLL", "COMPARE_MC", "SWITCH", ++"JUMP", "JUMP_EQUAL", "JUMP_BELOW", "JUMP_ABOVE", "JUMP_BELOW_OR_EQUAL", ++"JUMP_ABOVE_OR_EQUAL", "JUMP_NOT_EQUAL", "TEST_REG", "TEST_PS", "TEST_WS", ++"TEST_FB", "TEST_PLL", "TEST_MC", "DELAY_MILLISEC", "DELAY_MICROSEC", ++"CALL_TABLE", "REPEAT", "CLEAR_REG", "CLEAR_PS", "CLEAR_WS", "CLEAR_FB", ++"CLEAR_PLL", "CLEAR_MC", "NOP", "EOT", "MASK_REG", "MASK_PS", "MASK_WS", ++"MASK_FB", "MASK_PLL", "MASK_MC", "POST_CARD", "BEEP", "SAVE_REG", ++"RESTORE_REG", "SET_DATA_BLOCK", "XOR_REG", "XOR_PS", "XOR_WS", "XOR_FB", ++"XOR_PLL", "XOR_MC", "SHL_REG", "SHL_PS", "SHL_WS", "SHL_FB", "SHL_PLL", ++"SHL_MC", "SHR_REG", "SHR_PS", "SHR_WS", "SHR_FB", "SHR_PLL", "SHR_MC", ++"DEBUG", "CTB_DS", ++}; ++ ++#define ATOM_TABLE_NAMES_CNT 74 ++static char *atom_table_names[ATOM_TABLE_NAMES_CNT]={ ++"ASIC_Init", "GetDisplaySurfaceSize", "ASIC_RegistersInit", ++"VRAM_BlockVenderDetection", "SetClocksRatio", "MemoryControllerInit", ++"GPIO_PinInit", "MemoryParamAdjust", "DVOEncoderControl", ++"GPIOPinControl", "SetEngineClock", "SetMemoryClock", "SetPixelClock", ++"DynamicClockGating", "ResetMemoryDLL", "ResetMemoryDevice", ++"MemoryPLLInit", "EnableMemorySelfRefresh", "AdjustMemoryController", ++"EnableASIC_StaticPwrMgt", "ASIC_StaticPwrMgtStatusChange", ++"DAC_LoadDetection", "TMDS2EncoderControl", "LCD1OutputControl", ++"DAC1EncoderControl", "DAC2EncoderControl", "DVOOutputControl", ++"CV1OutputControl", "SetCRTC_DPM_State", "TVEncoderControl", ++"TMDS1EncoderControl", "LVDSEncoderControl", "TV1OutputControl", ++"EnableScaler", "BlankCRTC", "EnableCRTC", "GetPixelClock", ++"EnableVGA_Render", "EnableVGA_Access", "SetCRTC_Timing", ++"SetCRTC_OverScan", "SetCRTC_Replication", "SelectCRTC_Source", ++"EnableGraphSurfaces", "UpdateCRTC_DoubleBufferRegisters", ++"LUT_AutoFill", "EnableHW_IconCursor", "GetMemoryClock", ++"GetEngineClock", "SetCRTC_UsingDTDTiming", "TVBootUpStdPinDetection", ++"DFP2OutputControl", "VRAM_BlockDetectionByStrap", "MemoryCleanUp", ++"ReadEDIDFromHWAssistedI2C", "WriteOneByteToHWAssistedI2C", ++"ReadHWAssistedI2CStatus", "SpeedFanControl", "PowerConnectorDetection", ++"MC_Synchronization", "ComputeMemoryEnginePLL", "MemoryRefreshConversion", ++"VRAM_GetCurrentInfoBlock", "DynamicMemorySettings", "MemoryTraining", ++"EnableLVDS_SS", "DFP1OutputControl", "SetVoltage", "CRT1OutputControl", ++"CRT2OutputControl", "SetupHWAssistedI2CStatus", "ClockSource", ++"MemoryDeviceInit", "EnableYUV", ++}; ++ ++#define ATOM_IO_NAMES_CNT 5 ++static char *atom_io_names[ATOM_IO_NAMES_CNT]={ ++"MM", "PLL", "MC", "PCIE", "PCIE PORT", ++}; ++ ++#else ++ ++#define ATOM_OP_NAMES_CNT 0 ++#define ATOM_TABLE_NAMES_CNT 0 ++#define ATOM_IO_NAMES_CNT 0 ++ ++#endif ++ ++#endif +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/atom-types.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom-types.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/atom-types.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/atom-types.h 2009-04-26 03:00:15.818724822 +0200 +@@ -0,0 +1,42 @@ ++/* ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Author: Dave Airlie ++ */ ++ ++#ifndef ATOM_TYPES_H ++#define ATOM_TYPES_H ++ ++/* sync atom types to kernel types */ ++ ++typedef uint16_t USHORT; ++typedef uint32_t ULONG; ++typedef uint8_t UCHAR; ++ ++ ++#ifndef ATOM_BIG_ENDIAN ++#if defined(__BIG_ENDIAN) ++#define ATOM_BIG_ENDIAN 1 ++#else ++#define ATOM_BIG_ENDIAN 0 ++#endif ++#endif ++#endif +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/Makefile linux-2.6.29.1.patch/drivers/gpu/drm/radeon/Makefile +--- linux-2.6.29.1/drivers/gpu/drm/radeon/Makefile 2009-04-26 02:52:17.255729286 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/Makefile 2009-04-26 02:56:09.480975432 +0200 +@@ -3,7 +3,11 @@ + # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + + ccflags-y := -Iinclude/drm +-radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o r600_cp.o ++radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o r600_cp.o \ ++ radeon_gem.o radeon_buffer.o radeon_fence.o radeon_cs.o \ ++ radeon_i2c.o radeon_fb.o radeon_encoders.o radeon_connectors.o radeon_display.o \ ++ atombios_crtc.o atom.o radeon_atombios.o radeon_combios.o radeon_legacy_crtc.o \ ++ radeon_legacy_encoders.o radeon_cursor.o radeon_pm.o radeon_gem_debugfs.o + + radeon-$(CONFIG_COMPAT) += radeon_ioc32.o + +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/ObjectID.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/ObjectID.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/ObjectID.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/ObjectID.h 2009-04-26 03:00:20.051725369 +0200 +@@ -0,0 +1,518 @@ ++/* ++* Copyright 2006-2007 Advanced Micro Devices, Inc. ++* ++* Permission is hereby granted, free of charge, to any person obtaining a ++* copy of this software and associated documentation files (the "Software"), ++* to deal in the Software without restriction, including without limitation ++* the rights to use, copy, modify, merge, publish, distribute, sublicense, ++* and/or sell copies of the Software, and to permit persons to whom the ++* Software is furnished to do so, subject to the following conditions: ++* ++* The above copyright notice and this permission notice shall be included in ++* all copies or substantial portions of the Software. ++* ++* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++* OTHER DEALINGS IN THE SOFTWARE. ++*/ ++/* based on stg/asic_reg/drivers/inc/asic_reg/ObjectID.h ver 23 */ ++ ++#ifndef _OBJECTID_H ++#define _OBJECTID_H ++ ++#if defined(_X86_) ++#pragma pack(1) ++#endif ++ ++/****************************************************/ ++/* Graphics Object Type Definition */ ++/****************************************************/ ++#define GRAPH_OBJECT_TYPE_NONE 0x0 ++#define GRAPH_OBJECT_TYPE_GPU 0x1 ++#define GRAPH_OBJECT_TYPE_ENCODER 0x2 ++#define GRAPH_OBJECT_TYPE_CONNECTOR 0x3 ++#define GRAPH_OBJECT_TYPE_ROUTER 0x4 ++/* deleted */ ++ ++/****************************************************/ ++/* Encoder Object ID Definition */ ++/****************************************************/ ++#define ENCODER_OBJECT_ID_NONE 0x00 ++ ++/* Radeon Class Display Hardware */ ++#define ENCODER_OBJECT_ID_INTERNAL_LVDS 0x01 ++#define ENCODER_OBJECT_ID_INTERNAL_TMDS1 0x02 ++#define ENCODER_OBJECT_ID_INTERNAL_TMDS2 0x03 ++#define ENCODER_OBJECT_ID_INTERNAL_DAC1 0x04 ++#define ENCODER_OBJECT_ID_INTERNAL_DAC2 0x05 /* TV/CV DAC */ ++#define ENCODER_OBJECT_ID_INTERNAL_SDVOA 0x06 ++#define ENCODER_OBJECT_ID_INTERNAL_SDVOB 0x07 ++ ++/* External Third Party Encoders */ ++#define ENCODER_OBJECT_ID_SI170B 0x08 ++#define ENCODER_OBJECT_ID_CH7303 0x09 ++#define ENCODER_OBJECT_ID_CH7301 0x0A ++#define ENCODER_OBJECT_ID_INTERNAL_DVO1 0x0B /* This belongs to Radeon Class Display Hardware */ ++#define ENCODER_OBJECT_ID_EXTERNAL_SDVOA 0x0C ++#define ENCODER_OBJECT_ID_EXTERNAL_SDVOB 0x0D ++#define ENCODER_OBJECT_ID_TITFP513 0x0E ++#define ENCODER_OBJECT_ID_INTERNAL_LVTM1 0x0F /* not used for Radeon */ ++#define ENCODER_OBJECT_ID_VT1623 0x10 ++#define ENCODER_OBJECT_ID_HDMI_SI1930 0x11 ++#define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12 ++/* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */ ++#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13 ++#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14 ++#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 0x15 ++#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 0x16 /* Shared with CV/TV and CRT */ ++#define ENCODER_OBJECT_ID_SI178 0X17 /* External TMDS (dual link, no HDCP.) */ ++#define ENCODER_OBJECT_ID_MVPU_FPGA 0x18 /* MVPU FPGA chip */ ++#define ENCODER_OBJECT_ID_INTERNAL_DDI 0x19 ++#define ENCODER_OBJECT_ID_VT1625 0x1A ++#define ENCODER_OBJECT_ID_HDMI_SI1932 0x1B ++#define ENCODER_OBJECT_ID_DP_AN9801 0x1C ++#define ENCODER_OBJECT_ID_DP_DP501 0x1D ++#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY 0x1E ++#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA 0x1F ++#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 0x20 ++#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 0x21 ++ ++#define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO 0xFF ++ ++/****************************************************/ ++/* Connector Object ID Definition */ ++/****************************************************/ ++#define CONNECTOR_OBJECT_ID_NONE 0x00 ++#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I 0x01 ++#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I 0x02 ++#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D 0x03 ++#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D 0x04 ++#define CONNECTOR_OBJECT_ID_VGA 0x05 ++#define CONNECTOR_OBJECT_ID_COMPOSITE 0x06 ++#define CONNECTOR_OBJECT_ID_SVIDEO 0x07 ++#define CONNECTOR_OBJECT_ID_YPbPr 0x08 ++#define CONNECTOR_OBJECT_ID_D_CONNECTOR 0x09 ++#define CONNECTOR_OBJECT_ID_9PIN_DIN 0x0A /* Supports both CV & TV */ ++#define CONNECTOR_OBJECT_ID_SCART 0x0B ++#define CONNECTOR_OBJECT_ID_HDMI_TYPE_A 0x0C ++#define CONNECTOR_OBJECT_ID_HDMI_TYPE_B 0x0D ++#define CONNECTOR_OBJECT_ID_LVDS 0x0E ++#define CONNECTOR_OBJECT_ID_7PIN_DIN 0x0F ++#define CONNECTOR_OBJECT_ID_PCIE_CONNECTOR 0x10 ++#define CONNECTOR_OBJECT_ID_CROSSFIRE 0x11 ++#define CONNECTOR_OBJECT_ID_HARDCODE_DVI 0x12 ++#define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13 ++ ++/* deleted */ ++ ++/****************************************************/ ++/* Router Object ID Definition */ ++/****************************************************/ ++#define ROUTER_OBJECT_ID_NONE 0x00 ++#define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL 0x01 ++ ++/****************************************************/ ++// Graphics Object ENUM ID Definition */ ++/****************************************************/ ++#define GRAPH_OBJECT_ENUM_ID1 0x01 ++#define GRAPH_OBJECT_ENUM_ID2 0x02 ++#define GRAPH_OBJECT_ENUM_ID3 0x03 ++#define GRAPH_OBJECT_ENUM_ID4 0x04 ++#define GRAPH_OBJECT_ENUM_ID5 0x05 ++#define GRAPH_OBJECT_ENUM_ID6 0x06 ++ ++/****************************************************/ ++/* Graphics Object ID Bit definition */ ++/****************************************************/ ++#define OBJECT_ID_MASK 0x00FF ++#define ENUM_ID_MASK 0x0700 ++#define RESERVED1_ID_MASK 0x0800 ++#define OBJECT_TYPE_MASK 0x7000 ++#define RESERVED2_ID_MASK 0x8000 ++ ++#define OBJECT_ID_SHIFT 0x00 ++#define ENUM_ID_SHIFT 0x08 ++#define OBJECT_TYPE_SHIFT 0x0C ++ ++ ++/****************************************************/ ++/* Graphics Object family definition */ ++/****************************************************/ ++#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \ ++ GRAPHICS_OBJECT_ID << OBJECT_ID_SHIFT) ++/****************************************************/ ++/* GPU Object ID definition - Shared with BIOS */ ++/****************************************************/ ++#define GPU_ENUM_ID1 ( GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT) ++ ++/****************************************************/ ++/* Encoder Object ID definition - Shared with BIOS */ ++/****************************************************/ ++/* ++#define ENCODER_INTERNAL_LVDS_ENUM_ID1 0x2101 ++#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 0x2102 ++#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 0x2103 ++#define ENCODER_INTERNAL_DAC1_ENUM_ID1 0x2104 ++#define ENCODER_INTERNAL_DAC2_ENUM_ID1 0x2105 ++#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 0x2106 ++#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 0x2107 ++#define ENCODER_SIL170B_ENUM_ID1 0x2108 ++#define ENCODER_CH7303_ENUM_ID1 0x2109 ++#define ENCODER_CH7301_ENUM_ID1 0x210A ++#define ENCODER_INTERNAL_DVO1_ENUM_ID1 0x210B ++#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 0x210C ++#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 0x210D ++#define ENCODER_TITFP513_ENUM_ID1 0x210E ++#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 0x210F ++#define ENCODER_VT1623_ENUM_ID1 0x2110 ++#define ENCODER_HDMI_SI1930_ENUM_ID1 0x2111 ++#define ENCODER_HDMI_INTERNAL_ENUM_ID1 0x2112 ++#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 0x2113 ++#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 0x2114 ++#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 0x2115 ++#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 0x2116 ++#define ENCODER_SI178_ENUM_ID1 0x2117 ++#define ENCODER_MVPU_FPGA_ENUM_ID1 0x2118 ++#define ENCODER_INTERNAL_DDI_ENUM_ID1 0x2119 ++#define ENCODER_VT1625_ENUM_ID1 0x211A ++#define ENCODER_HDMI_SI1932_ENUM_ID1 0x211B ++#define ENCODER_ENCODER_DP_AN9801_ENUM_ID1 0x211C ++#define ENCODER_DP_DP501_ENUM_ID1 0x211D ++#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 0x211E ++*/ ++#define ENCODER_INTERNAL_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT) ++ ++#define ENCODER_SIL170B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT) ++ ++#define ENCODER_CH7303_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_CH7301_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) ++ ++#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) ++ ++ ++#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT) ++ ++ ++#define ENCODER_TITFP513_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_VT1623_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_HDMI_SI1930_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_HDMI_INTERNAL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) ++ ++ ++#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) ++ ++ ++#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) // Shared with CV/TV and CRT ++ ++#define ENCODER_SI178_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_MVPU_FPGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_DDI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT) ++ ++#define ENCODER_VT1625_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_HDMI_SI1932_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_DP_DP501_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_DP_AN9801_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) ++ ++#define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) ++ ++/****************************************************/ ++/* Connector Object ID definition - Shared with BIOS */ ++/****************************************************/ ++/* ++#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 0x3101 ++#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 0x3102 ++#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 0x3103 ++#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 0x3104 ++#define CONNECTOR_VGA_ENUM_ID1 0x3105 ++#define CONNECTOR_COMPOSITE_ENUM_ID1 0x3106 ++#define CONNECTOR_SVIDEO_ENUM_ID1 0x3107 ++#define CONNECTOR_YPbPr_ENUM_ID1 0x3108 ++#define CONNECTOR_D_CONNECTORE_ENUM_ID1 0x3109 ++#define CONNECTOR_9PIN_DIN_ENUM_ID1 0x310A ++#define CONNECTOR_SCART_ENUM_ID1 0x310B ++#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 0x310C ++#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 0x310D ++#define CONNECTOR_LVDS_ENUM_ID1 0x310E ++#define CONNECTOR_7PIN_DIN_ENUM_ID1 0x310F ++#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 0x3110 ++*/ ++#define CONNECTOR_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_VGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_VGA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_COMPOSITE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_SVIDEO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_YPbPr_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_D_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_9PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_SCART_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_CROSSFIRE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_CROSSFIRE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) ++ ++ ++#define CONNECTOR_HARDCODE_DVI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_HARDCODE_DVI_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_DISPLAYPORT_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_DISPLAYPORT_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_DISPLAYPORT_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) ++ ++#define CONNECTOR_DISPLAYPORT_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ ++ CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) ++ ++/****************************************************/ ++/* Router Object ID definition - Shared with BIOS */ ++/****************************************************/ ++#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\ ++ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ++ ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT) ++ ++/* deleted */ ++ ++/****************************************************/ ++/* Object Cap definition - Shared with BIOS */ ++/****************************************************/ ++#define GRAPHICS_OBJECT_CAP_I2C 0x00000001L ++#define GRAPHICS_OBJECT_CAP_TABLE_ID 0x00000002L ++ ++ ++#define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID 0x01 ++#define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID 0x02 ++#define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID 0x03 ++ ++#if defined(_X86_) ++#pragma pack() ++#endif ++ ++#endif /*GRAPHICTYPE */ ++ ++ ++ ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/r300_cmdbuf.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/r300_cmdbuf.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/r300_cmdbuf.c 2009-04-26 02:52:17.256740218 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/r300_cmdbuf.c 2009-04-26 02:56:18.139736963 +0200 +@@ -35,6 +35,7 @@ + #include "drm.h" + #include "radeon_drm.h" + #include "radeon_drv.h" ++#include "radeon_reg.h" + #include "r300_reg.h" + + #include +@@ -160,16 +161,15 @@ + + void r300_init_reg_flags(struct drm_device *dev) + { +- int i; ++ int i, j; + drm_radeon_private_t *dev_priv = dev->dev_private; + + memset(r300_reg_flags, 0, 0x10000 >> 2); +-#define ADD_RANGE_MARK(reg, count,mark) \ +- for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\ +- r300_reg_flags[i]|=(mark); ++#define ADD_RANGE_MARK(reg, count,mark) do { \ ++ for(i = ((reg) >> 2); i < ((reg) >> 2) + (count); i++) \ ++ r300_reg_flags[i] = (mark); \ ++ } while(0) + +-#define MARK_SAFE 1 +-#define MARK_CHECK_OFFSET 2 + + #define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE) + +@@ -211,7 +211,7 @@ + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) + ADD_RANGE(RV530_FG_ZBREG_DEST, 1); + +- ADD_RANGE(R300_SC_HYPERZ, 2); ++ ADD_RANGE(0x43A4, 2); + ADD_RANGE(0x43E8, 1); + + ADD_RANGE(0x46A4, 5); +@@ -230,12 +230,15 @@ + ADD_RANGE(0x4E50, 9); + ADD_RANGE(0x4E88, 1); + ADD_RANGE(0x4EA0, 2); +- ADD_RANGE(R300_ZB_CNTL, 3); +- ADD_RANGE(R300_ZB_FORMAT, 4); +- ADD_RANGE_MARK(R300_ZB_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */ +- ADD_RANGE(R300_ZB_DEPTHPITCH, 1); +- ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1); +- ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13); ++ ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3); ++ ADD_RANGE(R300_RB3D_ZSTENCIL_FORMAT, 4); ++ ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */ ++ ADD_RANGE(R300_RB3D_DEPTHPITCH, 1); ++ ADD_RANGE(0x4F28, 1); ++ ADD_RANGE(0x4F30, 2); ++ ADD_RANGE(0x4F44, 1); ++ ADD_RANGE(0x4F54, 1); ++ + ADD_RANGE(R300_ZB_ZPASS_DATA, 2); /* ZB_ZPASS_DATA, ZB_ZPASS_ADDR */ + + ADD_RANGE(R300_TX_FILTER_0, 16); +@@ -249,11 +252,21 @@ + ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); + + /* Sporadic registers used as primitives are emitted */ +- ADD_RANGE(R300_ZB_ZCACHE_CTLSTAT, 1); ++ ADD_RANGE(R300_RB3D_ZCACHE_CTLSTAT, 1); + ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1); + ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); + ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); + ++ ADD_RANGE(R500_SU_REG_DEST, 1); ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { ++ ADD_RANGE(R300_DST_PIPE_CONFIG, 1); ++ } ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) ++ ADD_RANGE_MARK(AVIVO_D1MODE_VLINE_START_END, 1, MARK_CHECK_WAIT_VLINE); ++ else ++ ADD_RANGE_MARK(RADEON_CRTC_GUI_TRIG_VLINE, 1, MARK_CHECK_WAIT_VLINE); ++ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { + ADD_RANGE(R500_VAP_INDEX_OFFSET, 1); + ADD_RANGE(R500_US_CONFIG, 2); +@@ -263,7 +276,9 @@ + ADD_RANGE(R500_RS_INST_0, 16); + ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2); + ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2); +- ADD_RANGE(R500_ZB_FIFO_SIZE, 2); ++// ADD_RANGE(R500_ZB_FIFO_SIZE 2); ++ ADD_RANGE(R500_GA_US_VECTOR_INDEX, 2); ++ + } else { + ADD_RANGE(R300_PFS_CNTL_0, 3); + ADD_RANGE(R300_PFS_NODE_0, 4); +@@ -274,11 +289,124 @@ + ADD_RANGE(R300_PFS_INSTR3_0, 64); + ADD_RANGE(R300_RS_INTERP_0, 8); + ADD_RANGE(R300_RS_ROUTE_0, 8); ++ } ++ ++ /* add 2d blit engine registers for DDX */ ++ ADD_RANGE(RADEON_SRC_Y_X, 3); /* 1434, 1438, 143c, ++ SRC_Y_X, DST_Y_X, DST_HEIGHT_WIDTH ++ */ ++ ADD_RANGE(RADEON_DP_GUI_MASTER_CNTL, 1); /* 146c */ ++ ADD_RANGE(RADEON_DP_BRUSH_BKGD_CLR, 2); /* 1478, 147c */ ++ ADD_RANGE(RADEON_DP_SRC_FRGD_CLR, 2); /* 15d8, 15dc */ ++ ADD_RANGE(RADEON_DP_CNTL, 1); /* 16c0 */ ++ ADD_RANGE(RADEON_DP_WRITE_MASK, 1); /* 16cc */ ++ ADD_RANGE(RADEON_DEFAULT_SC_BOTTOM_RIGHT, 1); /* 16e8 */ ++ ++ ADD_RANGE(RADEON_DSTCACHE_CTLSTAT, 1); ++ ADD_RANGE(RADEON_WAIT_UNTIL, 1); ++ ++ ADD_RANGE_MARK(RADEON_DST_OFFSET, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(RADEON_SRC_OFFSET, 1, MARK_CHECK_OFFSET); ++ ++ ADD_RANGE_MARK(RADEON_DST_PITCH_OFFSET, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(RADEON_SRC_PITCH_OFFSET, 1, MARK_CHECK_OFFSET); ++ ++ /* TODO SCISSOR */ ++ ADD_RANGE_MARK(R300_SC_SCISSOR0, 2, MARK_CHECK_SCISSOR); ++ ++ ADD_RANGE(R300_SC_CLIP_0_A, 2); ++ ADD_RANGE(R300_SC_CLIP_RULE, 1); ++ ADD_RANGE(R300_SC_SCREENDOOR, 1); ++ ++ ADD_RANGE(R300_VAP_PVS_CODE_CNTL_0, 4); ++ ADD_RANGE(R300_VAP_PVS_VECTOR_INDX_REG, 2); ++ ADD_RANGE(R300_VAP_PVS_UPLOAD_DATA, 1); ++ ++ if (dev_priv->chip_family <= CHIP_RV280) { + ++ for (j = 0; j < RADEON_MAX_STATE_PACKETS; j++) { ++ ADD_RANGE(radeon_packet[j].start, radeon_packet[j].len); ++ } ++ ++ ADD_RANGE(RADEON_SE_TCL_VECTOR_INDX_REG, 2); ++ ADD_RANGE(RADEON_SE_TCL_SCALAR_INDX_REG, 2); ++ ++ ADD_RANGE(RADEON_RE_TOP_LEFT, 1); ++ ADD_RANGE(RADEON_RE_WIDTH_HEIGHT, 1); ++ ADD_RANGE(RADEON_AUX_SC_CNTL, 1); ++ ADD_RANGE(RADEON_RB3D_DSTCACHE_CTLSTAT, 1); ++ ADD_RANGE(RADEON_RB3D_PLANEMASK, 1); ++ ADD_RANGE(RADEON_SE_CNTL, 1); ++ ADD_RANGE(RADEON_PP_CNTL, 1); ++ ADD_RANGE(RADEON_PP_MISC, 7); ++ ADD_RANGE(RADEON_RB3D_CNTL, 1); ++ ADD_RANGE_MARK(RADEON_RB3D_COLOROFFSET, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(RADEON_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE(RADEON_RB3D_COLORPITCH, 1); ++ ADD_RANGE(RADEON_RB3D_BLENDCNTL, 1); ++ ++ if (dev_priv->chip_family >= CHIP_R200) { ++ ADD_RANGE(R200_PP_CNTL_X, 1); ++ ADD_RANGE(R200_PP_TXMULTI_CTL_0, 1); ++ ADD_RANGE(R200_SE_VTX_STATE_CNTL, 1); ++ ADD_RANGE(R200_RE_CNTL, 1); ++ ADD_RANGE(R200_SE_VTE_CNTL, 1); ++ ADD_RANGE(R200_SE_VAP_CNTL, 1); ++ ++ ADD_RANGE(R200_PP_TXFILTER_0, 1); ++ ADD_RANGE(R200_PP_TXFORMAT_0, 1); ++ ADD_RANGE(R200_PP_TXFORMAT_X_0, 1); ++ ADD_RANGE(R200_PP_TXSIZE_0, 1); ++ ADD_RANGE(R200_PP_TXPITCH_0, 1); ++ ADD_RANGE(R200_PP_TFACTOR_0, 1); ++ ++ ADD_RANGE(R200_PP_TXFILTER_1, 1); ++ ADD_RANGE(R200_PP_TXFORMAT_1, 1); ++ ADD_RANGE(R200_PP_TXFORMAT_X_1, 1); ++ ADD_RANGE(R200_PP_TXSIZE_1, 1); ++ ADD_RANGE(R200_PP_TXPITCH_1, 1); ++ ADD_RANGE(R200_PP_TFACTOR_1, 1); ++ ++ ADD_RANGE_MARK(R200_PP_TXOFFSET_0, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(R200_PP_TXOFFSET_1, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(R200_PP_TXOFFSET_2, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(R200_PP_TXOFFSET_3, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(R200_PP_TXOFFSET_4, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(R200_PP_TXOFFSET_5, 1, MARK_CHECK_OFFSET); ++ ++ ADD_RANGE(R200_SE_VTX_FMT_0, 1); ++ ADD_RANGE(R200_SE_VTX_FMT_1, 1); ++ ADD_RANGE(R200_PP_TXCBLEND_0, 1); ++ ADD_RANGE(R200_PP_TXCBLEND2_0, 1); ++ ADD_RANGE(R200_PP_TXABLEND_0, 1); ++ ADD_RANGE(R200_PP_TXABLEND2_0, 1); ++ ++ } else { ++ ++ ADD_RANGE(RADEON_SE_COORD_FMT, 1); ++ ADD_RANGE(RADEON_SE_CNTL_STATUS, 1); ++ ++ ADD_RANGE(RADEON_PP_TXFILTER_0, 1); ++ ADD_RANGE(RADEON_PP_TXFORMAT_0, 1); ++ ADD_RANGE(RADEON_PP_TEX_SIZE_0, 1); ++ ADD_RANGE(RADEON_PP_TEX_PITCH_0, 1); ++ ++ ADD_RANGE(RADEON_PP_TXFILTER_1, 1); ++ ADD_RANGE(RADEON_PP_TXFORMAT_1, 1); ++ ADD_RANGE(RADEON_PP_TEX_SIZE_1, 1); ++ ADD_RANGE(RADEON_PP_TEX_PITCH_1, 1); ++ ++ ADD_RANGE(RADEON_PP_TXCBLEND_0, 1); ++ ADD_RANGE(RADEON_PP_TXABLEND_0, 1); ++ ADD_RANGE(RADEON_SE_VTX_FMT, 1); ++ ADD_RANGE_MARK(RADEON_PP_TXOFFSET_0, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(RADEON_PP_TXOFFSET_1, 1, MARK_CHECK_OFFSET); ++ ADD_RANGE_MARK(RADEON_PP_TXOFFSET_2, 1, MARK_CHECK_OFFSET); ++ } + } + } + +-static __inline__ int r300_check_range(unsigned reg, int count) ++int r300_check_range(unsigned reg, int count) + { + int i; + if (reg & ~0xffff) +@@ -289,6 +417,13 @@ + return 0; + } + ++int r300_get_reg_flags(unsigned reg) ++{ ++ if (reg & ~0xffff) ++ return -1; ++ return r300_reg_flags[(reg >> 2)]; ++} ++ + static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * + dev_priv, + drm_radeon_kcmd_buffer_t +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/r300_reg.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/r300_reg.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/r300_reg.h 2009-04-26 02:52:17.258724580 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/r300_reg.h 2009-04-26 02:56:23.997974685 +0200 +@@ -126,15 +126,6 @@ + /* END: Wild guesses */ + + #define R300_SE_VTE_CNTL 0x20b0 +-# define R300_VPORT_X_SCALE_ENA 0x00000001 +-# define R300_VPORT_X_OFFSET_ENA 0x00000002 +-# define R300_VPORT_Y_SCALE_ENA 0x00000004 +-# define R300_VPORT_Y_OFFSET_ENA 0x00000008 +-# define R300_VPORT_Z_SCALE_ENA 0x00000010 +-# define R300_VPORT_Z_OFFSET_ENA 0x00000020 +-# define R300_VTX_XY_FMT 0x00000100 +-# define R300_VTX_Z_FMT 0x00000200 +-# define R300_VTX_W0_FMT 0x00000400 + # define R300_VTX_W0_NORMALIZE 0x00000800 + # define R300_VTX_ST_DENORMALIZED 0x00001000 + +@@ -490,7 +481,7 @@ + # define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */ + # define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24 + +-#define R300_GB_SELECT 0x401C ++ + # define R300_GB_FOG_SELECT_C0A 0 + # define R300_GB_FOG_SELECT_C1A 1 + # define R300_GB_FOG_SELECT_C2A 2 +@@ -702,27 +693,6 @@ + # define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11) + /* END: Rasterization / Interpolators - many guesses */ + +-/* Hierarchical Z Enable */ +-#define R300_SC_HYPERZ 0x43a4 +-# define R300_SC_HYPERZ_DISABLE (0 << 0) +-# define R300_SC_HYPERZ_ENABLE (1 << 0) +-# define R300_SC_HYPERZ_MIN (0 << 1) +-# define R300_SC_HYPERZ_MAX (1 << 1) +-# define R300_SC_HYPERZ_ADJ_256 (0 << 2) +-# define R300_SC_HYPERZ_ADJ_128 (1 << 2) +-# define R300_SC_HYPERZ_ADJ_64 (2 << 2) +-# define R300_SC_HYPERZ_ADJ_32 (3 << 2) +-# define R300_SC_HYPERZ_ADJ_16 (4 << 2) +-# define R300_SC_HYPERZ_ADJ_8 (5 << 2) +-# define R300_SC_HYPERZ_ADJ_4 (6 << 2) +-# define R300_SC_HYPERZ_ADJ_2 (7 << 2) +-# define R300_SC_HYPERZ_HZ_Z0MIN_NO (0 << 5) +-# define R300_SC_HYPERZ_HZ_Z0MIN (1 << 5) +-# define R300_SC_HYPERZ_HZ_Z0MAX_NO (0 << 6) +-# define R300_SC_HYPERZ_HZ_Z0MAX (1 << 6) +- +-#define R300_SC_EDGERULE 0x43a8 +- + /* BEGIN: Scissors and cliprects */ + + /* There are four clipping rectangles. Their corner coordinates are inclusive. +@@ -952,7 +922,6 @@ + /* 32 bit chroma key */ + #define R300_TX_CHROMA_KEY_0 0x4580 + /* ff00ff00 == { 0, 1.0, 0, 1.0 } */ +-#define R300_TX_BORDER_COLOR_0 0x45C0 + + /* END: Texture specification */ + +@@ -1337,7 +1306,6 @@ + + /* gap */ + +-#define R300_RB3D_COLOROFFSET0 0x4E28 + # define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ + #define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */ + #define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */ +@@ -1349,7 +1317,6 @@ + * Bit 17: 4x2 tiles + * Bit 18: Extremely weird tile like, but some pixels duplicated? + */ +-#define R300_RB3D_COLORPITCH0 0x4E38 + # define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ + # define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ + # define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ +@@ -1362,7 +1329,7 @@ + #define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ + #define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ + +-#define R300_RB3D_AARESOLVE_CTL 0x4E88 ++//#define R300_RB3D_AARESOLVE_CTL 0x4E88 + /* gap */ + + /* Guess by Vladimir. +@@ -1377,14 +1344,19 @@ + * for this. + * Bit (1<<8) is the "test" bit. so plain write is 6 - vd + */ +-#define R300_ZB_CNTL 0x4F00 +-# define R300_STENCIL_ENABLE (1 << 0) +-# define R300_Z_ENABLE (1 << 1) +-# define R300_Z_WRITE_ENABLE (1 << 2) +-# define R300_Z_SIGNED_COMPARE (1 << 3) +-# define R300_STENCIL_FRONT_BACK (1 << 4) ++#define R300_RB3D_ZSTENCIL_CNTL_0 0x4F00 ++# define R300_RB3D_Z_DISABLED_1 0x00000010 ++# define R300_RB3D_Z_DISABLED_2 0x00000014 ++# define R300_RB3D_Z_TEST 0x00000012 ++# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016 ++# define R300_RB3D_Z_WRITE_ONLY 0x00000006 ++ ++# define R300_RB3D_Z_TEST 0x00000012 ++# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016 ++# define R300_RB3D_Z_WRITE_ONLY 0x00000006 ++# define R300_RB3D_STENCIL_ENABLE 0x00000001 + +-#define R300_ZB_ZSTENCILCNTL 0x4f04 ++#define R300_RB3D_ZSTENCIL_CNTL_1 0x4F04 + /* functions */ + # define R300_ZS_NEVER 0 + # define R300_ZS_LESS 1 +@@ -1404,166 +1376,52 @@ + # define R300_ZS_INVERT 5 + # define R300_ZS_INCR_WRAP 6 + # define R300_ZS_DECR_WRAP 7 +-# define R300_Z_FUNC_SHIFT 0 + /* front and back refer to operations done for front + and back faces, i.e. separate stencil function support */ +-# define R300_S_FRONT_FUNC_SHIFT 3 +-# define R300_S_FRONT_SFAIL_OP_SHIFT 6 +-# define R300_S_FRONT_ZPASS_OP_SHIFT 9 +-# define R300_S_FRONT_ZFAIL_OP_SHIFT 12 +-# define R300_S_BACK_FUNC_SHIFT 15 +-# define R300_S_BACK_SFAIL_OP_SHIFT 18 +-# define R300_S_BACK_ZPASS_OP_SHIFT 21 +-# define R300_S_BACK_ZFAIL_OP_SHIFT 24 +- +-#define R300_ZB_STENCILREFMASK 0x4f08 +-# define R300_STENCILREF_SHIFT 0 +-# define R300_STENCILREF_MASK 0x000000ff +-# define R300_STENCILMASK_SHIFT 8 +-# define R300_STENCILMASK_MASK 0x0000ff00 +-# define R300_STENCILWRITEMASK_SHIFT 16 +-# define R300_STENCILWRITEMASK_MASK 0x00ff0000 +- +-/* gap */ +- +-#define R300_ZB_FORMAT 0x4f10 +-# define R300_DEPTHFORMAT_16BIT_INT_Z (0 << 0) +-# define R300_DEPTHFORMAT_16BIT_13E3 (1 << 0) +-# define R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL (2 << 0) +-/* reserved up to (15 << 0) */ +-# define R300_INVERT_13E3_LEADING_ONES (0 << 4) +-# define R300_INVERT_13E3_LEADING_ZEROS (1 << 4) +- +-#define R300_ZB_ZTOP 0x4F14 +-# define R300_ZTOP_DISABLE (0 << 0) +-# define R300_ZTOP_ENABLE (1 << 0) +- +-/* gap */ +- +-#define R300_ZB_ZCACHE_CTLSTAT 0x4f18 +-# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT (0 << 0) +-# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0) +-# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT (0 << 1) +-# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE (1 << 1) +-# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 31) +-# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 31) +- +-#define R300_ZB_BW_CNTL 0x4f1c +-# define R300_HIZ_DISABLE (0 << 0) +-# define R300_HIZ_ENABLE (1 << 0) +-# define R300_HIZ_MIN (0 << 1) +-# define R300_HIZ_MAX (1 << 1) +-# define R300_FAST_FILL_DISABLE (0 << 2) +-# define R300_FAST_FILL_ENABLE (1 << 2) +-# define R300_RD_COMP_DISABLE (0 << 3) +-# define R300_RD_COMP_ENABLE (1 << 3) +-# define R300_WR_COMP_DISABLE (0 << 4) +-# define R300_WR_COMP_ENABLE (1 << 4) +-# define R300_ZB_CB_CLEAR_RMW (0 << 5) +-# define R300_ZB_CB_CLEAR_CACHE_LINEAR (1 << 5) +-# define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE (0 << 6) +-# define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE (1 << 6) +- +-# define R500_ZEQUAL_OPTIMIZE_ENABLE (0 << 7) +-# define R500_ZEQUAL_OPTIMIZE_DISABLE (1 << 7) +-# define R500_SEQUAL_OPTIMIZE_ENABLE (0 << 8) +-# define R500_SEQUAL_OPTIMIZE_DISABLE (1 << 8) +- +-# define R500_BMASK_ENABLE (0 << 10) +-# define R500_BMASK_DISABLE (1 << 10) +-# define R500_HIZ_EQUAL_REJECT_DISABLE (0 << 11) +-# define R500_HIZ_EQUAL_REJECT_ENABLE (1 << 11) +-# define R500_HIZ_FP_EXP_BITS_DISABLE (0 << 12) +-# define R500_HIZ_FP_EXP_BITS_1 (1 << 12) +-# define R500_HIZ_FP_EXP_BITS_2 (2 << 12) +-# define R500_HIZ_FP_EXP_BITS_3 (3 << 12) +-# define R500_HIZ_FP_EXP_BITS_4 (4 << 12) +-# define R500_HIZ_FP_EXP_BITS_5 (5 << 12) +-# define R500_HIZ_FP_INVERT_LEADING_ONES (0 << 15) +-# define R500_HIZ_FP_INVERT_LEADING_ZEROS (1 << 15) +-# define R500_TILE_OVERWRITE_RECOMPRESSION_ENABLE (0 << 16) +-# define R500_TILE_OVERWRITE_RECOMPRESSION_DISABLE (1 << 16) +-# define R500_CONTIGUOUS_6XAA_SAMPLES_ENABLE (0 << 17) +-# define R500_CONTIGUOUS_6XAA_SAMPLES_DISABLE (1 << 17) +-# define R500_PEQ_PACKING_DISABLE (0 << 18) +-# define R500_PEQ_PACKING_ENABLE (1 << 18) +-# define R500_COVERED_PTR_MASKING_DISABLE (0 << 18) +-# define R500_COVERED_PTR_MASKING_ENABLE (1 << 18) +- +- +-/* gap */ +- +-/* Z Buffer Address Offset. +- * Bits 31 to 5 are used for aligned Z buffer address offset for macro tiles. +- */ +-#define R300_ZB_DEPTHOFFSET 0x4f20 +- +-/* Z Buffer Pitch and Endian Control */ +-#define R300_ZB_DEPTHPITCH 0x4f24 +-# define R300_DEPTHPITCH_MASK 0x00003FFC +-# define R300_DEPTHMACROTILE_DISABLE (0 << 16) +-# define R300_DEPTHMACROTILE_ENABLE (1 << 16) +-# define R300_DEPTHMICROTILE_LINEAR (0 << 17) +-# define R300_DEPTHMICROTILE_TILED (1 << 17) +-# define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17) +-# define R300_DEPTHENDIAN_NO_SWAP (0 << 18) +-# define R300_DEPTHENDIAN_WORD_SWAP (1 << 18) +-# define R300_DEPTHENDIAN_DWORD_SWAP (2 << 18) +-# define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18) +- +-/* Z Buffer Clear Value */ +-#define R300_ZB_DEPTHCLEARVALUE 0x4f28 +- +-#define R300_ZB_ZMASK_OFFSET 0x4f30 +-#define R300_ZB_ZMASK_PITCH 0x4f34 +-#define R300_ZB_ZMASK_WRINDEX 0x4f38 +-#define R300_ZB_ZMASK_DWORD 0x4f3c +-#define R300_ZB_ZMASK_RDINDEX 0x4f40 +- +-/* Hierarchical Z Memory Offset */ +-#define R300_ZB_HIZ_OFFSET 0x4f44 +- +-/* Hierarchical Z Write Index */ +-#define R300_ZB_HIZ_WRINDEX 0x4f48 +- +-/* Hierarchical Z Data */ +-#define R300_ZB_HIZ_DWORD 0x4f4c +- +-/* Hierarchical Z Read Index */ +-#define R300_ZB_HIZ_RDINDEX 0x4f50 +- +-/* Hierarchical Z Pitch */ +-#define R300_ZB_HIZ_PITCH 0x4f54 +- +-/* Z Buffer Z Pass Counter Data */ +-#define R300_ZB_ZPASS_DATA 0x4f58 +- +-/* Z Buffer Z Pass Counter Address */ +-#define R300_ZB_ZPASS_ADDR 0x4f5c +- +-/* Depth buffer X and Y coordinate offset */ +-#define R300_ZB_DEPTHXY_OFFSET 0x4f60 +-# define R300_DEPTHX_OFFSET_SHIFT 1 +-# define R300_DEPTHX_OFFSET_MASK 0x000007FE +-# define R300_DEPTHY_OFFSET_SHIFT 17 +-# define R300_DEPTHY_OFFSET_MASK 0x07FE0000 +- +-/* Sets the fifo sizes */ +-#define R500_ZB_FIFO_SIZE 0x4fd0 +-# define R500_OP_FIFO_SIZE_FULL (0 << 0) +-# define R500_OP_FIFO_SIZE_HALF (1 << 0) +-# define R500_OP_FIFO_SIZE_QUATER (2 << 0) +-# define R500_OP_FIFO_SIZE_EIGTHS (4 << 0) +- +-/* Stencil Reference Value and Mask for backfacing quads */ +-/* R300_ZB_STENCILREFMASK handles front face */ +-#define R500_ZB_STENCILREFMASK_BF 0x4fd4 +-# define R500_STENCILREF_SHIFT 0 +-# define R500_STENCILREF_MASK 0x000000ff +-# define R500_STENCILMASK_SHIFT 8 +-# define R500_STENCILMASK_MASK 0x0000ff00 +-# define R500_STENCILWRITEMASK_SHIFT 16 +-# define R500_STENCILWRITEMASK_MASK 0x00ff0000 ++# define R300_RB3D_ZS1_DEPTH_FUNC_SHIFT 0 ++# define R300_RB3D_ZS1_FRONT_FUNC_SHIFT 3 ++# define R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT 6 ++# define R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT 9 ++# define R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT 12 ++# define R300_RB3D_ZS1_BACK_FUNC_SHIFT 15 ++# define R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT 18 ++# define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT 21 ++# define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT 24 ++ ++#define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08 ++# define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0 ++# define R300_RB3D_ZS2_STENCIL_MASK 0xFF ++# define R300_RB3D_ZS2_STENCIL_MASK_SHIFT 8 ++# define R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT 16 ++ ++/* gap */ ++ ++#define R300_RB3D_ZSTENCIL_FORMAT 0x4F10 ++# define R300_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) ++# define R300_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) ++ /* 16 bit format or some aditional bit ? */ ++# define R300_DEPTH_FORMAT_UNK32 (32 << 0) ++ ++#define R300_RB3D_EARLY_Z 0x4F14 ++# define R300_EARLY_Z_DISABLE (0 << 0) ++# define R300_EARLY_Z_ENABLE (1 << 0) ++ ++/* gap */ ++ ++//#define R300_RB3D_ZCACHE_CTLSTAT 0x4F18 /* GUESS */ ++# define R300_RB3D_ZCACHE_UNKNOWN_01 0x1 ++# define R300_RB3D_ZCACHE_UNKNOWN_03 0x3 ++ ++/* gap */ ++ ++#define R300_RB3D_DEPTHOFFSET 0x4F20 ++#define R300_RB3D_DEPTHPITCH 0x4F24 ++# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */ ++# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */ ++# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */ ++# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ ++# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ ++# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ + + /* BEGIN: Vertex program instruction set */ + +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/r600_cp.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/r600_cp.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/r600_cp.c 2009-04-26 02:52:17.262724871 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/r600_cp.c 2009-04-26 02:56:32.223975038 +0200 +@@ -1720,7 +1720,7 @@ + radeon_write_agp_location(dev_priv, + (((dev_priv->gart_vm_start - 1 + + dev_priv->gart_size) & 0xffff0000) | +- (dev_priv->gart_vm_start >> 16))); ++ (dev_priv->gart_vm_start >> 16)), 0); + + ring_start = (dev_priv->cp_ring->offset + - dev->agp->base +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_atombios.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_atombios.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_atombios.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_atombios.c 2009-04-26 03:00:26.370975444 +0200 +@@ -0,0 +1,1050 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++#include "atom.h" ++#include "atom-bits.h" ++ ++/* from radeon_encoder.c */ ++extern uint32_t ++radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac); ++extern void ++radeon_link_encoder_connector(struct drm_device *dev); ++extern void ++radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device); ++ ++extern int radeon_ddc_dump(struct drm_connector *connector); ++ ++/* from radeon_connector.c */ ++extern void ++radeon_add_atom_connector(struct drm_device *dev, ++ uint32_t connector_id, ++ uint32_t supported_device, ++ int connector_type, ++ struct radeon_i2c_bus_rec *i2c_bus, ++ bool linkb, ++ uint32_t igp_lane_info); ++ ++/* from radeon_legacy_encoder.c */ ++extern void ++radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device); ++ ++union atom_supported_devices { ++ struct _ATOM_SUPPORTED_DEVICES_INFO info; ++ struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2; ++ struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; ++}; ++ ++static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *dev, uint8_t id) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct atom_context *ctx = dev_priv->mode_info.atom_context; ++ ATOM_GPIO_I2C_ASSIGMENT gpio; ++ struct radeon_i2c_bus_rec i2c; ++ int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); ++ struct _ATOM_GPIO_I2C_INFO *i2c_info; ++ uint16_t data_offset; ++ ++ memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); ++ i2c.valid = false; ++ ++ atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); ++ ++ i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); ++ ++ gpio = i2c_info->asGPIO_Info[id]; ++ ++ i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4; ++ i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4; ++ i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4; ++ i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4; ++ i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4; ++ i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4; ++ i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4; ++ i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4; ++ i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift); ++ i2c.mask_data_mask = (1 << gpio.ucDataMaskShift); ++ i2c.put_clk_mask = (1 << gpio.ucClkEnShift); ++ i2c.put_data_mask = (1 << gpio.ucDataEnShift); ++ i2c.get_clk_mask = (1 << gpio.ucClkY_Shift); ++ i2c.get_data_mask = (1 << gpio.ucDataY_Shift); ++ i2c.a_clk_mask = (1 << gpio.ucClkA_Shift); ++ i2c.a_data_mask = (1 << gpio.ucDataA_Shift); ++ i2c.valid = true; ++ ++ return i2c; ++} ++ ++static bool radeon_atom_apply_quirks(struct drm_device *dev, ++ uint32_t supported_device, ++ int *connector_type, ++ struct radeon_i2c_bus_rec *i2c_bus) ++{ ++ ++ /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ ++ if ((dev->pdev->device == 0x791e) && ++ (dev->pdev->subsystem_vendor == 0x1043) && ++ (dev->pdev->subsystem_device == 0x826d)) { ++ if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) && ++ (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) ++ *connector_type = DRM_MODE_CONNECTOR_DVID; ++ } ++ ++ /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ ++ if ((dev->pdev->device == 0x7941) && ++ (dev->pdev->subsystem_vendor == 0x147b) && ++ (dev->pdev->subsystem_device == 0x2412)) { ++ if (*connector_type == DRM_MODE_CONNECTOR_DVII) ++ return false; ++ } ++ ++ /* Falcon NW laptop lists vga ddc line for LVDS */ ++ if ((dev->pdev->device == 0x5653) && ++ (dev->pdev->subsystem_vendor == 0x1462) && ++ (dev->pdev->subsystem_device == 0x0291)) { ++ if (*connector_type == DRM_MODE_CONNECTOR_LVDS) ++ i2c_bus->valid = false; ++ } ++ ++ /* Funky macbooks */ ++ if ((dev->pdev->device == 0x71C5) && ++ (dev->pdev->subsystem_vendor == 0x106b) && ++ (dev->pdev->subsystem_device == 0x0080)) { ++ if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) || ++ (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) ++ return false; ++ } ++ ++ /* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */ ++ if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) || ++ (*connector_type == DRM_MODE_CONNECTOR_HDMIB)) { ++ if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) ++ return false; ++ } ++ ++ /* ASUS HD 3600 XT board lists the DVI port as HDMI */ ++ if ((dev->pdev->device == 0x9598) && ++ (dev->pdev->subsystem_vendor == 0x1043) && ++ (dev->pdev->subsystem_device == 0x01da)) { ++ if (*connector_type == DRM_MODE_CONNECTOR_HDMIB) ++ *connector_type = DRM_MODE_CONNECTOR_DVID; ++ } ++ ++ return true; ++} ++ ++const int supported_devices_connector_convert[] = ++{ ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_VGA, ++ DRM_MODE_CONNECTOR_DVII, ++ DRM_MODE_CONNECTOR_DVID, ++ DRM_MODE_CONNECTOR_DVIA, ++ DRM_MODE_CONNECTOR_SVIDEO, ++ DRM_MODE_CONNECTOR_Composite, ++ DRM_MODE_CONNECTOR_LVDS, ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_HDMIA, ++ DRM_MODE_CONNECTOR_HDMIB, ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_9PinDIN, ++ DRM_MODE_CONNECTOR_DisplayPort ++}; ++ ++const int object_connector_convert[] = ++{ ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_DVII, ++ DRM_MODE_CONNECTOR_DVII, ++ DRM_MODE_CONNECTOR_DVID, ++ DRM_MODE_CONNECTOR_DVID, ++ DRM_MODE_CONNECTOR_VGA, ++ DRM_MODE_CONNECTOR_Composite, ++ DRM_MODE_CONNECTOR_SVIDEO, ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_9PinDIN, ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_HDMIA, ++ DRM_MODE_CONNECTOR_HDMIB, ++ DRM_MODE_CONNECTOR_HDMIB, ++ DRM_MODE_CONNECTOR_LVDS, ++ DRM_MODE_CONNECTOR_9PinDIN, ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_DisplayPort ++}; ++ ++bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct atom_context *ctx = mode_info->atom_context; ++ int index = GetIndexIntoMasterTable(DATA, Object_Header); ++ uint16_t size, data_offset; ++ uint8_t frev, crev, line_mux = 0; ++ ATOM_CONNECTOR_OBJECT_TABLE *con_obj; ++ ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; ++ ATOM_OBJECT_HEADER *obj_header; ++ int i, j, path_size, device_support; ++ int connector_type; ++ uint16_t igp_lane_info; ++ bool linkb; ++ struct drm_connector *connector; ++ struct radeon_i2c_bus_rec ddc_bus; ++ ++ atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); ++ ++ if (data_offset == 0) ++ return false; ++ ++ if (crev < 2) ++ return false; ++ ++ obj_header = (ATOM_OBJECT_HEADER *)(ctx->bios + data_offset); ++ path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) ++ (ctx->bios + data_offset + le16_to_cpu(obj_header->usDisplayPathTableOffset)); ++ con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *) ++ (ctx->bios + data_offset + le16_to_cpu(obj_header->usConnectorObjectTableOffset)); ++ device_support = le16_to_cpu(obj_header->usDeviceSupport); ++ ++ path_size = 0; ++ for (i = 0; i < path_obj->ucNumOfDispPath; i++) { ++ uint8_t *addr = (uint8_t *)path_obj->asDispPath; ++ ATOM_DISPLAY_OBJECT_PATH *path; ++ addr += path_size; ++ path = (ATOM_DISPLAY_OBJECT_PATH *)addr; ++ path_size += path->usSize; ++ linkb = false; ++ ++ if (device_support & path->usDeviceTag) { ++ uint8_t con_obj_id, con_obj_num, con_obj_type; ++ ++ con_obj_id = (path->usConnObjectId & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; ++ con_obj_num = (path->usConnObjectId & ENUM_ID_MASK) >> ENUM_ID_SHIFT; ++ con_obj_type = (path->usConnObjectId & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; ++ ++ if ((path->usDeviceTag == ATOM_DEVICE_TV1_SUPPORT) || ++ (path->usDeviceTag == ATOM_DEVICE_TV2_SUPPORT) || ++ (path->usDeviceTag == ATOM_DEVICE_CV_SUPPORT)) ++ continue; ++ ++ if ((dev_priv->chip_family == CHIP_RS780) && ++ (con_obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { ++ uint16_t igp_offset = 0; ++ ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj; ++ ++ index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); ++ ++ atom_parse_data_header(ctx, index, &size, &frev, &crev, &igp_offset); ++ ++ if (crev >= 2) { ++ igp_obj = (ATOM_INTEGRATED_SYSTEM_INFO_V2 *)(ctx->bios + igp_offset); ++ ++ if (igp_obj) { ++ uint32_t slot_config, ct; ++ ++ if (con_obj_num == 1) ++ slot_config = igp_obj->ulDDISlot1Config; ++ else ++ slot_config = igp_obj->ulDDISlot2Config; ++ ++ ct = (slot_config >> 16) & 0xff; ++ connector_type = object_connector_convert[ct]; ++ igp_lane_info = slot_config & 0xffff; ++ } else ++ continue; ++ } else ++ continue; ++ } else { ++ igp_lane_info = 0; ++ connector_type = object_connector_convert[con_obj_id]; ++ } ++ ++ if (connector_type == DRM_MODE_CONNECTOR_Unknown) ++ continue; ++ ++ for (j = 0; j < ((path->usSize - 8) / 2); j++) { ++ uint8_t enc_obj_id, enc_obj_num, enc_obj_type; ++ ++ enc_obj_id = (path->usGraphicObjIds[j] & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; ++ enc_obj_num = (path->usGraphicObjIds[j] & ENUM_ID_MASK) >> ENUM_ID_SHIFT; ++ enc_obj_type = (path->usGraphicObjIds[j] & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; ++ ++ /* FIXME: add support for router objects */ ++ if (enc_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { ++ if (enc_obj_num == 2) ++ linkb = true; ++ else ++ linkb = false; ++ ++ radeon_add_atom_encoder(dev, ++ enc_obj_id, ++ path->usDeviceTag); ++ ++ } ++ } ++ ++ /* look up gpio for ddc */ ++ if ((path->usDeviceTag & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) { ++ for (j = 0; j < con_obj->ucNumberOfObjects; j++) { ++ if (path->usConnObjectId == le16_to_cpu(con_obj->asObjects[j].usObjectID)) { ++ ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *) ++ (ctx->bios + data_offset + le16_to_cpu(con_obj->asObjects[j].usRecordOffset)); ++ ATOM_I2C_RECORD *i2c_record; ++ ++ while (record->ucRecordType > 0 && ++ record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { ++ DRM_ERROR("record type %d\n", record->ucRecordType); ++ switch (record->ucRecordType) { ++ case ATOM_I2C_RECORD_TYPE: ++ i2c_record = (ATOM_I2C_RECORD *)record; ++ line_mux = i2c_record->sucI2cId.bfI2C_LineMux; ++ break; ++ } ++ record = (ATOM_COMMON_RECORD_HEADER *)((char *)record + record->ucRecordSize); ++ } ++ break; ++ } ++ } ++ } else ++ line_mux = 0; ++ ++ if ((path->usDeviceTag == ATOM_DEVICE_TV1_SUPPORT) || ++ (path->usDeviceTag == ATOM_DEVICE_TV2_SUPPORT) || ++ (path->usDeviceTag == ATOM_DEVICE_CV_SUPPORT)) ++ ddc_bus.valid = false; ++ else ++ ddc_bus = radeon_lookup_gpio(dev, line_mux); ++ ++ radeon_add_atom_connector(dev, ++ path->usConnObjectId, ++ path->usDeviceTag, ++ connector_type, ++ &ddc_bus, ++ linkb, ++ igp_lane_info); ++ ++ ++ } ++ } ++ ++ radeon_link_encoder_connector(dev); ++ ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) ++ radeon_ddc_dump(connector); ++ ++ return true; ++} ++ ++bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct atom_context *ctx = mode_info->atom_context; ++ int index = GetIndexIntoMasterTable(DATA, SupportedDevicesInfo); ++ uint16_t size, data_offset; ++ uint8_t frev, crev; ++ uint16_t device_support; ++ uint8_t line_mux, dac; ++ int connector_type; ++ struct drm_connector *connector; ++ union atom_supported_devices *supported_devices; ++ struct radeon_i2c_bus_rec ddc_bus; ++ int i; ++ ++ atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); ++ ++ supported_devices = (union atom_supported_devices *)(ctx->bios + data_offset); ++ ++ device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); ++ ++ for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { ++ ++ ATOM_CONNECTOR_INFO_I2C ci = supported_devices->info.asConnInfo[i]; ++ ++ if (!(device_support & (1 << i))) { ++ continue; ++ } ++ ++ if (i == ATOM_DEVICE_CV_INDEX) { ++ DRM_DEBUG("Skipping Component Video\n"); ++ continue; ++ } ++ ++ if (i == ATOM_DEVICE_TV1_INDEX) { ++ DRM_DEBUG("Skipping TV Out\n"); ++ continue; ++ } ++ ++ connector_type = supported_devices_connector_convert[ci.sucConnectorInfo.sbfAccess.bfConnectorType]; ++ ++ if (connector_type == DRM_MODE_CONNECTOR_Unknown) ++ continue; ++ ++ dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC; ++ ++ if ((dev_priv->chip_family == CHIP_RS690) || ++ (dev_priv->chip_family == CHIP_RS740)) { ++ if ((i == ATOM_DEVICE_DFP2_INDEX) || (i == ATOM_DEVICE_DFP3_INDEX)) ++ line_mux = ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1; ++ else ++ line_mux = ci.sucI2cId.sbfAccess.bfI2C_LineMux; ++ } else ++ line_mux = ci.sucI2cId.sbfAccess.bfI2C_LineMux; ++ ++ /* give tv unique connector ids */ ++ if (i == ATOM_DEVICE_TV1_INDEX) { ++ ddc_bus.valid = false; ++ line_mux = 50; ++ } else if (i == ATOM_DEVICE_TV2_INDEX) { ++ ddc_bus.valid = false; ++ line_mux = 51; ++ } else if (i == ATOM_DEVICE_CV_INDEX) { ++ ddc_bus.valid = false; ++ line_mux = 52; ++ } else ++ ddc_bus = radeon_lookup_gpio(dev, line_mux); ++ ++ if (!radeon_atom_apply_quirks(dev, (1 << i), &connector_type, &ddc_bus)) ++ continue; ++ ++ radeon_add_atom_connector(dev, ++ line_mux, ++ (1 << i), ++ connector_type, ++ &ddc_bus, ++ false, ++ 0); ++ ++ if (radeon_is_avivo(dev_priv) || radeon_r4xx_atom) ++ radeon_add_atom_encoder(dev, ++ radeon_get_encoder_id(dev, (1 << i), dac), ++ (1 << i)); ++ else ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, (1 << i), dac), ++ (1 << i)); ++ } ++ ++ radeon_link_encoder_connector(dev); ++ ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) ++ radeon_ddc_dump(connector); ++ ++ return true; ++} ++ ++union firmware_info { ++ ATOM_FIRMWARE_INFO info; ++ ATOM_FIRMWARE_INFO_V1_2 info_12; ++ ATOM_FIRMWARE_INFO_V1_3 info_13; ++ ATOM_FIRMWARE_INFO_V1_4 info_14; ++}; ++ ++bool radeon_atom_get_clock_info(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); ++ union firmware_info *firmware_info; ++ uint8_t frev, crev; ++ struct radeon_pll *p1pll = &mode_info->p1pll; ++ struct radeon_pll *p2pll = &mode_info->p2pll; ++ struct radeon_pll *spll = &mode_info->spll; ++ struct radeon_pll *mpll = &mode_info->mpll; ++ uint16_t data_offset; ++ ++ atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); ++ ++ firmware_info = (union firmware_info *)(mode_info->atom_context->bios + data_offset); ++ ++ if (firmware_info) { ++ /* pixel clocks */ ++ p1pll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock); ++ p1pll->reference_div = 0; ++ ++ p1pll->pll_out_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); ++ p1pll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); ++ ++ if (p1pll->pll_out_min == 0) { ++ if (radeon_is_avivo(dev_priv)) ++ p1pll->pll_out_min = 64800; ++ else ++ p1pll->pll_out_min = 20000; ++ } ++ ++ p1pll->pll_in_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input); ++ p1pll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input); ++ ++ *p2pll = *p1pll; ++ ++ /* system clock */ ++ spll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock); ++ spll->reference_div = 0; ++ ++ spll->pll_out_min = le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Output); ++ spll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxEngineClockPLL_Output); ++ ++ /* ??? */ ++ if (spll->pll_out_min == 0) { ++ if (radeon_is_avivo(dev_priv)) ++ spll->pll_out_min = 64800; ++ else ++ spll->pll_out_min = 20000; ++ } ++ ++ spll->pll_in_min = le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Input); ++ spll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input); ++ ++ ++ /* memory clock */ ++ mpll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock); ++ mpll->reference_div = 0; ++ ++ mpll->pll_out_min = le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Output); ++ mpll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxMemoryClockPLL_Output); ++ ++ /* ??? */ ++ if (mpll->pll_out_min == 0) { ++ if (radeon_is_avivo(dev_priv)) ++ mpll->pll_out_min = 64800; ++ else ++ mpll->pll_out_min = 20000; ++ } ++ ++ mpll->pll_in_min = le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Input); ++ mpll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxMemoryClockPLL_Input); ++ ++ mode_info->sclk = le32_to_cpu(firmware_info->info.ulDefaultEngineClock); ++ mode_info->mclk = le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); ++ ++ return true; ++ } ++ return false; ++} ++ ++struct radeon_encoder_int_tmds * ++radeon_atombios_get_tmds_info(struct radeon_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ int index = GetIndexIntoMasterTable(DATA, TMDS_Info); ++ uint16_t data_offset; ++ struct _ATOM_TMDS_INFO *tmds_info; ++ uint8_t frev, crev; ++ uint16_t maxfreq; ++ int i; ++ struct radeon_encoder_int_tmds *tmds = NULL; ++ ++ atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); ++ ++ tmds_info = (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + data_offset); ++ ++ if (tmds_info) { ++ tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL); ++ ++ if (!tmds) ++ return NULL; ++ ++ maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); ++ for (i = 0; i < 4; i++) { ++ tmds->tmds_pll[i].freq = le16_to_cpu(tmds_info->asMiscInfo[i].usFrequency); ++ tmds->tmds_pll[i].value = tmds_info->asMiscInfo[i].ucPLL_ChargePump & 0x3f; ++ tmds->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VCO_Gain & 0x3f) << 6; ++ tmds->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_DutyCycle & 0xf) << 12; ++ tmds->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VoltageSwing & 0xf) << 16; ++ ++ DRM_DEBUG("TMDS PLL From ATOMBIOS %u %x\n", ++ tmds->tmds_pll[i].freq, ++ tmds->tmds_pll[i].value); ++ ++ if (maxfreq == tmds->tmds_pll[i].freq) { ++ tmds->tmds_pll[i].freq = 0xffffffff; ++ break; ++ } ++ } ++ } ++ return tmds; ++} ++ ++union lvds_info { ++ struct _ATOM_LVDS_INFO info; ++ struct _ATOM_LVDS_INFO_V12 info_12; ++}; ++ ++struct radeon_encoder_atom_dig * ++radeon_atombios_get_lvds_info(struct radeon_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ int index = GetIndexIntoMasterTable(DATA, LVDS_Info); ++ uint16_t data_offset; ++ union lvds_info *lvds_info; ++ uint8_t frev, crev; ++ struct radeon_encoder_atom_dig *lvds = NULL; ++ ++ atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); ++ ++ lvds_info = (union lvds_info *)(mode_info->atom_context->bios + data_offset); ++ ++ if (lvds_info) { ++ lvds = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); ++ ++ if (!lvds) ++ return NULL; ++ ++ lvds->native_mode.dotclock = le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; ++ lvds->native_mode.panel_xres = le16_to_cpu(lvds_info->info.sLCDTiming.usHActive); ++ lvds->native_mode.panel_yres = le16_to_cpu(lvds_info->info.sLCDTiming.usVActive); ++ lvds->native_mode.hblank = le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time); ++ lvds->native_mode.hoverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset); ++ lvds->native_mode.hsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth); ++ lvds->native_mode.vblank = le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); ++ lvds->native_mode.voverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset); ++ lvds->native_mode.vsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); ++ lvds->panel_pwr_delay = le16_to_cpu(lvds_info->info.usOffDelayInMs); ++ lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; ++ ++ encoder->native_mode = lvds->native_mode; ++ } ++ return lvds; ++} ++ ++void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct atom_context *ctx = mode_info->atom_context; ++ DYNAMIC_CLOCK_GATING_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating); ++ ++ args.ucEnable = enable; ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++} ++ ++void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct atom_context *ctx = mode_info->atom_context; ++ ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt); ++ ++ args.ucEnable = enable; ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++} ++ ++void radeon_atom_set_engine_clock(struct drm_device *dev, int eng_clock) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct atom_context *ctx = mode_info->atom_context; ++ SET_ENGINE_CLOCK_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock); ++ ++ args.ulTargetEngineClock = eng_clock; /* 10 khz */ ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++} ++ ++void radeon_atom_set_memory_clock(struct drm_device *dev, int mem_clock) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct atom_context *ctx = mode_info->atom_context; ++ SET_MEMORY_CLOCK_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, SetMemoryClock); ++ ++ args.ulTargetMemoryClock = mem_clock; /* 10 khz */ ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++} ++ ++void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t bios_2_scratch, bios_6_scratch; ++ ++ if (dev_priv->chip_family >= CHIP_R600) { ++ bios_2_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH); ++ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); ++ } else { ++ bios_2_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH); ++ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); ++ } ++ ++ /* let the bios control the backlight */ ++ bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE; ++ ++ /* tell the bios not to handle mode switching */ ++ bios_6_scratch |= (ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH | ++ ATOM_S6_ACC_MODE); ++ ++ if (dev_priv->chip_family >= CHIP_R600) { ++ RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch); ++ RADEON_WRITE(R600_BIOS_6_SCRATCH, bios_6_scratch); ++ } else { ++ RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch); ++ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); ++ } ++ ++} ++ ++void ++radeon_atom_output_lock(struct drm_encoder *encoder, bool lock) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t bios_6_scratch; ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ bios_6_scratch = RADEON_READ(R600_BIOS_6_SCRATCH); ++ else ++ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); ++ ++ if (lock) ++ bios_6_scratch |= ATOM_S6_CRITICAL_STATE; ++ else ++ bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE; ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ RADEON_WRITE(R600_BIOS_6_SCRATCH, bios_6_scratch); ++ else ++ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); ++} ++ ++/* at some point we may want to break this out into individual functions */ ++void ++radeon_atombios_connected_scratch_regs(struct drm_connector *connector, ++ struct drm_encoder *encoder, ++ bool connected) ++{ ++ struct drm_device *dev = connector->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t bios_0_scratch, bios_3_scratch, bios_6_scratch; ++ ++ if (dev_priv->chip_family >= CHIP_R600) { ++ bios_0_scratch = RADEON_READ(R600_BIOS_0_SCRATCH); ++ bios_3_scratch = RADEON_READ(R600_BIOS_3_SCRATCH); ++ bios_6_scratch = RADEON_READ(R600_BIOS_6_SCRATCH); ++ } else { ++ bios_0_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH); ++ bios_3_scratch = RADEON_READ(RADEON_BIOS_3_SCRATCH); ++ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); ++ } ++ ++ if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("TV1 connected\n"); ++ bios_3_scratch |= ATOM_S3_TV1_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_TV1; ++ } else { ++ DRM_DEBUG("TV1 disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_TV1_MASK; ++ bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_TV1; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("CV connected\n"); ++ bios_3_scratch |= ATOM_S3_CV_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_CV; ++ } else { ++ DRM_DEBUG("CV disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_CV_MASK; ++ bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_CV; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("LCD1 connected\n"); ++ bios_0_scratch |= ATOM_S0_LCD1; ++ bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1; ++ } else { ++ DRM_DEBUG("LCD1 disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_LCD1; ++ bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("CRT1 connected\n"); ++ bios_0_scratch |= ATOM_S0_CRT1_COLOR; ++ bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1; ++ } else { ++ DRM_DEBUG("CRT1 disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_CRT1_MASK; ++ bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("CRT2 connected\n"); ++ bios_0_scratch |= ATOM_S0_CRT2_COLOR; ++ bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2; ++ } else { ++ DRM_DEBUG("CRT2 disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_CRT2_MASK; ++ bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("DFP1 connected\n"); ++ bios_0_scratch |= ATOM_S0_DFP1; ++ bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1; ++ } else { ++ DRM_DEBUG("DFP1 disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_DFP1; ++ bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("DFP2 connected\n"); ++ bios_0_scratch |= ATOM_S0_DFP2; ++ bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2; ++ } else { ++ DRM_DEBUG("DFP2 disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_DFP2; ++ bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("DFP3 connected\n"); ++ bios_0_scratch |= ATOM_S0_DFP3; ++ bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3; ++ } else { ++ DRM_DEBUG("DFP3 disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_DFP3; ++ bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("DFP4 connected\n"); ++ bios_0_scratch |= ATOM_S0_DFP4; ++ bios_3_scratch |= ATOM_S3_DFP4_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4; ++ } else { ++ DRM_DEBUG("DFP4 disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_DFP4; ++ bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("DFP5 connected\n"); ++ bios_0_scratch |= ATOM_S0_DFP5; ++ bios_3_scratch |= ATOM_S3_DFP5_ACTIVE; ++ bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5; ++ } else { ++ DRM_DEBUG("DFP5 disconnected\n"); ++ bios_0_scratch &= ~ATOM_S0_DFP5; ++ bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE; ++ bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; ++ } ++ } ++ ++ if (dev_priv->chip_family >= CHIP_R600) { ++ RADEON_WRITE(R600_BIOS_0_SCRATCH, bios_0_scratch); ++ RADEON_WRITE(R600_BIOS_3_SCRATCH, bios_3_scratch); ++ RADEON_WRITE(R600_BIOS_6_SCRATCH, bios_6_scratch); ++ } else { ++ RADEON_WRITE(RADEON_BIOS_0_SCRATCH, bios_0_scratch); ++ RADEON_WRITE(RADEON_BIOS_3_SCRATCH, bios_3_scratch); ++ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); ++ } ++} ++ ++void ++radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t bios_3_scratch; ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ bios_3_scratch = RADEON_READ(R600_BIOS_3_SCRATCH); ++ else ++ bios_3_scratch = RADEON_READ(RADEON_BIOS_3_SCRATCH); ++ ++ if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { ++ bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE; ++ bios_3_scratch |= (crtc << 18); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { ++ bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE; ++ bios_3_scratch |= (crtc << 24); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { ++ bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE; ++ bios_3_scratch |= (crtc << 16); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { ++ bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE; ++ bios_3_scratch |= (crtc << 20); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { ++ bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE; ++ bios_3_scratch |= (crtc << 17); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) { ++ bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE; ++ bios_3_scratch |= (crtc << 19); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) { ++ bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE; ++ bios_3_scratch |= (crtc << 23); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) { ++ bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE; ++ bios_3_scratch |= (crtc << 25); ++ } ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ RADEON_WRITE(R600_BIOS_3_SCRATCH, bios_3_scratch); ++ else ++ RADEON_WRITE(RADEON_BIOS_3_SCRATCH, bios_3_scratch); ++} ++ ++void ++radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t bios_2_scratch; ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ bios_2_scratch = RADEON_READ(R600_BIOS_2_SCRATCH); ++ else ++ bios_2_scratch = RADEON_READ(RADEON_BIOS_2_SCRATCH); ++ ++ if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE; ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_CV_DPMS_STATE; ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE; ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE; ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE; ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE; ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE; ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE; ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE; ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) { ++ if (on) ++ bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE; ++ else ++ bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE; ++ } ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch); ++ else ++ RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch); ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_buffer.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_buffer.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_buffer.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_buffer.c 2009-04-26 03:00:31.190726725 +0200 +@@ -0,0 +1,473 @@ ++/************************************************************************** ++ * ++ * Copyright 2007 Dave Airlie ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * ++ **************************************************************************/ ++/* ++ * Authors: Dave Airlie ++ */ ++ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++extern int radeon_no_gart_wb; ++ ++struct drm_ttm_backend *radeon_create_ttm_backend_entry(struct drm_device * dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++#if __OS_HAS_AGP ++ if (dev_priv->flags & RADEON_IS_AGP) ++ return drm_agp_init_ttm(dev); ++ else ++#endif ++ return ati_pcigart_init_ttm(dev, &dev_priv->gart_info, radeon_gart_flush); ++} ++ ++int radeon_fence_types(struct drm_buffer_object *bo, uint32_t * class, uint32_t * type) ++{ ++ *class = 0; ++ *type = 1; ++ return 0; ++} ++ ++int radeon_invalidate_caches(struct drm_device * dev, uint64_t flags) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ RING_LOCALS; ++ ++ if (!dev_priv->cp_running) ++ return 0; ++ ++ BEGIN_RING(6); ++ RADEON_PURGE_CACHE(); ++ RADEON_PURGE_ZCACHE(); ++ RADEON_WAIT_UNTIL_3D_IDLE(); ++ ADVANCE_RING(); ++ COMMIT_RING(); ++ return 0; ++} ++ ++int radeon_init_mem_type(struct drm_device * dev, uint32_t type, ++ struct drm_mem_type_manager * man) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ switch (type) { ++ case DRM_BO_MEM_LOCAL: ++ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | ++ _DRM_FLAG_MEMTYPE_CACHED; ++ man->drm_bus_maptype = 0; ++ break; ++ case DRM_BO_MEM_VRAM: ++ man->flags = _DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_NEEDS_IOREMAP; ++ man->io_addr = NULL; ++ man->drm_bus_maptype = _DRM_FRAME_BUFFER; ++ man->io_offset = drm_get_resource_start(dev, 0); ++ man->io_size = drm_get_resource_len(dev, 0); ++ break; ++ case DRM_BO_MEM_TT: ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ if (!(drm_core_has_AGP(dev) && dev->agp)) { ++ DRM_ERROR("AGP is not enabled for memory type %u\n", ++ (unsigned)type); ++ return -EINVAL; ++ } ++ man->io_offset = dev->agp->agp_info.aper_base; ++ man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024; ++ man->io_addr = NULL; ++ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | ++ _DRM_FLAG_MEMTYPE_CSELECT; ++ if (radeon_no_gart_wb == 2) ++ man->flags |= _DRM_FLAG_MEMTYPE_CMA; ++ else ++ man->flags |= _DRM_FLAG_NEEDS_IOREMAP; ++ man->drm_bus_maptype = _DRM_AGP; ++ } else { ++ man->io_offset = dev_priv->gart_vm_start; ++ man->io_size = dev_priv->gart_size; ++ man->io_addr = NULL; ++ man->flags = _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_MEMTYPE_CMA; ++ man->drm_bus_maptype = _DRM_SCATTER_GATHER; ++ } ++ break; ++ default: ++ DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++void radeon_emit_copy_blit(struct drm_device * dev, ++ uint32_t src_offset, ++ uint32_t dst_offset, ++ uint32_t pages) ++{ ++ uint32_t cur_pages; ++ uint32_t stride_bytes = PAGE_SIZE; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t format, pitch; ++ const uint32_t clip = (0x1fff) | (0x1fff << 16); ++ uint32_t stride_pixels; ++ int num_loops; ++ RING_LOCALS; ++ ++ if (!dev_priv) ++ return; ++ ++ /* 32-bit copy format */ ++ format = RADEON_COLOR_FORMAT_ARGB8888; ++ ++ /* radeon limited to 16k stride */ ++ stride_bytes &= 0x3fff; ++ /* radeon pitch is /64 */ ++ pitch = stride_bytes / 64; ++ ++ stride_pixels = stride_bytes / 4; ++ ++ num_loops = DIV_ROUND_UP(pages, 8191); ++ ++ BEGIN_RING(4 + (10 * num_loops)); ++ ++ while(pages > 0) { ++ cur_pages = pages; ++ if (cur_pages > 8191) ++ cur_pages = 8191; ++ pages -= cur_pages; ++ ++ /* pages are in Y direction - height ++ page width in X direction - width */ ++ OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 8)); ++ OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | ++ RADEON_GMC_DST_PITCH_OFFSET_CNTL | ++ RADEON_GMC_SRC_CLIPPING | RADEON_GMC_DST_CLIPPING | ++ RADEON_GMC_BRUSH_NONE | ++ (format << 8) | ++ RADEON_GMC_SRC_DATATYPE_COLOR | ++ RADEON_ROP3_S | ++ RADEON_DP_SRC_SOURCE_MEMORY | ++ RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); ++ OUT_RING((pitch << 22) | (src_offset >> 10)); ++ OUT_RING((pitch << 22) | (dst_offset >> 10)); ++ OUT_RING(clip); // SRC _SC BOT_RITE ++ OUT_RING(0); // SC_TOP_LEFT ++ OUT_RING(clip); // SC_BOT_RITE ++ ++ OUT_RING(pages); ++ OUT_RING(pages); /* x - y */ ++ OUT_RING(cur_pages | (stride_pixels << 16)); ++ } ++ ++ OUT_RING(CP_PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); ++ OUT_RING(RADEON_RB2D_DC_FLUSH_ALL); ++ RADEON_WAIT_UNTIL_2D_IDLE(); ++ ADVANCE_RING(); ++ ++ COMMIT_RING(); ++ return; ++} ++ ++int radeon_move_blit(struct drm_buffer_object * bo, ++ int evict, int no_wait, struct drm_bo_mem_reg *new_mem, ++ struct drm_bo_mem_reg *old_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t old_start, new_start; ++ ++ old_start = old_mem->mm_node->start << PAGE_SHIFT; ++ new_start = new_mem->mm_node->start << PAGE_SHIFT; ++ ++ if (old_mem->mem_type == DRM_BO_MEM_VRAM) ++ old_start += dev_priv->fb_location; ++ if (old_mem->mem_type == DRM_BO_MEM_TT) ++ old_start += dev_priv->gart_vm_start; ++ ++ if (new_mem->mem_type == DRM_BO_MEM_VRAM) ++ new_start += dev_priv->fb_location; ++ if (new_mem->mem_type == DRM_BO_MEM_TT) ++ new_start += dev_priv->gart_vm_start; ++ ++ radeon_emit_copy_blit(bo->dev, ++ old_start, ++ new_start, ++ new_mem->num_pages); ++ ++ /* invalidate the chip caches */ ++ ++ return drm_bo_move_accel_cleanup(bo, evict, no_wait, 0, ++ DRM_FENCE_TYPE_EXE, 0, ++ new_mem); ++} ++ ++void radeon_emit_solid_fill(struct drm_device * dev, ++ uint32_t dst_offset, ++ uint32_t pages, uint8_t value) ++{ ++ uint32_t cur_pages; ++ uint32_t stride_bytes = PAGE_SIZE; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t format, pitch; ++ const uint32_t clip = (0x1fff) | (0x1fff << 16); ++ uint32_t stride_pixels; ++ int num_loops; ++ RING_LOCALS; ++ ++ if (!dev_priv) ++ return; ++ ++ if (!radeon_vram_zero) ++ return; ++ ++ /* 32-bit copy format */ ++ format = RADEON_COLOR_FORMAT_ARGB8888; ++ ++ /* radeon limited to 16k stride */ ++ stride_bytes &= 0x3fff; ++ /* radeon pitch is /64 */ ++ pitch = stride_bytes / 64; ++ ++ stride_pixels = stride_bytes / 4; ++ ++ num_loops = DIV_ROUND_UP(pages, 8191); ++ ++ BEGIN_RING(4 + (8*num_loops)); ++ ++ while(pages > 0) { ++ cur_pages = pages; ++ if (cur_pages > 8191) ++ cur_pages = 8191; ++ pages -= cur_pages; ++ ++ /* pages are in Y direction - height ++ page width in X direction - width */ ++ OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 6)); ++ OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | ++ RADEON_GMC_DST_CLIPPING | ++ RADEON_GMC_BRUSH_SOLID_COLOR | ++ (format << 8) | ++ RADEON_ROP3_P | ++ RADEON_CLR_CMP_SRC_SOURCE | ++ RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); ++ OUT_RING((pitch << 22) | (dst_offset >> 10)); // PITCH ++ OUT_RING(0); // SC_TOP_LEFT // DST CLIPPING ++ OUT_RING(clip); // SC_BOT_RITE ++ ++ OUT_RING(0); // COLOR ++ ++ OUT_RING(pages); /* x - y */ ++ OUT_RING(cur_pages | (stride_pixels << 16)); ++ } ++ ++ OUT_RING(CP_PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); ++ OUT_RING(RADEON_RB2D_DC_FLUSH_ALL); ++ RADEON_WAIT_UNTIL_2D_IDLE(); ++ ADVANCE_RING(); ++ ++ COMMIT_RING(); ++ return; ++} ++ ++int radeon_move_zero_fill(struct drm_buffer_object * bo, ++ int evict, int no_wait, struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t new_start; ++ ++ if (new_mem->mem_type != DRM_BO_MEM_VRAM) ++ return -1; ++ ++ ++ new_start = new_mem->mm_node->start << PAGE_SHIFT; ++ new_start += dev_priv->fb_location; ++ ++ radeon_emit_solid_fill(bo->dev, ++ new_start, ++ new_mem->num_pages, 0); ++ ++ /* invalidate the chip caches */ ++ ++ return drm_bo_move_accel_cleanup(bo, 1, no_wait, 0, ++ DRM_FENCE_TYPE_EXE, 0, ++ new_mem); ++} ++ ++static int radeon_move_flip(struct drm_buffer_object * bo, ++ int evict, int no_wait, struct drm_bo_mem_reg * new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_bo_mem_reg tmp_mem; ++ int ret; ++ ++ tmp_mem = *new_mem; ++ ++ /* if we are flipping into LOCAL memory we have no TTM so create one */ ++ if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { ++ tmp_mem.mm_node = NULL; ++ tmp_mem.proposed_flags = DRM_BO_FLAG_MEM_TT; ++ ++ ret = drm_bo_mem_space(bo, &tmp_mem, no_wait); ++ if (ret) ++ return ret; ++ ++ ret = drm_ttm_bind(bo->ttm, &tmp_mem); ++ if (ret) ++ goto out_cleanup; ++ } ++ ++ ret = radeon_move_blit(bo, 1, no_wait, &tmp_mem, &bo->mem); ++ if (ret) ++ goto out_cleanup; ++ ++ if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { ++ ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem); ++ } else { ++ tmp_mem.mm_node = NULL; ++ new_mem->mm_node = NULL; ++ } ++ ++out_cleanup: ++ if (tmp_mem.mm_node) { ++ mutex_lock(&dev->struct_mutex); ++ if (tmp_mem.mm_node != bo->pinned_node) ++ drm_mm_put_block(tmp_mem.mm_node); ++ tmp_mem.mm_node = NULL; ++ mutex_unlock(&dev->struct_mutex); ++ } ++ return ret; ++} ++ ++static int radeon_move_vram(struct drm_buffer_object * bo, ++ int evict, int no_wait, struct drm_bo_mem_reg * new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_bo_mem_reg tmp_mem; ++ struct drm_bo_mem_reg *old_mem = &bo->mem; ++ int ret; ++ ++ /* old - LOCAL memory node bo->mem ++ tmp - TT type memory node ++ new - VRAM memory node */ ++ ++ tmp_mem = *old_mem; ++ tmp_mem.mm_node = NULL; ++ ++ if (old_mem->mem_type == DRM_BO_MEM_LOCAL) { ++ tmp_mem.proposed_flags = DRM_BO_FLAG_MEM_TT; ++ ++ ret = drm_bo_mem_space(bo, &tmp_mem, no_wait); ++ if (ret) ++ return ret; ++ } ++ ++ if (!bo->ttm) { ++ ret = drm_bo_add_ttm(bo); ++ if (ret) ++ goto out_cleanup; ++ } ++ ++ if (old_mem->mem_type == DRM_BO_MEM_LOCAL) { ++ ret = drm_bo_move_ttm(bo, evict, no_wait, &tmp_mem); ++ if (ret) ++ return ret; ++ } ++ ++ ret = radeon_move_blit(bo, 1, no_wait, new_mem, &bo->mem); ++ if (ret) ++ goto out_cleanup; ++ ++out_cleanup: ++ if (tmp_mem.mm_node) { ++ mutex_lock(&dev->struct_mutex); ++ if (tmp_mem.mm_node != bo->pinned_node) ++ drm_mm_put_block(tmp_mem.mm_node); ++ tmp_mem.mm_node = NULL; ++ mutex_unlock(&dev->struct_mutex); ++ } ++ return ret; ++} ++ ++int radeon_move(struct drm_buffer_object * bo, ++ int evict, int no_wait, struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ if (!dev_priv->cp_running) ++ goto fallback; ++ ++ if (bo->mem.mem_type == DRM_BO_MEM_VRAM && radeon_no_gart_wb) ++ goto fallback; ++ ++ if (bo->mem.flags & DRM_BO_FLAG_CLEAN) /* need to implement solid fill */ ++ { ++ if (radeon_move_zero_fill(bo, evict, no_wait, new_mem)) ++ return drm_bo_move_zero(bo, evict, no_wait, new_mem); ++ return 0; ++ } ++ ++ if (new_mem->mem_type == DRM_BO_MEM_VRAM) { ++ if (radeon_move_vram(bo, evict, no_wait, new_mem)) ++ goto fallback; ++ } else { ++ if (radeon_move_flip(bo, evict, no_wait, new_mem)) ++ goto fallback; ++ } ++ return 0; ++fallback: ++ if (bo->mem.flags & DRM_BO_FLAG_CLEAN) ++ return drm_bo_move_zero(bo, evict, no_wait, new_mem); ++ else ++ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++} ++ ++ ++/* ++ * i915_evict_flags: ++ * ++ * @bo: the buffer object to be evicted ++ * ++ * Return the bo flags for a buffer which is not mapped to the hardware. ++ * These will be placed in proposed_flags so that when the move is ++ * finished, they'll end up in bo->mem.flags ++ */ ++uint64_t radeon_evict_flags(struct drm_buffer_object *bo) ++{ ++ struct drm_device *dev = bo->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ int cached = 0; ++ ++ if (!(dev_priv->flags & RADEON_IS_AGP)) ++ cached = DRM_BO_FLAG_CACHED; ++ ++ switch (bo->mem.mem_type) { ++ case DRM_BO_MEM_LOCAL: ++ case DRM_BO_MEM_TT: ++ return DRM_BO_FLAG_MEM_LOCAL | cached; ++ default: ++ return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_LOCAL | cached; ++ } ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_combios.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_combios.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_combios.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_combios.c 2009-04-26 03:00:36.029742908 +0200 +@@ -0,0 +1,1767 @@ ++/* ++ * Copyright 2004 ATI Technologies Inc., Markham, Ontario ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++/* from radeon_encoder.c */ ++extern uint32_t ++radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac); ++extern void ++radeon_link_encoder_connector(struct drm_device *dev); ++ ++extern int radeon_ddc_dump(struct drm_connector *connector); ++ ++/* from radeon_connector.c */ ++extern void ++radeon_add_legacy_connector(struct drm_device *dev, ++ uint32_t connector_id, ++ uint32_t supported_device, ++ int connector_type, ++ struct radeon_i2c_bus_rec *i2c_bus); ++ ++/* from radeon_legacy_encoder.c */ ++extern void ++radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device); ++ ++/* old legacy ATI BIOS routines */ ++ ++/* COMBIOS table offsets */ ++enum radeon_combios_table_offset ++{ ++ /* absolute offset tables */ ++ COMBIOS_ASIC_INIT_1_TABLE, ++ COMBIOS_BIOS_SUPPORT_TABLE, ++ COMBIOS_DAC_PROGRAMMING_TABLE, ++ COMBIOS_MAX_COLOR_DEPTH_TABLE, ++ COMBIOS_CRTC_INFO_TABLE, ++ COMBIOS_PLL_INFO_TABLE, ++ COMBIOS_TV_INFO_TABLE, ++ COMBIOS_DFP_INFO_TABLE, ++ COMBIOS_HW_CONFIG_INFO_TABLE, ++ COMBIOS_MULTIMEDIA_INFO_TABLE, ++ COMBIOS_TV_STD_PATCH_TABLE, ++ COMBIOS_LCD_INFO_TABLE, ++ COMBIOS_MOBILE_INFO_TABLE, ++ COMBIOS_PLL_INIT_TABLE, ++ COMBIOS_MEM_CONFIG_TABLE, ++ COMBIOS_SAVE_MASK_TABLE, ++ COMBIOS_HARDCODED_EDID_TABLE, ++ COMBIOS_ASIC_INIT_2_TABLE, ++ COMBIOS_CONNECTOR_INFO_TABLE, ++ COMBIOS_DYN_CLK_1_TABLE, ++ COMBIOS_RESERVED_MEM_TABLE, ++ COMBIOS_EXT_TMDS_INFO_TABLE, ++ COMBIOS_MEM_CLK_INFO_TABLE, ++ COMBIOS_EXT_DAC_INFO_TABLE, ++ COMBIOS_MISC_INFO_TABLE, ++ COMBIOS_CRT_INFO_TABLE, ++ COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE, ++ COMBIOS_COMPONENT_VIDEO_INFO_TABLE, ++ COMBIOS_FAN_SPEED_INFO_TABLE, ++ COMBIOS_OVERDRIVE_INFO_TABLE, ++ COMBIOS_OEM_INFO_TABLE, ++ COMBIOS_DYN_CLK_2_TABLE, ++ COMBIOS_POWER_CONNECTOR_INFO_TABLE, ++ COMBIOS_I2C_INFO_TABLE, ++ /* relative offset tables */ ++ COMBIOS_ASIC_INIT_3_TABLE, /* offset from misc info */ ++ COMBIOS_ASIC_INIT_4_TABLE, /* offset from misc info */ ++ COMBIOS_DETECTED_MEM_TABLE, /* offset from misc info */ ++ COMBIOS_ASIC_INIT_5_TABLE, /* offset from misc info */ ++ COMBIOS_RAM_RESET_TABLE, /* offset from mem config */ ++ COMBIOS_POWERPLAY_INFO_TABLE, /* offset from mobile info */ ++ COMBIOS_GPIO_INFO_TABLE, /* offset from mobile info */ ++ COMBIOS_LCD_DDC_INFO_TABLE, /* offset from mobile info */ ++ COMBIOS_TMDS_POWER_TABLE, /* offset from mobile info */ ++ COMBIOS_TMDS_POWER_ON_TABLE, /* offset from tmds power */ ++ COMBIOS_TMDS_POWER_OFF_TABLE, /* offset from tmds power */ ++}; ++ ++enum radeon_combios_ddc ++{ ++ DDC_NONE_DETECTED, ++ DDC_MONID, ++ DDC_DVI, ++ DDC_VGA, ++ DDC_CRT2, ++ DDC_LCD, ++ DDC_GPIO, ++}; ++ ++enum radeon_combios_connector ++{ ++ CONNECTOR_NONE_LEGACY, ++ CONNECTOR_PROPRIETARY_LEGACY, ++ CONNECTOR_CRT_LEGACY, ++ CONNECTOR_DVI_I_LEGACY, ++ CONNECTOR_DVI_D_LEGACY, ++ CONNECTOR_CTV_LEGACY, ++ CONNECTOR_STV_LEGACY, ++ CONNECTOR_UNSUPPORTED_LEGACY ++}; ++ ++const int legacy_connector_convert[] = ++{ ++ DRM_MODE_CONNECTOR_Unknown, ++ DRM_MODE_CONNECTOR_DVID, ++ DRM_MODE_CONNECTOR_VGA, ++ DRM_MODE_CONNECTOR_DVII, ++ DRM_MODE_CONNECTOR_DVID, ++ DRM_MODE_CONNECTOR_Composite, ++ DRM_MODE_CONNECTOR_SVIDEO, ++ DRM_MODE_CONNECTOR_Unknown, ++}; ++ ++static uint16_t combios_get_table_offset(struct drm_device *dev, enum radeon_combios_table_offset table) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int rev; ++ uint16_t offset = 0, check_offset; ++ ++ switch (table) { ++ /* absolute offset tables */ ++ case COMBIOS_ASIC_INIT_1_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0xc); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_BIOS_SUPPORT_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x14); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_DAC_PROGRAMMING_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x2a); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_MAX_COLOR_DEPTH_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x2c); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_CRTC_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x2e); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_PLL_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x30); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_TV_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x32); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_DFP_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x34); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_HW_CONFIG_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x36); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_MULTIMEDIA_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x38); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_TV_STD_PATCH_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x3e); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_LCD_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x40); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_MOBILE_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x42); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_PLL_INIT_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x46); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_MEM_CONFIG_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x48); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_SAVE_MASK_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x4a); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_HARDCODED_EDID_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x4c); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_ASIC_INIT_2_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x4e); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_CONNECTOR_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x50); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_DYN_CLK_1_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x52); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_RESERVED_MEM_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x54); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_EXT_TMDS_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x58); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_MEM_CLK_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x5a); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_EXT_DAC_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x5c); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_MISC_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x5e); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_CRT_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x60); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x62); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_COMPONENT_VIDEO_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x64); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_FAN_SPEED_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x66); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_OVERDRIVE_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x68); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_OEM_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x6a); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_DYN_CLK_2_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x6c); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_POWER_CONNECTOR_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x6e); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ case COMBIOS_I2C_INFO_TABLE: ++ check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x70); ++ if (check_offset) ++ offset = check_offset; ++ break; ++ /* relative offset tables */ ++ case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); ++ if (check_offset) { ++ rev = radeon_bios8(dev_priv, check_offset); ++ if (rev > 0) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x3); ++ if (check_offset) ++ offset = check_offset; ++ } ++ } ++ break; ++ case COMBIOS_ASIC_INIT_4_TABLE: /* offset from misc info */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); ++ if (check_offset) { ++ rev = radeon_bios8(dev_priv, check_offset); ++ if (rev > 0) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x5); ++ if (check_offset) ++ offset = check_offset; ++ } ++ } ++ break; ++ case COMBIOS_DETECTED_MEM_TABLE: /* offset from misc info */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); ++ if (check_offset) { ++ rev = radeon_bios8(dev_priv, check_offset); ++ if (rev > 0) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x7); ++ if (check_offset) ++ offset = check_offset; ++ } ++ } ++ break; ++ case COMBIOS_ASIC_INIT_5_TABLE: /* offset from misc info */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); ++ if (check_offset) { ++ rev = radeon_bios8(dev_priv, check_offset); ++ if (rev == 2) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x9); ++ if (check_offset) ++ offset = check_offset; ++ } ++ } ++ break; ++ case COMBIOS_RAM_RESET_TABLE: /* offset from mem config */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE); ++ if (check_offset) { ++ while (radeon_bios8(dev_priv, check_offset++)); ++ check_offset += 2; ++ if (check_offset) ++ offset = check_offset; ++ } ++ break; ++ case COMBIOS_POWERPLAY_INFO_TABLE: /* offset from mobile info */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); ++ if (check_offset) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x11); ++ if (check_offset) ++ offset = check_offset; ++ } ++ break; ++ case COMBIOS_GPIO_INFO_TABLE: /* offset from mobile info */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); ++ if (check_offset) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x13); ++ if (check_offset) ++ offset = check_offset; ++ } ++ break; ++ case COMBIOS_LCD_DDC_INFO_TABLE: /* offset from mobile info */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); ++ if (check_offset) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x15); ++ if (check_offset) ++ offset = check_offset; ++ } ++ break; ++ case COMBIOS_TMDS_POWER_TABLE: /* offset from mobile info */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); ++ if (check_offset) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x17); ++ if (check_offset) ++ offset = check_offset; ++ } ++ break; ++ case COMBIOS_TMDS_POWER_ON_TABLE: /* offset from tmds power */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE); ++ if (check_offset) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x2); ++ if (check_offset) ++ offset = check_offset; ++ } ++ break; ++ case COMBIOS_TMDS_POWER_OFF_TABLE: /* offset from tmds power */ ++ check_offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE); ++ if (check_offset) { ++ check_offset = radeon_bios16(dev_priv, check_offset + 0x4); ++ if (check_offset) ++ offset = check_offset; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return offset; ++ ++} ++ ++struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line) ++{ ++ struct radeon_i2c_bus_rec i2c; ++ ++ i2c.mask_clk_mask = RADEON_GPIO_EN_1; ++ i2c.mask_data_mask = RADEON_GPIO_EN_0; ++ i2c.a_clk_mask = RADEON_GPIO_A_1; ++ i2c.a_data_mask = RADEON_GPIO_A_0; ++ i2c.put_clk_mask = RADEON_GPIO_EN_1; ++ i2c.put_data_mask = RADEON_GPIO_EN_0; ++ i2c.get_clk_mask = RADEON_GPIO_Y_1; ++ i2c.get_data_mask = RADEON_GPIO_Y_0; ++ if ((ddc_line == RADEON_LCD_GPIO_MASK) || ++ (ddc_line == RADEON_MDGPIO_EN_REG)) { ++ i2c.mask_clk_reg = ddc_line; ++ i2c.mask_data_reg = ddc_line; ++ i2c.a_clk_reg = ddc_line; ++ i2c.a_data_reg = ddc_line; ++ i2c.put_clk_reg = ddc_line; ++ i2c.put_data_reg = ddc_line; ++ i2c.get_clk_reg = ddc_line + 4; ++ i2c.get_data_reg = ddc_line + 4; ++ } else { ++ i2c.mask_clk_reg = ddc_line; ++ i2c.mask_data_reg = ddc_line; ++ i2c.a_clk_reg = ddc_line; ++ i2c.a_data_reg = ddc_line; ++ i2c.put_clk_reg = ddc_line; ++ i2c.put_data_reg = ddc_line; ++ i2c.get_clk_reg = ddc_line; ++ i2c.get_data_reg = ddc_line; ++ } ++ ++ if (ddc_line) ++ i2c.valid = true; ++ else ++ i2c.valid = false; ++ ++ return i2c; ++} ++ ++bool radeon_combios_get_clock_info(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ uint16_t pll_info; ++ struct radeon_pll *p1pll = &mode_info->p1pll; ++ struct radeon_pll *p2pll = &mode_info->p2pll; ++ struct radeon_pll *spll = &mode_info->spll; ++ struct radeon_pll *mpll = &mode_info->mpll; ++ int8_t rev; ++ uint16_t sclk, mclk; ++ ++ pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE); ++ if (pll_info) { ++ rev = radeon_bios8(dev_priv, pll_info); ++ ++ /* pixel clocks */ ++ p1pll->reference_freq = radeon_bios16(dev_priv, pll_info + 0xe); ++ p1pll->reference_div = radeon_bios16(dev_priv, pll_info + 0x10); ++ p1pll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x12); ++ p1pll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x16); ++ ++ if (rev > 9) { ++ p1pll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x36); ++ p1pll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x3a); ++ } else { ++ p1pll->pll_in_min = 40; ++ p1pll->pll_in_max = 500; ++ } ++ *p2pll = *p1pll; ++ ++ /* system clock */ ++ spll->reference_freq = radeon_bios16(dev_priv, pll_info + 0x1a); ++ spll->reference_div = radeon_bios16(dev_priv, pll_info + 0x1c); ++ spll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x1e); ++ spll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x22); ++ ++ if (rev > 10) { ++ spll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x48); ++ spll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x4c); ++ } else { ++ /* ??? */ ++ spll->pll_in_min = 40; ++ spll->pll_in_max = 500; ++ } ++ ++ /* memory clock */ ++ mpll->reference_freq = radeon_bios16(dev_priv, pll_info + 0x26); ++ mpll->reference_div = radeon_bios16(dev_priv, pll_info + 0x28); ++ mpll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x2a); ++ mpll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x2e); ++ ++ if (rev > 10) { ++ mpll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x5a); ++ mpll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x5e); ++ } else { ++ /* ??? */ ++ mpll->pll_in_min = 40; ++ mpll->pll_in_max = 500; ++ } ++ ++ /* default sclk/mclk */ ++ sclk = radeon_bios16(dev_priv, pll_info + 0xa); ++ mclk = radeon_bios16(dev_priv, pll_info + 0x8); ++ if (sclk == 0) ++ sclk = 200 * 100; ++ if (mclk == 0) ++ mclk = 200 * 100; ++ ++ mode_info->sclk = sclk; ++ mode_info->mclk = mclk; ++ ++ return true; ++ } ++ return false; ++} ++ ++struct radeon_encoder_primary_dac * ++radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint16_t dac_info; ++ uint8_t rev, bg, dac; ++ struct radeon_encoder_primary_dac *p_dac = NULL; ++ ++ /* check CRT table */ ++ dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); ++ if (dac_info) { ++ p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL); ++ ++ if (!p_dac) ++ return NULL; ++ ++ rev = radeon_bios8(dev_priv, dac_info) & 0x3; ++ if (rev < 2) { ++ bg = radeon_bios8(dev_priv, dac_info + 0x2) & 0xf; ++ dac = (radeon_bios8(dev_priv, dac_info + 0x2) >> 4) & 0xf; ++ p_dac->ps2_pdac_adj = (bg << 8) | (dac); ++ } else { ++ bg = radeon_bios8(dev_priv, dac_info + 0x2) & 0xf; ++ dac = radeon_bios8(dev_priv, dac_info + 0x3) & 0xf; ++ p_dac->ps2_pdac_adj = (bg << 8) | (dac); ++ } ++ ++ } ++ ++ return p_dac; ++} ++ ++static enum radeon_tv_std ++radeon_combios_get_tv_info(struct radeon_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint16_t tv_info; ++ enum radeon_tv_std tv_std = TV_STD_NTSC; ++ ++ tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); ++ if (tv_info) { ++ if (radeon_bios8(dev_priv, tv_info + 6) == 'T') { ++ switch (radeon_bios8(dev_priv, tv_info + 7) & 0xf) { ++ case 1: ++ tv_std = TV_STD_NTSC; ++ DRM_INFO("Default TV standard: NTSC\n"); ++ break; ++ case 2: ++ tv_std = TV_STD_PAL; ++ DRM_INFO("Default TV standard: PAL\n"); ++ break; ++ case 3: ++ tv_std = TV_STD_PAL_M; ++ DRM_INFO("Default TV standard: PAL-M\n"); ++ break; ++ case 4: ++ tv_std = TV_STD_PAL_60; ++ DRM_INFO("Default TV standard: PAL-60\n"); ++ break; ++ case 5: ++ tv_std = TV_STD_NTSC_J; ++ DRM_INFO("Default TV standard: NTSC-J\n"); ++ break; ++ case 6: ++ tv_std = TV_STD_SCART_PAL; ++ DRM_INFO("Default TV standard: SCART-PAL\n"); ++ break; ++ default: ++ tv_std = TV_STD_NTSC; ++ DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); ++ break; ++ } ++ ++ switch ((radeon_bios8(dev_priv, tv_info + 9) >> 2) & 0x3) { ++ case 0: ++ DRM_INFO("29.498928713 MHz TV ref clk\n"); ++ break; ++ case 1: ++ DRM_INFO("28.636360000 MHz TV ref clk\n"); ++ break; ++ case 2: ++ DRM_INFO("14.318180000 MHz TV ref clk\n"); ++ break; ++ case 3: ++ DRM_INFO("27.000000000 MHz TV ref clk\n"); ++ break; ++ default: ++ break; ++ } ++ } ++ } ++ return tv_std; ++} ++ ++struct radeon_encoder_tv_dac * ++radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint16_t dac_info; ++ uint8_t rev, bg, dac; ++ struct radeon_encoder_tv_dac *tv_dac = NULL; ++ ++ /* first check TV table */ ++ dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); ++ if (dac_info) { ++ tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); ++ ++ if (!tv_dac) ++ return NULL; ++ ++ rev = radeon_bios8(dev_priv, dac_info + 0x3); ++ if (rev > 4) { ++ bg = radeon_bios8(dev_priv, dac_info + 0xc) & 0xf; ++ dac = radeon_bios8(dev_priv, dac_info + 0xd) & 0xf; ++ tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20); ++ ++ bg = radeon_bios8(dev_priv, dac_info + 0xe) & 0xf; ++ dac = radeon_bios8(dev_priv, dac_info + 0xf) & 0xf; ++ tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20); ++ ++ bg = radeon_bios8(dev_priv, dac_info + 0x10) & 0xf; ++ dac = radeon_bios8(dev_priv, dac_info + 0x11) & 0xf; ++ tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); ++ } else if (rev > 1) { ++ bg = radeon_bios8(dev_priv, dac_info + 0xc) & 0xf; ++ dac = (radeon_bios8(dev_priv, dac_info + 0xc) >> 4) & 0xf; ++ tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20); ++ ++ bg = radeon_bios8(dev_priv, dac_info + 0xd) & 0xf; ++ dac = (radeon_bios8(dev_priv, dac_info + 0xd) >> 4) & 0xf; ++ tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20); ++ ++ bg = radeon_bios8(dev_priv, dac_info + 0xe) & 0xf; ++ dac = (radeon_bios8(dev_priv, dac_info + 0xe) >> 4) & 0xf; ++ tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); ++ } ++ ++ tv_dac->tv_std = radeon_combios_get_tv_info(encoder); ++ ++ } else { ++ /* then check CRT table */ ++ dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); ++ if (dac_info) { ++ tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); ++ ++ if (!tv_dac) ++ return NULL; ++ ++ rev = radeon_bios8(dev_priv, dac_info) & 0x3; ++ if (rev < 2) { ++ bg = radeon_bios8(dev_priv, dac_info + 0x3) & 0xf; ++ dac = (radeon_bios8(dev_priv, dac_info + 0x3) >> 4) & 0xf; ++ tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20); ++ tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; ++ tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; ++ } else { ++ bg = radeon_bios8(dev_priv, dac_info + 0x4) & 0xf; ++ dac = radeon_bios8(dev_priv, dac_info + 0x5) & 0xf; ++ tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20); ++ tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; ++ tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; ++ } ++ } ++ } ++ ++ return tv_dac; ++} ++ ++struct radeon_encoder_lvds * ++radeon_combios_get_lvds_info(struct radeon_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint16_t lcd_info; ++ uint32_t panel_setup; ++ char stmp[30]; ++ int tmp, i; ++ struct radeon_encoder_lvds *lvds = NULL; ++ ++ lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); ++ ++ if (lcd_info) { ++ lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL); ++ ++ if (!lvds) ++ return NULL; ++ ++ for (i = 0; i < 24; i++) ++ stmp[i] = radeon_bios8(dev_priv, lcd_info + i + 1); ++ stmp[24] = 0; ++ ++ DRM_INFO("Panel ID String: %s\n", stmp); ++ ++ lvds->native_mode.panel_xres = radeon_bios16(dev_priv, lcd_info + 25); ++ lvds->native_mode.panel_yres = radeon_bios16(dev_priv, lcd_info + 27); ++ ++ DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres, lvds->native_mode.panel_yres); ++ ++ lvds->panel_vcc_delay = radeon_bios16(dev_priv, lcd_info + 44); ++ if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0) ++ lvds->panel_vcc_delay = 2000; ++ ++ lvds->panel_pwr_delay = radeon_bios16(dev_priv, lcd_info + 0x24); ++ lvds->panel_digon_delay = radeon_bios16(dev_priv, lcd_info + 0x38) & 0xf; ++ lvds->panel_blon_delay = (radeon_bios16(dev_priv, lcd_info + 0x38) >> 4) & 0xf; ++ ++ lvds->panel_ref_divider = radeon_bios16(dev_priv, lcd_info + 46); ++ lvds->panel_post_divider = radeon_bios8(dev_priv, lcd_info + 48); ++ lvds->panel_fb_divider = radeon_bios16(dev_priv, lcd_info + 49); ++ if ((lvds->panel_ref_divider != 0) && ++ (lvds->panel_fb_divider > 3)) ++ lvds->use_bios_dividers = true; ++ ++ panel_setup = radeon_bios32(dev_priv, lcd_info + 0x39); ++ lvds->lvds_gen_cntl = 0xff00; ++ if (panel_setup & 0x1) ++ lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_FORMAT; ++ ++ if ((panel_setup >> 4) & 0x1) ++ lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_TYPE; ++ ++ switch ((panel_setup >> 8) & 0x7) { ++ case 0: ++ lvds->lvds_gen_cntl |= RADEON_LVDS_NO_FM; ++ break; ++ case 1: ++ lvds->lvds_gen_cntl |= RADEON_LVDS_2_GREY; ++ break; ++ case 2: ++ lvds->lvds_gen_cntl |= RADEON_LVDS_4_GREY; ++ break; ++ default: ++ break; ++ } ++ ++ if ((panel_setup >> 16) & 0x1) ++ lvds->lvds_gen_cntl |= RADEON_LVDS_FP_POL_LOW; ++ ++ if ((panel_setup >> 17) & 0x1) ++ lvds->lvds_gen_cntl |= RADEON_LVDS_LP_POL_LOW; ++ ++ if ((panel_setup >> 18) & 0x1) ++ lvds->lvds_gen_cntl |= RADEON_LVDS_DTM_POL_LOW; ++ ++ if ((panel_setup >> 23) & 0x1) ++ lvds->lvds_gen_cntl |= RADEON_LVDS_BL_CLK_SEL; ++ ++ lvds->lvds_gen_cntl |= (panel_setup & 0xf0000000); ++ ++ ++ for (i = 0; i < 32; i++) { ++ tmp = radeon_bios16(dev_priv, lcd_info + 64 + i * 2); ++ if (tmp == 0) break; ++ ++ if ((radeon_bios16(dev_priv, tmp) == lvds->native_mode.panel_xres) && ++ (radeon_bios16(dev_priv, tmp + 2) == lvds->native_mode.panel_yres)) { ++ lvds->native_mode.hblank = (radeon_bios16(dev_priv, tmp + 17) - ++ radeon_bios16(dev_priv, tmp + 19)) * 8; ++ lvds->native_mode.hoverplus = (radeon_bios16(dev_priv, tmp + 21) - ++ radeon_bios16(dev_priv, tmp + 19) - 1) * 8; ++ lvds->native_mode.hsync_width = radeon_bios8(dev_priv, tmp + 23) * 8; ++ ++ lvds->native_mode.vblank = (radeon_bios16(dev_priv, tmp + 24) - ++ radeon_bios16(dev_priv, tmp + 26)); ++ lvds->native_mode.voverplus = ((radeon_bios16(dev_priv, tmp + 28) & 0x7ff) - ++ radeon_bios16(dev_priv, tmp + 26)); ++ lvds->native_mode.vsync_width = ((radeon_bios16(dev_priv, tmp + 28) & 0xf800) >> 11); ++ lvds->native_mode.dotclock = radeon_bios16(dev_priv, tmp + 9) * 10; ++ lvds->native_mode.flags = 0; ++ } ++ } ++ encoder->native_mode = lvds->native_mode; ++ } else ++ DRM_INFO("No panel info found in BIOS\n"); ++ return lvds; ++} ++ ++struct radeon_encoder_int_tmds * ++radeon_combios_get_tmds_info(struct radeon_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint16_t tmds_info; ++ int i, n; ++ uint8_t ver; ++ struct radeon_encoder_int_tmds *tmds = NULL; ++ ++ tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); ++ ++ if (tmds_info) { ++ tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL); ++ ++ if (!tmds) ++ return NULL; ++ ++ ver = radeon_bios8(dev_priv, tmds_info); ++ DRM_INFO("DFP table revision: %d\n", ver); ++ if (ver == 3) { ++ n = radeon_bios8(dev_priv, tmds_info + 5) + 1; ++ if (n > 4) ++ n = 4; ++ for (i = 0; i < n; i++) { ++ tmds->tmds_pll[i].value = radeon_bios32(dev_priv, tmds_info + i * 10 + 0x08); ++ tmds->tmds_pll[i].freq = radeon_bios16(dev_priv, tmds_info + i * 10 + 0x10); ++ DRM_DEBUG("TMDS PLL From COMBIOS %u %x\n", ++ tmds->tmds_pll[i].freq, ++ tmds->tmds_pll[i].value); ++ } ++ } else if (ver == 4) { ++ int stride = 0; ++ n = radeon_bios8(dev_priv, tmds_info + 5) + 1; ++ if (n > 4) ++ n = 4; ++ for (i = 0; i < n; i++) { ++ tmds->tmds_pll[i].value = radeon_bios32(dev_priv, tmds_info + stride + 0x08); ++ tmds->tmds_pll[i].freq = radeon_bios16(dev_priv, tmds_info + stride + 0x10); ++ if (i == 0) ++ stride += 10; ++ else ++ stride += 6; ++ DRM_DEBUG("TMDS PLL From COMBIOS %u %x\n", ++ tmds->tmds_pll[i].freq, ++ tmds->tmds_pll[i].value); ++ } ++ } ++ } else ++ DRM_INFO("No TMDS info found in BIOS\n"); ++ return tmds; ++} ++ ++void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint16_t ext_tmds_info; ++ uint8_t ver; ++ ++ ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); ++ if (ext_tmds_info) { ++ ver = radeon_bios8(dev_priv, ext_tmds_info); ++ DRM_INFO("External TMDS Table revision: %d\n", ver); ++ // TODO ++ } ++} ++ ++static bool radeon_apply_legacy_quirks(struct drm_device *dev, ++ int bios_index, ++ enum radeon_combios_connector *legacy_connector, ++ struct radeon_i2c_bus_rec *ddc_i2c) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ ++ /* XPRESS DDC quirks */ ++ if ((dev_priv->chip_family == CHIP_RS400 || ++ dev_priv->chip_family == CHIP_RS480) && ++ ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) ++ *ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID); ++ else if ((dev_priv->chip_family == CHIP_RS400 || ++ dev_priv->chip_family == CHIP_RS480) && ++ ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) { ++ ddc_i2c->valid = true; ++ ddc_i2c->mask_clk_mask = (0x20 << 8); ++ ddc_i2c->mask_data_mask = 0x80; ++ ddc_i2c->a_clk_mask = (0x20 << 8); ++ ddc_i2c->a_data_mask = 0x80; ++ ddc_i2c->put_clk_mask = (0x20 << 8); ++ ddc_i2c->put_data_mask = 0x80; ++ ddc_i2c->get_clk_mask = (0x20 << 8); ++ ddc_i2c->get_data_mask = 0x80; ++ ddc_i2c->mask_clk_reg = RADEON_GPIOPAD_MASK; ++ ddc_i2c->mask_data_reg = RADEON_GPIOPAD_MASK; ++ ddc_i2c->a_clk_reg = RADEON_GPIOPAD_A; ++ ddc_i2c->a_data_reg = RADEON_GPIOPAD_A; ++ ddc_i2c->put_clk_reg = RADEON_GPIOPAD_EN; ++ ddc_i2c->put_data_reg = RADEON_GPIOPAD_EN; ++ ddc_i2c->get_clk_reg = RADEON_LCD_GPIO_Y_REG; ++ ddc_i2c->get_data_reg = RADEON_LCD_GPIO_Y_REG; ++ } ++ ++ /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, ++ one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ ++ if (dev->pdev->device == 0x515e && ++ dev->pdev->subsystem_vendor == 0x1014) { ++ if (*legacy_connector == CONNECTOR_CRT_LEGACY && ++ ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) ++ return false; ++ } ++ ++ /* Some RV100 cards with 2 VGA ports show up with DVI+VGA */ ++ if (dev->pdev->device == 0x5159 && ++ dev->pdev->subsystem_vendor == 0x1002 && ++ dev->pdev->subsystem_device == 0x013a) { ++ if (*legacy_connector == CONNECTOR_DVI_I_LEGACY) ++ *legacy_connector = CONNECTOR_CRT_LEGACY; ++ ++ } ++ ++ /* X300 card with extra non-existent DVI port */ ++ if (dev->pdev->device == 0x5B60 && ++ dev->pdev->subsystem_vendor == 0x17af && ++ dev->pdev->subsystem_device == 0x201e && ++ bios_index == 2) { ++ if (*legacy_connector == CONNECTOR_DVI_I_LEGACY) ++ return false; ++ } ++ ++ return true; ++} ++ ++bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t conn_info, entry, devices; ++ uint16_t tmp; ++ enum radeon_combios_ddc ddc_type; ++ enum radeon_combios_connector connector; ++ int i = 0; ++ struct radeon_i2c_bus_rec ddc_i2c; ++ struct drm_connector *drm_connector; ++ ++ DRM_DEBUG("\n"); ++ conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE); ++ if (conn_info) { ++ for (i = 0; i < 4; i++) { ++ entry = conn_info + 2 + i * 2; ++ ++ if (!radeon_bios16(dev_priv, entry)) ++ break; ++ ++ tmp = radeon_bios16(dev_priv, entry); ++ ++ connector = (tmp >> 12) & 0xf; ++ ++ ddc_type = (tmp >> 8) & 0xf; ++ switch (ddc_type) { ++ case DDC_MONID: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID); ++ break; ++ case DDC_DVI: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); ++ break; ++ case DDC_VGA: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); ++ break; ++ case DDC_CRT2: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); ++ break; ++ default: ++ break; ++ } ++ ++ radeon_apply_legacy_quirks(dev, i, &connector, &ddc_i2c); ++ ++ switch (connector) { ++ case CONNECTOR_PROPRIETARY_LEGACY: ++ if ((tmp >> 4) & 0x1) ++ devices = ATOM_DEVICE_DFP2_SUPPORT; ++ else ++ devices= ATOM_DEVICE_DFP1_SUPPORT; ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, devices, 0), ++ devices); ++ radeon_add_legacy_connector(dev, ++ i, ++ devices, ++ legacy_connector_convert[connector], ++ &ddc_i2c); ++ break; ++ case CONNECTOR_CRT_LEGACY: ++ if (tmp & 0x1) { ++ devices = ATOM_DEVICE_CRT2_SUPPORT; ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_CRT2_SUPPORT, 2), ++ ATOM_DEVICE_CRT2_SUPPORT); ++ } else { ++ devices = ATOM_DEVICE_CRT1_SUPPORT; ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_CRT1_SUPPORT, 1), ++ ATOM_DEVICE_CRT1_SUPPORT); ++ } ++ radeon_add_legacy_connector(dev, ++ i, ++ devices, ++ legacy_connector_convert[connector], ++ &ddc_i2c); ++ break; ++ case CONNECTOR_DVI_I_LEGACY: ++ devices = 0; ++ if (tmp & 0x1) { ++ devices |= ATOM_DEVICE_CRT2_SUPPORT; ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_CRT2_SUPPORT, 2), ++ ATOM_DEVICE_CRT2_SUPPORT); ++ } else { ++ devices |= ATOM_DEVICE_CRT1_SUPPORT; ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_CRT1_SUPPORT, 1), ++ ATOM_DEVICE_CRT1_SUPPORT); ++ } ++ if ((tmp >> 4) & 0x1) { ++ devices |= ATOM_DEVICE_DFP2_SUPPORT; ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_DFP2_SUPPORT, 0), ++ ATOM_DEVICE_DFP2_SUPPORT); ++ } else { ++ devices |= ATOM_DEVICE_DFP1_SUPPORT; ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_DFP1_SUPPORT, 0), ++ ATOM_DEVICE_DFP1_SUPPORT); ++ } ++ radeon_add_legacy_connector(dev, ++ i, ++ devices, ++ legacy_connector_convert[connector], ++ &ddc_i2c); ++ break; ++ case CONNECTOR_DVI_D_LEGACY: ++ if ((tmp >> 4) & 0x1) ++ devices = ATOM_DEVICE_DFP2_SUPPORT; ++ else ++ devices= ATOM_DEVICE_DFP1_SUPPORT; ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, devices, 0), ++ devices); ++ radeon_add_legacy_connector(dev, ++ i, ++ devices, ++ legacy_connector_convert[connector], ++ &ddc_i2c); ++ break; ++ case CONNECTOR_CTV_LEGACY: ++ case CONNECTOR_STV_LEGACY: ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_TV1_SUPPORT, 2), ++ ATOM_DEVICE_TV1_SUPPORT); ++ radeon_add_legacy_connector(dev, ++ i, ++ ATOM_DEVICE_TV1_SUPPORT, ++ legacy_connector_convert[connector], ++ &ddc_i2c); ++ break; ++ default: ++ DRM_ERROR("Unknown connector type: %d\n", connector); ++ continue; ++ } ++ ++ } ++ } else { ++ uint16_t tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); ++ if (tmds_info) { ++ DRM_DEBUG("Found DFP table, assuming DVI connector\n"); ++ ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_CRT1_SUPPORT, 1), ++ ATOM_DEVICE_CRT1_SUPPORT); ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_DFP1_SUPPORT, 0), ++ ATOM_DEVICE_DFP1_SUPPORT); ++ ++ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); ++ radeon_add_legacy_connector(dev, ++ 0, ++ ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT, ++ DRM_MODE_CONNECTOR_DVII, ++ &ddc_i2c); ++ } else { ++ DRM_DEBUG("No connector info found\n"); ++ return false; ++ } ++ } ++ ++ if (dev_priv->flags & RADEON_IS_MOBILITY || ++ dev_priv->flags & RADEON_IS_IGP) { ++ uint16_t lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); ++ if (lcd_info) { ++ uint16_t lcd_ddc_info = combios_get_table_offset(dev, COMBIOS_LCD_DDC_INFO_TABLE); ++ ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_LCD1_SUPPORT, 0), ++ ATOM_DEVICE_LCD1_SUPPORT); ++ ++ if (lcd_ddc_info) { ++ ddc_type = radeon_bios8(dev_priv, lcd_ddc_info + 2); ++ switch(ddc_type) { ++ case DDC_MONID: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID); ++ break; ++ case DDC_DVI: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); ++ break; ++ case DDC_VGA: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); ++ break; ++ case DDC_CRT2: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); ++ break; ++ case DDC_LCD: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK); ++ ddc_i2c.mask_clk_mask = radeon_bios32(dev_priv, lcd_ddc_info + 3); ++ ddc_i2c.mask_data_mask = radeon_bios32(dev_priv, lcd_ddc_info + 7); ++ ddc_i2c.a_clk_mask = radeon_bios32(dev_priv, lcd_ddc_info + 3); ++ ddc_i2c.a_data_mask = radeon_bios32(dev_priv, lcd_ddc_info + 7); ++ ddc_i2c.put_clk_mask = radeon_bios32(dev_priv, lcd_ddc_info + 3); ++ ddc_i2c.put_data_mask = radeon_bios32(dev_priv, lcd_ddc_info + 7); ++ ddc_i2c.get_clk_mask = radeon_bios32(dev_priv, lcd_ddc_info + 3); ++ ddc_i2c.get_data_mask = radeon_bios32(dev_priv, lcd_ddc_info + 7); ++ break; ++ case DDC_GPIO: ++ ddc_i2c = combios_setup_i2c_bus(RADEON_MDGPIO_EN_REG); ++ ddc_i2c.mask_clk_mask = radeon_bios32(dev_priv, lcd_ddc_info + 3); ++ ddc_i2c.mask_data_mask = radeon_bios32(dev_priv, lcd_ddc_info + 7); ++ ddc_i2c.a_clk_mask = radeon_bios32(dev_priv, lcd_ddc_info + 3); ++ ddc_i2c.a_data_mask = radeon_bios32(dev_priv, lcd_ddc_info + 7); ++ ddc_i2c.put_clk_mask = radeon_bios32(dev_priv, lcd_ddc_info + 3); ++ ddc_i2c.put_data_mask = radeon_bios32(dev_priv, lcd_ddc_info + 7); ++ ddc_i2c.get_clk_mask = radeon_bios32(dev_priv, lcd_ddc_info + 3); ++ ddc_i2c.get_data_mask = radeon_bios32(dev_priv, lcd_ddc_info + 7); ++ break; ++ default: ++ break; ++ } ++ DRM_DEBUG("LCD DDC Info Table found!\n"); ++ } else ++ ddc_i2c.valid = false; ++ ++ radeon_add_legacy_connector(dev, ++ 5, ++ ATOM_DEVICE_LCD1_SUPPORT, ++ DRM_MODE_CONNECTOR_LVDS, ++ &ddc_i2c); ++ } ++ } ++ ++ /* check TV table */ ++ if (dev_priv->chip_family != CHIP_R100 && ++ dev_priv->chip_family != CHIP_R200) { ++ uint32_t tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); ++ if (tv_info) { ++ if (radeon_bios8(dev_priv, tv_info + 6) == 'T') { ++ radeon_add_legacy_encoder(dev, ++ radeon_get_encoder_id(dev, ATOM_DEVICE_TV1_SUPPORT, 2), ++ ATOM_DEVICE_TV1_SUPPORT); ++ radeon_add_legacy_connector(dev, ++ 6, ++ ATOM_DEVICE_TV1_SUPPORT, ++ DRM_MODE_CONNECTOR_SVIDEO, ++ &ddc_i2c); ++ } ++ } ++ } ++ ++ radeon_link_encoder_connector(dev); ++ ++ list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) ++ radeon_ddc_dump(drm_connector); ++ ++ return true; ++} ++ ++static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ ++ if (offset) { ++ while (radeon_bios16(dev_priv, offset)) { ++ uint16_t cmd = ((radeon_bios16(dev_priv, offset) & 0xe000) >> 13); ++ uint32_t addr = (radeon_bios16(dev_priv, offset) & 0x1fff); ++ uint32_t val, and_mask, or_mask; ++ uint32_t tmp; ++ ++ offset += 2; ++ switch (cmd) { ++ case 0: ++ val = radeon_bios32(dev_priv, offset); ++ offset += 4; ++ RADEON_WRITE(addr, val); ++ break; ++ case 1: ++ val = radeon_bios32(dev_priv, offset); ++ offset += 4; ++ RADEON_WRITE(addr, val); ++ break; ++ case 2: ++ and_mask = radeon_bios32(dev_priv, offset); ++ offset += 4; ++ or_mask = radeon_bios32(dev_priv, offset); ++ offset += 4; ++ tmp = RADEON_READ(addr); ++ tmp &= and_mask; ++ tmp |= or_mask; ++ RADEON_WRITE(addr, tmp); ++ break; ++ case 3: ++ and_mask = radeon_bios32(dev_priv, offset); ++ offset += 4; ++ or_mask = radeon_bios32(dev_priv, offset); ++ offset += 4; ++ tmp = RADEON_READ(addr); ++ tmp &= and_mask; ++ tmp |= or_mask; ++ RADEON_WRITE(addr, tmp); ++ break; ++ case 4: ++ val = radeon_bios16(dev_priv, offset); ++ offset += 2; ++ udelay(val); ++ break; ++ case 5: ++ val = radeon_bios16(dev_priv, offset); ++ offset += 2; ++ switch (addr) { ++ case 8: ++ while (val--) { ++ if (!(RADEON_READ_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL) & ++ RADEON_MC_BUSY)) ++ break; ++ } ++ break; ++ case 9: ++ while (val--) { ++ if ((RADEON_READ(RADEON_MC_STATUS) & ++ RADEON_MC_IDLE)) ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ } ++} ++ ++static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ ++ if (offset) { ++ while (radeon_bios8(dev_priv, offset)) { ++ uint8_t cmd = ((radeon_bios8(dev_priv, offset) & 0xc0) >> 6); ++ uint8_t addr = (radeon_bios8(dev_priv, offset) & 0x3f); ++ uint32_t val, shift, tmp; ++ uint32_t and_mask, or_mask; ++ ++ offset++; ++ switch (cmd) { ++ case 0: ++ val = radeon_bios32(dev_priv, offset); ++ offset += 4; ++ RADEON_WRITE_PLL(dev_priv, addr, val); ++ break; ++ case 1: ++ shift = radeon_bios8(dev_priv, offset) * 8; ++ offset++; ++ and_mask = radeon_bios8(dev_priv, offset) << shift; ++ and_mask |= ~(0xff << shift); ++ offset++; ++ or_mask = radeon_bios8(dev_priv, offset) << shift; ++ offset++; ++ tmp = RADEON_READ_PLL(dev_priv, addr); ++ tmp &= and_mask; ++ tmp |= or_mask; ++ RADEON_WRITE_PLL(dev_priv, addr, tmp); ++ break; ++ case 2: ++ case 3: ++ tmp = 1000; ++ switch (addr) { ++ case 1: ++ udelay(150); ++ break; ++ case 2: ++ udelay(1000); ++ break; ++ case 3: ++ while (tmp--) { ++ if (!(RADEON_READ_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL) & ++ RADEON_MC_BUSY)) ++ break; ++ } ++ break; ++ case 4: ++ while (tmp--) { ++ if (RADEON_READ_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL) & ++ RADEON_DLL_READY) ++ break; ++ } ++ break; ++ case 5: ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL); ++ if (tmp & RADEON_CG_NO1_DEBUG_0) { ++#if 0 ++ uint32_t mclk_cntl = RADEON_READ_PLL(RADEON_MCLK_CNTL); ++ mclk_cntl &= 0xffff0000; ++ //mclk_cntl |= 0x00001111; /* ??? */ ++ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, mclk_cntl); ++ udelay(10000); ++#endif ++ RADEON_WRITE_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL, ++ tmp & ~RADEON_CG_NO1_DEBUG_0); ++ udelay(10000); ++ } ++ break; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ } ++} ++ ++static void combios_parse_ram_reset_table(struct drm_device *dev, uint16_t offset) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ if (offset) { ++ uint8_t val = radeon_bios8(dev_priv, offset); ++ while (val != 0xff) { ++ offset++; ++ ++ if (val == 0x0f) { ++ uint32_t channel_complete_mask; ++ ++ if (radeon_is_r300(dev_priv)) ++ channel_complete_mask = R300_MEM_PWRUP_COMPLETE; ++ else ++ channel_complete_mask = RADEON_MEM_PWRUP_COMPLETE; ++ tmp = 20000; ++ while (tmp--) { ++ if ((RADEON_READ(RADEON_MEM_STR_CNTL) & ++ channel_complete_mask) == ++ channel_complete_mask) ++ break; ++ } ++ } else { ++ uint32_t or_mask = radeon_bios16(dev_priv, offset); ++ offset += 2; ++ ++ tmp = RADEON_READ(RADEON_MEM_SDRAM_MODE_REG); ++ tmp &= RADEON_SDRAM_MODE_MASK; ++ tmp |= or_mask; ++ RADEON_WRITE(RADEON_MEM_SDRAM_MODE_REG, tmp); ++ ++ or_mask = val << 24; ++ tmp = RADEON_READ(RADEON_MEM_SDRAM_MODE_REG); ++ tmp &= RADEON_B3MEM_RESET_MASK; ++ tmp |= or_mask; ++ RADEON_WRITE(RADEON_MEM_SDRAM_MODE_REG, tmp); ++ } ++ val = radeon_bios8(dev_priv, offset); ++ } ++ } ++} ++ ++static uint32_t combios_detect_ram(struct drm_device *dev, int ram, int mem_addr_mapping) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t mem_cntl; ++ uint32_t mem_size; ++ uint32_t addr = 0; ++ ++ mem_cntl = RADEON_READ(RADEON_MEM_CNTL); ++ if (mem_cntl & RV100_HALF_MODE) ++ ram /= 2; ++ mem_size = ram; ++ mem_cntl &= ~(0xff << 8); ++ mem_cntl |= (mem_addr_mapping & 0xff) << 8; ++ RADEON_WRITE(RADEON_MEM_CNTL, mem_cntl); ++ RADEON_READ(RADEON_MEM_CNTL); ++ ++ /* sdram reset ? */ ++ ++ /* something like this???? */ ++ while (ram--) { ++ addr = ram * 1024 * 1024; ++ /* write to each page */ ++ RADEON_WRITE(RADEON_MM_INDEX, (addr) | RADEON_MM_APER); ++ RADEON_WRITE(RADEON_MM_DATA, 0xdeadbeef); ++ /* read back and verify */ ++ RADEON_WRITE(RADEON_MM_INDEX, (addr) | RADEON_MM_APER); ++ if (RADEON_READ(RADEON_MM_DATA) != 0xdeadbeef) ++ return 0; ++ } ++ ++ return mem_size; ++} ++ ++static void combios_write_ram_size(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint8_t rev; ++ uint16_t offset; ++ uint32_t mem_size = 0; ++ uint32_t mem_cntl = 0; ++ ++ /* should do something smarter here I guess... */ ++ if (dev_priv->flags & RADEON_IS_IGP) ++ return; ++ ++ /* first check detected mem table */ ++ offset = combios_get_table_offset(dev, COMBIOS_DETECTED_MEM_TABLE); ++ if (offset) { ++ rev = radeon_bios8(dev_priv, offset); ++ if (rev < 3) { ++ mem_cntl = radeon_bios32(dev_priv, offset + 1); ++ mem_size = radeon_bios16(dev_priv, offset + 5); ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R200) && ++ ((dev->pdev->device != 0x515e) && (dev->pdev->device != 0x5969))) ++ RADEON_WRITE(RADEON_MEM_CNTL, mem_cntl); ++ } ++ } ++ ++ if (!mem_size) { ++ offset = combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE); ++ if (offset) { ++ rev = radeon_bios8(dev_priv, offset - 1); ++ if (rev < 1) { ++ if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R200) && ++ ((dev->pdev->device != 0x515e) && (dev->pdev->device != 0x5969))) { ++ int ram = 0; ++ int mem_addr_mapping = 0; ++ ++ while (radeon_bios8(dev_priv, offset)) { ++ ram = radeon_bios8(dev_priv, offset); ++ mem_addr_mapping = radeon_bios8(dev_priv, offset + 1); ++ if (mem_addr_mapping != 0x25) ++ ram *= 2; ++ mem_size = combios_detect_ram(dev, ram, mem_addr_mapping); ++ if (mem_size) ++ break; ++ offset += 2; ++ } ++ } else ++ mem_size = radeon_bios8(dev_priv, offset); ++ } else { ++ mem_size = radeon_bios8(dev_priv, offset); ++ mem_size *= 2; /* convert to MB */ ++ } ++ } ++ } ++ ++ mem_size *= (1024 * 1024); /* convert to bytes */ ++ RADEON_WRITE(RADEON_CONFIG_MEMSIZE, mem_size); ++} ++ ++void radeon_combios_dyn_clk_setup(struct drm_device *dev, int enable) ++{ ++ uint16_t dyn_clk_info = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); ++ ++ if (dyn_clk_info) ++ combios_parse_pll_table(dev, dyn_clk_info); ++} ++ ++void radeon_combios_asic_init(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint16_t table; ++ ++ /* ASIC INIT 1 */ ++ table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_1_TABLE); ++ if (table) ++ combios_parse_mmio_table(dev, table); ++ ++ /* PLL INIT */ ++ table = combios_get_table_offset(dev, COMBIOS_PLL_INIT_TABLE); ++ if (table) ++ combios_parse_pll_table(dev, table); ++ ++ /* ASIC INIT 2 */ ++ table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_2_TABLE); ++ if (table) ++ combios_parse_mmio_table(dev, table); ++ ++ if (!(dev_priv->flags & RADEON_IS_IGP)) { ++ /* ASIC INIT 4 */ ++ table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_4_TABLE); ++ if (table) ++ combios_parse_mmio_table(dev, table); ++ ++ /* RAM RESET */ ++ table = combios_get_table_offset(dev, COMBIOS_RAM_RESET_TABLE); ++ if (table) ++ combios_parse_ram_reset_table(dev, table); ++ ++ /* ASIC INIT 3 */ ++ table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_3_TABLE); ++ if (table) ++ combios_parse_mmio_table(dev, table); ++ ++ /* write CONFIG_MEMSIZE */ ++ combios_write_ram_size(dev); ++ } ++ ++ /* DYN CLK 1 */ ++ table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); ++ if (table) ++ combios_parse_pll_table(dev, table); ++ ++} ++ ++void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t bios_0_scratch, bios_6_scratch, bios_7_scratch; ++ ++ bios_0_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH); ++ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); ++ //bios_7_scratch = RADEON_READ(RADEON_BIOS_7_SCRATCH); ++ ++ /* let the bios control the backlight */ ++ bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN; ++ ++ /* tell the bios not to handle mode switching */ ++ bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS | ++ RADEON_ACC_MODE_CHANGE); ++ ++ /* tell the bios a driver is loaded */ ++ //bios_7_scratch |= RADEON_DRV_LOADED; ++ ++ RADEON_WRITE(RADEON_BIOS_0_SCRATCH, bios_0_scratch); ++ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); ++ //RADEON_WRITE(RADEON_BIOS_7_SCRATCH, bios_7_scratch); ++} ++ ++void ++radeon_combios_output_lock(struct drm_encoder *encoder, bool lock) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t bios_6_scratch; ++ ++ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); ++ ++ if (lock) ++ bios_6_scratch |= RADEON_DRIVER_CRITICAL; ++ else ++ bios_6_scratch &= ~RADEON_DRIVER_CRITICAL; ++ ++ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); ++} ++ ++void ++radeon_combios_connected_scratch_regs(struct drm_connector *connector, ++ struct drm_encoder *encoder, ++ bool connected) ++{ ++ struct drm_device *dev = connector->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t bios_4_scratch = RADEON_READ(RADEON_BIOS_4_SCRATCH); ++ uint32_t bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH); ++ ++ if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("TV1 connected\n"); ++ /* fix me */ ++ bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; ++ /*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP;*/ ++ bios_5_scratch |= RADEON_TV1_ON; ++ bios_5_scratch |= RADEON_ACC_REQ_TV1; ++ } else { ++ DRM_DEBUG("TV1 disconnected\n"); ++ bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK; ++ bios_5_scratch &= ~RADEON_TV1_ON; ++ bios_5_scratch &= ~RADEON_ACC_REQ_TV1; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("LCD1 connected\n"); ++ bios_4_scratch |= RADEON_LCD1_ATTACHED; ++ bios_5_scratch |= RADEON_LCD1_ON; ++ bios_5_scratch |= RADEON_ACC_REQ_LCD1; ++ } else { ++ DRM_DEBUG("LCD1 disconnected\n"); ++ bios_4_scratch &= ~RADEON_LCD1_ATTACHED; ++ bios_5_scratch &= ~RADEON_LCD1_ON; ++ bios_5_scratch &= ~RADEON_ACC_REQ_LCD1; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("CRT1 connected\n"); ++ bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; ++ bios_5_scratch |= RADEON_CRT1_ON; ++ bios_5_scratch |= RADEON_ACC_REQ_CRT1; ++ } else { ++ DRM_DEBUG("CRT1 disconnected\n"); ++ bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; ++ bios_5_scratch &= ~RADEON_CRT1_ON; ++ bios_5_scratch &= ~RADEON_ACC_REQ_CRT1; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("CRT2 connected\n"); ++ bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; ++ bios_5_scratch |= RADEON_CRT2_ON; ++ bios_5_scratch |= RADEON_ACC_REQ_CRT2; ++ } else { ++ DRM_DEBUG("CRT2 disconnected\n"); ++ bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; ++ bios_5_scratch &= ~RADEON_CRT2_ON; ++ bios_5_scratch &= ~RADEON_ACC_REQ_CRT2; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("DFP1 connected\n"); ++ bios_4_scratch |= RADEON_DFP1_ATTACHED; ++ bios_5_scratch |= RADEON_DFP1_ON; ++ bios_5_scratch |= RADEON_ACC_REQ_DFP1; ++ } else { ++ DRM_DEBUG("DFP1 disconnected\n"); ++ bios_4_scratch &= ~RADEON_DFP1_ATTACHED; ++ bios_5_scratch &= ~RADEON_DFP1_ON; ++ bios_5_scratch &= ~RADEON_ACC_REQ_DFP1; ++ } ++ } ++ if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && ++ (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { ++ if (connected) { ++ DRM_DEBUG("DFP2 connected\n"); ++ bios_4_scratch |= RADEON_DFP2_ATTACHED; ++ bios_5_scratch |= RADEON_DFP2_ON; ++ bios_5_scratch |= RADEON_ACC_REQ_DFP2; ++ } else { ++ DRM_DEBUG("DFP2 disconnected\n"); ++ bios_4_scratch &= ~RADEON_DFP2_ATTACHED; ++ bios_5_scratch &= ~RADEON_DFP2_ON; ++ bios_5_scratch &= ~RADEON_ACC_REQ_DFP2; ++ } ++ } ++ RADEON_WRITE(RADEON_BIOS_4_SCRATCH, bios_4_scratch); ++ RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch); ++} ++ ++void ++radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH); ++ ++ if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { ++ bios_5_scratch &= ~RADEON_TV1_CRTC_MASK; ++ bios_5_scratch |= (crtc << RADEON_TV1_CRTC_SHIFT); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { ++ bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK; ++ bios_5_scratch |= (crtc << RADEON_CRT1_CRTC_SHIFT); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { ++ bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK; ++ bios_5_scratch |= (crtc << RADEON_CRT2_CRTC_SHIFT); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { ++ bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK; ++ bios_5_scratch |= (crtc << RADEON_LCD1_CRTC_SHIFT); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) { ++ bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK; ++ bios_5_scratch |= (crtc << RADEON_DFP1_CRTC_SHIFT); ++ } ++ if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) { ++ bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK; ++ bios_5_scratch |= (crtc << RADEON_DFP2_CRTC_SHIFT); ++ } ++ RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch); ++} ++ ++void ++radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); ++ ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { ++ if (on) ++ bios_6_scratch |= RADEON_TV_DPMS_ON; ++ else ++ bios_6_scratch &= ~RADEON_TV_DPMS_ON; ++ } ++ if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { ++ if (on) ++ bios_6_scratch |= RADEON_CRT_DPMS_ON; ++ else ++ bios_6_scratch &= ~RADEON_CRT_DPMS_ON; ++ } ++ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { ++ if (on) ++ bios_6_scratch |= RADEON_LCD_DPMS_ON; ++ else ++ bios_6_scratch &= ~RADEON_LCD_DPMS_ON; ++ } ++ if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { ++ if (on) ++ bios_6_scratch |= RADEON_DFP_DPMS_ON; ++ else ++ bios_6_scratch &= ~RADEON_DFP_DPMS_ON; ++ } ++ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_connectors.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_connectors.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_connectors.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_connectors.c 2009-04-26 03:00:41.120725462 +0200 +@@ -0,0 +1,608 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "drm_edid.h" ++#include "drm_crtc_helper.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++extern void ++radeon_combios_connected_scratch_regs(struct drm_connector *connector, ++ struct drm_encoder *encoder, ++ bool connected); ++extern void ++radeon_atombios_connected_scratch_regs(struct drm_connector *connector, ++ struct drm_encoder *encoder, ++ bool connected); ++ ++static void ++radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) ++{ ++ struct drm_device *dev = connector->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_encoder *best_encoder = NULL; ++ struct drm_encoder *encoder = NULL; ++ struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; ++ struct drm_mode_object *obj; ++ bool connected; ++ int i; ++ ++ best_encoder = connector_funcs->best_encoder(connector); ++ ++ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { ++ if (connector->encoder_ids[i] == 0) ++ break; ++ ++ obj = drm_mode_object_find(connector->dev, ++ connector->encoder_ids[i], ++ DRM_MODE_OBJECT_ENCODER); ++ if (!obj) ++ continue; ++ ++ encoder = obj_to_encoder(obj); ++ ++ if ((encoder == best_encoder) && (status == connector_status_connected)) ++ connected = true; ++ else ++ connected = false; ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_connected_scratch_regs(connector, encoder, connected); ++ else ++ radeon_combios_connected_scratch_regs(connector, encoder, connected); ++ ++ } ++} ++ ++struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) ++{ ++ int enc_id = connector->encoder_ids[0]; ++ struct drm_mode_object *obj; ++ struct drm_encoder *encoder; ++ ++ /* pick the encoder ids */ ++ if (enc_id) { ++ obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); ++ if (!obj) ++ return NULL; ++ encoder = obj_to_encoder(obj); ++ return encoder; ++ } ++ return NULL; ++} ++ ++static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct drm_display_mode *mode = NULL; ++ struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; ++ ++ if (native_mode->panel_xres != 0 && ++ native_mode->panel_yres != 0 && ++ native_mode->dotclock != 0) { ++ mode = drm_mode_create(dev); ++ ++ mode->hdisplay = native_mode->panel_xres; ++ mode->vdisplay = native_mode->panel_yres; ++ ++ mode->htotal = mode->hdisplay + native_mode->hblank; ++ mode->hsync_start = mode->hdisplay + native_mode->hoverplus; ++ mode->hsync_end = mode->hsync_start + native_mode->hsync_width; ++ mode->vtotal = mode->vdisplay + native_mode->vblank; ++ mode->vsync_start = mode->vdisplay + native_mode->voverplus; ++ mode->vsync_end = mode->vsync_start + native_mode->vsync_width; ++ mode->clock = native_mode->dotclock; ++ mode->flags = 0; ++ ++ mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; ++ drm_mode_set_name(mode); ++ ++ DRM_DEBUG("Adding native panel mode %s\n", mode->name); ++ } ++ return mode; ++} ++ ++int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, ++ uint64_t val) ++{ ++ struct drm_device *dev = connector->dev; ++ ++ if (property == dev->mode_config.dpms_property) { ++ if (val > 3) ++ return -EINVAL; ++ ++ drm_helper_set_connector_dpms(connector, val); ++ ++ } ++ return 0; ++} ++ ++ ++static int radeon_lvds_get_modes(struct drm_connector *connector) ++{ ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ struct drm_encoder *encoder; ++ int ret = 0; ++ struct edid *edid; ++ struct drm_display_mode *mode; ++ ++ if (radeon_connector->ddc_bus) { ++ radeon_i2c_do_lock(radeon_connector, 1); ++ edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); ++ radeon_i2c_do_lock(radeon_connector, 0); ++ if (edid) { ++ drm_mode_connector_update_edid_property(&radeon_connector->base, edid); ++ ret = drm_add_edid_modes(&radeon_connector->base, edid); ++ kfree(edid); ++ if (ret == 0) ++ goto native; ++ return ret; ++ } ++ } ++ ++native: ++ encoder = radeon_best_single_encoder(connector); ++ if (!encoder) ++ return 0; ++ ++ /* we have no EDID modes */ ++ mode = radeon_fp_native_mode(encoder); ++ if (mode) { ++ ret = 1; ++ drm_mode_probed_add(connector, mode); ++ } ++ return ret; ++} ++ ++static int radeon_lvds_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) ++{ ++ return MODE_OK; ++} ++ ++static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) ++{ ++ enum drm_connector_status ret = connector_status_connected; ++ // check acpi lid status ??? ++ radeon_connector_update_scratch_regs(connector, ret); ++ return ret; ++} ++ ++static void radeon_connector_destroy(struct drm_connector *connector) ++{ ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ ++ if (radeon_connector->ddc_bus) ++ radeon_i2c_destroy(radeon_connector->ddc_bus); ++ kfree(radeon_connector->con_priv); ++ drm_sysfs_connector_remove(connector); ++ drm_connector_cleanup(connector); ++ kfree(connector); ++} ++ ++struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = { ++ .get_modes = radeon_lvds_get_modes, ++ .mode_valid = radeon_lvds_mode_valid, ++ .best_encoder = radeon_best_single_encoder, ++}; ++ ++struct drm_connector_funcs radeon_lvds_connector_funcs = { ++ .detect = radeon_lvds_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .destroy = radeon_connector_destroy, ++ .set_property = radeon_connector_set_property, ++}; ++ ++static int radeon_vga_get_modes(struct drm_connector *connector) ++{ ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ int ret; ++ ++ ret = radeon_ddc_get_modes(radeon_connector); ++ ++ return ret; ++} ++ ++static int radeon_vga_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) ++{ ++ ++ return MODE_OK; ++} ++ ++static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector) ++{ ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ struct drm_encoder *encoder; ++ struct drm_encoder_helper_funcs *encoder_funcs; ++ bool dret; ++ enum drm_connector_status ret = connector_status_disconnected; ++ ++ radeon_i2c_do_lock(radeon_connector, 1); ++ dret = radeon_ddc_probe(radeon_connector); ++ radeon_i2c_do_lock(radeon_connector, 0); ++ if (dret) ++ ret = connector_status_connected; ++ else { ++ /* if EDID fails to a load detect */ ++ encoder = radeon_best_single_encoder(connector); ++ if (!encoder) ++ ret = connector_status_disconnected; ++ else { ++ encoder_funcs = encoder->helper_private; ++ ret = encoder_funcs->detect(encoder, connector); ++ } ++ } ++ ++ radeon_connector_update_scratch_regs(connector, ret); ++ return ret; ++} ++ ++struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = { ++ .get_modes = radeon_vga_get_modes, ++ .mode_valid = radeon_vga_mode_valid, ++ .best_encoder = radeon_best_single_encoder, ++}; ++ ++struct drm_connector_funcs radeon_vga_connector_funcs = { ++ .detect = radeon_vga_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .destroy = radeon_connector_destroy, ++ .set_property = radeon_connector_set_property, ++}; ++ ++static int radeon_dvi_get_modes(struct drm_connector *connector) ++{ ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ int ret; ++ ++ ret = radeon_ddc_get_modes(radeon_connector); ++ /* reset scratch regs here since radeon_dvi_detect doesn't check digital bit */ ++ radeon_connector_update_scratch_regs(connector, connector_status_connected); ++ return ret; ++} ++ ++static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) ++{ ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ struct drm_encoder *encoder; ++ struct drm_encoder_helper_funcs *encoder_funcs; ++ struct drm_mode_object *obj; ++ int i; ++ enum drm_connector_status ret = connector_status_disconnected; ++ bool dret; ++ ++ radeon_i2c_do_lock(radeon_connector, 1); ++ dret = radeon_ddc_probe(radeon_connector); ++ radeon_i2c_do_lock(radeon_connector, 0); ++ if (dret) ++ ret = connector_status_connected; ++ else { ++ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { ++ if (connector->encoder_ids[i] == 0) ++ break; ++ ++ obj = drm_mode_object_find(connector->dev, ++ connector->encoder_ids[i], ++ DRM_MODE_OBJECT_ENCODER); ++ if (!obj) ++ continue; ++ ++ encoder = obj_to_encoder(obj); ++ ++ encoder_funcs = encoder->helper_private; ++ if (encoder_funcs->detect) { ++ ret = encoder_funcs->detect(encoder, connector); ++ if (ret == connector_status_connected) { ++ radeon_connector->use_digital = 0; ++ break; ++ } ++ } ++ } ++ } ++ ++ /* updated in get modes as well since we need to know if it's analog or digital */ ++ radeon_connector_update_scratch_regs(connector, ret); ++ return ret; ++} ++ ++/* okay need to be smart in here about which encoder to pick */ ++struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) ++{ ++ int enc_id = connector->encoder_ids[0]; ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ struct drm_mode_object *obj; ++ struct drm_encoder *encoder; ++ int i; ++ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { ++ if (connector->encoder_ids[i] == 0) ++ break; ++ ++ obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); ++ if (!obj) ++ continue; ++ ++ encoder = obj_to_encoder(obj); ++ ++ if (radeon_connector->use_digital) { ++ if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) ++ return encoder; ++ } else { ++ if (encoder->encoder_type == DRM_MODE_ENCODER_DAC || ++ encoder->encoder_type == DRM_MODE_ENCODER_TVDAC) ++ return encoder; ++ } ++ } ++ ++ /* see if we have a default encoder TODO */ ++ ++ /* then check use digitial */ ++ /* pick the first one */ ++ if (enc_id) { ++ obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); ++ if (!obj) ++ return NULL; ++ encoder = obj_to_encoder(obj); ++ return encoder; ++ } ++ return NULL; ++} ++ ++struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { ++ .get_modes = radeon_dvi_get_modes, ++ .mode_valid = radeon_vga_mode_valid, ++ .best_encoder = radeon_dvi_encoder, ++}; ++ ++struct drm_connector_funcs radeon_dvi_connector_funcs = { ++ .detect = radeon_dvi_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .set_property = radeon_connector_set_property, ++ .destroy = radeon_connector_destroy, ++}; ++ ++void ++radeon_add_atom_connector(struct drm_device *dev, ++ uint32_t connector_id, ++ uint32_t supported_device, ++ int connector_type, ++ struct radeon_i2c_bus_rec *i2c_bus, ++ bool linkb, ++ uint32_t igp_lane_info) ++{ ++ struct drm_connector *connector; ++ struct radeon_connector *radeon_connector; ++ struct radeon_connector_atom_dig *radeon_dig_connector; ++ ++ /* fixme - tv/cv/din */ ++ if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || ++ (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || ++ (connector_type == DRM_MODE_CONNECTOR_Composite) || ++ (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) ++ return; ++ ++ /* see if we already added it */ ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { ++ radeon_connector = to_radeon_connector(connector); ++ if (radeon_connector->connector_id == connector_id) { ++ radeon_connector->devices |= supported_device; ++ return; ++ } ++ } ++ ++ radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); ++ if (!radeon_connector) ++ return; ++ ++ connector = &radeon_connector->base; ++ ++ radeon_connector->connector_id = connector_id; ++ radeon_connector->devices = supported_device; ++ switch (connector_type) { ++ case DRM_MODE_CONNECTOR_VGA: ++ drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ case DRM_MODE_CONNECTOR_DVIA: ++ drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ case DRM_MODE_CONNECTOR_DVII: ++ case DRM_MODE_CONNECTOR_DVID: ++ radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); ++ if (!radeon_dig_connector) ++ goto failed; ++ radeon_dig_connector->linkb = linkb; ++ radeon_dig_connector->igp_lane_info = igp_lane_info; ++ radeon_connector->con_priv = radeon_dig_connector; ++ drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ case DRM_MODE_CONNECTOR_HDMIA: ++ case DRM_MODE_CONNECTOR_HDMIB: ++ radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); ++ if (!radeon_dig_connector) ++ goto failed; ++ radeon_dig_connector->linkb = linkb; ++ radeon_dig_connector->igp_lane_info = igp_lane_info; ++ radeon_connector->con_priv = radeon_dig_connector; ++ drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ case DRM_MODE_CONNECTOR_DisplayPort: ++ radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); ++ if (!radeon_dig_connector) ++ goto failed; ++ radeon_dig_connector->linkb = linkb; ++ radeon_dig_connector->igp_lane_info = igp_lane_info; ++ radeon_connector->con_priv = radeon_dig_connector; ++ drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ case DRM_MODE_CONNECTOR_SVIDEO: ++ case DRM_MODE_CONNECTOR_Composite: ++ case DRM_MODE_CONNECTOR_9PinDIN: ++ break; ++ case DRM_MODE_CONNECTOR_LVDS: ++ radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); ++ if (!radeon_dig_connector) ++ goto failed; ++ radeon_dig_connector->linkb = linkb; ++ radeon_dig_connector->igp_lane_info = igp_lane_info; ++ radeon_connector->con_priv = radeon_dig_connector; ++ drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ } ++ ++ drm_sysfs_connector_add(connector); ++ return; ++ ++failed: ++ if (radeon_connector->ddc_bus) ++ radeon_i2c_destroy(radeon_connector->ddc_bus); ++ drm_connector_cleanup(connector); ++ kfree(connector); ++} ++ ++void ++radeon_add_legacy_connector(struct drm_device *dev, ++ uint32_t connector_id, ++ uint32_t supported_device, ++ int connector_type, ++ struct radeon_i2c_bus_rec *i2c_bus) ++{ ++ struct drm_connector *connector; ++ struct radeon_connector *radeon_connector; ++ ++ /* fixme - tv/cv/din */ ++ if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || ++ (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || ++ (connector_type == DRM_MODE_CONNECTOR_Composite) || ++ (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) ++ return; ++ ++ /* see if we already added it */ ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { ++ radeon_connector = to_radeon_connector(connector); ++ if (radeon_connector->connector_id == connector_id) { ++ radeon_connector->devices |= supported_device; ++ return; ++ } ++ } ++ ++ radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); ++ if (!radeon_connector) ++ return; ++ ++ connector = &radeon_connector->base; ++ ++ radeon_connector->connector_id = connector_id; ++ radeon_connector->devices = supported_device; ++ switch (connector_type) { ++ case DRM_MODE_CONNECTOR_VGA: ++ drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ case DRM_MODE_CONNECTOR_DVIA: ++ drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ case DRM_MODE_CONNECTOR_DVII: ++ case DRM_MODE_CONNECTOR_DVID: ++ drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ case DRM_MODE_CONNECTOR_SVIDEO: ++ case DRM_MODE_CONNECTOR_Composite: ++ case DRM_MODE_CONNECTOR_9PinDIN: ++ break; ++ case DRM_MODE_CONNECTOR_LVDS: ++ drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); ++ if (i2c_bus->valid) { ++ radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); ++ if (!radeon_connector->ddc_bus) ++ goto failed; ++ } ++ break; ++ } ++ ++ drm_sysfs_connector_add(connector); ++ return; ++ ++failed: ++ if (radeon_connector->ddc_bus) ++ radeon_i2c_destroy(radeon_connector->ddc_bus); ++ drm_connector_cleanup(connector); ++ kfree(connector); ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_cp.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_cp.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_cp.c 2009-04-26 02:52:17.301726065 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_cp.c 2009-04-26 02:56:39.186726473 +0200 +@@ -46,8 +46,12 @@ + u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off) + { + u32 val; +- +- if (dev_priv->flags & RADEON_IS_AGP) { ++ if (dev_priv->mm.ring_read.bo) { ++ val = *(((volatile u32 *) ++ dev_priv->mm.ring_read.kmap.virtual) + ++ (off / sizeof(u32))); ++ val = le32_to_cpu(val); ++ } else if (dev_priv->flags & RADEON_IS_AGP) { + val = DRM_READ32(dev_priv->ring_rptr, off); + } else { + val = *(((volatile u32 *) +@@ -60,9 +64,11 @@ + + u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv) + { +- if (dev_priv->writeback_works) ++ if (dev_priv->writeback_works) { ++ if (dev_priv->mm.ring_read.bo) ++ return readl(dev_priv->mm.ring_read.kmap.virtual); + return radeon_read_ring_rptr(dev_priv, 0); +- else { ++ } else { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return RADEON_READ(R600_CP_RB_RPTR); + else +@@ -72,7 +78,10 @@ + + void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val) + { +- if (dev_priv->flags & RADEON_IS_AGP) ++ if (dev_priv->mm.ring_read.bo) ++ *(((volatile u32 *) dev_priv->mm.ring_read.kmap.virtual) + ++ (off / sizeof(u32))) = cpu_to_le32(val); ++ else if (dev_priv->flags & RADEON_IS_AGP) + DRM_WRITE32(dev_priv->ring_rptr, off, val); + else + *(((volatile u32 *) dev_priv->ring_rptr->handle) + +@@ -81,12 +90,19 @@ + + void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val) + { ++ if (dev_priv->mm.ring_read.bo) { ++ writel(val, dev_priv->mm.ring_read.kmap.virtual); ++ return; ++ } + radeon_write_ring_rptr(dev_priv, 0, val); + } + + u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index) + { + if (dev_priv->writeback_works) { ++ if (dev_priv->mm.ring_read.bo) { ++ return readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(index)); ++ } + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return radeon_read_ring_rptr(dev_priv, + R600_SCRATCHOFF(index)); +@@ -151,15 +167,18 @@ + return ret; + } + +-static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) ++u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) + { + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + return RS690_READ_MCIND(dev_priv, addr); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + return RS600_READ_MCIND(dev_priv, addr); +- else ++ else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) + return RS480_READ_MCIND(dev_priv, addr); ++ else ++ return R500_READ_MCIND(dev_priv, addr); + } + + u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) +@@ -169,39 +188,66 @@ + return RADEON_READ(R700_MC_VM_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return RADEON_READ(R600_MC_VM_FB_LOCATION); +- else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) +- return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); + else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ++ return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) + return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); + else + return RADEON_READ(RADEON_MC_FB_LOCATION); + } + +-static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) ++void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *agp_hi) ++{ ++ if (dev_priv->chip_family == CHIP_RV770) { ++ *agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT); ++ *agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP); ++ } else if (dev_priv->chip_family == CHIP_R600) { ++ *agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT); ++ *agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP); ++ } else if (dev_priv->chip_family == CHIP_RV515) { ++ *agp_lo = RADEON_READ_MCIND(dev_priv, RV515_MC_AGP_LOCATION); ++ *agp_hi = 0; ++ } else if (dev_priv->chip_family == CHIP_RS600) { ++ *agp_lo = RADEON_READ_MCIND(dev_priv, RS600_MC_AGP_LOCATION); ++ *agp_hi = 0; ++ } else if (dev_priv->chip_family == CHIP_RS690 || ++ dev_priv->chip_family == CHIP_RS740) { ++ *agp_lo = RADEON_READ_MCIND(dev_priv, RS690_MC_AGP_LOCATION); ++ *agp_hi = 0; ++ } else if (dev_priv->chip_family >= CHIP_R520) { ++ *agp_lo = RADEON_READ_MCIND(dev_priv, R520_MC_AGP_LOCATION); ++ *agp_hi = 0; ++ } else { ++ *agp_lo = RADEON_READ(RADEON_MC_AGP_LOCATION); ++ *agp_hi = 0; ++ } ++} ++ ++void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) + { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); +- else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) +- R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); + else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ++ R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) + R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); + else + RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); + } + +-void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) ++void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc, u32 agp_loc_hi) + { + /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { +@@ -210,13 +256,13 @@ + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ + RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); +- } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) +- R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); +- else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || +- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) ++ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc); ++ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ++ R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) + R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); + else +@@ -234,16 +280,16 @@ + RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base); +- else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { +- R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); +- R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); +- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ++ else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); + RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { + RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo); + RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi); ++ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { ++ R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); ++ R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { + R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); + R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); +@@ -277,20 +323,111 @@ + } /* PCIE cards appears to not need this */ + } + +-static int RADEON_READ_PLL(struct drm_device * dev, int addr) ++void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv) + { +- drm_radeon_private_t *dev_priv = dev->dev_private; ++ if (!(dev_priv->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) ++ return; + +- RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); +- return RADEON_READ(RADEON_CLOCK_CNTL_DATA); ++ (void)RADEON_READ(RADEON_CLOCK_CNTL_DATA); ++ (void)RADEON_READ(RADEON_CRTC_GEN_CNTL); + } + +-static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) ++void radeon_pll_errata_after_data(struct drm_radeon_private *dev_priv) ++{ ++ /* This workarounds is necessary on RV100, RS100 and RS200 chips ++ * or the chip could hang on a subsequent access ++ */ ++ if (dev_priv->pll_errata & CHIP_ERRATA_PLL_DELAY) ++ udelay(5000); ++ ++ /* This function is required to workaround a hardware bug in some (all?) ++ * revisions of the R300. This workaround should be called after every ++ * CLOCK_CNTL_INDEX register access. If not, register reads afterward ++ * may not be correct. ++ */ ++ if (dev_priv->pll_errata & CHIP_ERRATA_R300_CG) { ++ uint32_t save, tmp; ++ ++ save = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); ++ tmp = save & ~(0x3f | RADEON_PLL_WR_EN); ++ RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, tmp); ++ tmp = RADEON_READ(RADEON_CLOCK_CNTL_DATA); ++ RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, save); ++ } ++} ++ ++u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr) ++{ ++ uint32_t data; ++ ++ RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f); ++ radeon_pll_errata_after_index(dev_priv); ++ data = RADEON_READ(RADEON_CLOCK_CNTL_DATA); ++ radeon_pll_errata_after_data(dev_priv); ++ return data; ++} ++ ++void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data) ++{ ++ RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, ((addr & 0x3f) | RADEON_PLL_WR_EN)); ++ radeon_pll_errata_after_index(dev_priv); ++ RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, data); ++ radeon_pll_errata_after_data(dev_priv); ++} ++ ++u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) + { + RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); + return RADEON_READ(RADEON_PCIE_DATA); + } + ++/* ATOM accessor methods */ ++static uint32_t cail_pll_read(struct card_info *info, uint32_t reg) ++{ ++ uint32_t ret = RADEON_READ_PLL(info->dev->dev_private, reg); ++ DRM_DEBUG("(%x) = %x\n", reg, ret); ++ return ret; ++} ++ ++static void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val) ++{ ++ DRM_DEBUG("(%x, %x)\n", reg, val); ++ RADEON_WRITE_PLL(info->dev->dev_private, reg, val); ++} ++ ++static uint32_t cail_mc_read(struct card_info *info, uint32_t reg) ++{ ++ uint32_t ret = RADEON_READ_MCIND(info->dev->dev_private, reg); ++ ++ /* DRM_DEBUG("(%x) = %x\n", reg, ret); */ ++ return ret; ++} ++ ++static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val) ++{ ++ drm_radeon_private_t *dev_priv = info->dev->dev_private; ++ /* DRM_DEBUG("(%x, %x)\n", reg, val);*/ ++ RADEON_WRITE_MCIND(reg, val); ++} ++ ++static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val) ++{ ++ drm_radeon_private_t *dev_priv = info->dev->dev_private; ++ ++ // DRM_DEBUG("(%x, %x)\n", reg*4, val); ++ RADEON_WRITE(reg*4, val); ++} ++ ++static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) ++{ ++ uint32_t ret; ++ drm_radeon_private_t *dev_priv = info->dev->dev_private; ++ ++ ret = RADEON_READ(reg*4); ++ // DRM_DEBUG("(%x) = %x\n", reg*4, ret); ++ return ret; ++} ++ + #if RADEON_FIFO_DEBUG + static void radeon_status(drm_radeon_private_t * dev_priv) + { +@@ -373,7 +510,7 @@ + return -EBUSY; + } + +-static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) ++int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) + { + int i, ret; + +@@ -433,7 +570,7 @@ + } + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { +- RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); ++ RADEON_WRITE_PLL(dev_priv, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); + RADEON_WRITE(R300_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); + } + RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); +@@ -547,7 +684,6 @@ + DRM_DEBUG("\n"); + #if 0 + u32 tmp; +- + tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31); + RADEON_WRITE(RADEON_CP_RB_WPTR, tmp); + #endif +@@ -588,10 +724,15 @@ + BEGIN_RING(8); + /* isync can only be written through cp on r5xx write it here */ + OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0)); ++ if (dev_priv->chip_family > CHIP_RV280) ++ OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | ++ RADEON_ISYNC_ANY3D_IDLE2D | ++ RADEON_ISYNC_WAIT_IDLEGUI | ++ dev_priv->mm_enabled ? 0 : RADEON_ISYNC_CPSCRATCH_IDLEGUI); ++ else + OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | +- RADEON_ISYNC_WAIT_IDLEGUI | +- RADEON_ISYNC_CPSCRATCH_IDLEGUI); ++ RADEON_ISYNC_WAIT_IDLEGUI); + RADEON_PURGE_CACHE(); + RADEON_PURGE_ZCACHE(); + RADEON_WAIT_UNTIL_IDLE(); +@@ -642,15 +783,15 @@ + if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { + /* may need something similar for newer chips */ + clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); +- mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); ++ mclk_cntl = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); + +- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | +- RADEON_FORCEON_MCLKA | +- RADEON_FORCEON_MCLKB | +- RADEON_FORCEON_YCLKA | +- RADEON_FORCEON_YCLKB | +- RADEON_FORCEON_MC | +- RADEON_FORCEON_AIC)); ++ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, (mclk_cntl | ++ RADEON_FORCEON_MCLKA | ++ RADEON_FORCEON_MCLKB | ++ RADEON_FORCEON_YCLKA | ++ RADEON_FORCEON_YCLKB | ++ RADEON_FORCEON_MC | ++ RADEON_FORCEON_AIC)); + } + + rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); +@@ -675,7 +816,7 @@ + RADEON_READ(RADEON_RBBM_SOFT_RESET); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { +- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); ++ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, mclk_cntl); + RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); + RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); + } +@@ -691,7 +832,8 @@ + dev_priv->cp_running = 0; + + /* Reset any pending vertex, indirect buffers */ +- radeon_freelist_reset(dev); ++ if (dev->dma) ++ radeon_freelist_reset(dev); + + return 0; + } +@@ -710,9 +852,13 @@ + */ + if (!dev_priv->new_memmap) + radeon_write_fb_location(dev_priv, +- ((dev_priv->gart_vm_start - 1) & 0xffff0000) +- | (dev_priv->fb_location >> 16)); +- ++ ((dev_priv->gart_vm_start - 1) & 0xffff0000) ++ | (dev_priv->fb_location >> 16)); ++ ++ if (dev_priv->mm.ring.bo) { ++ ring_start = dev_priv->mm.ring.bo->offset + ++ dev_priv->gart_vm_start; ++ } else + #if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + radeon_write_agp_base(dev_priv, dev->agp->base); +@@ -720,7 +866,7 @@ + radeon_write_agp_location(dev_priv, + (((dev_priv->gart_vm_start - 1 + + dev_priv->gart_size) & 0xffff0000) | +- (dev_priv->gart_vm_start >> 16))); ++ (dev_priv->gart_vm_start >> 16)), 0); + + ring_start = (dev_priv->cp_ring->offset + - dev->agp->base +@@ -742,6 +888,12 @@ + SET_RING_HEAD(dev_priv, cur_read_ptr); + dev_priv->ring.tail = cur_read_ptr; + ++ ++ if (dev_priv->mm.ring_read.bo) { ++ RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, ++ dev_priv->mm.ring_read.bo->offset + ++ dev_priv->gart_vm_start); ++ } else + #if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, +@@ -781,7 +933,10 @@ + RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + + RADEON_SCRATCH_REG_OFFSET); + +- RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); ++ if (dev_priv->chip_family > CHIP_R300) ++ RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7f); ++ else ++ RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x1f); + + radeon_enable_bm(dev_priv); + +@@ -794,32 +949,53 @@ + radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0); + RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); + ++ RADEON_WRITE(RADEON_LAST_SWI_REG, 0); ++ ++ RADEON_WRITE(RADEON_SCRATCH_REG4, 0); ++ ++ RADEON_WRITE(RADEON_SCRATCH_REG6, 0); ++ + /* reset sarea copies of these */ +- master_priv = file_priv->master->driver_priv; +- if (master_priv->sarea_priv) { +- master_priv->sarea_priv->last_frame = 0; +- master_priv->sarea_priv->last_dispatch = 0; +- master_priv->sarea_priv->last_clear = 0; ++ if (file_priv) { ++ master_priv = file_priv->master->driver_priv; ++ if (master_priv->sarea_priv) { ++ master_priv->sarea_priv->last_frame = 0; ++ master_priv->sarea_priv->last_dispatch = 0; ++ master_priv->sarea_priv->last_clear = 0; ++ } + } + + radeon_do_wait_for_idle(dev_priv); + + /* Sync everything up */ ++ if (dev_priv->chip_family > CHIP_RV280) { + RADEON_WRITE(RADEON_ISYNC_CNTL, + (RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | + RADEON_ISYNC_WAIT_IDLEGUI | + RADEON_ISYNC_CPSCRATCH_IDLEGUI)); +- ++ } else { ++ RADEON_WRITE(RADEON_ISYNC_CNTL, ++ (RADEON_ISYNC_ANY2D_IDLE3D | ++ RADEON_ISYNC_ANY3D_IDLE2D | ++ RADEON_ISYNC_WAIT_IDLEGUI)); ++ } + } + + static void radeon_test_writeback(drm_radeon_private_t * dev_priv) + { +- u32 tmp; ++ u32 tmp, scratch1_store; ++ void *ring_read_ptr; ++ ++ if (dev_priv->mm.ring_read.bo) ++ ring_read_ptr = dev_priv->mm.ring_read.kmap.virtual; ++ else ++ ring_read_ptr = dev_priv->ring_rptr->handle; + + /* Start with assuming that writeback doesn't work */ + dev_priv->writeback_works = 0; + ++ scratch1_store = RADEON_READ(RADEON_SCRATCH_REG1); + /* Writeback doesn't seem to work everywhere, test it here and possibly + * enable it if it appears to work + */ +@@ -848,10 +1024,12 @@ + DRM_INFO("writeback forced off\n"); + } + ++ /* write back previous value */ ++ RADEON_WRITE(RADEON_SCRATCH_REG1, scratch1_store); ++ + if (!dev_priv->writeback_works) { +- /* Disable writeback to avoid unnecessary bus master transfer */ +- RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | +- RADEON_RB_NO_UPDATE); ++ /* Disable writeback to avoid unnecessary bus master transfers */ ++ RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | RADEON_RB_NO_UPDATE); + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0); + } + } +@@ -862,68 +1040,90 @@ + u32 temp; + + if (on) { ++ u32 size_reg; + DRM_DEBUG("programming igp gart %08X %08lX %08X\n", +- dev_priv->gart_vm_start, +- (long)dev_priv->gart_info.bus_addr, +- dev_priv->gart_size); ++ dev_priv->gart_vm_start, ++ (long)dev_priv->gart_info.bus_addr, ++ dev_priv->gart_size); ++ ++ switch(dev_priv->gart_size/(1024*1024)) { ++ case 32: size_reg = RS480_VA_SIZE_32MB; break; ++ case 64: size_reg = RS480_VA_SIZE_64MB; break; ++ case 128: size_reg = RS480_VA_SIZE_128MB; break; ++ case 256: size_reg = RS480_VA_SIZE_256MB; break; ++ case 512: size_reg = RS480_VA_SIZE_512MB; break; ++ case 1024: size_reg = RS480_VA_SIZE_1GB; break; ++ case 2048: size_reg = RS480_VA_SIZE_2GB; break; ++ default: ++ DRM_ERROR("Unable to use IGP GART table size %d\n", dev_priv->gart_info.table_size); ++ size_reg = RS480_VA_SIZE_32MB; ++ break; ++ } + +- temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); ++ temp = RADEON_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) +- IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | +- RS690_BLOCK_GFX_D3_EN)); ++ RADEON_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | ++ RS690_BLOCK_GFX_D3_EN)); + else +- IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); ++ RADEON_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); + +- IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | +- RS480_VA_SIZE_32MB)); ++ RADEON_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg)); + +- temp = IGP_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID); +- IGP_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN | +- RS480_TLB_ENABLE | +- RS480_GTW_LAC_EN | +- RS480_1LEVEL_GART)); ++ temp = RADEON_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID); ++ RADEON_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN | ++ RS480_TLB_ENABLE | ++ RS480_GTW_LAC_EN | ++ RS480_1LEVEL_GART)); + + temp = dev_priv->gart_info.bus_addr & 0xfffff000; + temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4; +- IGP_WRITE_MCIND(RS480_GART_BASE, temp); ++ RADEON_WRITE_MCIND(RS480_GART_BASE, temp); + +- temp = IGP_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL); +- IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) | +- RS480_REQ_TYPE_SNOOP_DIS)); +- +- radeon_write_agp_base(dev_priv, dev_priv->gart_vm_start); ++ /* enable snooping on gart mapped address */ ++ temp = RADEON_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL); ++ temp &= (RS480_REQ_TYPE_SNOOP_DIS); ++ temp |= (1 << RS480_REQ_TYPE_SNOOP_SHIFT); ++ RADEON_WRITE_MCIND(RS480_AGP_MODE_CNTL, temp); ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { ++ RADEON_WRITE_MCIND(RS690_MC_AGP_BASE, ++ (unsigned int)dev_priv->gart_vm_start); ++ RADEON_WRITE_MCIND(RS690_MC_AGP_BASE_2, 0); ++ } else { ++ RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start); ++ RADEON_WRITE(RS480_AGP_BASE_2, 0); ++ } + +- dev_priv->gart_size = 32*1024*1024; +- temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & +- 0xffff0000) | (dev_priv->gart_vm_start >> 16)); ++ temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & ++ 0xffff0000) | (dev_priv->gart_vm_start >> 16)); + +- radeon_write_agp_location(dev_priv, temp); ++ radeon_write_agp_location(dev_priv, temp, 0); + +- temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE); +- IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | +- RS480_VA_SIZE_32MB)); ++ temp = RADEON_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE); ++ RADEON_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | ++ size_reg)); + + do { +- temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); ++ temp = RADEON_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); + if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) + break; + DRM_UDELAY(1); +- } while (1); ++ } while(1); + +- IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, +- RS480_GART_CACHE_INVALIDATE); ++ RADEON_WRITE_MCIND(RS480_GART_CACHE_CNTRL, ++ RS480_GART_CACHE_INVALIDATE); + + do { +- temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); ++ temp = RADEON_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); + if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) + break; + DRM_UDELAY(1); +- } while (1); ++ } while(1); + +- IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); ++ RADEON_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); + } else { +- IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0); ++ RADEON_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0); + } + } + +@@ -939,11 +1139,11 @@ + (long)dev_priv->gart_info.bus_addr, + dev_priv->gart_size); + +- IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | +- RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | ++ RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); + + for (i = 0; i < 19; i++) +- IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, + (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | + RS600_SYSTEM_ACCESS_MODE_IN_SYS | + RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH | +@@ -951,55 +1151,55 @@ + RS600_ENABLE_FRAGMENT_PROCESSING | + RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); + +- IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | +- RS600_PAGE_TABLE_TYPE_FLAT)); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | ++ RS600_PAGE_TABLE_TYPE_FLAT)); + + /* disable all other contexts */ + for (i = 1; i < 8; i++) +- IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); + + /* setup the page table aperture */ +- IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, +- dev_priv->gart_info.bus_addr); +- IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, +- dev_priv->gart_vm_start); +- IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, +- (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); +- IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, ++ dev_priv->gart_info.bus_addr); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, ++ dev_priv->gart_vm_start); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, ++ (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); + + /* setup the system aperture */ +- IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, +- dev_priv->gart_vm_start); +- IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, +- (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, ++ dev_priv->gart_vm_start); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, ++ (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); + + /* enable page tables */ +- temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); +- IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); + +- temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); +- IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_CNTL1); ++ RADEON_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); + + /* invalidate the cache */ +- temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); +- IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); +- temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; +- IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); +- temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); +- IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); +- temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + } else { +- IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); +- temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_CNTL1); + temp &= ~RS600_ENABLE_PAGE_TABLES; +- IGP_WRITE_MCIND(RS600_MC_CNTL1, temp); ++ RADEON_WRITE_MCIND(RS600_MC_CNTL1, temp); + } + } + +@@ -1022,7 +1222,7 @@ + dev_priv->gart_vm_start + + dev_priv->gart_size - 1); + +- radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */ ++ radeon_write_agp_location(dev_priv, 0xffffffc0, 0); /* ?? */ + + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, + RADEON_PCIE_TX_GART_EN); +@@ -1033,7 +1233,7 @@ + } + + /* Enable or disable PCI GART on the chip */ +-static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) ++void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) + { + u32 tmp; + +@@ -1072,7 +1272,7 @@ + + /* Turn off AGP aperture -- is this required for PCI GART? + */ +- radeon_write_agp_location(dev_priv, 0xffffffc0); ++ radeon_write_agp_location(dev_priv, 0xffffffc0, 0); + RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ + } else { + RADEON_WRITE(RADEON_AIC_CNTL, +@@ -1162,17 +1362,6 @@ + */ + dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; + +- switch(init->func) { +- case RADEON_INIT_R200_CP: +- dev_priv->microcode_version = UCODE_R200; +- break; +- case RADEON_INIT_R300_CP: +- dev_priv->microcode_version = UCODE_R300; +- break; +- default: +- dev_priv->microcode_version = UCODE_R100; +- } +- + dev_priv->do_boxes = 0; + dev_priv->cp_mode = init->cp_mode; + +@@ -1220,9 +1409,8 @@ + */ + dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | + (dev_priv->color_fmt << 10) | +- (dev_priv->microcode_version == +- UCODE_R100 ? RADEON_ZBLOCK16 : 0)); +- ++ (dev_priv->chip_family < CHIP_R200 ? RADEON_ZBLOCK16 : 0)); ++ + dev_priv->depth_clear.rb3d_zstencilcntl = + (dev_priv->depth_fmt | + RADEON_Z_TEST_ALWAYS | +@@ -1419,28 +1607,41 @@ + dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); + /* if we have an offset set from userspace */ + if (dev_priv->pcigart_offset_set) { +- dev_priv->gart_info.bus_addr = +- (resource_size_t)dev_priv->pcigart_offset + dev_priv->fb_location; +- dev_priv->gart_info.mapping.offset = +- dev_priv->pcigart_offset + dev_priv->fb_aper_offset; +- dev_priv->gart_info.mapping.size = +- dev_priv->gart_info.table_size; +- +- drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); +- dev_priv->gart_info.addr = +- dev_priv->gart_info.mapping.handle; +- +- if (dev_priv->flags & RADEON_IS_PCIE) +- dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; +- else +- dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; +- dev_priv->gart_info.gart_table_location = +- DRM_ATI_GART_FB; + +- DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", +- dev_priv->gart_info.addr, +- dev_priv->pcigart_offset); ++ /* if it came from userspace - remap it */ ++ if (dev_priv->pcigart_offset_set == 1) { ++ dev_priv->gart_info.bus_addr = ++ (resource_size_t)dev_priv->pcigart_offset + dev_priv->fb_location; ++ dev_priv->gart_info.mapping.offset = ++ dev_priv->pcigart_offset + dev_priv->fb_aper_offset; ++ dev_priv->gart_info.mapping.size = ++ dev_priv->gart_info.table_size; ++ ++ /* this is done by the mm now */ ++ drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); ++ dev_priv->gart_info.addr = ++ dev_priv->gart_info.mapping.handle; ++ ++ memset(dev_priv->gart_info.addr, 0, dev_priv->gart_info.table_size); ++ if (dev_priv->flags & RADEON_IS_PCIE) ++ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; ++ else ++ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; ++ dev_priv->gart_info.gart_table_location = ++ DRM_ATI_GART_FB; ++ ++ DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", ++ dev_priv->gart_info.addr, ++ dev_priv->pcigart_offset); ++ } + } else { ++ ++ if (dev_priv->flags & RADEON_IS_PCIE) { ++ DRM_ERROR ++ ("Cannot use PCI Express without GART in FB memory\n"); ++ radeon_do_cleanup_cp(dev); ++ return -EINVAL; ++ } + if (dev_priv->flags & RADEON_IS_IGPGART) + dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; + else +@@ -1449,12 +1650,7 @@ + DRM_ATI_GART_MAIN; + dev_priv->gart_info.addr = NULL; + dev_priv->gart_info.bus_addr = 0; +- if (dev_priv->flags & RADEON_IS_PCIE) { +- DRM_ERROR +- ("Cannot use PCI Express without GART in FB memory\n"); +- radeon_do_cleanup_cp(dev); +- return -EINVAL; +- } ++ + } + + sctrl = RADEON_READ(RADEON_SURFACE_CNTL); +@@ -1486,6 +1682,9 @@ + radeon_set_pcigart(dev_priv, 1); + } + ++ /* Start with assuming that writeback doesn't work */ ++ dev_priv->writeback_works = 0; ++ + radeon_cp_load_microcode(dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); + +@@ -1540,8 +1739,11 @@ + + if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) + { +- drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); +- dev_priv->gart_info.addr = NULL; ++ if (dev_priv->pcigart_offset_set == 1) { ++ drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); ++ dev_priv->gart_info.addr = NULL; ++ dev_priv->pcigart_offset_set = 0; ++ } + } + } + /* only clear to the start of flags */ +@@ -1594,6 +1796,10 @@ + { + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_init_t *init = data; ++ ++ /* on a modesetting driver ignore this stuff */ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; + + LOCK_TEST_WITH_RETURN(dev, file_priv); + +@@ -1622,6 +1828,9 @@ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; ++ + LOCK_TEST_WITH_RETURN(dev, file_priv); + + if (dev_priv->cp_running) { +@@ -1652,6 +1861,9 @@ + int ret; + DRM_DEBUG("\n"); + ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; ++ + LOCK_TEST_WITH_RETURN(dev, file_priv); + + if (!dev_priv->cp_running) +@@ -1699,6 +1911,9 @@ + drm_radeon_private_t *dev_priv = dev->dev_private; + int i, ret; + ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return; ++ + if (dev_priv) { + if (dev_priv->cp_running) { + /* Stop the cp */ +@@ -1750,6 +1965,9 @@ + radeon_mem_takedown(&(dev_priv->gart_heap)); + radeon_mem_takedown(&(dev_priv->fb_heap)); + ++ if (dev_priv->user_mm_enable) ++ radeon_gem_mm_fini(dev); ++ + /* deallocate kernel resources */ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_cleanup_cp(dev); +@@ -1765,6 +1983,9 @@ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; ++ + LOCK_TEST_WITH_RETURN(dev, file_priv); + + if (!dev_priv) { +@@ -1788,7 +2009,9 @@ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + +- LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) ++ LOCK_TEST_WITH_RETURN(dev, file_priv); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_cp_idle(dev_priv); +@@ -1803,6 +2026,9 @@ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; ++ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_resume_cp(dev, file_priv); + else +@@ -1814,6 +2040,9 @@ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; ++ + LOCK_TEST_WITH_RETURN(dev, file_priv); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) +@@ -2040,6 +2269,822 @@ + return ret; + } + ++static void radeon_get_vram_type(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ if (dev_priv->flags & RADEON_IS_IGP || (dev_priv->chip_family >= CHIP_R300)) ++ dev_priv->is_ddr = true; ++ else if (RADEON_READ(RADEON_MEM_SDRAM_MODE_REG) & RADEON_MEM_CFG_TYPE_DDR) ++ dev_priv->is_ddr = true; ++ else ++ dev_priv->is_ddr = false; ++ ++ if ((dev_priv->chip_family >= CHIP_R600) && ++ (dev_priv->chip_family <= CHIP_RV635)) { ++ int chansize; ++ ++ tmp = RADEON_READ(R600_RAMCFG); ++ if (tmp & R600_CHANSIZE_OVERRIDE) ++ chansize = 16; ++ else if (tmp & R600_CHANSIZE) ++ chansize = 64; ++ else ++ chansize = 32; ++ ++ if (dev_priv->chip_family == CHIP_R600) ++ dev_priv->ram_width = 8 * chansize; ++ else if (dev_priv->chip_family == CHIP_RV670) ++ dev_priv->ram_width = 4 * chansize; ++ else if ((dev_priv->chip_family == CHIP_RV610) || ++ (dev_priv->chip_family == CHIP_RV620)) ++ dev_priv->ram_width = chansize; ++ else if ((dev_priv->chip_family == CHIP_RV630) || ++ (dev_priv->chip_family == CHIP_RV635)) ++ dev_priv->ram_width = 2 * chansize; ++ } else if (dev_priv->chip_family == CHIP_RV515) { ++ tmp = RADEON_READ_MCIND(dev_priv, RV515_MC_CNTL); ++ tmp &= RV515_MEM_NUM_CHANNELS_MASK; ++ switch (tmp) { ++ case 0: dev_priv->ram_width = 64; break; ++ case 1: dev_priv->ram_width = 128; break; ++ default: dev_priv->ram_width = 128; break; ++ } ++ } else if ((dev_priv->chip_family >= CHIP_R520) && ++ (dev_priv->chip_family <= CHIP_RV570)) { ++ tmp = RADEON_READ_MCIND(dev_priv, R520_MC_CNTL0); ++ switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) { ++ case 0: dev_priv->ram_width = 32; break; ++ case 1: dev_priv->ram_width = 64; break; ++ case 2: dev_priv->ram_width = 128; break; ++ case 3: dev_priv->ram_width = 256; break; ++ default: dev_priv->ram_width = 128; break; ++ } ++ } else if ((dev_priv->chip_family == CHIP_RV100) || ++ (dev_priv->chip_family == CHIP_RS100) || ++ (dev_priv->chip_family == CHIP_RS200)) { ++ tmp = RADEON_READ(RADEON_MEM_CNTL); ++ if (tmp & RV100_HALF_MODE) ++ dev_priv->ram_width = 32; ++ else ++ dev_priv->ram_width = 64; ++ ++ if (dev_priv->flags & RADEON_SINGLE_CRTC) { ++ dev_priv->ram_width /= 4; ++ dev_priv->is_ddr = true; ++ } ++ } else if (dev_priv->chip_family <= CHIP_RV280) { ++ tmp = RADEON_READ(RADEON_MEM_CNTL); ++ if (tmp & RADEON_MEM_NUM_CHANNELS_MASK) ++ dev_priv->ram_width = 128; ++ else ++ dev_priv->ram_width = 64; ++ } else { ++ /* newer IGPs */ ++ dev_priv->ram_width = 128; ++ } ++ DRM_DEBUG("RAM width %d bits %cDR\n", dev_priv->ram_width, dev_priv->is_ddr ? 'D' : 'S'); ++} ++ ++static void radeon_force_some_clocks(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); ++ tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP; ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); ++} ++ ++static void radeon_set_dynamic_clock(struct drm_device *dev, int mode) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ switch(mode) { ++ case 0: ++ if (dev_priv->flags & RADEON_SINGLE_CRTC) { ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); ++ tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP | ++ RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP | ++ RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE | ++ RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP | ++ RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB | ++ RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM | ++ RADEON_SCLK_FORCE_RB); ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); ++ } else if (dev_priv->chip_family == CHIP_RV350) { ++ /* for RV350/M10, no delays are required. */ ++ tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); ++ tmp |= (R300_SCLK_FORCE_TCL | ++ R300_SCLK_FORCE_GA | ++ R300_SCLK_FORCE_CBA); ++ RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); ++ tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | ++ RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | ++ RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | ++ R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | ++ RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | ++ R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | ++ R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | ++ R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); ++ tmp |= RADEON_DYN_STOP_LAT_MASK; ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); ++ tmp &= ~RADEON_SCLK_MORE_FORCEON; ++ tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); ++ tmp |= (RADEON_PIXCLK_ALWAYS_ONb | ++ RADEON_PIXCLK_DAC_ALWAYS_ONb); ++ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); ++ tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | ++ RADEON_PIX2CLK_DAC_ALWAYS_ONb | ++ RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | ++ R300_DVOCLK_ALWAYS_ONb | ++ RADEON_PIXCLK_BLEND_ALWAYS_ONb | ++ RADEON_PIXCLK_GV_ALWAYS_ONb | ++ R300_PIXCLK_DVO_ALWAYS_ONb | ++ RADEON_PIXCLK_LVDS_ALWAYS_ONb | ++ RADEON_PIXCLK_TMDS_ALWAYS_ONb | ++ R300_PIXCLK_TRANS_ALWAYS_ONb | ++ R300_PIXCLK_TVO_ALWAYS_ONb | ++ R300_P2G2CLK_ALWAYS_ONb | ++ R300_P2G2CLK_ALWAYS_ONb); ++ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); ++ } else { ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); ++ tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2); ++ tmp |= RADEON_SCLK_FORCE_SE; ++ ++ if ( dev_priv->flags & RADEON_SINGLE_CRTC ) { ++ tmp |= ( RADEON_SCLK_FORCE_RB | ++ RADEON_SCLK_FORCE_TDM | ++ RADEON_SCLK_FORCE_TAM | ++ RADEON_SCLK_FORCE_PB | ++ RADEON_SCLK_FORCE_RE | ++ RADEON_SCLK_FORCE_VIP | ++ RADEON_SCLK_FORCE_IDCT | ++ RADEON_SCLK_FORCE_TOP | ++ RADEON_SCLK_FORCE_DISP1 | ++ RADEON_SCLK_FORCE_DISP2 | ++ RADEON_SCLK_FORCE_HDP ); ++ } else if ((dev_priv->chip_family == CHIP_R300) || ++ (dev_priv->chip_family == CHIP_R350)) { ++ tmp |= ( RADEON_SCLK_FORCE_HDP | ++ RADEON_SCLK_FORCE_DISP1 | ++ RADEON_SCLK_FORCE_DISP2 | ++ RADEON_SCLK_FORCE_TOP | ++ RADEON_SCLK_FORCE_IDCT | ++ RADEON_SCLK_FORCE_VIP); ++ } ++ ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); ++ ++ udelay(16000); ++ ++ if ((dev_priv->chip_family == CHIP_R300) || ++ (dev_priv->chip_family == CHIP_R350)) { ++ tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); ++ tmp |= ( R300_SCLK_FORCE_TCL | ++ R300_SCLK_FORCE_GA | ++ R300_SCLK_FORCE_CBA); ++ RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); ++ udelay(16000); ++ } ++ ++ if (dev_priv->flags & RADEON_IS_IGP) { ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); ++ tmp &= ~(RADEON_FORCEON_MCLKA | ++ RADEON_FORCEON_YCLKA); ++ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, tmp); ++ udelay(16000); ++ } ++ ++ if ((dev_priv->chip_family == CHIP_RV200) || ++ (dev_priv->chip_family == CHIP_RV250) || ++ (dev_priv->chip_family == CHIP_RV280)) { ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); ++ tmp |= RADEON_SCLK_MORE_FORCEON; ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); ++ udelay(16000); ++ } ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); ++ tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | ++ RADEON_PIX2CLK_DAC_ALWAYS_ONb | ++ RADEON_PIXCLK_BLEND_ALWAYS_ONb | ++ RADEON_PIXCLK_GV_ALWAYS_ONb | ++ RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | ++ RADEON_PIXCLK_LVDS_ALWAYS_ONb | ++ RADEON_PIXCLK_TMDS_ALWAYS_ONb); ++ ++ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); ++ udelay(16000); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); ++ tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | ++ RADEON_PIXCLK_DAC_ALWAYS_ONb); ++ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); ++ } ++ DRM_DEBUG("Dynamic Clock Scaling Disabled\n"); ++ break; ++ case 1: ++ if (dev_priv->flags & RADEON_SINGLE_CRTC) { ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); ++ if ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) > ++ RADEON_CFG_ATI_REV_A13) { ++ tmp &= ~(RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_RB); ++ } ++ tmp &= ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | ++ RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE | ++ RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE | ++ RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM | ++ RADEON_SCLK_FORCE_TDM); ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); ++ } else if ((dev_priv->chip_family == CHIP_R300) || ++ (dev_priv->chip_family == CHIP_R350) || ++ (dev_priv->chip_family == CHIP_RV350)) { ++ if (dev_priv->chip_family == CHIP_RV350) { ++ tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); ++ tmp &= ~(R300_SCLK_FORCE_TCL | ++ R300_SCLK_FORCE_GA | ++ R300_SCLK_FORCE_CBA); ++ tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT | ++ R300_SCLK_GA_MAX_DYN_STOP_LAT | ++ R300_SCLK_CBA_MAX_DYN_STOP_LAT); ++ RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); ++ tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | ++ RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | ++ RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | ++ R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | ++ RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | ++ R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | ++ R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | ++ R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); ++ tmp |= RADEON_DYN_STOP_LAT_MASK; ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); ++ tmp &= ~RADEON_SCLK_MORE_FORCEON; ++ tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); ++ tmp |= (RADEON_PIXCLK_ALWAYS_ONb | ++ RADEON_PIXCLK_DAC_ALWAYS_ONb); ++ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); ++ tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | ++ RADEON_PIX2CLK_DAC_ALWAYS_ONb | ++ RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | ++ R300_DVOCLK_ALWAYS_ONb | ++ RADEON_PIXCLK_BLEND_ALWAYS_ONb | ++ RADEON_PIXCLK_GV_ALWAYS_ONb | ++ R300_PIXCLK_DVO_ALWAYS_ONb | ++ RADEON_PIXCLK_LVDS_ALWAYS_ONb | ++ RADEON_PIXCLK_TMDS_ALWAYS_ONb | ++ R300_PIXCLK_TRANS_ALWAYS_ONb | ++ R300_PIXCLK_TVO_ALWAYS_ONb | ++ R300_P2G2CLK_ALWAYS_ONb | ++ R300_P2G2CLK_ALWAYS_ONb); ++ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_MISC); ++ tmp |= (RADEON_MC_MCLK_DYN_ENABLE | ++ RADEON_IO_MCLK_DYN_ENABLE); ++ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_MISC, tmp); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); ++ tmp |= (RADEON_FORCEON_MCLKA | ++ RADEON_FORCEON_MCLKB); ++ ++ tmp &= ~(RADEON_FORCEON_YCLKA | ++ RADEON_FORCEON_YCLKB | ++ RADEON_FORCEON_MC); ++ ++ /* Some releases of vbios have set DISABLE_MC_MCLKA ++ and DISABLE_MC_MCLKB bits in the vbios table. Setting these ++ bits will cause H/W hang when reading video memory with dynamic clocking ++ enabled. */ ++ if ((tmp & R300_DISABLE_MC_MCLKA) && ++ (tmp & R300_DISABLE_MC_MCLKB)) { ++ /* If both bits are set, then check the active channels */ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); ++ if (dev_priv->ram_width == 64) { ++ if (RADEON_READ(RADEON_MEM_CNTL) & R300_MEM_USE_CD_CH_ONLY) ++ tmp &= ~R300_DISABLE_MC_MCLKB; ++ else ++ tmp &= ~R300_DISABLE_MC_MCLKA; ++ } else { ++ tmp &= ~(R300_DISABLE_MC_MCLKA | ++ R300_DISABLE_MC_MCLKB); ++ } ++ } ++ ++ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, tmp); ++ } else { ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); ++ tmp &= ~(R300_SCLK_FORCE_VAP); ++ tmp |= RADEON_SCLK_FORCE_CP; ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); ++ udelay(15000); ++ ++ tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); ++ tmp &= ~(R300_SCLK_FORCE_TCL | ++ R300_SCLK_FORCE_GA | ++ R300_SCLK_FORCE_CBA); ++ RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); ++ } ++ } else { ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL); ++ tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK | ++ RADEON_DISP_DYN_STOP_LAT_MASK | ++ RADEON_DYN_STOP_MODE_MASK); ++ ++ tmp |= (RADEON_ENGIN_DYNCLK_MODE | ++ (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); ++ RADEON_WRITE_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL, tmp); ++ udelay(15000); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_CLK_PIN_CNTL); ++ tmp |= RADEON_SCLK_DYN_START_CNTL; ++ RADEON_WRITE_PLL(dev_priv, RADEON_CLK_PIN_CNTL, tmp); ++ udelay(15000); ++ ++ /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 ++ to lockup randomly, leave them as set by BIOS. ++ */ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); ++ /*tmp &= RADEON_SCLK_SRC_SEL_MASK;*/ ++ tmp &= ~RADEON_SCLK_FORCEON_MASK; ++ ++ /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/ ++ if (((dev_priv->chip_family == CHIP_RV250) && ++ ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < ++ RADEON_CFG_ATI_REV_A13)) || ++ ((dev_priv->chip_family == CHIP_RV100) && ++ ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <= ++ RADEON_CFG_ATI_REV_A13))){ ++ tmp |= RADEON_SCLK_FORCE_CP; ++ tmp |= RADEON_SCLK_FORCE_VIP; ++ } ++ ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); ++ ++ if ((dev_priv->chip_family == CHIP_RV200) || ++ (dev_priv->chip_family == CHIP_RV250) || ++ (dev_priv->chip_family == CHIP_RV280)) { ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); ++ tmp &= ~RADEON_SCLK_MORE_FORCEON; ++ ++ /* RV200::A11 A12 RV250::A11 A12 */ ++ if (((dev_priv->chip_family == CHIP_RV200) || ++ (dev_priv->chip_family == CHIP_RV250)) && ++ ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < ++ RADEON_CFG_ATI_REV_A13)) { ++ tmp |= RADEON_SCLK_MORE_FORCEON; ++ } ++ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); ++ udelay(15000); ++ } ++ ++ /* RV200::A11 A12, RV250::A11 A12 */ ++ if (((dev_priv->chip_family == CHIP_RV200) || ++ (dev_priv->chip_family == CHIP_RV250)) && ++ ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < ++ RADEON_CFG_ATI_REV_A13)) { ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_PLL_PWRMGT_CNTL); ++ tmp |= RADEON_TCL_BYPASS_DISABLE; ++ RADEON_WRITE_PLL(dev_priv, RADEON_PLL_PWRMGT_CNTL, tmp); ++ } ++ udelay(15000); ++ ++ /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK)*/ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); ++ tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | ++ RADEON_PIX2CLK_DAC_ALWAYS_ONb | ++ RADEON_PIXCLK_BLEND_ALWAYS_ONb | ++ RADEON_PIXCLK_GV_ALWAYS_ONb | ++ RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | ++ RADEON_PIXCLK_LVDS_ALWAYS_ONb | ++ RADEON_PIXCLK_TMDS_ALWAYS_ONb); ++ ++ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); ++ udelay(15000); ++ ++ tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); ++ tmp |= (RADEON_PIXCLK_ALWAYS_ONb | ++ RADEON_PIXCLK_DAC_ALWAYS_ONb); ++ ++ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); ++ udelay(15000); ++ } ++ DRM_DEBUG("Dynamic Clock Scaling Enabled\n"); ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++int radeon_modeset_cp_suspend(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ int ret; ++ ++ ret = radeon_do_cp_idle(dev_priv); ++ if (ret) ++ DRM_ERROR("failed to idle CP on suspend\n"); ++ ++ radeon_do_cp_stop(dev_priv); ++ radeon_do_engine_reset(dev); ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ } else { ++ radeon_set_pcigart(dev_priv, 0); ++ } ++ ++ return 0; ++} ++ ++int radeon_modeset_cp_resume(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ radeon_do_wait_for_idle(dev_priv); ++#if __OS_HAS_AGP ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ /* Turn off PCI GART */ ++ radeon_set_pcigart(dev_priv, 0); ++ } else ++#endif ++ { ++ /* Turn on PCI GART */ ++ radeon_set_pcigart(dev_priv, 1); ++ } ++ radeon_gart_flush(dev); ++ ++ radeon_cp_load_microcode(dev_priv); ++ radeon_cp_init_ring_buffer(dev, dev_priv, NULL); ++ ++ radeon_do_engine_reset(dev); ++ ++ radeon_test_writeback(dev_priv); ++ ++ radeon_do_cp_start(dev_priv); ++ return 0; ++} ++ ++int radeon_modeset_cp_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ /* allocate a ring and ring rptr bits from GART space */ ++ /* these are allocated in GEM files */ ++ ++ /* Start with assuming that writeback doesn't work */ ++ dev_priv->writeback_works = 0; ++ ++ if (dev_priv->chip_family > CHIP_R600) ++ return 0; ++ ++ dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT; ++ dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; ++ dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; ++ ++ dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring.kmap.virtual; ++ dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring.kmap.virtual + ++ dev_priv->ring.size / sizeof(u32); ++ dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8); ++ dev_priv->ring.rptr_update = 4096; ++ dev_priv->ring.rptr_update_l2qw = drm_order(4096 / 8); ++ dev_priv->ring.fetch_size = 32; ++ dev_priv->ring.fetch_size_l2ow = drm_order(32 / 16); ++ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; ++ dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; ++ ++ dev_priv->new_memmap = true; ++ ++ r300_init_reg_flags(dev); ++ ++ /* turn off HDP read cache for now */ ++ RADEON_WRITE(RADEON_HOST_PATH_CNTL, RADEON_READ(RADEON_HOST_PATH_CNTL) | RADEON_HP_LIN_RD_CACHE_DIS); ++ ++ return radeon_modeset_cp_resume(dev); ++} ++ ++static bool radeon_read_bios(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ u8 __iomem *bios; ++ size_t size; ++ ++ bios = pci_map_rom(dev->pdev, &size); ++ if (!bios) { ++ return false; ++ } ++ ++ if (size == 0) ++ goto fail; ++ ++ if (bios[0] != 0x55 || bios[1] != 0xaa) ++ goto fail; ++ ++ dev_priv->bios = kmalloc(size, GFP_KERNEL); ++ if (!dev_priv->bios) { ++ pci_unmap_rom(dev->pdev, bios); ++ return -1; ++ } ++ ++ memcpy(dev_priv->bios, bios, size); ++ ++ pci_unmap_rom(dev->pdev, bios); ++ ++ return true; ++fail: ++ pci_unmap_rom(dev->pdev, bios); ++ kfree(dev_priv->bios); ++ dev_priv->bios = NULL; ++ return false; ++} ++ ++static bool radeon_read_disabled_bios(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ bool ret; ++ ++ if (dev_priv->chip_family >= CHIP_R600) { ++ uint32_t viph_control = RADEON_READ(RADEON_VIPH_CONTROL); ++ uint32_t bus_cntl = RADEON_READ(RADEON_BUS_CNTL); ++ uint32_t d1vga_control = RADEON_READ(AVIVO_D1VGA_CONTROL); ++ uint32_t d2vga_control = RADEON_READ(AVIVO_D2VGA_CONTROL); ++ uint32_t vga_render_control = RADEON_READ(AVIVO_VGA_RENDER_CONTROL); ++ uint32_t rom_cntl = RADEON_READ(R600_ROM_CNTL); ++ uint32_t general_pwrmgt = RADEON_READ(R600_GENERAL_PWRMGT); ++ uint32_t low_vid_lower_gpio_cntl = RADEON_READ(R600_LOW_VID_LOWER_GPIO_CNTL); ++ uint32_t medium_vid_lower_gpio_cntl = RADEON_READ(R600_MEDIUM_VID_LOWER_GPIO_CNTL); ++ uint32_t high_vid_lower_gpio_cntl = RADEON_READ(R600_HIGH_VID_LOWER_GPIO_CNTL); ++ uint32_t ctxsw_vid_lower_gpio_cntl = RADEON_READ(R600_CTXSW_VID_LOWER_GPIO_CNTL); ++ uint32_t lower_gpio_enable = RADEON_READ(R600_LOWER_GPIO_ENABLE); ++ ++ /* disable VIP */ ++ RADEON_WRITE(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); ++ ++ /* enable the rom */ ++ RADEON_WRITE(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); ++ ++ /* Disable VGA mode */ ++ RADEON_WRITE(AVIVO_D1VGA_CONTROL, (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | ++ AVIVO_DVGA_CONTROL_TIMING_SELECT))); ++ RADEON_WRITE(AVIVO_D2VGA_CONTROL, (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | ++ AVIVO_DVGA_CONTROL_TIMING_SELECT))); ++ RADEON_WRITE(AVIVO_VGA_RENDER_CONTROL, (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); ++ ++ RADEON_WRITE(R600_ROM_CNTL, ((rom_cntl & ~R600_SCK_PRESCALE_CRYSTAL_CLK_MASK) | ++ (1 << R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT) | ++ R600_SCK_OVERWRITE)); ++ ++ RADEON_WRITE(R600_GENERAL_PWRMGT, (general_pwrmgt & ~R600_OPEN_DRAIN_PADS)); ++ RADEON_WRITE(R600_LOW_VID_LOWER_GPIO_CNTL, (low_vid_lower_gpio_cntl & ~0x400)); ++ RADEON_WRITE(R600_MEDIUM_VID_LOWER_GPIO_CNTL, (medium_vid_lower_gpio_cntl & ~0x400)); ++ RADEON_WRITE(R600_HIGH_VID_LOWER_GPIO_CNTL, (high_vid_lower_gpio_cntl & ~0x400)); ++ RADEON_WRITE(R600_CTXSW_VID_LOWER_GPIO_CNTL, (ctxsw_vid_lower_gpio_cntl & ~0x400)); ++ RADEON_WRITE(R600_LOWER_GPIO_ENABLE, (lower_gpio_enable | 0x400)); ++ ++ ret = radeon_read_bios(dev); ++ ++ /* restore regs */ ++ RADEON_WRITE(RADEON_VIPH_CONTROL, viph_control); ++ RADEON_WRITE(RADEON_BUS_CNTL, bus_cntl); ++ RADEON_WRITE(AVIVO_D1VGA_CONTROL, d1vga_control); ++ RADEON_WRITE(AVIVO_D2VGA_CONTROL, d2vga_control); ++ RADEON_WRITE(AVIVO_VGA_RENDER_CONTROL, vga_render_control); ++ RADEON_WRITE(R600_ROM_CNTL, rom_cntl); ++ RADEON_WRITE(R600_GENERAL_PWRMGT, general_pwrmgt); ++ RADEON_WRITE(R600_LOW_VID_LOWER_GPIO_CNTL, low_vid_lower_gpio_cntl); ++ RADEON_WRITE(R600_MEDIUM_VID_LOWER_GPIO_CNTL, medium_vid_lower_gpio_cntl); ++ RADEON_WRITE(R600_HIGH_VID_LOWER_GPIO_CNTL, high_vid_lower_gpio_cntl); ++ RADEON_WRITE(R600_CTXSW_VID_LOWER_GPIO_CNTL, ctxsw_vid_lower_gpio_cntl); ++ RADEON_WRITE(R600_LOWER_GPIO_ENABLE, lower_gpio_enable); ++ } else if (dev_priv->chip_family >= CHIP_RS600) { ++ uint32_t seprom_cntl1 = RADEON_READ(RADEON_SEPROM_CNTL1); ++ uint32_t viph_control = RADEON_READ(RADEON_VIPH_CONTROL); ++ uint32_t bus_cntl = RADEON_READ(RADEON_BUS_CNTL); ++ uint32_t d1vga_control = RADEON_READ(AVIVO_D1VGA_CONTROL); ++ uint32_t d2vga_control = RADEON_READ(AVIVO_D2VGA_CONTROL); ++ uint32_t vga_render_control = RADEON_READ(AVIVO_VGA_RENDER_CONTROL); ++ uint32_t gpiopad_a = RADEON_READ(RADEON_GPIOPAD_A); ++ uint32_t gpiopad_en = RADEON_READ(RADEON_GPIOPAD_EN); ++ uint32_t gpiopad_mask = RADEON_READ(RADEON_GPIOPAD_MASK); ++ ++ RADEON_WRITE(RADEON_SEPROM_CNTL1, ((seprom_cntl1 & ~RADEON_SCK_PRESCALE_MASK) | ++ (0xc << RADEON_SCK_PRESCALE_SHIFT))); ++ ++ RADEON_WRITE(RADEON_GPIOPAD_A, 0); ++ RADEON_WRITE(RADEON_GPIOPAD_EN, 0); ++ RADEON_WRITE(RADEON_GPIOPAD_MASK, 0); ++ ++ /* disable VIP */ ++ RADEON_WRITE(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); ++ ++ /* enable the rom */ ++ RADEON_WRITE(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); ++ ++ /* Disable VGA mode */ ++ RADEON_WRITE(AVIVO_D1VGA_CONTROL, (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | ++ AVIVO_DVGA_CONTROL_TIMING_SELECT))); ++ RADEON_WRITE(AVIVO_D2VGA_CONTROL, (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | ++ AVIVO_DVGA_CONTROL_TIMING_SELECT))); ++ RADEON_WRITE(AVIVO_VGA_RENDER_CONTROL, (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); ++ ++ ret = radeon_read_bios(dev); ++ ++ /* restore regs */ ++ RADEON_WRITE(RADEON_SEPROM_CNTL1, seprom_cntl1); ++ RADEON_WRITE(RADEON_VIPH_CONTROL, viph_control); ++ RADEON_WRITE(RADEON_BUS_CNTL, bus_cntl); ++ RADEON_WRITE(AVIVO_D1VGA_CONTROL, d1vga_control); ++ RADEON_WRITE(AVIVO_D2VGA_CONTROL, d2vga_control); ++ RADEON_WRITE(AVIVO_VGA_RENDER_CONTROL, vga_render_control); ++ RADEON_WRITE(RADEON_GPIOPAD_A, gpiopad_a); ++ RADEON_WRITE(RADEON_GPIOPAD_EN, gpiopad_en); ++ RADEON_WRITE(RADEON_GPIOPAD_MASK, gpiopad_mask); ++ ++ } else { ++ uint32_t seprom_cntl1 = RADEON_READ(RADEON_SEPROM_CNTL1); ++ uint32_t viph_control = RADEON_READ(RADEON_VIPH_CONTROL); ++ uint32_t bus_cntl = RADEON_READ(RADEON_BUS_CNTL); ++ uint32_t crtc_gen_cntl = RADEON_READ(RADEON_CRTC_GEN_CNTL); ++ uint32_t crtc2_gen_cntl = 0; ++ uint32_t crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL); ++ uint32_t fp2_gen_cntl = 0; ++ ++ if (dev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) ++ fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL); ++ ++ if (!(dev_priv->flags & RADEON_SINGLE_CRTC)) ++ crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL); ++ ++ RADEON_WRITE(RADEON_SEPROM_CNTL1, ((seprom_cntl1 & ~RADEON_SCK_PRESCALE_MASK) | ++ (0xc << RADEON_SCK_PRESCALE_SHIFT))); ++ ++ /* disable VIP */ ++ RADEON_WRITE(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); ++ ++ /* enable the rom */ ++ RADEON_WRITE(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); ++ ++ /* Turn off mem requests and CRTC for both controllers */ ++ RADEON_WRITE(RADEON_CRTC_GEN_CNTL, ((crtc_gen_cntl & ~RADEON_CRTC_EN) | ++ (RADEON_CRTC_DISP_REQ_EN_B | ++ RADEON_CRTC_EXT_DISP_EN))); ++ if (!(dev_priv->flags & RADEON_SINGLE_CRTC)) ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, ((crtc2_gen_cntl & ~RADEON_CRTC2_EN) | ++ RADEON_CRTC2_DISP_REQ_EN_B)); ++ ++ /* Turn off CRTC */ ++ RADEON_WRITE(RADEON_CRTC_EXT_CNTL, ((crtc_ext_cntl & ~RADEON_CRTC_CRT_ON) | ++ (RADEON_CRTC_SYNC_TRISTAT | ++ RADEON_CRTC_DISPLAY_DIS))); ++ ++ if (dev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) ++ RADEON_WRITE(RADEON_FP2_GEN_CNTL, (fp2_gen_cntl & ~RADEON_FP2_ON)); ++ ++ ret = radeon_read_bios(dev); ++ ++ /* restore regs */ ++ RADEON_WRITE(RADEON_SEPROM_CNTL1, seprom_cntl1); ++ RADEON_WRITE(RADEON_VIPH_CONTROL, viph_control); ++ RADEON_WRITE(RADEON_BUS_CNTL, bus_cntl); ++ RADEON_WRITE(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); ++ if (!(dev_priv->flags & RADEON_SINGLE_CRTC)) ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); ++ RADEON_WRITE(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); ++ if (dev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) ++ RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); ++ } ++ return ret; ++} ++ ++ ++static bool radeon_get_bios(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ int ret = 0; ++ uint16_t tmp; ++ ++ ret = radeon_read_bios(dev); ++ if (ret == false) ++ ret = radeon_read_disabled_bios(dev); ++ ++ if (ret == false || !dev_priv->bios) { ++ DRM_ERROR("Unable to locate a BIOS ROM\n"); ++ return false; ++ } ++ ++ if (dev_priv->bios[0] != 0x55 || dev_priv->bios[1] != 0xaa) ++ goto free_bios; ++ ++ dev_priv->bios_header_start = radeon_bios16(dev_priv, 0x48); ++ ++ if (!dev_priv->bios_header_start) ++ goto free_bios; ++ ++ tmp = dev_priv->bios_header_start + 4; ++ if (!memcmp(dev_priv->bios + tmp, "ATOM", 4) || ++ !memcmp(dev_priv->bios + tmp, "MOTA", 4)) ++ dev_priv->is_atom_bios = true; ++ else ++ dev_priv->is_atom_bios = false; ++ ++ DRM_DEBUG("%sBIOS detected\n", dev_priv->is_atom_bios ? "ATOM" : "COM"); ++ return true; ++free_bios: ++ kfree(dev_priv->bios); ++ dev_priv->bios = NULL; ++ return false; ++} ++ ++int radeon_modeset_preinit(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ static struct card_info card; ++ int ret; ++ ++ card.dev = dev; ++ card.reg_read = cail_reg_read; ++ card.reg_write = cail_reg_write; ++ card.mc_read = cail_mc_read; ++ card.mc_write = cail_mc_write; ++ card.pll_read = cail_pll_read; ++ card.pll_write = cail_pll_write; ++ ++ ret = radeon_get_bios(dev); ++ if (!ret) ++ return -1; ++ ++ if (dev_priv->is_atom_bios) { ++ dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios); ++ radeon_atom_initialize_bios_scratch_regs(dev); ++ } else ++ radeon_combios_initialize_bios_scratch_regs(dev); ++ ++ radeon_get_clock_info(dev); ++ ++ return 0; ++} ++ ++int radeon_static_clocks_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ if (radeon_dynclks != -1) { ++ ++ if (dev_priv->chip_family == CHIP_RS400 || ++ dev_priv->chip_family == CHIP_RS480) ++ radeon_dynclks = 0; ++ ++ if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { ++ radeon_set_dynamic_clock(dev, radeon_dynclks); ++ } else if (radeon_is_avivo(dev_priv)) { ++ if (radeon_dynclks) { ++ radeon_atom_static_pwrmgt_setup(dev, 1); ++ radeon_atom_dyn_clk_setup(dev, 1); ++ } ++ } ++ } ++ if (radeon_is_r300(dev_priv) || radeon_is_rv100(dev_priv)) ++ radeon_force_some_clocks(dev); ++ return 0; ++} ++ ++static bool radeon_card_posted(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t reg; ++ ++ if (radeon_is_avivo(dev_priv)) { ++ reg = RADEON_READ(AVIVO_D1CRTC_CONTROL) | RADEON_READ(AVIVO_D2CRTC_CONTROL); ++ if (reg & AVIVO_CRTC_EN) ++ return true; ++ } else { ++ reg = RADEON_READ(RADEON_CRTC_GEN_CNTL) | RADEON_READ(RADEON_CRTC2_GEN_CNTL); ++ if (reg & RADEON_CRTC_EN) ++ return true; ++ } ++ return false; ++ ++} + int radeon_driver_load(struct drm_device *dev, unsigned long flags) + { + drm_radeon_private_t *dev_priv; +@@ -2053,6 +3098,8 @@ + dev->dev_private = (void *)dev_priv; + dev_priv->flags = flags; + ++ dev_priv->chip_family = flags & RADEON_FAMILY_MASK; ++ + switch (flags & RADEON_FAMILY_MASK) { + case CHIP_R100: + case CHIP_RV200: +@@ -2073,6 +3120,21 @@ + break; + } + ++ /* don't enable kms by default on r600 yet */ ++ if (radeon_modeset == -1) { ++ if ((dev_priv->chip_family >= CHIP_R600)) { ++ dev->driver->driver_features &= ~DRIVER_MODESET; ++ drm_put_minor(&dev->control); ++ radeon_modeset = 0; ++ } else ++ radeon_modeset = 1; ++ } ++ ++ /* rs480s have a gart size issue */ ++ if ((radeon_gart_size == 512) && ++ ((dev_priv->chip_family == CHIP_RS400 || dev_priv->chip_family == CHIP_RS480))) ++ radeon_gart_size = 32; ++ + if (drm_device_is_agp(dev)) + dev_priv->flags |= RADEON_IS_AGP; + else if (drm_device_is_pcie(dev)) +@@ -2080,9 +3142,34 @@ + else + dev_priv->flags |= RADEON_IS_PCI; + ++ DRM_DEBUG("%s card detected\n", ++ ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ /* disable AGP for any chips after RV280 if not specified */ ++ if ((dev_priv->chip_family > CHIP_RV280) && (radeon_agpmode == 0)) ++ radeon_agpmode = -1; ++ ++ if (radeon_agpmode == -1) { ++ dev_priv->flags &= ~RADEON_IS_AGP; ++ if (dev_priv->chip_family > CHIP_RV515 || ++ dev_priv->chip_family == CHIP_RV380 || ++ dev_priv->chip_family == CHIP_RV410 || ++ dev_priv->chip_family == CHIP_R423) { ++ DRM_INFO("Forcing AGP to PCIE mode\n"); ++ dev_priv->flags |= RADEON_IS_PCIE; ++ } else { ++ DRM_INFO("Forcing AGP to PCI mode\n"); ++ dev_priv->flags |= RADEON_IS_PCI; ++ } ++ } ++ } ++ } ++ + ret = drm_addmap(dev, drm_get_resource_start(dev, 2), + drm_get_resource_len(dev, 2), _DRM_REGISTERS, +- _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); ++ _DRM_DRIVER | _DRM_READ_ONLY, &dev_priv->mmio); + if (ret != 0) + return ret; + +@@ -2092,8 +3179,63 @@ + return ret; + } + +- DRM_DEBUG("%s card detected\n", +- ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ radeon_modeset_preinit(dev); ++ ++ radeon_get_vram_type(dev); ++ ++ dev_priv->pll_errata = 0; ++ ++ if (dev_priv->chip_family == CHIP_R300 && ++ (RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11) ++ dev_priv->pll_errata |= CHIP_ERRATA_R300_CG; ++ ++ if (dev_priv->chip_family == CHIP_RV200 || ++ dev_priv->chip_family == CHIP_RS200) ++ dev_priv->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS; ++ ++ ++ if (dev_priv->chip_family == CHIP_RV100 || ++ dev_priv->chip_family == CHIP_RS100 || ++ dev_priv->chip_family == CHIP_RS200) ++ dev_priv->pll_errata |= CHIP_ERRATA_PLL_DELAY; ++ ++ /* check if cards are posted or not */ ++ if (!radeon_card_posted(dev) && dev_priv->bios) { ++ DRM_INFO("GPU not posted. posting now...\n"); ++ if (dev_priv->is_atom_bios) { ++ struct atom_context *ctx = dev_priv->mode_info.atom_context; ++ atom_asic_init(ctx); ++ } else { ++ radeon_combios_asic_init(dev); ++ } ++ } ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ radeon_static_clocks_init(dev); ++ ++ /* init memory manager - start with all of VRAM and a 32MB GART aperture for now */ ++ dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ ++ ret = radeon_gem_mm_init(dev); ++ if (ret) ++ goto modeset_fail; ++ ++ radeon_modeset_init(dev); ++ ++ radeon_modeset_cp_init(dev); ++ dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); ++ ++ drm_irq_install(dev); ++ } ++ ++ ++ return ret; ++modeset_fail: ++ dev->driver->driver_features &= ~DRIVER_MODESET; ++ drm_put_minor(&dev->control); + return ret; + } + +@@ -2147,18 +3289,12 @@ + */ + int radeon_driver_firstopen(struct drm_device *dev) + { +- int ret; +- drm_local_map_t *map; + drm_radeon_private_t *dev_priv = dev->dev_private; + +- dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; + +- dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); +- ret = drm_addmap(dev, dev_priv->fb_aper_offset, +- drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, +- _DRM_WRITE_COMBINING, &map); +- if (ret != 0) +- return ret; ++ dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; + + return 0; + } +@@ -2167,6 +3303,14 @@ + { + drm_radeon_private_t *dev_priv = dev->dev_private; + ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ drm_irq_uninstall(dev); ++ radeon_modeset_cleanup(dev); ++ radeon_gem_mm_fini(dev); ++ } ++ ++ drm_rmmap(dev, dev_priv->mmio); ++ + DRM_DEBUG("\n"); + + drm_rmmap(dev, dev_priv->mmio); +@@ -2214,3 +3358,41 @@ + RADEON_READ(RADEON_CP_RB_RPTR); + } + } ++ ++void radeon_gart_flush(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t loop = 0, val; ++ if (dev_priv->flags & RADEON_IS_IGPGART) { ++ RADEON_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); ++ RADEON_WRITE_MCIND(RS480_GART_CACHE_CNTRL, RS480_GART_CACHE_INVALIDATE); ++ val = RADEON_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); ++ while ((val & RS480_GART_CACHE_INVALIDATE) && loop++ < 100000) { ++ val = RADEON_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); ++ } ++ if (loop == 100000) ++ DRM_ERROR("Failed to invalidate IGP GART TLB\n"); ++ RADEON_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); ++ } else if (dev_priv->flags & RADEON_IS_PCIE) { ++ u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); ++ tmp |= RADEON_PCIE_TX_GART_INVALIDATE_TLB; ++ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); ++ tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); ++ tmp &= ~RADEON_PCIE_TX_GART_INVALIDATE_TLB; ++ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); ++ } else if (dev_priv->chip_family == CHIP_RS600) { ++ u32 temp = RADEON_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ ++ temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ ++ temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ ++ temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); ++ RADEON_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); ++ temp = RADEON_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); ++ } ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_cs.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_cs.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_cs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_cs.c 2009-04-26 03:00:46.671725623 +0200 +@@ -0,0 +1,684 @@ ++/* ++ * Copyright 2008 Jerome Glisse. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * Jerome Glisse ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++#include "r300_reg.h" ++ ++int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) ++{ ++ struct drm_radeon_cs_parser parser; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_radeon_cs *cs = data; ++ uint32_t cs_id; ++ struct drm_radeon_cs_chunk __user **chunk_ptr = NULL; ++ uint64_t *chunk_array; ++ uint64_t *chunk_array_ptr; ++ long size; ++ int r, i; ++ ++ mutex_lock(&dev_priv->cs.cs_mutex); ++ /* set command stream id to 0 which is fake id */ ++ cs_id = 0; ++ cs->cs_id = cs_id; ++ ++ if (dev_priv == NULL) { ++ DRM_ERROR("called with no initialization\n"); ++ mutex_unlock(&dev_priv->cs.cs_mutex); ++ return -EINVAL; ++ } ++ if (!cs->num_chunks) { ++ mutex_unlock(&dev_priv->cs.cs_mutex); ++ return 0; ++ } ++ ++ ++ chunk_array = drm_calloc(cs->num_chunks, sizeof(uint64_t), DRM_MEM_DRIVER); ++ if (!chunk_array) { ++ mutex_unlock(&dev_priv->cs.cs_mutex); ++ return -ENOMEM; ++ } ++ ++ chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks); ++ ++ if (DRM_COPY_FROM_USER(chunk_array, chunk_array_ptr, sizeof(uint64_t)*cs->num_chunks)) { ++ r = -EFAULT; ++ goto out; ++ } ++ ++ parser.dev = dev; ++ parser.file_priv = fpriv; ++ parser.reloc_index = -1; ++ parser.ib_index = -1; ++ parser.num_chunks = cs->num_chunks; ++ /* copy out the chunk headers */ ++ parser.chunks = drm_calloc(parser.num_chunks, sizeof(struct drm_radeon_kernel_chunk), DRM_MEM_DRIVER); ++ if (!parser.chunks) { ++ r = -ENOMEM; ++ goto out; ++ } ++ ++ for (i = 0; i < parser.num_chunks; i++) { ++ struct drm_radeon_cs_chunk user_chunk; ++ ++ chunk_ptr = (void __user *)(unsigned long)chunk_array[i]; ++ ++ if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr, sizeof(struct drm_radeon_cs_chunk))){ ++ r = -EFAULT; ++ goto out; ++ } ++ parser.chunks[i].chunk_id = user_chunk.chunk_id; ++ ++ if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) ++ parser.reloc_index = i; ++ ++ if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_IB) ++ parser.ib_index = i; ++ ++ parser.chunks[i].length_dw = user_chunk.length_dw; ++ parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data; ++ ++ parser.chunks[i].kdata = NULL; ++ size = parser.chunks[i].length_dw * sizeof(uint32_t); ++ ++ switch(parser.chunks[i].chunk_id) { ++ case RADEON_CHUNK_ID_IB: ++ if (size == 0) { ++ r = -EINVAL; ++ goto out; ++ } ++ case RADEON_CHUNK_ID_RELOCS: ++ if (size) { ++ parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER); ++ if (!parser.chunks[i].kdata) { ++ r = -ENOMEM; ++ goto out; ++ } ++ ++ if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) { ++ r = -EFAULT; ++ goto out; ++ } ++ } else ++ parser.chunks[i].kdata = NULL; ++ break; ++ default: ++ break; ++ } ++ DRM_DEBUG("chunk %d %d %d %p\n", i, parser.chunks[i].chunk_id, parser.chunks[i].length_dw, ++ parser.chunks[i].chunk_data); ++ } ++ ++ ++ if (parser.chunks[parser.ib_index].length_dw > (16 * 1024)) { ++ DRM_ERROR("cs->dwords too big: %d\n", parser.chunks[parser.ib_index].length_dw); ++ r = -EINVAL; ++ goto out; ++ } ++ ++ /* get ib */ ++ r = dev_priv->cs.ib_get(&parser); ++ if (r) { ++ DRM_ERROR("ib_get failed\n"); ++ goto out; ++ } ++ ++ ++ r = radeon_gem_prelocate(&parser); ++ if (r) { ++ goto out; ++ } ++ ++ /* now parse command stream */ ++ r = dev_priv->cs.parse(&parser); ++ if (r) { ++ goto out; ++ } ++ ++ /* emit cs id sequence */ ++ dev_priv->cs.id_emit(&parser, &cs_id); ++ ++ cs->cs_id = cs_id; ++ cs->gart_limit = dev_priv->mm.gart_useable; ++ cs->vram_limit = dev_priv->mm.vram_visible; ++ ++out: ++ dev_priv->cs.ib_free(&parser, r); ++ mutex_unlock(&dev_priv->cs.cs_mutex); ++ ++ for (i = 0; i < parser.num_chunks; i++) { ++ if (parser.chunks[i].kdata) ++ drm_free(parser.chunks[i].kdata, parser.chunks[i].length_dw * sizeof(uint32_t), DRM_MEM_DRIVER); ++ } ++ ++ drm_free(parser.chunks, sizeof(struct drm_radeon_kernel_chunk)*parser.num_chunks, DRM_MEM_DRIVER); ++ drm_free(chunk_array, sizeof(uint64_t)*parser.num_chunks, DRM_MEM_DRIVER); ++ ++ return r; ++} ++ ++/* for non-mm */ ++static int radeon_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *reloc, uint32_t *offset) ++{ ++ *offset = reloc[1]; ++ return 0; ++} ++ ++/* special case CRTC relocation for vline waits ++ * userspace doesn't know which CRTC it controls so we have a special sequence ++ * packet0 VLINE_START_END, value ++ * packet0 WAIT_UNTIL, crtc line | crtc_num ++ * packet0 NOP, crtc_id ++ * we relocate the vline register and the wait until crtc_num bit ++ */ ++static int radeon_cs_relocate_crtc(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) ++{ ++ struct drm_device *dev = parser->dev; ++ struct drm_mode_object *obj; ++ struct drm_crtc *crtc; ++ struct radeon_crtc *radeon_crtc; ++ uint32_t hdr, reg, val, packet3_hdr; ++ int ret = 0; ++ int crtc_id; ++ struct drm_radeon_kernel_chunk *ib_chunk; ++ ++ ib_chunk = &parser->chunks[parser->ib_index]; ++ ++ hdr = ib_chunk->kdata[offset_dw]; ++ reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; ++ val = ib_chunk->kdata[offset_dw + 1]; ++ packet3_hdr = ib_chunk->kdata[offset_dw + 4]; ++ ++ mutex_lock(&dev->mode_config.mutex); ++ obj = drm_mode_object_find(parser->dev, ib_chunk->kdata[offset_dw + 5], DRM_MODE_OBJECT_CRTC); ++ if (!obj) { ++ ret = -EINVAL; ++ goto out; ++ } ++ crtc = obj_to_crtc(obj); ++ radeon_crtc = to_radeon_crtc(crtc); ++ ++ crtc_id = radeon_crtc->crtc_id; ++ ++ /* ++ * need to edit both packets ++ */ ++ /* vline start end - for crtc0 no work to do */ ++ if (crtc_id == 1) { ++ switch (reg) { ++ case AVIVO_D1MODE_VLINE_START_END: ++ hdr &= R300_CP_PACKET0_REG_MASK; ++ hdr |= AVIVO_D2MODE_VLINE_START_END >> 2; ++ break; ++ case RADEON_CRTC_GUI_TRIG_VLINE: ++ hdr &= R300_CP_PACKET0_REG_MASK; ++ hdr |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; ++ break; ++ default: ++ DRM_ERROR("unknown CRTC relocation\n"); ++ ret = -EINVAL; ++ goto out; ++ } ++ /* relocate the WAIT_UNTIL */ ++ ib_chunk->kdata[offset_dw] = hdr; ++ ib_chunk->kdata[offset_dw + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; ++ } ++out: ++ mutex_unlock(&dev->mode_config.mutex); ++ return ret; ++} ++ ++#define RELOC_SIZE 2 ++#define RELOC_SIZE_NEW 0 ++#define RADEON_2D_OFFSET_MASK 0x3fffff ++ ++static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) ++{ ++ struct drm_device *dev = parser->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t hdr, reg, val, packet3_hdr; ++ uint32_t tmp, offset; ++ struct drm_radeon_kernel_chunk *ib_chunk; ++ int ret; ++ ++ ib_chunk = &parser->chunks[parser->ib_index]; ++// if (parser->reloc_index == -1) ++// is_old = 1; ++ ++ hdr = ib_chunk->kdata[offset_dw]; ++ reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; ++ val = ib_chunk->kdata[offset_dw + 1]; ++ packet3_hdr = ib_chunk->kdata[offset_dw + 2]; ++ ++ /* this is too strict we may want to expand the length in the future and have ++ old kernels ignore it. */ ++ if (parser->reloc_index == -1) { ++ if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) { ++ DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg); ++ return -EINVAL; ++ } ++ } else { ++ if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16))) { ++ DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16), reg); ++ return -EINVAL; ++ ++ } ++ } ++ ++ switch(reg) { ++ case RADEON_DST_PITCH_OFFSET: ++ case RADEON_SRC_PITCH_OFFSET: ++ /* pass in the start of the reloc */ ++ ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset); ++ if (ret) ++ return ret; ++ tmp = (val & RADEON_2D_OFFSET_MASK) << 10; ++ val &= ~RADEON_2D_OFFSET_MASK; ++ offset += tmp; ++ offset >>= 10; ++ val |= offset; ++ break; ++ case RADEON_RB3D_DEPTHOFFSET: ++ case RADEON_RB3D_COLOROFFSET: ++ case R300_RB3D_COLOROFFSET0: ++ case R300_RB3D_DEPTHOFFSET: ++ case R200_PP_TXOFFSET_0: ++ case R200_PP_TXOFFSET_1: ++ case R200_PP_TXOFFSET_2: ++ case R200_PP_TXOFFSET_3: ++ case R200_PP_TXOFFSET_4: ++ case R200_PP_TXOFFSET_5: ++ case RADEON_PP_TXOFFSET_0: ++ case RADEON_PP_TXOFFSET_1: ++ case RADEON_PP_TXOFFSET_2: ++ case R300_TX_OFFSET_0: ++ case R300_TX_OFFSET_0+4: ++ case R300_TX_OFFSET_0+8: ++ case R300_TX_OFFSET_0+12: ++ case R300_TX_OFFSET_0+16: ++ case R300_TX_OFFSET_0+20: ++ case R300_TX_OFFSET_0+24: ++ case R300_TX_OFFSET_0+28: ++ case R300_TX_OFFSET_0+32: ++ case R300_TX_OFFSET_0+36: ++ case R300_TX_OFFSET_0+40: ++ case R300_TX_OFFSET_0+44: ++ case R300_TX_OFFSET_0+48: ++ case R300_TX_OFFSET_0+52: ++ case R300_TX_OFFSET_0+56: ++ case R300_TX_OFFSET_0+60: ++ ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset); ++ if (ret) ++ return ret; ++ ++ offset &= 0xffffffe0; ++ val += offset; ++ break; ++ default: ++ break; ++ } ++ ++ ib_chunk->kdata[offset_dw + 1] = val; ++ return 0; ++} ++ ++static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser, ++ uint32_t offset_dw) ++{ ++ drm_radeon_private_t *dev_priv = parser->dev->dev_private; ++ uint32_t hdr, num_dw, reg, i; ++ uint32_t offset, val, tmp, nptr, cptr; ++ uint32_t *reloc; ++ int ret; ++ struct drm_radeon_kernel_chunk *ib_chunk; ++ ++ ib_chunk = &parser->chunks[parser->ib_index]; ++// if (parser->reloc_index == -1) ++// is_old = 1; ++ ++ hdr = ib_chunk->kdata[offset_dw]; ++ num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; ++ reg = hdr & 0xff00; ++ ++ switch(reg) { ++ case RADEON_CNTL_HOSTDATA_BLT: ++ { ++ val = ib_chunk->kdata[offset_dw + 2]; ++ ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + num_dw + 2, &offset); ++ if (ret) ++ return ret; ++ ++ tmp = (val & RADEON_2D_OFFSET_MASK) << 10; ++ val &= ~RADEON_2D_OFFSET_MASK; ++ offset += tmp; ++ offset >>= 10; ++ val |= offset; ++ ++ ib_chunk->kdata[offset_dw + 2] = val; ++ } ++ case RADEON_3D_LOAD_VBPNTR: ++ nptr = ib_chunk->kdata[offset_dw + 1]; ++ cptr = offset_dw + 3; ++ for (i = 0; i < (nptr & ~1); i+= 2) { ++ reloc = ib_chunk->kdata + offset_dw + num_dw + 2; ++ reloc += ((i + 0) * 2); ++ ret = dev_priv->cs.relocate(parser, reloc, &offset); ++ if (ret) { ++ return ret; ++ } ++ ib_chunk->kdata[cptr] += offset; ++ cptr += 1; ++ reloc = ib_chunk->kdata + offset_dw + num_dw + 2; ++ reloc += ((i + 1) * 2); ++ ret = dev_priv->cs.relocate(parser, reloc, &offset); ++ if (ret) { ++ return ret; ++ } ++ ib_chunk->kdata[cptr] += offset; ++ cptr += 2; ++ } ++ if (nptr & 1) { ++ reloc = ib_chunk->kdata + offset_dw + num_dw + 2; ++ reloc += ((nptr - 1) * 2); ++ ret = dev_priv->cs.relocate(parser, reloc, &offset); ++ if (ret) { ++ return ret; ++ } ++ ib_chunk->kdata[cptr] += offset; ++ } ++ break; ++ case RADEON_CP_INDX_BUFFER: ++ reloc = ib_chunk->kdata + offset_dw + num_dw + 2; ++ ret = dev_priv->cs.relocate(parser, reloc, &offset); ++ if (ret) { ++ return ret; ++ } ++ ib_chunk->kdata[offset_dw + 2] += offset; ++ break; ++ case RADEON_3D_RNDR_GEN_INDX_PRIM: ++ reloc = ib_chunk->kdata + offset_dw + num_dw + 2; ++ ret = dev_priv->cs.relocate(parser, reloc, &offset); ++ if (ret) { ++ return ret; ++ } ++ ib_chunk->kdata[offset_dw + 1] += offset; ++ break; ++ default: ++ DRM_ERROR("reg is %x, not RADEON_CNTL_HOSTDATA_BLT\n", reg); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t *offset_dw_p) ++{ ++ uint32_t hdr, num_dw, reg; ++ int count_dw = 1; ++ int ret; ++ bool one_reg; ++ uint32_t offset_dw = *offset_dw_p; ++ int incr = 2; ++ ++ hdr = parser->chunks[parser->ib_index].kdata[offset_dw]; ++ num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; ++ reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; ++ one_reg = !!(hdr & RADEON_ONE_REG_WR); ++ ++ while (count_dw < num_dw) { ++ /* need to have something like the r300 validation here - ++ list of allowed registers */ ++ int flags; ++ ++ ret = r300_check_range(reg, 1); ++ switch(ret) { ++ case -1: ++ DRM_ERROR("Illegal register %x\n", reg); ++ break; ++ case 0: ++ break; ++ case 1: ++ flags = r300_get_reg_flags(reg); ++ if (flags == MARK_CHECK_OFFSET) { ++ if (num_dw > 2) { ++ DRM_ERROR("Cannot relocate inside type stream of reg0 packets\n"); ++ return -EINVAL; ++ } ++ ++ ret = radeon_cs_relocate_packet0(parser, offset_dw); ++ if (ret) { ++ DRM_ERROR("failed to relocate packet\n"); ++ return ret; ++ } ++ DRM_DEBUG("need to relocate %x %d\n", reg, flags); ++ /* okay it should be followed by a NOP */ ++ } else if (flags == MARK_CHECK_SCISSOR) { ++ DRM_DEBUG("need to validate scissor %x %d\n", reg, flags); ++ } else if (flags == MARK_CHECK_WAIT_VLINE) { ++ ret = radeon_cs_relocate_crtc(parser, offset_dw); ++ if (ret) { ++ DRM_ERROR("failed to relocate packet\n"); ++ return ret; ++ } ++ incr = 4; ++ } else { ++ DRM_ERROR("illegal register %x %d %d\n", reg, flags, offset_dw); ++ return -EINVAL; ++ } ++ break; ++ } ++ if (one_reg) ++ break; ++ ++ count_dw++; ++ reg += 4; ++ } ++ *offset_dw_p += incr; ++ return 0; ++} ++ ++int radeon_cs_parse(struct drm_radeon_cs_parser *parser) ++{ ++ volatile int rb; ++ struct drm_radeon_kernel_chunk *ib_chunk; ++ /* scan the packet for various things */ ++ int count_dw = 0, size_dw; ++ int ret = 0; ++ ++ ib_chunk = &parser->chunks[parser->ib_index]; ++ size_dw = ib_chunk->length_dw; ++ ++ while (count_dw < size_dw && ret == 0) { ++ int hdr = ib_chunk->kdata[count_dw]; ++ int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; ++ int reg; ++ ++ switch (hdr & RADEON_CP_PACKET_MASK) { ++ case RADEON_CP_PACKET0: ++ ret = radeon_cs_packet0(parser, &count_dw); ++ break; ++ case RADEON_CP_PACKET1: ++ case RADEON_CP_PACKET2: ++ reg = hdr & RADEON_CP_PACKET0_REG_MASK; ++ DRM_DEBUG("Packet 1/2: %d %x\n", num_dw, reg); ++ num_dw += 1; ++ break; ++ ++ case RADEON_CP_PACKET3: ++ reg = hdr & 0xff00; ++ num_dw += 2; ++ switch(reg) { ++ case RADEON_CNTL_HOSTDATA_BLT: ++ case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ ++ case RADEON_CP_INDX_BUFFER: ++ case RADEON_3D_RNDR_GEN_INDX_PRIM: ++ radeon_cs_relocate_packet3(parser, count_dw); ++ break; ++ ++ case RADEON_CNTL_BITBLT_MULTI: ++ DRM_ERROR("need relocate packet 3 for %x\n", reg); ++ break; ++ ++ case RADEON_3D_DRAW_IMMD: /* triggers drawing using in-packet vertex data */ ++ case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ ++ case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ ++ case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ ++ case RADEON_3D_DRAW_VBUF: /* triggers drawing of vertex buffers setup elsewhere */ ++ case RADEON_3D_DRAW_INDX: /* triggers drawing using indices to vertex buffer */ ++ case RADEON_WAIT_FOR_IDLE: ++ case RADEON_CP_NOP: ++ break; ++ default: ++ DRM_ERROR("unknown packet 3 %x\n", reg); ++ ret = -EINVAL; ++ } ++ break; ++ } ++ ++ count_dw += num_dw; ++ } ++ ++ if (ret) ++ return ret; ++ ++ ++ /* copy the packet into the IB */ ++ memcpy(parser->ib, ib_chunk->kdata, ib_chunk->length_dw * sizeof(uint32_t)); ++ ++ /* read back last byte to flush WC buffers */ ++ rb = readl((parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t))); ++ ++ return 0; ++} ++ ++uint32_t radeon_cs_id_get(struct drm_radeon_private *radeon) ++{ ++ /* FIXME: protect with a spinlock */ ++ /* FIXME: check if wrap affect last reported wrap & sequence */ ++ radeon->cs.id_scnt = (radeon->cs.id_scnt + 1) & 0x00FFFFFF; ++ if (!radeon->cs.id_scnt) { ++ /* increment wrap counter */ ++ radeon->cs.id_wcnt += 0x01000000; ++ /* valid sequence counter start at 1 */ ++ radeon->cs.id_scnt = 1; ++ } ++ return (radeon->cs.id_scnt | radeon->cs.id_wcnt); ++} ++ ++void r100_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id) ++{ ++ drm_radeon_private_t *dev_priv = parser->dev->dev_private; ++ RING_LOCALS; ++ ++ dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev); ++ /* ISYNC_CNTL should have CPSCRACTH bit set */ ++ *id = radeon_cs_id_get(dev_priv); ++ /* emit id in SCRATCH4 (not used yet in old drm) */ ++ BEGIN_RING(10); ++ OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); ++ OUT_RING(parser->card_offset); ++ OUT_RING(parser->chunks[parser->ib_index].length_dw); ++ OUT_RING(CP_PACKET2()); ++ OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG4, 0)); ++ OUT_RING(*id); ++ OUT_RING_REG(RADEON_LAST_SWI_REG, dev_priv->irq_emitted); ++ OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); ++ ADVANCE_RING(); ++ COMMIT_RING(); ++ ++} ++ ++void r300_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id) ++{ ++ drm_radeon_private_t *dev_priv = parser->dev->dev_private; ++ RING_LOCALS; ++ ++ dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev); ++ ++ /* ISYNC_CNTL should not have CPSCRACTH bit set */ ++ *id = radeon_cs_id_get(dev_priv); ++ ++ /* emit id in SCRATCH6 */ ++ BEGIN_RING(18); ++ OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); ++ OUT_RING(parser->card_offset); ++ OUT_RING(parser->chunks[parser->ib_index].length_dw); ++ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); ++ OUT_RING(0); ++ ++ OUT_RING_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH); ++ OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1)); ++ OUT_RING(6); ++ OUT_RING(*id); ++ OUT_RING_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FINISH|R300_RB3D_DC_FLUSH); ++ /* emit inline breadcrumb for TTM fencing */ ++#if 1 ++ RADEON_WAIT_UNTIL_3D_IDLE(); ++ OUT_RING_REG(RADEON_LAST_SWI_REG, dev_priv->irq_emitted); ++#else ++ OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1)); ++ OUT_RING(3); /* breadcrumb register */ ++ OUT_RING(dev_priv->irq_emitted); ++ OUT_RING(CP_PACKET2()); ++#endif ++ OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); ++ ADVANCE_RING(); ++ COMMIT_RING(); ++ ++} ++ ++uint32_t r100_cs_id_last_get(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ return GET_SCRATCH(dev_priv, 4); ++} ++ ++uint32_t r300_cs_id_last_get(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ return GET_SCRATCH(dev_priv, 6); ++} ++ ++int radeon_cs_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ mutex_init(&dev_priv->cs.cs_mutex); ++ if (dev_priv->chip_family < CHIP_RV280) { ++ dev_priv->cs.id_emit = r100_cs_id_emit; ++ dev_priv->cs.id_last_get = r100_cs_id_last_get; ++ } else if (dev_priv->chip_family < CHIP_R600) { ++ dev_priv->cs.id_emit = r300_cs_id_emit; ++ dev_priv->cs.id_last_get = r300_cs_id_last_get; ++ } ++ ++ dev_priv->cs.parse = radeon_cs_parse; ++ /* ib get depends on memory manager or not so memory manager */ ++ dev_priv->cs.relocate = radeon_nomm_relocate; ++ return 0; ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_cursor.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_cursor.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_cursor.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_cursor.c 2009-04-26 03:00:49.725983259 +0200 +@@ -0,0 +1,264 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++#define CURSOR_WIDTH 64 ++#define CURSOR_HEIGHT 64 ++ ++static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock) ++{ ++ struct drm_radeon_private *dev_priv = crtc->dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ uint32_t cur_lock; ++ ++ if (radeon_is_avivo(dev_priv)) { ++ cur_lock = RADEON_READ(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset); ++ if (lock) ++ cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK; ++ else ++ cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK; ++ RADEON_WRITE(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock); ++ } else { ++ switch(radeon_crtc->crtc_id) { ++ case 0: ++ cur_lock = RADEON_READ(RADEON_CUR_OFFSET); ++ if (lock) ++ cur_lock |= RADEON_CUR_LOCK; ++ else ++ cur_lock &= ~RADEON_CUR_LOCK; ++ RADEON_WRITE(RADEON_CUR_OFFSET, cur_lock); ++ break; ++ case 1: ++ cur_lock = RADEON_READ(RADEON_CUR2_OFFSET); ++ if (lock) ++ cur_lock |= RADEON_CUR2_LOCK; ++ else ++ cur_lock &= ~RADEON_CUR2_LOCK; ++ RADEON_WRITE(RADEON_CUR2_OFFSET, cur_lock); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++static void radeon_hide_cursor(struct drm_crtc *crtc) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_radeon_private *dev_priv = crtc->dev->dev_private; ++ ++ if (radeon_is_avivo(dev_priv)) { ++ RADEON_WRITE(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); ++ RADEON_WRITE_P(RADEON_MM_DATA, 0, ~AVIVO_D1CURSOR_EN); ++ } else { ++ switch(radeon_crtc->crtc_id) { ++ case 0: ++ RADEON_WRITE(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL); ++ break; ++ case 1: ++ RADEON_WRITE(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL); ++ break; ++ default: ++ return; ++ } ++ RADEON_WRITE_P(RADEON_MM_DATA, 0, ~RADEON_CRTC_CUR_EN); ++ } ++} ++ ++static void radeon_show_cursor(struct drm_crtc *crtc) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_radeon_private *dev_priv = crtc->dev->dev_private; ++ ++ if (radeon_is_avivo(dev_priv)) { ++ RADEON_WRITE(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); ++ RADEON_WRITE(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | ++ (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); ++ } else { ++ switch(radeon_crtc->crtc_id) { ++ case 0: ++ RADEON_WRITE(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL); ++ break; ++ case 1: ++ RADEON_WRITE(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL); ++ break; ++ default: ++ return; ++ } ++ ++ RADEON_WRITE_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN | ++ (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)), ++ ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK)); ++ } ++} ++ ++static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, ++ uint32_t width, uint32_t height) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_radeon_private *dev_priv = crtc->dev->dev_private; ++ struct drm_radeon_gem_object *obj_priv; ++ ++ obj_priv = obj->driver_private; ++ ++ if (radeon_is_avivo(dev_priv)) { ++ RADEON_WRITE(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, ++ dev_priv->fb_location + obj_priv->bo->offset); ++ RADEON_WRITE(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset, ++ (width - 1) << 16 | (height - 1)); ++ } else { ++ switch(radeon_crtc->crtc_id) { ++ case 0: ++ /* offset is from DISP_BASE_ADDRESS */ ++ RADEON_WRITE(RADEON_CUR_OFFSET, obj_priv->bo->offset); ++ break; ++ case 1: ++ /* offset is from DISP2_BASE_ADDRESS */ ++ RADEON_WRITE(RADEON_CUR2_OFFSET, obj_priv->bo->offset); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++int radeon_crtc_cursor_set(struct drm_crtc *crtc, ++ struct drm_file *file_priv, ++ uint32_t handle, ++ uint32_t width, ++ uint32_t height) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_gem_object *obj; ++ int ret; ++ ++ if (!handle) { ++ /* turn off cursor */ ++ radeon_hide_cursor(crtc); ++ obj = NULL; ++ goto unpin; ++ } ++ ++ if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { ++ DRM_ERROR("bad cursor width or height %d x %d\n", width, height); ++ return -EINVAL; ++ } ++ ++ obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); ++ if (!obj) { ++ DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); ++ return -EINVAL; ++ } ++ ++ ret = radeon_gem_object_pin(obj, 0, RADEON_GEM_DOMAIN_VRAM); ++ if (ret) ++ goto fail; ++ ++ radeon_lock_cursor(crtc, true); ++ // XXX only 27 bit offset for legacy cursor ++ radeon_set_cursor(crtc, obj, width, height); ++ radeon_show_cursor(crtc); ++ radeon_lock_cursor(crtc, false); ++ ++unpin: ++ if (radeon_crtc->cursor_bo) { ++ radeon_gem_object_unpin(radeon_crtc->cursor_bo); ++ mutex_lock(&crtc->dev->struct_mutex); ++ drm_gem_object_unreference(radeon_crtc->cursor_bo); ++ mutex_unlock(&crtc->dev->struct_mutex); ++ } ++ ++ radeon_crtc->cursor_bo = obj; ++ return 0; ++fail: ++ mutex_lock(&crtc->dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&crtc->dev->struct_mutex); ++ ++ return 0; ++} ++ ++int radeon_crtc_cursor_move(struct drm_crtc *crtc, ++ int x, int y) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_radeon_private *dev_priv = crtc->dev->dev_private; ++ int xorigin = 0, yorigin = 0; ++ ++ if (x < 0) ++ xorigin = -x + 1; ++ if (y < 0) ++ yorigin = -y + 1; ++ if (xorigin >= CURSOR_WIDTH) ++ xorigin = CURSOR_WIDTH - 1; ++ if (yorigin >= CURSOR_HEIGHT) ++ yorigin = CURSOR_HEIGHT - 1; ++ ++ radeon_lock_cursor(crtc, true); ++ if (radeon_is_avivo(dev_priv)) { ++ /* avivo cursor are offset into the total surface */ ++ x += crtc->x; ++ y += crtc->y; ++ DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); ++ RADEON_WRITE(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, ++ ((xorigin ? 0: x) << 16) | ++ (yorigin ? 0 : y)); ++ RADEON_WRITE(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); ++ } else { ++ if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) ++ y /= 2; ++ else if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN) ++ y *= 2; ++ ++ switch(radeon_crtc->crtc_id) { ++ case 0: ++ RADEON_WRITE(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK ++ | (xorigin << 16) ++ | yorigin)); ++ RADEON_WRITE(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK ++ | ((xorigin ? 0 : x) << 16) ++ | (yorigin ? 0 : y))); ++ break; ++ case 1: ++ RADEON_WRITE(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK ++ | (xorigin << 16) ++ | yorigin)); ++ RADEON_WRITE(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK ++ | ((xorigin ? 0 : x) << 16) ++ | (yorigin ? 0 : y))); ++ break; ++ default: ++ break; ++ } ++ ++ } ++ radeon_lock_cursor(crtc, false); ++ ++ return 0; ++} ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_display.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_display.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_display.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_display.c 2009-04-26 03:00:54.186724674 +0200 +@@ -0,0 +1,680 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++#include "atom.h" ++#include ++ ++#include "drm_crtc_helper.h" ++#include "drm_edid.h" ++ ++int radeon_ddc_dump(struct drm_connector *connector); ++ ++ ++ ++static void avivo_crtc_load_lut(struct drm_crtc *crtc) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int i; ++ ++ RADEON_WRITE(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0); ++ ++ RADEON_WRITE(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); ++ RADEON_WRITE(AVIVO_DC_LUTA_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); ++ RADEON_WRITE(AVIVO_DC_LUTA_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); ++ ++ RADEON_WRITE(AVIVO_DC_LUTA_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); ++ RADEON_WRITE(AVIVO_DC_LUTA_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); ++ RADEON_WRITE(AVIVO_DC_LUTA_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); ++ ++ RADEON_WRITE(AVIVO_DC_LUT_RW_SELECT, radeon_crtc->crtc_id); ++ RADEON_WRITE(AVIVO_DC_LUT_RW_MODE, 0); ++ RADEON_WRITE(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f); ++ ++ RADEON_WRITE8(AVIVO_DC_LUT_RW_INDEX, 0); ++ for (i = 0; i < 256; i++) { ++ RADEON_WRITE(AVIVO_DC_LUT_30_COLOR, ++ (radeon_crtc->lut_r[i] << 20) | ++ (radeon_crtc->lut_g[i] << 10) | ++ (radeon_crtc->lut_b[i] << 0)); ++ } ++ ++ RADEON_WRITE(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); ++} ++ ++static void legacy_crtc_load_lut(struct drm_crtc *crtc) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int i; ++ uint32_t dac2_cntl; ++ ++ dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2); ++ if (radeon_crtc->crtc_id == 0) ++ dac2_cntl &= (uint32_t)~RADEON_DAC2_PALETTE_ACC_CTL; ++ else ++ dac2_cntl |= RADEON_DAC2_PALETTE_ACC_CTL; ++ RADEON_WRITE(RADEON_DAC_CNTL2, dac2_cntl); ++ ++ RADEON_WRITE8(RADEON_PALETTE_INDEX, 0); ++ for (i = 0; i < 256; i++) { ++ RADEON_WRITE(RADEON_PALETTE_30_DATA, ++ (radeon_crtc->lut_r[i] << 20) | ++ (radeon_crtc->lut_g[i] << 10) | ++ (radeon_crtc->lut_b[i] << 0)); ++ } ++} ++ ++void radeon_crtc_load_lut(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ ++ if (!crtc->enabled) ++ return; ++ ++ if (radeon_is_avivo(dev_priv)) ++ avivo_crtc_load_lut(crtc); ++ else ++ legacy_crtc_load_lut(crtc); ++} ++ ++/** Sets the color ramps on behalf of RandR */ ++void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, ++ u16 blue, int regno) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ ++ if (regno==0) ++ DRM_DEBUG("gamma set %d\n", radeon_crtc->crtc_id); ++ radeon_crtc->lut_r[regno] = red >> 6; ++ radeon_crtc->lut_g[regno] = green >> 6; ++ radeon_crtc->lut_b[regno] = blue >> 6; ++} ++ ++static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, ++ u16 *blue, uint32_t size) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ int i, j; ++ ++ if (size != 256) ++ return; ++ ++ if (!crtc->fb) ++ return; ++ ++ if (crtc->fb->depth == 16) { ++ for (i = 0; i < 64; i++) { ++ if (i <= 31) { ++ for (j = 0; j < 8; j++) { ++ radeon_crtc->lut_r[i * 8 + j] = red[i] >> 6; ++ radeon_crtc->lut_b[i * 8 + j] = blue[i] >> 6; ++ } ++ } ++ for (j = 0; j < 4; j++) ++ radeon_crtc->lut_g[i * 4 + j] = green[i] >> 6; ++ } ++ } else { ++ for (i = 0; i < 256; i++) { ++ radeon_crtc->lut_r[i] = red[i] >> 6; ++ radeon_crtc->lut_g[i] = green[i] >> 6; ++ radeon_crtc->lut_b[i] = blue[i] >> 6; ++ } ++ } ++ ++ radeon_crtc_load_lut(crtc); ++} ++ ++static void radeon_crtc_destroy(struct drm_crtc *crtc) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ ++ drm_crtc_cleanup(crtc); ++ kfree(radeon_crtc); ++} ++ ++static const struct drm_crtc_funcs radeon_crtc_funcs = { ++ .cursor_set = radeon_crtc_cursor_set, ++ .cursor_move = radeon_crtc_cursor_move, ++ .gamma_set = radeon_crtc_gamma_set, ++ .set_config = drm_crtc_helper_set_config, ++ .destroy = radeon_crtc_destroy, ++}; ++ ++static void radeon_crtc_init(struct drm_device *dev, int index) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_crtc *radeon_crtc; ++ int i; ++ ++ radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); ++ // radeon_crtc = kzalloc(sizeof(struct radeon_crtc), GFP_KERNEL); ++ if (radeon_crtc == NULL) ++ return; ++ ++ drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); ++ ++ drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); ++ radeon_crtc->crtc_id = index; ++ ++ radeon_crtc->mode_set.crtc = &radeon_crtc->base; ++ radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); ++ radeon_crtc->mode_set.num_connectors = 0; ++ ++ for (i = 0; i < 256; i++) { ++ radeon_crtc->lut_r[i] = i << 2; ++ radeon_crtc->lut_g[i] = i << 2; ++ radeon_crtc->lut_b[i] = i << 2; ++ } ++ ++ if (dev_priv->is_atom_bios && (radeon_is_avivo(dev_priv) || radeon_r4xx_atom)) ++ radeon_atombios_init_crtc(dev, radeon_crtc); ++ else ++ radeon_legacy_init_crtc(dev, radeon_crtc); ++} ++ ++bool radeon_legacy_setup_enc_conn(struct drm_device *dev) ++{ ++ ++ radeon_get_legacy_connector_info_from_bios(dev); ++ return false; ++} ++ ++bool radeon_setup_enc_conn(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ /* do all the mac and stuff */ ++ ++ if (dev_priv->is_atom_bios) { ++ if (dev_priv->chip_family >= CHIP_R600) ++ return radeon_get_atom_connector_info_from_object_table(dev); ++ else ++ return radeon_get_atom_connector_info_from_supported_devices_table(dev); ++ } else ++ return radeon_get_legacy_connector_info_from_bios(dev); ++} ++ ++int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) ++{ ++ struct edid *edid; ++ int ret = 0; ++ ++ if (!radeon_connector->ddc_bus) ++ return -1; ++ radeon_i2c_do_lock(radeon_connector, 1); ++ edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); ++ radeon_i2c_do_lock(radeon_connector, 0); ++ if (edid) { ++ /* update digital bits here */ ++ if (edid->digital) ++ radeon_connector->use_digital = 1; ++ else ++ radeon_connector->use_digital = 0; ++ drm_mode_connector_update_edid_property(&radeon_connector->base, edid); ++ ret = drm_add_edid_modes(&radeon_connector->base, edid); ++ kfree(edid); ++ return ret; ++ } ++ drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); ++ return -1; ++} ++ ++int radeon_ddc_dump(struct drm_connector *connector) ++{ ++ struct edid *edid; ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ int ret = 0; ++ ++ if (!radeon_connector->ddc_bus) ++ return -1; ++ radeon_i2c_do_lock(radeon_connector, 1); ++ edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); ++ radeon_i2c_do_lock(radeon_connector, 0); ++ if (edid) { ++ kfree(edid); ++ } ++ return ret; ++} ++ ++static inline uint32_t radeon_div(uint64_t n, uint32_t d) ++{ ++ uint64_t x, y, result; ++ uint64_t mod; ++ ++ n += d / 2; ++ ++ mod = do_div(n, d); ++ return n; ++} ++ ++void radeon_compute_pll(struct radeon_pll *pll, ++ uint64_t freq, ++ uint32_t *dot_clock_p, ++ uint32_t *fb_div_p, ++ uint32_t *ref_div_p, ++ uint32_t *post_div_p, ++ int flags) ++{ ++ uint32_t min_ref_div = pll->min_ref_div; ++ uint32_t max_ref_div = pll->max_ref_div; ++ uint32_t best_vco = pll->best_vco; ++ uint32_t best_post_div = 1; ++ uint32_t best_ref_div = 1; ++ uint32_t best_feedback_div = 1; ++ uint32_t best_freq = -1; ++ uint32_t best_error = 0xffffffff; ++ uint32_t best_vco_diff = 1; ++ uint32_t post_div; ++ ++ DRM_DEBUG("PLL freq %llu %lu %lu\n", freq, pll->min_ref_div, pll->max_ref_div); ++ freq = freq * 1000; ++ ++ if (flags & RADEON_PLL_USE_REF_DIV) ++ min_ref_div = max_ref_div = pll->reference_div; ++ else { ++ while (min_ref_div < max_ref_div-1) { ++ uint32_t mid=(min_ref_div+max_ref_div)/2; ++ uint32_t pll_in = pll->reference_freq / mid; ++ if (pll_in < pll->pll_in_min) ++ max_ref_div = mid; ++ else if (pll_in > pll->pll_in_max) ++ min_ref_div = mid; ++ else ++ break; ++ } ++ } ++ ++ for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) { ++ uint32_t ref_div; ++ ++ if ((flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) ++ continue; ++ ++ /* legacy radeons only have a few post_divs */ ++ if (flags & RADEON_PLL_LEGACY) { ++ if ((post_div == 5) || ++ (post_div == 7) || ++ (post_div == 9) || ++ (post_div == 10) || ++ (post_div == 11) || ++ (post_div == 13) || ++ (post_div == 14) || ++ (post_div == 15)) ++ continue; ++ } ++ ++ for (ref_div = min_ref_div; ref_div <= max_ref_div; ++ref_div) { ++ uint32_t feedback_div, current_freq, error, vco_diff; ++ uint32_t pll_in = pll->reference_freq / ref_div; ++ uint32_t min_feed_div = pll->min_feedback_div; ++ uint32_t max_feed_div = pll->max_feedback_div+1; ++ ++ if (pll_in < pll->pll_in_min || pll_in > pll->pll_in_max) ++ continue; ++ ++ while (min_feed_div < max_feed_div) { ++ uint32_t vco; ++ feedback_div = (min_feed_div+max_feed_div)/2; ++ ++ vco = radeon_div((uint64_t)pll->reference_freq * feedback_div, ++ ref_div); ++ ++ if (vco < pll->pll_out_min) { ++ min_feed_div = feedback_div+1; ++ continue; ++ } else if(vco > pll->pll_out_max) { ++ max_feed_div = feedback_div; ++ continue; ++ } ++ ++ current_freq = radeon_div((uint64_t)pll->reference_freq * 10000 * feedback_div, ++ ref_div * post_div); ++ ++ error = abs(current_freq - freq); ++ vco_diff = abs(vco - best_vco); ++ ++ if ((best_vco == 0 && error < best_error) || ++ (best_vco != 0 && ++ (error < best_error - 100 || ++ (abs(error - best_error) < 100 && vco_diff < best_vco_diff )))) { ++ best_post_div = post_div; ++ best_ref_div = ref_div; ++ best_feedback_div = feedback_div; ++ best_freq = current_freq; ++ best_error = error; ++ best_vco_diff = vco_diff; ++ } else if (current_freq == freq) { ++ if (best_freq == -1) { ++ best_post_div = post_div; ++ best_ref_div = ref_div; ++ best_feedback_div = feedback_div; ++ best_freq = current_freq; ++ best_error = error; ++ best_vco_diff = vco_diff; ++ } else if (((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) || ++ ((flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) || ++ ((flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) || ++ ((flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) || ++ ((flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) || ++ ((flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) { ++ best_post_div = post_div; ++ best_ref_div = ref_div; ++ best_feedback_div = feedback_div; ++ best_freq = current_freq; ++ best_error = error; ++ best_vco_diff = vco_diff; ++ } ++ } ++ ++ if (current_freq < freq) ++ min_feed_div = feedback_div+1; ++ else ++ max_feed_div = feedback_div; ++ } ++ } ++ } ++ ++ *dot_clock_p = best_freq / 10000; ++ *fb_div_p = best_feedback_div; ++ *ref_div_p = best_ref_div; ++ *post_div_p = best_post_div; ++} ++ ++void radeon_get_clock_info(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct radeon_pll *p1pll = &dev_priv->mode_info.p1pll; ++ struct radeon_pll *p2pll = &dev_priv->mode_info.p2pll; ++ struct radeon_pll *spll = &dev_priv->mode_info.spll; ++ struct radeon_pll *mpll = &dev_priv->mode_info.mpll; ++ int ret; ++ ++ if (dev_priv->is_atom_bios) ++ ret = radeon_atom_get_clock_info(dev); ++ else ++ ret = radeon_combios_get_clock_info(dev); ++ ++ if (ret) { ++ if (p1pll->reference_div < 2) ++ p1pll->reference_div = 12; ++ if (p2pll->reference_div < 2) ++ p2pll->reference_div = 12; ++ } else { ++ // TODO FALLBACK ++ } ++ ++ /* pixel clocks */ ++ if (radeon_is_avivo(dev_priv)) { ++ p1pll->min_post_div = 2; ++ p1pll->max_post_div = 0x7f; ++ p2pll->min_post_div = 2; ++ p2pll->max_post_div = 0x7f; ++ } else { ++ p1pll->min_post_div = 1; ++ p1pll->max_post_div = 16; ++ p2pll->min_post_div = 1; ++ p2pll->max_post_div = 12; ++ } ++ ++ p1pll->min_ref_div = 2; ++ p1pll->max_ref_div = 0x3ff; ++ p1pll->min_feedback_div = 4; ++ p1pll->max_feedback_div = 0x7ff; ++ p1pll->best_vco = 0; ++ ++ p2pll->min_ref_div = 2; ++ p2pll->max_ref_div = 0x3ff; ++ p2pll->min_feedback_div = 4; ++ p2pll->max_feedback_div = 0x7ff; ++ p2pll->best_vco = 0; ++ ++ /* system clock */ ++ spll->min_post_div = 1; ++ spll->max_post_div = 1; ++ spll->min_ref_div = 2; ++ spll->max_ref_div = 0xff; ++ spll->min_feedback_div = 4; ++ spll->max_feedback_div = 0xff; ++ spll->best_vco = 0; ++ ++ /* memory clock */ ++ mpll->min_post_div = 1; ++ mpll->max_post_div = 1; ++ mpll->min_ref_div = 2; ++ mpll->max_ref_div = 0xff; ++ mpll->min_feedback_div = 4; ++ mpll->max_feedback_div = 0xff; ++ mpll->best_vco = 0; ++ ++} ++ ++/* not sure of the best place for these */ ++/* 10 khz */ ++void radeon_legacy_set_engine_clock(struct drm_device *dev, int eng_clock) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct radeon_pll *spll = &mode_info->spll; ++ uint32_t ref_div, fb_div; ++ uint32_t m_spll_ref_fb_div; ++ ++ /* FIXME wait for idle */ ++ ++ m_spll_ref_fb_div = RADEON_READ_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV); ++ m_spll_ref_fb_div &= ((RADEON_M_SPLL_REF_DIV_MASK << RADEON_M_SPLL_REF_DIV_SHIFT) | ++ (RADEON_MPLL_FB_DIV_MASK << RADEON_MPLL_FB_DIV_SHIFT)); ++ ref_div = m_spll_ref_fb_div & RADEON_M_SPLL_REF_DIV_MASK; ++ ++ fb_div = radeon_div(eng_clock * ref_div, spll->reference_freq); ++ m_spll_ref_fb_div |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT; ++ RADEON_WRITE_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV, m_spll_ref_fb_div); ++ ++} ++ ++/* 10 khz */ ++void radeon_legacy_set_memory_clock(struct drm_device *dev, int mem_clock) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_mode_info *mode_info = &dev_priv->mode_info; ++ struct radeon_pll *mpll = &mode_info->mpll; ++ uint32_t ref_div, fb_div; ++ uint32_t m_spll_ref_fb_div; ++ ++ /* FIXME wait for idle */ ++ ++ m_spll_ref_fb_div = RADEON_READ_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV); ++ m_spll_ref_fb_div &= ((RADEON_M_SPLL_REF_DIV_MASK << RADEON_M_SPLL_REF_DIV_SHIFT) | ++ (RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT)); ++ ref_div = m_spll_ref_fb_div & RADEON_M_SPLL_REF_DIV_MASK; ++ ++ fb_div = radeon_div(mem_clock * ref_div, mpll->reference_freq); ++ m_spll_ref_fb_div |= (fb_div & RADEON_MPLL_FB_DIV_MASK) << RADEON_MPLL_FB_DIV_SHIFT; ++ RADEON_WRITE_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV, m_spll_ref_fb_div); ++ ++} ++ ++static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) ++{ ++ struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); ++ struct drm_device *dev = fb->dev; ++ ++ if (fb->fbdev) ++ radeonfb_remove(dev, fb); ++ ++ if (radeon_fb->obj) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(radeon_fb->obj); ++ mutex_unlock(&dev->struct_mutex); ++ } ++ drm_framebuffer_cleanup(fb); ++ kfree(radeon_fb); ++} ++ ++static int radeon_user_framebuffer_create_handle(struct drm_framebuffer *fb, ++ struct drm_file *file_priv, ++ unsigned int *handle) ++{ ++ struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); ++ ++ return drm_gem_handle_create(file_priv, radeon_fb->obj, handle); ++} ++ ++static const struct drm_framebuffer_funcs radeon_fb_funcs = { ++ .destroy = radeon_user_framebuffer_destroy, ++ .create_handle = radeon_user_framebuffer_create_handle, ++}; ++ ++struct drm_framebuffer * ++radeon_framebuffer_create(struct drm_device *dev, ++ struct drm_mode_fb_cmd *mode_cmd, ++ struct drm_gem_object *obj) ++{ ++ struct radeon_framebuffer *radeon_fb; ++ ++ radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); ++ if (!radeon_fb) ++ return NULL; ++ ++ drm_framebuffer_init(dev, &radeon_fb->base, &radeon_fb_funcs); ++ drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd); ++ ++ radeon_fb->obj = obj; ++ ++ return &radeon_fb->base; ++} ++ ++static struct drm_framebuffer * ++radeon_user_framebuffer_create(struct drm_device *dev, ++ struct drm_file *file_priv, ++ struct drm_mode_fb_cmd *mode_cmd) ++{ ++ ++ struct radeon_framebuffer *radeon_fb; ++ struct drm_gem_object *obj; ++ ++ obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); ++ ++ return radeon_framebuffer_create(dev, mode_cmd, obj); ++} ++ ++static const struct drm_mode_config_funcs radeon_mode_funcs = { ++ .fb_create = radeon_user_framebuffer_create, ++ .fb_changed = radeonfb_probe, ++}; ++ ++ ++int radeon_modeset_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ static struct card_info card; ++ size_t size; ++ int num_crtc = 2, i; ++ int ret; ++ ++ drm_mode_config_init(dev); ++ ++ dev->mode_config.funcs = (void *)&radeon_mode_funcs; ++ ++ if (radeon_is_avivo(dev_priv)) { ++ dev->mode_config.max_width = 8192; ++ dev->mode_config.max_height = 8192; ++ } else { ++ dev->mode_config.max_width = 4096; ++ dev->mode_config.max_height = 4096; ++ } ++ ++ dev->mode_config.fb_base = dev_priv->fb_aper_offset; ++ ++ /* allocate crtcs - TODO single crtc */ ++ for (i = 0; i < num_crtc; i++) { ++ radeon_crtc_init(dev, i); ++ } ++ ++ /* okay we should have all the bios connectors */ ++ ++ ret = radeon_setup_enc_conn(dev); ++ ++ if (!ret) ++ return ret; ++ ++ drm_helper_initial_config(dev); ++ ++ return 0; ++} ++ ++ ++int radeon_load_modeset_init(struct drm_device *dev) ++{ ++ int ret; ++ ret = radeon_modeset_init(dev); ++ ++ return ret; ++} ++ ++void radeon_modeset_cleanup(struct drm_device *dev) ++{ ++ drm_mode_config_cleanup(dev); ++} ++ ++void radeon_init_disp_bandwidth(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_display_mode *modes[2]; ++ int pixel_bytes[2]; ++ struct drm_crtc *crtc; ++ ++ pixel_bytes[0] = pixel_bytes[1] = 0; ++ modes[0] = modes[1] = NULL; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ ++ if (crtc->enabled) { ++ modes[radeon_crtc->crtc_id] = &crtc->mode; ++ pixel_bytes[radeon_crtc->crtc_id] = crtc->fb->bits_per_pixel / 8; ++ } ++ } ++ ++ if (radeon_is_avivo(dev_priv)) { ++ radeon_init_disp_bw_avivo(dev, ++ modes[0], ++ pixel_bytes[0], ++ modes[1], ++ pixel_bytes[1]); ++ } else { ++ radeon_init_disp_bw_legacy(dev, ++ modes[0], ++ pixel_bytes[0], ++ modes[1], ++ pixel_bytes[1]); ++ } ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_drv.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_drv.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_drv.c 2009-04-26 02:52:17.304735537 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_drv.c 2009-04-26 02:56:45.926729189 +0200 +@@ -35,48 +35,105 @@ + #include "radeon_drv.h" + + #include "drm_pciids.h" ++#include + + int radeon_no_wb; ++int radeon_dynclks = -1; ++int radeon_r4xx_atom = 0; ++int radeon_agpmode = 0; ++int radeon_vram_zero = 0; ++int radeon_gart_size = 512; /* default gart size */ ++int radeon_vram_limit = -1; ++int radeon_no_gart_wb = 0; + + MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); + module_param_named(no_wb, radeon_no_wb, int, 0444); + +-static int radeon_suspend(struct drm_device *dev, pm_message_t state) +-{ +- drm_radeon_private_t *dev_priv = dev->dev_private; ++int radeon_modeset = -1; ++module_param_named(modeset, radeon_modeset, int, 0400); ++ ++MODULE_PARM_DESC(dynclks, "Disable/Enable dynamic clocks"); ++module_param_named(dynclks, radeon_dynclks, int, 0444); ++ ++MODULE_PARM_DESC(r4xx_atom, "Enable ATOMBIOS modesetting for R4xx"); ++module_param_named(r4xx_atom, radeon_r4xx_atom, int, 0444); ++ ++MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)"); ++module_param_named(agpmode, radeon_agpmode, int, 0444); ++ ++MODULE_PARM_DESC(vramzero, "Zero VRAM for new objects"); ++module_param_named(vramzero, radeon_vram_zero, int, 0600); ++ ++MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32,64, etc)\n"); ++module_param_named(gartsize, radeon_gart_size, int, 0600); ++ ++MODULE_PARM_DESC(vramlimit, "Restrict VRAM vfor testing"); ++module_param_named(vramlimit, radeon_vram_limit, int, 0600); ++ ++MODULE_PARM_DESC(no_gart_wb, "avoid using GART for moves from VRAM to GTT"); ++module_param_named(no_gart_wb, radeon_no_gart_wb, int, 0600); ++ ++static struct drm_driver driver; + +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) +- return 0; ++static struct pci_device_id pciidlist[] = { ++ radeon_PCI_IDS ++}; ++ ++#if defined(CONFIG_DRM_RADEON_KMS) ++MODULE_DEVICE_TABLE(pci, pciidlist); ++#endif + +- /* Disable *all* interrupts */ +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) +- RADEON_WRITE(R500_DxMODE_INT_MASK, 0); +- RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); +- return 0; ++static int __devinit ++radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ++{ ++ return drm_get_dev(pdev, ent, &driver); + } + +-static int radeon_resume(struct drm_device *dev) ++static void ++radeon_pci_remove(struct pci_dev *pdev) + { +- drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct drm_device *dev = pci_get_drvdata(pdev); + +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) +- return 0; ++ drm_put_dev(dev); ++} + +- /* Restore interrupt registers */ +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) +- RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); +- RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); +- return 0; ++static int ++radeon_pci_suspend(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct drm_device *dev = pci_get_drvdata(pdev); ++ return radeon_suspend(dev, state); + } + +-static struct pci_device_id pciidlist[] = { +- radeon_PCI_IDS ++static int ++radeon_pci_resume(struct pci_dev *pdev) ++{ ++ struct drm_device *dev = pci_get_drvdata(pdev); ++ return radeon_resume(dev); ++} ++ ++ ++extern struct drm_fence_driver radeon_fence_driver; ++ ++static uint32_t radeon_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL}; ++static uint32_t radeon_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL}; ++ ++static struct drm_bo_driver radeon_bo_driver = { ++ .mem_type_prio = radeon_mem_prios, ++ .mem_busy_prio = radeon_busy_prios, ++ .num_mem_type_prio = sizeof(radeon_mem_prios)/sizeof(uint32_t), ++ .num_mem_busy_prio = sizeof(radeon_busy_prios)/sizeof(uint32_t), ++ .create_ttm_backend_entry = radeon_create_ttm_backend_entry, ++ .fence_type = radeon_fence_types, ++ .invalidate_caches = radeon_invalidate_caches, ++ .init_mem_type = radeon_init_mem_type, ++ .move = radeon_move, ++ .evict_flags = radeon_evict_flags, + }; + + static struct drm_driver driver = { + .driver_features = + DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | +- DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED, ++ DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_GEM, + .dev_priv_size = sizeof(drm_radeon_buf_priv_t), + .load = radeon_driver_load, + .firstopen = radeon_driver_firstopen, +@@ -92,6 +149,10 @@ + .disable_vblank = radeon_disable_vblank, + .master_create = radeon_master_create, + .master_destroy = radeon_master_destroy, ++#if defined(CONFIG_DEBUG_FS) ++ .debugfs_init = radeon_gem_debugfs_init, ++ .debugfs_cleanup = radeon_gem_debugfs_cleanup, ++#endif + .irq_preinstall = radeon_driver_irq_preinstall, + .irq_postinstall = radeon_driver_irq_postinstall, + .irq_uninstall = radeon_driver_irq_uninstall, +@@ -100,7 +161,11 @@ + .get_map_ofs = drm_core_get_map_ofs, + .get_reg_ofs = drm_core_get_reg_ofs, + .ioctls = radeon_ioctls, ++ .gem_init_object = radeon_gem_init_object, ++ .gem_free_object = radeon_gem_free_object, + .dma_ioctl = radeon_cp_buffers, ++ .master_create = radeon_master_create, ++ .master_destroy = radeon_master_destroy, + .fops = { + .owner = THIS_MODULE, + .open = drm_open, +@@ -117,8 +182,15 @@ + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, ++ .probe = radeon_pci_probe, ++ .remove = radeon_pci_remove, ++ .suspend = radeon_pci_suspend, ++ .resume = radeon_pci_resume, + }, + ++ .fence_driver = &radeon_fence_driver, ++ .bo_driver = &radeon_bo_driver, ++ + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, +@@ -130,6 +202,29 @@ + static int __init radeon_init(void) + { + driver.num_ioctls = radeon_max_ioctl; ++ ++ /* if enabled by default */ ++#if defined(CONFIG_DRM_RADEON_KMS) && defined(CONFIG_X86) ++ driver.driver_features |= DRIVER_MODESET; ++ if (radeon_modeset == 0) ++ driver.driver_features &= ~DRIVER_MODESET; ++#else ++ if (radeon_modeset == -1) ++ radeon_modeset = 0; ++#endif ++ ++ if (radeon_modeset == 1) ++ driver.driver_features |= DRIVER_MODESET; ++ ++ /* if the vga console setting is enabled still ++ * let modprobe override it */ ++#ifdef CONFIG_VGA_CONSOLE ++ if (vgacon_text_force() && radeon_modeset == -1) { ++ driver.driver_features &= ~DRIVER_MODESET; ++ radeon_modeset = 0; ++ } ++#endif ++ + return drm_init(&driver); + } + +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_drv.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_drv.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_drv.h 2009-04-26 02:52:17.306724718 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_drv.h 2009-04-26 02:56:49.314976518 +0200 +@@ -34,6 +34,8 @@ + /* General customization: + */ + ++#include "atom.h" ++ + #define DRIVER_AUTHOR "Gareth Hughes, Keith Whitwell, others." + + #define DRIVER_NAME "radeon" +@@ -148,12 +150,6 @@ + CHIP_LAST, + }; + +-enum radeon_cp_microcode_version { +- UCODE_R100, +- UCODE_R200, +- UCODE_R300, +-}; +- + /* + * Chip flags + */ +@@ -171,6 +167,34 @@ + RADEON_IS_IGPGART = 0x01000000UL, + }; + ++/* ++ * Errata workarounds ++ */ ++enum radeon_pll_errata { ++ CHIP_ERRATA_R300_CG = 0x00000001, ++ CHIP_ERRATA_PLL_DUMMYREADS = 0x00000002, ++ CHIP_ERRATA_PLL_DELAY = 0x00000004 ++}; ++ ++enum radeon_ext_tmds_chip { ++ RADEON_DVOCHIP_NONE, ++ RADEON_SIL_164, ++ RADEON_SIL_1178 ++}; ++ ++#if defined(__powerpc__) ++enum radeon_mac_model { ++ RADEON_MAC_NONE, ++ RADEON_MAC_IBOOK, ++ RADEON_MAC_POWERBOOK_EXTERNAL, ++ RADEON_MAC_POWERBOOK_INTERNAL, ++ RADEON_MAC_POWERBOOK_VGA, ++ RADEON_MAC_MINI_EXTERNAL, ++ RADEON_MAC_MINI_INTERNAL, ++ RADEON_MAC_IMAC_G5_ISIGHT ++}; ++#endif ++ + typedef struct drm_radeon_freelist { + unsigned int age; + struct drm_buf *buf; +@@ -234,18 +258,90 @@ + #define RADEON_FLUSH_EMITED (1 << 0) + #define RADEON_PURGE_EMITED (1 << 1) + ++struct radeon_mm_obj { ++ struct drm_buffer_object *bo; ++ struct drm_bo_kmap_obj kmap; ++}; ++ ++struct radeon_mm_info { ++ uint64_t vram_offset; // Offset into GPU space ++ uint64_t vram_size; ++ uint64_t vram_visible; ++ ++ uint64_t gart_start; ++ uint64_t gart_size; ++ ++ uint64_t gart_useable; ++ ++ void *pcie_table_backup; ++ ++ struct radeon_mm_obj pcie_table; ++ struct radeon_mm_obj ring; ++ struct radeon_mm_obj ring_read; ++ ++ struct radeon_mm_obj dma_bufs; ++ struct drm_map fake_agp_map; ++}; ++ ++#include "radeon_mode.h" ++ + struct drm_radeon_master_private { + drm_local_map_t *sarea; + drm_radeon_sarea_t *sarea_priv; + }; + ++struct drm_radeon_kernel_chunk { ++ uint32_t chunk_id; ++ uint32_t length_dw; ++ uint32_t __user *chunk_data; ++ uint32_t *kdata; ++}; ++ ++struct drm_radeon_cs_parser { ++ struct drm_device *dev; ++ struct drm_file *file_priv; ++ uint32_t num_chunks; ++ struct drm_radeon_kernel_chunk *chunks; ++ int ib_index; ++ int reloc_index; ++ uint32_t card_offset; ++ void *ib; ++}; ++ ++/* command submission struct */ ++struct drm_radeon_cs_priv { ++ struct mutex cs_mutex; ++ uint32_t id_wcnt; ++ uint32_t id_scnt; ++ uint32_t id_last_wcnt; ++ uint32_t id_last_scnt; ++ ++ int (*parse)(struct drm_radeon_cs_parser *parser); ++ void (*id_emit)(struct drm_radeon_cs_parser *parser, uint32_t *id); ++ uint32_t (*id_last_get)(struct drm_device *dev); ++ /* this ib handling callback are for hidding memory manager drm ++ * from memory manager less drm, free have to emit ib discard ++ * sequence into the ring */ ++ int (*ib_get)(struct drm_radeon_cs_parser *parser); ++ uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib); ++ void (*ib_free)(struct drm_radeon_cs_parser *parser, int error); ++ /* do a relocation either MM or non-MM */ ++ int (*relocate)(struct drm_radeon_cs_parser *parser, ++ uint32_t *reloc, uint32_t *offset); ++}; ++ ++ ++ ++struct radeon_pm_regs { ++ uint32_t crtc_ext_cntl; ++ uint32_t bios_scratch[8]; ++}; ++ + typedef struct drm_radeon_private { + drm_radeon_ring_buffer_t ring; + +- u32 fb_location; +- u32 fb_size; +- int new_memmap; +- ++ bool new_memmap; ++ bool user_mm_enable; /* userspace enabled the memory manager */ + int gart_size; + u32 gart_vm_start; + unsigned long gart_buffers_offset; +@@ -260,8 +356,6 @@ + + int usec_timeout; + +- int microcode_version; +- + struct { + u32 boxes; + int freelist_timeouts; +@@ -297,7 +391,6 @@ + unsigned long buffers_offset; + unsigned long gart_textures_offset; + +- drm_local_map_t *sarea; + drm_local_map_t *cp_ring; + drm_local_map_t *ring_rptr; + drm_local_map_t *gart_textures; +@@ -306,8 +399,8 @@ + struct mem_block *fb_heap; + + /* SW interrupt */ ++ int counter; + wait_queue_head_t swi_queue; +- atomic_t swi_emitted; + int vblank_crtc; + uint32_t irq_enable_reg; + uint32_t r500_disp_irq_reg; +@@ -315,9 +408,6 @@ + struct radeon_surface surfaces[RADEON_MAX_SURFACES]; + struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; + +- unsigned long pcigart_offset; +- unsigned int pcigart_offset_set; +- struct drm_ati_pcigart_info gart_info; + + u32 scratch_ages[5]; + +@@ -327,6 +417,9 @@ + + int num_gb_pipes; + int track_flush; ++ ++ bool mm_enabled; ++ struct radeon_mm_info mm; + drm_local_map_t *mmio; + + /* r6xx/r7xx pipe/shader config */ +@@ -348,6 +441,40 @@ + int r700_sc_hiz_tile_fifo_size; + int r700_sc_earlyz_tile_fifo_fize; + ++ uint32_t chip_family; ++ ++ unsigned long pcigart_offset; ++ unsigned int pcigart_offset_set; ++ struct drm_ati_pcigart_info gart_info; ++ ++ struct radeon_mode_info mode_info; ++ ++ uint8_t *bios; /* copy of the BIOS image */ ++ bool is_atom_bios; ++ uint16_t bios_header_start; ++ u32 fb_location; ++ u32 fb_size; ++ bool is_ddr; ++ u32 ram_width; ++ ++ uint32_t mc_fb_location; ++ uint32_t mc_agp_loc_lo; ++ uint32_t mc_agp_loc_hi; ++ ++ enum radeon_pll_errata pll_errata; ++ ++ struct radeon_mm_obj **ib_objs; ++ /* ib bitmap */ ++ uint64_t ib_alloc_bitmap; // TO DO replace with a real bitmap ++ struct drm_radeon_cs_priv cs; ++ ++ struct radeon_pm_regs pmregs; ++ int irq_emitted; ++ atomic_t irq_received; ++ ++ uint32_t aper_size; ++ int vram_mtrr; ++ int disp_priority; + } drm_radeon_private_t; + + typedef struct drm_radeon_buf_priv { +@@ -362,8 +489,15 @@ + } drm_radeon_kcmd_buffer_t; + + extern int radeon_no_wb; ++extern int radeon_dynclks; ++extern int radeon_r4xx_atom; + extern struct drm_ioctl_desc radeon_ioctls[]; + extern int radeon_max_ioctl; ++extern int radeon_agpmode; ++extern int radeon_modeset; ++extern int radeon_vram_zero; ++extern int radeon_gart_size; ++extern int radeon_vram_limit; + + extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv); + extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val); +@@ -397,7 +531,7 @@ + extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); + extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); + extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv); +-extern void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc); ++extern void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc, u32 agp_loc_hi); + extern void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base); + extern u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr); + +@@ -406,12 +540,9 @@ + + extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); + ++extern int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv); + extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); + +-extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags); +-extern int radeon_presetup(struct drm_device *dev); +-extern int radeon_driver_postcleanup(struct drm_device *dev); +- + extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); + extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv); + extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv); +@@ -427,6 +558,7 @@ + extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state); + extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); + extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); ++extern u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int); + + extern void radeon_do_release(struct drm_device * dev); + extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc); +@@ -443,13 +575,13 @@ + extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); + extern int radeon_driver_unload(struct drm_device *dev); + extern int radeon_driver_firstopen(struct drm_device *dev); +-extern void radeon_driver_preclose(struct drm_device *dev, ++extern void radeon_driver_preclose(struct drm_device * dev, + struct drm_file *file_priv); +-extern void radeon_driver_postclose(struct drm_device *dev, ++extern void radeon_driver_postclose(struct drm_device * dev, + struct drm_file *file_priv); + extern void radeon_driver_lastclose(struct drm_device * dev); +-extern int radeon_driver_open(struct drm_device *dev, +- struct drm_file *file_priv); ++extern int radeon_driver_open(struct drm_device * dev, ++ struct drm_file * file_priv); + extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); + +@@ -478,6 +610,12 @@ + extern int r600_page_table_init(struct drm_device *dev); + extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); + ++extern int radeon_modeset_cp_suspend(struct drm_device *dev); ++extern int radeon_modeset_cp_resume(struct drm_device *dev); ++/* radeon_pm.c */ ++int radeon_suspend(struct drm_device *dev, pm_message_t state); ++int radeon_resume(struct drm_device *dev); ++ + /* Flags for stats.boxes + */ + #define RADEON_BOX_DMA_IDLE 0x1 +@@ -486,12 +624,17 @@ + #define RADEON_BOX_WAIT_IDLE 0x8 + #define RADEON_BOX_TEXTURE_LOAD 0x10 + ++#define R600_CONFIG_MEMSIZE 0x5428 ++#define R600_CONFIG_APER_SIZE 0x5430 + /* Register definitions, register access macros and drmAddMap constants + * for Radeon kernel driver. + */ + #define RADEON_MM_INDEX 0x0000 ++# define RADEON_MM_APER (1 << 31) + #define RADEON_MM_DATA 0x0004 + ++#include "radeon_reg.h" ++ + #define RADEON_AGP_COMMAND 0x0f60 + #define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ + # define RADEON_AGP_ENABLE (1<<8) +@@ -667,16 +810,6 @@ + #define R520_MC_IND_WR_EN (1 << 24) + #define R520_MC_IND_DATA 0x74 + +-#define RV515_MC_FB_LOCATION 0x01 +-#define RV515_MC_AGP_LOCATION 0x02 +-#define RV515_MC_AGP_BASE 0x03 +-#define RV515_MC_AGP_BASE_2 0x04 +- +-#define R520_MC_FB_LOCATION 0x04 +-#define R520_MC_AGP_LOCATION 0x05 +-#define R520_MC_AGP_BASE 0x06 +-#define R520_MC_AGP_BASE_2 0x07 +- + #define RADEON_MPP_TB_CONFIG 0x01c0 + #define RADEON_MEM_CNTL 0x0140 + #define RADEON_MEM_SDRAM_MODE_REG 0x0158 +@@ -740,6 +873,7 @@ + #define RADEON_SCRATCH_REG3 0x15ec + #define RADEON_SCRATCH_REG4 0x15f0 + #define RADEON_SCRATCH_REG5 0x15f4 ++#define RADEON_SCRATCH_REG6 0x15f8 + #define RADEON_SCRATCH_UMSK 0x0770 + #define RADEON_SCRATCH_ADDR 0x0774 + +@@ -762,6 +896,12 @@ + + #define R600_SCRATCHOFF(x) (R600_SCRATCH_REG_OFFSET + 4*(x)) + ++#define RADEON_CRTC_CRNT_FRAME 0x0214 ++#define RADEON_CRTC2_CRNT_FRAME 0x0314 ++ ++#define RADEON_CRTC_STATUS 0x005c ++#define RADEON_CRTC2_STATUS 0x03fc ++ + #define RADEON_GEN_INT_CNTL 0x0040 + # define RADEON_CRTC_VBLANK_MASK (1 << 0) + # define RADEON_CRTC2_VBLANK_MASK (1 << 9) +@@ -779,10 +919,13 @@ + # define RADEON_SW_INT_FIRE (1 << 26) + # define R500_DISPLAY_INT_STATUS (1 << 0) + +-#define RADEON_HOST_PATH_CNTL 0x0130 +-# define RADEON_HDP_SOFT_RESET (1 << 26) +-# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) +-# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28) ++#define RADEON_HOST_PATH_CNTL 0x0130 ++# define RADEON_HDP_APER_CNTL (1 << 23) ++# define RADEON_HP_LIN_RD_CACHE_DIS (1 << 24) ++# define RADEON_HDP_SOFT_RESET (1 << 26) ++# define RADEON_HDP_READ_BUFFER_INVALIDATED (1 << 27) ++ ++#define RADEON_NB_TOM 0x15c + + #define RADEON_ISYNC_CNTL 0x1724 + # define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0) +@@ -821,12 +964,17 @@ + #define RADEON_PP_TXFILTER_1 0x1c6c + #define RADEON_PP_TXFILTER_2 0x1c84 + +-#define R300_RB2D_DSTCACHE_CTLSTAT 0x342c /* use R300_DSTCACHE_CTLSTAT */ +-#define R300_DSTCACHE_CTLSTAT 0x1714 +-# define R300_RB2D_DC_FLUSH (3 << 0) +-# define R300_RB2D_DC_FREE (3 << 2) +-# define R300_RB2D_DC_FLUSH_ALL 0xf +-# define R300_RB2D_DC_BUSY (1 << 31) ++#define R300_RB2D_DSTCACHE_CTLSTAT 0x342c /* use R300_DSTCACHE_CTLSTAT */ ++#define R300_DSTCACHE_CTLSTAT 0x1714 ++# define R300_RB2D_DC_FLUSH (3 << 0) ++# define R300_RB2D_DC_FREE (3 << 2) ++//# define R300_RB2D_DC_FLUSH_ALL 0xf ++# define R300_RB2D_DC_BUSY (1 << 31) ++#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c ++# define RADEON_RB2D_DC_FLUSH (3 << 0) ++# define RADEON_RB2D_DC_FREE (3 << 2) ++# define RADEON_RB2D_DC_FLUSH_ALL 0xf ++# define RADEON_RB2D_DC_BUSY (1 << 31) + #define RADEON_RB3D_CNTL 0x1c3c + # define RADEON_ALPHA_BLEND_ENABLE (1 << 0) + # define RADEON_PLANE_MASK_ENABLE (1 << 1) +@@ -853,11 +1001,6 @@ + # define R300_ZC_FLUSH (1 << 0) + # define R300_ZC_FREE (1 << 1) + # define R300_ZC_BUSY (1 << 31) +-#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c +-# define RADEON_RB3D_DC_FLUSH (3 << 0) +-# define RADEON_RB3D_DC_FREE (3 << 2) +-# define RADEON_RB3D_DC_FLUSH_ALL 0xf +-# define RADEON_RB3D_DC_BUSY (1 << 31) + #define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c + # define R300_RB3D_DC_FLUSH (2 << 0) + # define R300_RB3D_DC_FREE (2 << 2) +@@ -865,15 +1008,15 @@ + #define RADEON_RB3D_ZSTENCILCNTL 0x1c2c + # define RADEON_Z_TEST_MASK (7 << 4) + # define RADEON_Z_TEST_ALWAYS (7 << 4) +-# define RADEON_Z_HIERARCHY_ENABLE (1 << 8) ++# define RADEON_Z_HIERARCHY_ENABLE (1 << 8) + # define RADEON_STENCIL_TEST_ALWAYS (7 << 12) + # define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) + # define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) + # define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) +-# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) +-# define RADEON_FORCE_Z_DIRTY (1 << 29) ++# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) ++# define RADEON_FORCE_Z_DIRTY (1 << 29) + # define RADEON_Z_WRITE_ENABLE (1 << 30) +-# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31) ++# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31) + #define RADEON_RBBM_SOFT_RESET 0x00f0 + # define RADEON_SOFT_RESET_CP (1 << 0) + # define RADEON_SOFT_RESET_HI (1 << 1) +@@ -1051,6 +1194,7 @@ + # define RADEON_PRE_WRITE_LIMIT_SHIFT 23 + + #define RADEON_CP_IB_BASE 0x0738 ++#define RADEON_CP_IB_BUFSZ 0x073c + + #define RADEON_CP_CSQ_CNTL 0x0740 + # define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) +@@ -1061,6 +1205,8 @@ + # define RADEON_CSQ_PRIBM_INDBM (4 << 28) + # define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) + ++#define RADEON_CP_CSQ_STAT 0x07f8 ++ + #define RADEON_AIC_CNTL 0x01d0 + # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) + # define RS400_MSI_REARM (1 << 3) +@@ -1143,27 +1289,6 @@ + #define RADEON_NUM_VERTICES_SHIFT 16 + + #define RADEON_COLOR_FORMAT_CI8 2 +-#define RADEON_COLOR_FORMAT_ARGB1555 3 +-#define RADEON_COLOR_FORMAT_RGB565 4 +-#define RADEON_COLOR_FORMAT_ARGB8888 6 +-#define RADEON_COLOR_FORMAT_RGB332 7 +-#define RADEON_COLOR_FORMAT_RGB8 9 +-#define RADEON_COLOR_FORMAT_ARGB4444 15 +- +-#define RADEON_TXFORMAT_I8 0 +-#define RADEON_TXFORMAT_AI88 1 +-#define RADEON_TXFORMAT_RGB332 2 +-#define RADEON_TXFORMAT_ARGB1555 3 +-#define RADEON_TXFORMAT_RGB565 4 +-#define RADEON_TXFORMAT_ARGB4444 5 +-#define RADEON_TXFORMAT_ARGB8888 6 +-#define RADEON_TXFORMAT_RGBA8888 7 +-#define RADEON_TXFORMAT_Y8 8 +-#define RADEON_TXFORMAT_VYUY422 10 +-#define RADEON_TXFORMAT_YVYU422 11 +-#define RADEON_TXFORMAT_DXT1 12 +-#define RADEON_TXFORMAT_DXT23 14 +-#define RADEON_TXFORMAT_DXT45 15 + + #define R200_PP_TXCBLEND_0 0x2f00 + #define R200_PP_TXCBLEND_1 0x2f10 +@@ -1274,16 +1399,44 @@ + + #define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4 + +-#define R200_PP_TRI_PERF 0x2cf8 ++#define R200_PP_TRI_PERF 0x2cf8 + + #define R200_PP_AFS_0 0x2f80 +-#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ ++#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ + + #define R200_VAP_PVS_CNTL_1 0x22D0 + + #define RADEON_CRTC_CRNT_FRAME 0x0214 + #define RADEON_CRTC2_CRNT_FRAME 0x0314 + ++/* MPEG settings from VHA code */ ++#define RADEON_VHA_SETTO16_1 0x2694 ++#define RADEON_VHA_SETTO16_2 0x2680 ++#define RADEON_VHA_SETTO0_1 0x1840 ++#define RADEON_VHA_FB_OFFSET 0x19e4 ++#define RADEON_VHA_SETTO1AND70S 0x19d8 ++#define RADEON_VHA_DST_PITCH 0x1408 ++ ++// set as reference header ++#define RADEON_VHA_BACKFRAME0_OFF_Y 0x1840 ++#define RADEON_VHA_BACKFRAME1_OFF_PITCH_Y 0x1844 ++#define RADEON_VHA_BACKFRAME0_OFF_U 0x1848 ++#define RADEON_VHA_BACKFRAME1_OFF_PITCH_U 0x184c ++#define RADOEN_VHA_BACKFRAME0_OFF_V 0x1850 ++#define RADEON_VHA_BACKFRAME1_OFF_PITCH_V 0x1854 ++#define RADEON_VHA_FORWFRAME0_OFF_Y 0x1858 ++#define RADEON_VHA_FORWFRAME1_OFF_PITCH_Y 0x185c ++#define RADEON_VHA_FORWFRAME0_OFF_U 0x1860 ++#define RADEON_VHA_FORWFRAME1_OFF_PITCH_U 0x1864 ++#define RADEON_VHA_FORWFRAME0_OFF_V 0x1868 ++#define RADEON_VHA_FORWFRAME0_OFF_PITCH_V 0x1880 ++#define RADEON_VHA_BACKFRAME0_OFF_Y_2 0x1884 ++#define RADEON_VHA_BACKFRAME1_OFF_PITCH_Y_2 0x1888 ++#define RADEON_VHA_BACKFRAME0_OFF_U_2 0x188c ++#define RADEON_VHA_BACKFRAME1_OFF_PITCH_U_2 0x1890 ++#define RADEON_VHA_BACKFRAME0_OFF_V_2 0x1894 ++#define RADEON_VHA_BACKFRAME1_OFF_PITCH_V_2 0x1898 ++ + #define R500_D1CRTC_STATUS 0x609c + #define R500_D2CRTC_STATUS 0x689c + #define R500_CRTC_V_BLANK (1<<0) +@@ -1745,6 +1898,8 @@ + #define RADEON_RING_HIGH_MARK 128 + + #define RADEON_PCIGART_TABLE_SIZE (32*1024) ++#define RADEON_DEFAULT_RING_SIZE (1024*1024) ++#define RADEON_DEFAULT_CP_TIMEOUT 100000 /* usecs */ + + #define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) + #define RADEON_WRITE(reg, val) \ +@@ -1759,11 +1914,24 @@ + #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) + #define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) + +-#define RADEON_WRITE_PLL(addr, val) \ +-do { \ +- RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \ +- ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \ +- RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \ ++extern u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr); ++extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data); ++extern u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr); ++ ++#define RADEON_WRITE_P(reg, val, mask) \ ++do { \ ++ uint32_t tmp = RADEON_READ(reg); \ ++ tmp &= (mask); \ ++ tmp |= ((val) & ~(mask)); \ ++ RADEON_WRITE(reg, tmp); \ ++} while(0) ++ ++#define RADEON_WRITE_PLL_P(dev_priv, addr, val, mask) \ ++do { \ ++ uint32_t tmp_ = RADEON_READ_PLL(dev_priv, addr); \ ++ tmp_ &= (mask); \ ++ tmp_ |= ((val) & ~(mask)); \ ++ RADEON_WRITE_PLL(dev_priv, addr, tmp_); \ + } while (0) + + #define RADEON_WRITE_PCIE(addr, val) \ +@@ -1801,15 +1969,18 @@ + RADEON_WRITE(RS600_MC_DATA, val); \ + } while (0) + +-#define IGP_WRITE_MCIND(addr, val) \ ++#define RADEON_WRITE_MCIND(addr, val) \ + do { \ + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ +- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ + RS690_WRITE_MCIND(addr, val); \ + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) \ + RS600_WRITE_MCIND(addr, val); \ +- else \ ++ else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || \ ++ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) \ + RS480_WRITE_MCIND(addr, val); \ ++ else \ ++ R500_WRITE_MCIND(addr, val); \ + } while (0) + + #define CP_PACKET0( reg, n ) \ +@@ -1830,7 +2001,7 @@ + #define RADEON_WAIT_UNTIL_2D_IDLE() do { \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ +- RADEON_WAIT_HOST_IDLECLEAN) ); \ ++ RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE) ); \ + } while (0) + + #define RADEON_WAIT_UNTIL_3D_IDLE() do { \ +@@ -2035,4 +2206,159 @@ + write &= mask; \ + } while (0) + ++/* radeon GEM->TTM munger */ ++struct drm_radeon_gem_object { ++ /* wrap a TTM bo */ ++ struct drm_buffer_object *bo; ++ struct drm_fence_object *fence; ++ struct drm_gem_object *obj; ++ int pin_count; ++}; ++ ++#define RADEON_IB_MEMORY (1*1024*1024) ++#define RADEON_IB_SIZE (65536) ++#define RADEON_NUM_IB (RADEON_IB_MEMORY / RADEON_IB_SIZE) ++ ++extern int radeon_gem_info_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++ ++extern int radeon_gem_create_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++ ++extern int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++ ++extern int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int radeon_gem_pread_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++ ++extern void radeon_fence_handler(struct drm_device *dev); ++extern int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class, ++ uint32_t flags, uint32_t *sequence, ++ uint32_t *native_type); ++extern void radeon_poke_flush(struct drm_device *dev, uint32_t class); ++extern int radeon_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags); ++ ++/* radeon_buffer.c */ ++extern struct drm_ttm_backend *radeon_create_ttm_backend_entry(struct drm_device *dev); ++extern int radeon_fence_types(struct drm_buffer_object *bo, uint32_t *class, uint32_t *type); ++extern int radeon_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags); ++extern int radeon_init_mem_type(struct drm_device * dev, uint32_t type, ++ struct drm_mem_type_manager * man); ++extern int radeon_move(struct drm_buffer_object * bo, ++ int evict, int no_wait, struct drm_bo_mem_reg * new_mem); ++ ++extern void radeon_gart_flush(struct drm_device *dev); ++extern uint64_t radeon_evict_flags(struct drm_buffer_object *bo); ++ ++#define BREADCRUMB_BITS 31 ++#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) ++ ++/* Breadcrumb - swi irq */ ++#define READ_BREADCRUMB(dev_priv) GET_SCRATCH(dev_priv, 3) ++ ++static inline int radeon_update_breadcrumb(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_radeon_master_private *master_priv; ++ ++ ++dev_priv->counter; ++ if (dev_priv->counter > BREADCRUMB_MASK) ++ dev_priv->counter = 1; ++ ++ if (dev->primary->master) { ++ master_priv = dev->primary->master->driver_priv; ++ } ++ return dev_priv->counter; ++} ++ ++#define radeon_is_avivo(dev_priv) ((dev_priv->chip_family >= CHIP_RS600)) ++ ++#define radeon_is_dce3(dev_priv) ((dev_priv->chip_family >= CHIP_RV620)) ++ ++#define radeon_is_dce32(dev_priv) ((dev_priv->chip_family >= CHIP_RV730)) ++ ++#define radeon_is_rv100(dev_priv) ((dev_priv->chip_family == CHIP_RV100) || \ ++ (dev_priv->chip_family == CHIP_RV200) || \ ++ (dev_priv->chip_family == CHIP_RS100) || \ ++ (dev_priv->chip_family == CHIP_RS200) || \ ++ (dev_priv->chip_family == CHIP_RV250) || \ ++ (dev_priv->chip_family == CHIP_RV280) || \ ++ (dev_priv->chip_family == CHIP_RS300)) ++ ++#define radeon_is_r300(dev_priv) ((dev_priv->chip_family == CHIP_R300) || \ ++ (dev_priv->chip_family == CHIP_RV350) || \ ++ (dev_priv->chip_family == CHIP_R350) || \ ++ (dev_priv->chip_family == CHIP_RV380) || \ ++ (dev_priv->chip_family == CHIP_R420) || \ ++ (dev_priv->chip_family == CHIP_R423) || \ ++ (dev_priv->chip_family == CHIP_RV410) || \ ++ (dev_priv->chip_family == CHIP_RS400) || \ ++ (dev_priv->chip_family == CHIP_RS480)) ++ ++#define radeon_bios8(dev_priv, v) (dev_priv->bios[v]) ++#define radeon_bios16(dev_priv, v) (dev_priv->bios[v] | (dev_priv->bios[(v) + 1] << 8)) ++#define radeon_bios32(dev_priv, v) ((dev_priv->bios[v]) | \ ++ (dev_priv->bios[(v) + 1] << 8) | \ ++ (dev_priv->bios[(v) + 2] << 16) | \ ++ (dev_priv->bios[(v) + 3] << 24)) ++ ++extern void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv); ++extern int radeon_emit_irq(struct drm_device * dev); ++ ++extern void radeon_gem_free_object(struct drm_gem_object *obj); ++extern int radeon_gem_init_object(struct drm_gem_object *obj); ++extern int radeon_gem_mm_init(struct drm_device *dev); ++extern void radeon_gem_mm_fini(struct drm_device *dev); ++extern int radeon_gem_pin_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++int radeon_gem_object_pin(struct drm_gem_object *obj, ++ uint32_t alignment, uint32_t pin_domain); ++int radeon_gem_object_unpin(struct drm_gem_object *obj); ++int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++int radeon_gem_wait_rendering(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment, ++ int initial_domain, bool discardable); ++int radeon_modeset_init(struct drm_device *dev); ++void radeon_modeset_cleanup(struct drm_device *dev); ++extern u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr); ++void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *agp_hi); ++void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc); ++extern void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on); ++#define RADEONFB_CONN_LIMIT 4 ++ ++extern int radeon_master_create(struct drm_device *dev, struct drm_master *master); ++extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master); ++extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master); ++extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); ++extern int radeon_cs_init(struct drm_device *dev); ++void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master); ++void radeon_init_memory_map(struct drm_device *dev); ++void radeon_enable_bm(struct drm_radeon_private *dev_priv); ++ ++extern int radeon_gem_debugfs_init(struct drm_minor *minor); ++extern void radeon_gem_debugfs_cleanup(struct drm_minor *minor); ++ ++#define MARK_SAFE 1 ++#define MARK_CHECK_OFFSET 2 ++#define MARK_CHECK_SCISSOR 3 ++#define MARK_CHECK_WAIT_VLINE 4 /* VLINE on a crtc relocation */ ++ ++struct _radeon_pkt_s { ++ int start; ++ int len; ++ const char *name; ++}; ++extern struct _radeon_pkt_s radeon_packet[]; ++ ++extern int r300_check_range(unsigned reg, int count); ++extern int r300_get_reg_flags(unsigned reg); ++int radeon_gem_prelocate(struct drm_radeon_cs_parser *parser); ++void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base); ++int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); + #endif /* __RADEON_DRV_H__ */ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_encoders.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_encoders.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_encoders.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_encoders.c 2009-04-26 03:00:59.039974671 +0200 +@@ -0,0 +1,1716 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "drm_crtc_helper.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++extern int atom_debug; ++ ++uint32_t ++radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t ret = 0; ++ ++ switch (supported_device) { ++ case ATOM_DEVICE_CRT1_SUPPORT: ++ case ATOM_DEVICE_TV1_SUPPORT: ++ case ATOM_DEVICE_TV2_SUPPORT: ++ case ATOM_DEVICE_CRT2_SUPPORT: ++ case ATOM_DEVICE_CV_SUPPORT: ++ switch (dac) { ++ case 1: /* dac a */ ++ if ((dev_priv->chip_family == CHIP_RS300) || ++ (dev_priv->chip_family == CHIP_RS400) || ++ (dev_priv->chip_family == CHIP_RS480)) ++ ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; ++ else if (radeon_is_avivo(dev_priv)) ++ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; ++ else ++ ret = ENCODER_OBJECT_ID_INTERNAL_DAC1; ++ break; ++ case 2: /* dac b */ ++ if (radeon_is_avivo(dev_priv)) ++ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; ++ else { ++ /*if (dev_priv->chip_family == CHIP_R200) ++ ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; ++ else*/ ++ ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; ++ } ++ break; ++ case 3: /* external dac */ ++ if (radeon_is_avivo(dev_priv)) ++ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; ++ else ++ ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; ++ break; ++ } ++ break; ++ case ATOM_DEVICE_LCD1_SUPPORT: ++ if (radeon_is_avivo(dev_priv)) ++ ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; ++ else ++ ret = ENCODER_OBJECT_ID_INTERNAL_LVDS; ++ break; ++ case ATOM_DEVICE_DFP1_SUPPORT: ++ if ((dev_priv->chip_family == CHIP_RS300) || ++ (dev_priv->chip_family == CHIP_RS400) || ++ (dev_priv->chip_family == CHIP_RS480)) ++ ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; ++ else if (radeon_is_avivo(dev_priv)) ++ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1; ++ else ++ ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1; ++ break; ++ case ATOM_DEVICE_LCD2_SUPPORT: ++ case ATOM_DEVICE_DFP2_SUPPORT: ++ if ((dev_priv->chip_family == CHIP_RS600) || ++ (dev_priv->chip_family == CHIP_RS690) || ++ (dev_priv->chip_family == CHIP_RS740)) ++ ret = ENCODER_OBJECT_ID_INTERNAL_DDI; ++ else if (radeon_is_avivo(dev_priv)) ++ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; ++ else ++ ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; ++ break; ++ case ATOM_DEVICE_DFP3_SUPPORT: ++ ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; ++ break; ++ } ++ ++ return ret; ++} ++ ++void ++radeon_link_encoder_connector(struct drm_device *dev) ++{ ++ struct drm_connector *connector; ++ struct radeon_connector *radeon_connector; ++ struct drm_encoder *encoder; ++ struct radeon_encoder *radeon_encoder; ++ ++ /* walk the list and link encoders to connectors */ ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { ++ radeon_connector = to_radeon_connector(connector); ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ radeon_encoder = to_radeon_encoder(encoder); ++ if (radeon_encoder->devices & radeon_connector->devices) ++ drm_mode_connector_attach_encoder(connector, encoder); ++ } ++ } ++} ++ ++static struct drm_connector * ++radeon_get_connector_for_encoder(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct drm_connector *connector; ++ struct radeon_connector *radeon_connector; ++ ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { ++ radeon_connector = to_radeon_connector(connector); ++ if (radeon_encoder->devices & radeon_connector->devices) ++ return connector; ++ } ++ return NULL; ++} ++ ++/* used for both atom and legacy */ ++void radeon_rmx_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; ++ ++ if (mode->hdisplay < native_mode->panel_xres || ++ mode->vdisplay < native_mode->panel_yres) { ++ radeon_encoder->flags |= RADEON_USE_RMX; ++ if (radeon_is_avivo(dev_priv)) { ++ adjusted_mode->hdisplay = native_mode->panel_xres; ++ adjusted_mode->vdisplay = native_mode->panel_yres; ++ adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank; ++ adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus; ++ adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width; ++ adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank; ++ adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus; ++ adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width; ++ /* update crtc values */ ++ drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); ++ /* adjust crtc values */ ++ adjusted_mode->crtc_hdisplay = native_mode->panel_xres; ++ adjusted_mode->crtc_vdisplay = native_mode->panel_yres; ++ adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank; ++ adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus; ++ adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width; ++ adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank; ++ adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus; ++ adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width; ++ } else { ++ adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank; ++ adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus; ++ adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width; ++ adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank; ++ adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus; ++ adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width; ++ /* update crtc values */ ++ drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); ++ /* adjust crtc values */ ++ adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank; ++ adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus; ++ adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width; ++ adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank; ++ adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus; ++ adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width; ++ } ++ adjusted_mode->flags = native_mode->flags; ++ adjusted_mode->clock = native_mode->dotclock; ++ } ++} ++ ++static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ ++ radeon_encoder->flags &= ~RADEON_USE_RMX; ++ ++ drm_mode_set_crtcinfo(adjusted_mode, 0); ++ ++ if (radeon_encoder->rmx_type != RMX_OFF) ++ radeon_rmx_mode_fixup(encoder, mode, adjusted_mode); ++ ++ /* hw bug */ ++ if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ++ && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) ++ adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; ++ ++ return true; ++} ++ ++static void ++atombios_dac_setup(struct drm_encoder *encoder, int action) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ DAC_ENCODER_CONTROL_PS_ALLOCATION args; ++ int index = 0, num = 0; ++ /* fixme - fill in enc_priv for atom dac */ ++ enum radeon_tv_std tv_std = TV_STD_NTSC; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_DAC1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: ++ index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); ++ num = 1; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC2: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: ++ index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); ++ num = 2; ++ break; ++ } ++ ++ args.ucAction = action; ++ ++ if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) ++ args.ucDacStandard = ATOM_DAC1_PS2; ++ else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) ++ args.ucDacStandard = ATOM_DAC1_CV; ++ else { ++ switch (tv_std) { ++ case TV_STD_PAL: ++ case TV_STD_PAL_M: ++ case TV_STD_SCART_PAL: ++ case TV_STD_SECAM: ++ case TV_STD_PAL_CN: ++ args.ucDacStandard = ATOM_DAC1_PAL; ++ break; ++ case TV_STD_NTSC: ++ case TV_STD_NTSC_J: ++ case TV_STD_PAL_60: ++ default: ++ args.ucDacStandard = ATOM_DAC1_NTSC; ++ break; ++ } ++ } ++ args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++} ++ ++static void ++atombios_tv_setup(struct drm_encoder *encoder, int action) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ TV_ENCODER_CONTROL_PS_ALLOCATION args; ++ int index = 0; ++ /* fixme - fill in enc_priv for atom dac */ ++ enum radeon_tv_std tv_std = TV_STD_NTSC; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); ++ ++ args.sTVEncoder.ucAction = action; ++ ++ if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) ++ args.sTVEncoder.ucTvStandard = ATOM_TV_CV; ++ else { ++ switch (tv_std) { ++ case TV_STD_NTSC: ++ args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; ++ break; ++ case TV_STD_PAL: ++ args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; ++ break; ++ case TV_STD_PAL_M: ++ args.sTVEncoder.ucTvStandard = ATOM_TV_PALM; ++ break; ++ case TV_STD_PAL_60: ++ args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60; ++ break; ++ case TV_STD_NTSC_J: ++ args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ; ++ break; ++ case TV_STD_SCART_PAL: ++ args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */ ++ break; ++ case TV_STD_SECAM: ++ args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM; ++ break; ++ case TV_STD_PAL_CN: ++ args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN; ++ break; ++ default: ++ args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; ++ break; ++ } ++ } ++ ++ args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++} ++ ++void ++atombios_external_tmds_setup(struct drm_encoder *encoder, int action) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args; ++ int index = 0; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); ++ ++ args.sXTmdsEncoder.ucEnable = action; ++ ++ if (radeon_encoder->pixel_clock > 165000) ++ args.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL; ++ ++ /*if (pScrn->rgbBits == 8)*/ ++ args.sXTmdsEncoder.ucMisc |= (1 << 1); ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++} ++ ++static void ++atombios_ddia_setup(struct drm_encoder *encoder, int action) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ DVO_ENCODER_CONTROL_PS_ALLOCATION args; ++ int index = 0; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); ++ ++ args.sDVOEncoder.ucAction = action; ++ args.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); ++ ++ if (radeon_encoder->pixel_clock > 165000) ++ args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL; ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++} ++ ++union lvds_encoder_control { ++ LVDS_ENCODER_CONTROL_PS_ALLOCATION v1; ++ LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; ++}; ++ ++static void ++atombios_digital_setup(struct drm_encoder *encoder, int action) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ union lvds_encoder_control args; ++ int index = 0; ++ uint8_t frev, crev; ++ struct radeon_encoder_atom_dig *dig; ++ struct drm_connector *connector; ++ struct radeon_connector *radeon_connector; ++ struct radeon_connector_atom_dig *dig_connector; ++ ++ connector = radeon_get_connector_for_encoder(encoder); ++ if (!connector) ++ return; ++ ++ radeon_connector = to_radeon_connector(connector); ++ ++ if (!radeon_encoder->enc_priv) ++ return; ++ ++ dig = radeon_encoder->enc_priv; ++ ++ if (!radeon_connector->con_priv) ++ return; ++ ++ dig_connector = radeon_connector->con_priv; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_LVDS: ++ index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_TMDS1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: ++ index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_LVTM1: ++ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) ++ index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); ++ else ++ index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl); ++ break; ++ } ++ ++ atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev); ++ ++ switch (frev) { ++ case 1: ++ case 2: ++ switch (crev) { ++ case 1: ++ args.v1.ucMisc = 0; ++ args.v1.ucAction = action; ++ /* XXX should probably check based on edid */ ++ if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) || ++ (connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) ++ args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; ++ args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); ++ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { ++ if (dig->lvds_misc & (1 << 0)) ++ args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; ++ if (dig->lvds_misc & (1 << 1)) ++ args.v1.ucMisc |= (1 << 1); ++ } else { ++ if (dig_connector->linkb) ++ args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; ++ if (radeon_encoder->pixel_clock > 165000) ++ args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; ++ /*if (pScrn->rgbBits == 8) */ ++ args.v1.ucMisc |= (1 << 1); ++ } ++ break; ++ case 2: ++ case 3: ++ args.v2.ucMisc = 0; ++ args.v2.ucAction = action; ++ if (crev == 3) { ++ if (dig->coherent_mode) ++ args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; ++ } ++ /* XXX should probably check based on edid */ ++ if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) || ++ (connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) ++ args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; ++ args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); ++ args.v2.ucTruncate = 0; ++ args.v2.ucSpatial = 0; ++ args.v2.ucTemporal = 0; ++ args.v2.ucFRC = 0; ++ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { ++ if (dig->lvds_misc & (1 << 0)) ++ args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; ++ if (dig->lvds_misc & (1 << 5)) { ++ args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; ++ if (dig->lvds_misc & (1 << 1)) ++ args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; ++ } ++ if (dig->lvds_misc & (1 << 6)) { ++ args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; ++ if (dig->lvds_misc & (1 << 1)) ++ args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; ++ if (((dig->lvds_misc >> 2) & 0x3) == 2) ++ args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; ++ } ++ } else { ++ if (dig_connector->linkb) ++ args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; ++ if (radeon_encoder->pixel_clock > 165000) ++ args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; ++ } ++ break; ++ default: ++ DRM_ERROR("Unknown table version %d, %d\n", frev, crev); ++ break; ++ } ++ break; ++ default: ++ DRM_ERROR("Unknown table version %d, %d\n", frev, crev); ++ break; ++ } ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++} ++ ++static int ++atombios_maybe_hdmi_mode(struct drm_encoder *encoder) ++{ ++ /* there's no getting this right unless we have complete EDID */ ++ return ATOM_ENCODER_MODE_HDMI; ++ ++ /*if (output && xf86MonitorIsHDMI(output->MonInfo)) ++ return ATOM_ENCODER_MODE_HDMI; ++ ++ return ATOM_ENCODER_MODE_DVI;*/ ++ ++} ++ ++int ++atombios_get_encoder_mode(struct drm_encoder *encoder) ++{ ++ struct drm_connector *connector; ++ struct radeon_connector *radeon_connector; ++ ++ connector = radeon_get_connector_for_encoder(encoder); ++ if (!connector) ++ return 0; ++ ++ radeon_connector = to_radeon_connector(connector); ++ ++ /* DVI should really be atombios_maybe_hdmi_mode() as well */ ++ switch (connector->connector_type) { ++ case DRM_MODE_CONNECTOR_DVII: ++ /*return atombios_maybe_hdmi_mode(encoder);*/ ++ if (radeon_connector->use_digital) ++ return ATOM_ENCODER_MODE_DVI; ++ else ++ return ATOM_ENCODER_MODE_CRT; ++ break; ++ case DRM_MODE_CONNECTOR_DVID: ++ default: ++ return ATOM_ENCODER_MODE_DVI; ++ break; ++ case DRM_MODE_CONNECTOR_HDMIA: ++ case DRM_MODE_CONNECTOR_HDMIB: ++ return atombios_maybe_hdmi_mode(encoder); ++ break; ++ case DRM_MODE_CONNECTOR_LVDS: ++ return ATOM_ENCODER_MODE_LVDS; ++ break; ++ case DRM_MODE_CONNECTOR_DisplayPort: ++ /*if (radeon_output->MonType == MT_DP) ++ return ATOM_ENCODER_MODE_DP; ++ else ++ return atombios_maybe_hdmi_mode(encoder);*/ ++ return ATOM_ENCODER_MODE_DVI; ++ break; ++ case CONNECTOR_DVI_A: ++ case CONNECTOR_VGA: ++ return ATOM_ENCODER_MODE_CRT; ++ break; ++ case CONNECTOR_STV: ++ case CONNECTOR_CTV: ++ case CONNECTOR_DIN: ++ /* fix me */ ++ return ATOM_ENCODER_MODE_TV; ++ /*return ATOM_ENCODER_MODE_CV;*/ ++ break; ++ } ++} ++ ++static void ++atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ DIG_ENCODER_CONTROL_PS_ALLOCATION args; ++ int index = 0, num = 0; ++ uint8_t frev, crev; ++ struct radeon_encoder_atom_dig *dig; ++ struct drm_connector *connector; ++ struct radeon_connector *radeon_connector; ++ struct radeon_connector_atom_dig *dig_connector; ++ ++ connector = radeon_get_connector_for_encoder(encoder); ++ if (!connector) ++ return; ++ ++ radeon_connector = to_radeon_connector(connector); ++ ++ if (!radeon_connector->con_priv) ++ return; ++ ++ dig_connector = radeon_connector->con_priv; ++ ++ if (!radeon_encoder->enc_priv) ++ return; ++ ++ dig = radeon_encoder->enc_priv; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ if (radeon_is_dce32(dev_priv)) { ++ if (dig->dig_block) ++ index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); ++ else ++ index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); ++ num = dig->dig_block + 1; ++ } else { ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); ++ num = 1; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: ++ index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); ++ num = 2; ++ break; ++ } ++ } ++ ++ atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev); ++ ++ args.ucAction = action; ++ args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); ++ ++ if (radeon_is_dce32(dev_priv)) { ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: ++ args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: ++ args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; ++ break; ++ } ++ } else { ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: ++ args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2; ++ break; ++ } ++ } ++ ++ if (radeon_encoder->pixel_clock > 165000) { ++ args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B; ++ args.ucLaneNum = 8; ++ } else { ++ if (dig_connector->linkb) ++ args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; ++ else ++ args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; ++ args.ucLaneNum = 4; ++ } ++ ++ args.ucEncoderMode = atombios_get_encoder_mode(encoder); ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++} ++ ++union dig_transmitter_control { ++ DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; ++ DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; ++}; ++ ++static void ++atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ union dig_transmitter_control args; ++ int index = 0, num = 0; ++ uint8_t frev, crev; ++ struct radeon_encoder_atom_dig *dig; ++ struct drm_connector *connector; ++ struct radeon_connector *radeon_connector; ++ struct radeon_connector_atom_dig *dig_connector; ++ ++ connector = radeon_get_connector_for_encoder(encoder); ++ if (!connector) ++ return; ++ ++ radeon_connector = to_radeon_connector(connector); ++ ++ if (!radeon_encoder->enc_priv) ++ return; ++ ++ dig = radeon_encoder->enc_priv; ++ ++ if (!radeon_connector->con_priv) ++ return; ++ ++ dig_connector = radeon_connector->con_priv; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ if (radeon_is_dce32(dev_priv)) ++ index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); ++ else { ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: ++ index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl); ++ break; ++ } ++ } ++ ++ atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev); ++ ++ args.v1.ucAction = action; ++ ++ if (radeon_is_dce32(dev_priv)) { ++ if (radeon_encoder->pixel_clock > 165000) { ++ args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 2) / 100); ++ args.v2.acConfig.fDualLinkConnector = 1; ++ } else { ++ args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 4) / 100); ++ } ++ if (dig->dig_block) ++ args.v2.acConfig.ucEncoderSel = 1; ++ ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ args.v2.acConfig.ucTransmitterSel = 0; ++ num = 0; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: ++ args.v2.acConfig.ucTransmitterSel = 1; ++ num = 1; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: ++ args.v2.acConfig.ucTransmitterSel = 2; ++ num = 2; ++ break; ++ } ++ ++ if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { ++ if (dig->coherent_mode) ++ args.v2.acConfig.fCoherentMode = 1; ++ } ++ } else { ++ args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; ++ args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock) / 10); ++ ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; ++ if (dev_priv->flags & RADEON_IS_IGP) { ++ if (radeon_encoder->pixel_clock > 165000) { ++ args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | ++ ATOM_TRANSMITTER_CONFIG_LINKA_B); ++ if (dig_connector->igp_lane_info & 0x3) ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; ++ else if (dig_connector->igp_lane_info & 0xc) ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; ++ } else { ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; ++ if (dig_connector->igp_lane_info & 0x1) ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; ++ else if (dig_connector->igp_lane_info & 0x2) ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; ++ else if (dig_connector->igp_lane_info & 0x4) ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; ++ else if (dig_connector->igp_lane_info & 0x8) ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; ++ } ++ } else { ++ if (radeon_encoder->pixel_clock > 165000) ++ args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | ++ ATOM_TRANSMITTER_CONFIG_LINKA_B | ++ ATOM_TRANSMITTER_CONFIG_LANE_0_7); ++ else { ++ if (dig_connector->linkb) ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; ++ else ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; ++ } ++ } ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; ++ if (radeon_encoder->pixel_clock > 165000) ++ args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | ++ ATOM_TRANSMITTER_CONFIG_LINKA_B | ++ ATOM_TRANSMITTER_CONFIG_LANE_0_7); ++ else { ++ if (dig_connector->linkb) ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; ++ else ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; ++ } ++ break; ++ } ++ ++ if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { ++ if (dig->coherent_mode) ++ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; ++ } ++ } ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++} ++ ++static void atom_rv515_force_tv_scaler(struct drm_radeon_private *dev_priv) ++{ ++ ++ RADEON_WRITE(0x659C, 0x0); ++ RADEON_WRITE(0x6594, 0x705); ++ RADEON_WRITE(0x65A4, 0x10001); ++ RADEON_WRITE(0x65D8, 0x0); ++ RADEON_WRITE(0x65B0, 0x0); ++ RADEON_WRITE(0x65C0, 0x0); ++ RADEON_WRITE(0x65D4, 0x0); ++ RADEON_WRITE(0x6578, 0x0); ++ RADEON_WRITE(0x657C, 0x841880A8); ++ RADEON_WRITE(0x6578, 0x1); ++ RADEON_WRITE(0x657C, 0x84208680); ++ RADEON_WRITE(0x6578, 0x2); ++ RADEON_WRITE(0x657C, 0xBFF880B0); ++ RADEON_WRITE(0x6578, 0x100); ++ RADEON_WRITE(0x657C, 0x83D88088); ++ RADEON_WRITE(0x6578, 0x101); ++ RADEON_WRITE(0x657C, 0x84608680); ++ RADEON_WRITE(0x6578, 0x102); ++ RADEON_WRITE(0x657C, 0xBFF080D0); ++ RADEON_WRITE(0x6578, 0x200); ++ RADEON_WRITE(0x657C, 0x83988068); ++ RADEON_WRITE(0x6578, 0x201); ++ RADEON_WRITE(0x657C, 0x84A08680); ++ RADEON_WRITE(0x6578, 0x202); ++ RADEON_WRITE(0x657C, 0xBFF080F8); ++ RADEON_WRITE(0x6578, 0x300); ++ RADEON_WRITE(0x657C, 0x83588058); ++ RADEON_WRITE(0x6578, 0x301); ++ RADEON_WRITE(0x657C, 0x84E08660); ++ RADEON_WRITE(0x6578, 0x302); ++ RADEON_WRITE(0x657C, 0xBFF88120); ++ RADEON_WRITE(0x6578, 0x400); ++ RADEON_WRITE(0x657C, 0x83188040); ++ RADEON_WRITE(0x6578, 0x401); ++ RADEON_WRITE(0x657C, 0x85008660); ++ RADEON_WRITE(0x6578, 0x402); ++ RADEON_WRITE(0x657C, 0xBFF88150); ++ RADEON_WRITE(0x6578, 0x500); ++ RADEON_WRITE(0x657C, 0x82D88030); ++ RADEON_WRITE(0x6578, 0x501); ++ RADEON_WRITE(0x657C, 0x85408640); ++ RADEON_WRITE(0x6578, 0x502); ++ RADEON_WRITE(0x657C, 0xBFF88180); ++ RADEON_WRITE(0x6578, 0x600); ++ RADEON_WRITE(0x657C, 0x82A08018); ++ RADEON_WRITE(0x6578, 0x601); ++ RADEON_WRITE(0x657C, 0x85808620); ++ RADEON_WRITE(0x6578, 0x602); ++ RADEON_WRITE(0x657C, 0xBFF081B8); ++ RADEON_WRITE(0x6578, 0x700); ++ RADEON_WRITE(0x657C, 0x82608010); ++ RADEON_WRITE(0x6578, 0x701); ++ RADEON_WRITE(0x657C, 0x85A08600); ++ RADEON_WRITE(0x6578, 0x702); ++ RADEON_WRITE(0x657C, 0x800081F0); ++ RADEON_WRITE(0x6578, 0x800); ++ RADEON_WRITE(0x657C, 0x8228BFF8); ++ RADEON_WRITE(0x6578, 0x801); ++ RADEON_WRITE(0x657C, 0x85E085E0); ++ RADEON_WRITE(0x6578, 0x802); ++ RADEON_WRITE(0x657C, 0xBFF88228); ++ RADEON_WRITE(0x6578, 0x10000); ++ RADEON_WRITE(0x657C, 0x82A8BF00); ++ RADEON_WRITE(0x6578, 0x10001); ++ RADEON_WRITE(0x657C, 0x82A08CC0); ++ RADEON_WRITE(0x6578, 0x10002); ++ RADEON_WRITE(0x657C, 0x8008BEF8); ++ RADEON_WRITE(0x6578, 0x10100); ++ RADEON_WRITE(0x657C, 0x81F0BF28); ++ RADEON_WRITE(0x6578, 0x10101); ++ RADEON_WRITE(0x657C, 0x83608CA0); ++ RADEON_WRITE(0x6578, 0x10102); ++ RADEON_WRITE(0x657C, 0x8018BED0); ++ RADEON_WRITE(0x6578, 0x10200); ++ RADEON_WRITE(0x657C, 0x8148BF38); ++ RADEON_WRITE(0x6578, 0x10201); ++ RADEON_WRITE(0x657C, 0x84408C80); ++ RADEON_WRITE(0x6578, 0x10202); ++ RADEON_WRITE(0x657C, 0x8008BEB8); ++ RADEON_WRITE(0x6578, 0x10300); ++ RADEON_WRITE(0x657C, 0x80B0BF78); ++ RADEON_WRITE(0x6578, 0x10301); ++ RADEON_WRITE(0x657C, 0x85008C20); ++ RADEON_WRITE(0x6578, 0x10302); ++ RADEON_WRITE(0x657C, 0x8020BEA0); ++ RADEON_WRITE(0x6578, 0x10400); ++ RADEON_WRITE(0x657C, 0x8028BF90); ++ RADEON_WRITE(0x6578, 0x10401); ++ RADEON_WRITE(0x657C, 0x85E08BC0); ++ RADEON_WRITE(0x6578, 0x10402); ++ RADEON_WRITE(0x657C, 0x8018BE90); ++ RADEON_WRITE(0x6578, 0x10500); ++ RADEON_WRITE(0x657C, 0xBFB8BFB0); ++ RADEON_WRITE(0x6578, 0x10501); ++ RADEON_WRITE(0x657C, 0x86C08B40); ++ RADEON_WRITE(0x6578, 0x10502); ++ RADEON_WRITE(0x657C, 0x8010BE90); ++ RADEON_WRITE(0x6578, 0x10600); ++ RADEON_WRITE(0x657C, 0xBF58BFC8); ++ RADEON_WRITE(0x6578, 0x10601); ++ RADEON_WRITE(0x657C, 0x87A08AA0); ++ RADEON_WRITE(0x6578, 0x10602); ++ RADEON_WRITE(0x657C, 0x8010BE98); ++ RADEON_WRITE(0x6578, 0x10700); ++ RADEON_WRITE(0x657C, 0xBF10BFF0); ++ RADEON_WRITE(0x6578, 0x10701); ++ RADEON_WRITE(0x657C, 0x886089E0); ++ RADEON_WRITE(0x6578, 0x10702); ++ RADEON_WRITE(0x657C, 0x8018BEB0); ++ RADEON_WRITE(0x6578, 0x10800); ++ RADEON_WRITE(0x657C, 0xBED8BFE8); ++ RADEON_WRITE(0x6578, 0x10801); ++ RADEON_WRITE(0x657C, 0x89408940); ++ RADEON_WRITE(0x6578, 0x10802); ++ RADEON_WRITE(0x657C, 0xBFE8BED8); ++ RADEON_WRITE(0x6578, 0x20000); ++ RADEON_WRITE(0x657C, 0x80008000); ++ RADEON_WRITE(0x6578, 0x20001); ++ RADEON_WRITE(0x657C, 0x90008000); ++ RADEON_WRITE(0x6578, 0x20002); ++ RADEON_WRITE(0x657C, 0x80008000); ++ RADEON_WRITE(0x6578, 0x20003); ++ RADEON_WRITE(0x657C, 0x80008000); ++ RADEON_WRITE(0x6578, 0x20100); ++ RADEON_WRITE(0x657C, 0x80108000); ++ RADEON_WRITE(0x6578, 0x20101); ++ RADEON_WRITE(0x657C, 0x8FE0BF70); ++ RADEON_WRITE(0x6578, 0x20102); ++ RADEON_WRITE(0x657C, 0xBFE880C0); ++ RADEON_WRITE(0x6578, 0x20103); ++ RADEON_WRITE(0x657C, 0x80008000); ++ RADEON_WRITE(0x6578, 0x20200); ++ RADEON_WRITE(0x657C, 0x8018BFF8); ++ RADEON_WRITE(0x6578, 0x20201); ++ RADEON_WRITE(0x657C, 0x8F80BF08); ++ RADEON_WRITE(0x6578, 0x20202); ++ RADEON_WRITE(0x657C, 0xBFD081A0); ++ RADEON_WRITE(0x6578, 0x20203); ++ RADEON_WRITE(0x657C, 0xBFF88000); ++ RADEON_WRITE(0x6578, 0x20300); ++ RADEON_WRITE(0x657C, 0x80188000); ++ RADEON_WRITE(0x6578, 0x20301); ++ RADEON_WRITE(0x657C, 0x8EE0BEC0); ++ RADEON_WRITE(0x6578, 0x20302); ++ RADEON_WRITE(0x657C, 0xBFB082A0); ++ RADEON_WRITE(0x6578, 0x20303); ++ RADEON_WRITE(0x657C, 0x80008000); ++ RADEON_WRITE(0x6578, 0x20400); ++ RADEON_WRITE(0x657C, 0x80188000); ++ RADEON_WRITE(0x6578, 0x20401); ++ RADEON_WRITE(0x657C, 0x8E00BEA0); ++ RADEON_WRITE(0x6578, 0x20402); ++ RADEON_WRITE(0x657C, 0xBF8883C0); ++ RADEON_WRITE(0x6578, 0x20403); ++ RADEON_WRITE(0x657C, 0x80008000); ++ RADEON_WRITE(0x6578, 0x20500); ++ RADEON_WRITE(0x657C, 0x80188000); ++ RADEON_WRITE(0x6578, 0x20501); ++ RADEON_WRITE(0x657C, 0x8D00BE90); ++ RADEON_WRITE(0x6578, 0x20502); ++ RADEON_WRITE(0x657C, 0xBF588500); ++ RADEON_WRITE(0x6578, 0x20503); ++ RADEON_WRITE(0x657C, 0x80008008); ++ RADEON_WRITE(0x6578, 0x20600); ++ RADEON_WRITE(0x657C, 0x80188000); ++ RADEON_WRITE(0x6578, 0x20601); ++ RADEON_WRITE(0x657C, 0x8BC0BE98); ++ RADEON_WRITE(0x6578, 0x20602); ++ RADEON_WRITE(0x657C, 0xBF308660); ++ RADEON_WRITE(0x6578, 0x20603); ++ RADEON_WRITE(0x657C, 0x80008008); ++ RADEON_WRITE(0x6578, 0x20700); ++ RADEON_WRITE(0x657C, 0x80108000); ++ RADEON_WRITE(0x6578, 0x20701); ++ RADEON_WRITE(0x657C, 0x8A80BEB0); ++ RADEON_WRITE(0x6578, 0x20702); ++ RADEON_WRITE(0x657C, 0xBF0087C0); ++ RADEON_WRITE(0x6578, 0x20703); ++ RADEON_WRITE(0x657C, 0x80008008); ++ RADEON_WRITE(0x6578, 0x20800); ++ RADEON_WRITE(0x657C, 0x80108000); ++ RADEON_WRITE(0x6578, 0x20801); ++ RADEON_WRITE(0x657C, 0x8920BED0); ++ RADEON_WRITE(0x6578, 0x20802); ++ RADEON_WRITE(0x657C, 0xBED08920); ++ RADEON_WRITE(0x6578, 0x20803); ++ RADEON_WRITE(0x657C, 0x80008010); ++ RADEON_WRITE(0x6578, 0x30000); ++ RADEON_WRITE(0x657C, 0x90008000); ++ RADEON_WRITE(0x6578, 0x30001); ++ RADEON_WRITE(0x657C, 0x80008000); ++ RADEON_WRITE(0x6578, 0x30100); ++ RADEON_WRITE(0x657C, 0x8FE0BF90); ++ RADEON_WRITE(0x6578, 0x30101); ++ RADEON_WRITE(0x657C, 0xBFF880A0); ++ RADEON_WRITE(0x6578, 0x30200); ++ RADEON_WRITE(0x657C, 0x8F60BF40); ++ RADEON_WRITE(0x6578, 0x30201); ++ RADEON_WRITE(0x657C, 0xBFE88180); ++ RADEON_WRITE(0x6578, 0x30300); ++ RADEON_WRITE(0x657C, 0x8EC0BF00); ++ RADEON_WRITE(0x6578, 0x30301); ++ RADEON_WRITE(0x657C, 0xBFC88280); ++ RADEON_WRITE(0x6578, 0x30400); ++ RADEON_WRITE(0x657C, 0x8DE0BEE0); ++ RADEON_WRITE(0x6578, 0x30401); ++ RADEON_WRITE(0x657C, 0xBFA083A0); ++ RADEON_WRITE(0x6578, 0x30500); ++ RADEON_WRITE(0x657C, 0x8CE0BED0); ++ RADEON_WRITE(0x6578, 0x30501); ++ RADEON_WRITE(0x657C, 0xBF7884E0); ++ RADEON_WRITE(0x6578, 0x30600); ++ RADEON_WRITE(0x657C, 0x8BA0BED8); ++ RADEON_WRITE(0x6578, 0x30601); ++ RADEON_WRITE(0x657C, 0xBF508640); ++ RADEON_WRITE(0x6578, 0x30700); ++ RADEON_WRITE(0x657C, 0x8A60BEE8); ++ RADEON_WRITE(0x6578, 0x30701); ++ RADEON_WRITE(0x657C, 0xBF2087A0); ++ RADEON_WRITE(0x6578, 0x30800); ++ RADEON_WRITE(0x657C, 0x8900BF00); ++ RADEON_WRITE(0x6578, 0x30801); ++ RADEON_WRITE(0x657C, 0xBF008900); ++} ++ ++static void ++atombios_yuv_setup(struct drm_encoder *encoder, bool enable) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ ENABLE_YUV_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, EnableYUV); ++ uint32_t temp, reg; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ reg = R600_BIOS_3_SCRATCH; ++ else ++ reg = RADEON_BIOS_3_SCRATCH; ++ ++ temp = RADEON_READ(reg); ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) ++ RADEON_WRITE(reg, (ATOM_S3_TV1_ACTIVE | ++ (radeon_crtc->crtc_id << 18))); ++ else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) ++ RADEON_WRITE(reg, (ATOM_S3_CV_ACTIVE | ++ (radeon_crtc->crtc_id << 18))); ++ else ++ RADEON_WRITE(reg, 0); ++ ++ if (enable) ++ args.ucEnable = ATOM_ENABLE; ++ args.ucCRTC = radeon_crtc->crtc_id; ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++ RADEON_WRITE(reg, 0); ++} ++ ++static void ++atombios_overscan_setup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ SET_CRTC_OVERSCAN_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan); ++ ++ memset(&args, 0, sizeof(args)); ++ ++ args.usOverscanRight = 0; ++ args.usOverscanLeft = 0; ++ args.usOverscanBottom = 0; ++ args.usOverscanTop = 0; ++ args.ucCRTC = radeon_crtc->crtc_id; ++ ++ if (radeon_encoder->flags & RADEON_USE_RMX) { ++ if (radeon_encoder->rmx_type == RMX_FULL) { ++ args.usOverscanRight = 0; ++ args.usOverscanLeft = 0; ++ args.usOverscanBottom = 0; ++ args.usOverscanTop = 0; ++ } else if (radeon_encoder->rmx_type == RMX_CENTER) { ++ args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; ++ args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; ++ args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; ++ args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; ++ } else if (radeon_encoder->rmx_type == RMX_ASPECT) { ++ int a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; ++ int a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay; ++ ++ if (a1 > a2) { ++ args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; ++ args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; ++ } else if (a2 > a1) { ++ args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; ++ args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; ++ } ++ } ++ } ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++} ++ ++static void ++atombios_scaler_setup(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ ENABLE_SCALER_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); ++ /* fixme - fill in enc_priv for atom dac */ ++ enum radeon_tv_std tv_std = TV_STD_NTSC; ++ ++ if (!radeon_is_avivo(dev_priv) && radeon_crtc->crtc_id) ++ return; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ args.ucScaler = radeon_crtc->crtc_id; ++ ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { ++ switch (tv_std) { ++ case TV_STD_NTSC: ++ default: ++ args.ucTVStandard = ATOM_TV_NTSC; ++ break; ++ case TV_STD_PAL: ++ args.ucTVStandard = ATOM_TV_PAL; ++ break; ++ case TV_STD_PAL_M: ++ args.ucTVStandard = ATOM_TV_PALM; ++ break; ++ case TV_STD_PAL_60: ++ args.ucTVStandard = ATOM_TV_PAL60; ++ break; ++ case TV_STD_NTSC_J: ++ args.ucTVStandard = ATOM_TV_NTSCJ; ++ break; ++ case TV_STD_SCART_PAL: ++ args.ucTVStandard = ATOM_TV_PAL; /* ??? */ ++ break; ++ case TV_STD_SECAM: ++ args.ucTVStandard = ATOM_TV_SECAM; ++ break; ++ case TV_STD_PAL_CN: ++ args.ucTVStandard = ATOM_TV_PALCN; ++ break; ++ } ++ args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; ++ } else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) { ++ args.ucTVStandard = ATOM_TV_CV; ++ args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; ++ } else if (radeon_encoder->flags & RADEON_USE_RMX) { ++ if (radeon_encoder->rmx_type == RMX_FULL) ++ args.ucEnable = ATOM_SCALER_EXPANSION; ++ else if (radeon_encoder->rmx_type == RMX_CENTER) ++ args.ucEnable = ATOM_SCALER_CENTER; ++ else if (radeon_encoder->rmx_type == RMX_ASPECT) ++ args.ucEnable = ATOM_SCALER_EXPANSION; ++ } else { ++ if (radeon_is_avivo(dev_priv)) ++ args.ucEnable = ATOM_SCALER_DISABLE; ++ else ++ args.ucEnable = ATOM_SCALER_CENTER; ++ } ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++ if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT) ++ && dev_priv->chip_family >= CHIP_RV515 && dev_priv->chip_family <= CHIP_RV570) { ++ atom_rv515_force_tv_scaler(dev_priv); ++ } ++ ++} ++ ++static void ++radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; ++ int index = 0; ++ bool is_dig = false; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_TMDS1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: ++ index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: ++ is_dig = true; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DVO1: ++ case ENCODER_OBJECT_ID_INTERNAL_DDI: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: ++ index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_LVDS: ++ index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_LVTM1: ++ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) ++ index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); ++ else ++ index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) ++ index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); ++ else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) ++ index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); ++ else ++ index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC2: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) ++ index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); ++ else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) ++ index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); ++ else ++ index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); ++ break; ++ } ++ ++ if (is_dig) { ++ switch (mode) { ++ case DRM_MODE_DPMS_ON: ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); ++ break; ++ case DRM_MODE_DPMS_STANDBY: ++ case DRM_MODE_DPMS_SUSPEND: ++ case DRM_MODE_DPMS_OFF: ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE); ++ break; ++ } ++ } else { ++ switch (mode) { ++ case DRM_MODE_DPMS_ON: ++ args.ucAction = ATOM_ENABLE; ++ break; ++ case DRM_MODE_DPMS_STANDBY: ++ case DRM_MODE_DPMS_SUSPEND: ++ case DRM_MODE_DPMS_OFF: ++ args.ucAction = ATOM_DISABLE; ++ break; ++ } ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ } ++ radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++} ++ ++union crtc_sourc_param { ++ SELECT_CRTC_SOURCE_PS_ALLOCATION v1; ++ SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; ++}; ++ ++static void ++atombios_set_encoder_crtc_source(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ union crtc_sourc_param args; ++ int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); ++ uint8_t frev, crev; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev); ++ ++ switch (frev) { ++ case 1: ++ switch (crev) { ++ case 1: ++ default: ++ if (radeon_is_avivo(dev_priv)) ++ args.v1.ucCRTC = radeon_crtc->crtc_id; ++ else { ++ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ++ args.v1.ucCRTC = radeon_crtc->crtc_id; ++ else ++ args.v1.ucCRTC = radeon_crtc->crtc_id << 2; ++ } ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_TMDS1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: ++ args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_LVDS: ++ case ENCODER_OBJECT_ID_INTERNAL_LVTM1: ++ if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) ++ args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX; ++ else ++ args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DVO1: ++ case ENCODER_OBJECT_ID_INTERNAL_DDI: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: ++ args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) ++ args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; ++ else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) ++ args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; ++ else ++ args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC2: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) ++ args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; ++ else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) ++ args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; ++ else ++ args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; ++ break; ++ } ++ break; ++ case 2: ++ args.v2.ucCRTC = radeon_crtc->crtc_id; ++ args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: ++ if (radeon_is_dce32(dev_priv)) { ++ if (radeon_crtc->crtc_id) ++ args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; ++ else ++ args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; ++ } else ++ args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: ++ args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: ++ args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) ++ args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; ++ else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) ++ args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; ++ else ++ args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) ++ args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; ++ else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) ++ args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; ++ else ++ args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; ++ break; ++ } ++ break; ++ } ++ break; ++ default: ++ DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); ++ break; ++ } ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++} ++ ++static void ++atombios_apply_encoder_quirks(struct drm_encoder *encoder, ++ struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ ++ /* Funky macbooks */ ++ if ((dev->pdev->device == 0x71C5) && ++ (dev->pdev->subsystem_vendor == 0x106b) && ++ (dev->pdev->subsystem_device == 0x0080)) { ++ if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { ++ uint32_t lvtma_bit_depth_control = RADEON_READ(AVIVO_LVTMA_BIT_DEPTH_CONTROL); ++ ++ lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN; ++ lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN; ++ ++ RADEON_WRITE(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control); ++ } ++ } ++ ++ /* set scaler clears this on some chips */ ++ if (radeon_is_avivo(dev_priv) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) ++ RADEON_WRITE(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN); ++} ++ ++static void ++radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ ++ if (radeon_encoder->enc_priv) { ++ struct radeon_encoder_atom_dig *dig; ++ ++ dig = radeon_encoder->enc_priv; ++ dig->dig_block = radeon_crtc->crtc_id; ++ } ++ radeon_encoder->pixel_clock = adjusted_mode->clock; ++ ++ radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++ atombios_overscan_setup(encoder, mode, adjusted_mode); ++ atombios_scaler_setup(encoder); ++ atombios_set_encoder_crtc_source(encoder); ++ ++ if (radeon_is_avivo(dev_priv)) { ++ if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) ++ atombios_yuv_setup(encoder, true); ++ else ++ atombios_yuv_setup(encoder, false); ++ } ++ ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_TMDS1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: ++ case ENCODER_OBJECT_ID_INTERNAL_LVDS: ++ case ENCODER_OBJECT_ID_INTERNAL_LVTM1: ++ atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: ++ atombios_dig_encoder_setup(encoder, ATOM_ENABLE); ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT); ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP); ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DDI: ++ atombios_ddia_setup(encoder, ATOM_ENABLE); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DVO1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: ++ atombios_external_tmds_setup(encoder, ATOM_ENABLE); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: ++ case ENCODER_OBJECT_ID_INTERNAL_DAC2: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: ++ atombios_dac_setup(encoder, ATOM_ENABLE); ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) ++ atombios_tv_setup(encoder, ATOM_ENABLE); ++ break; ++ } ++ atombios_apply_encoder_quirks(encoder, adjusted_mode); ++} ++ ++static bool ++atombios_dac_load_detect(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ ++ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ++ ATOM_DEVICE_CV_SUPPORT | ++ ATOM_DEVICE_CRT_SUPPORT)) { ++ DAC_LOAD_DETECTION_PS_ALLOCATION args; ++ int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); ++ uint8_t frev, crev; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev); ++ ++ args.sDacload.ucMisc = 0; ++ ++ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1 || ++ radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) ++ args.sDacload.ucDacType = ATOM_DAC_A; ++ else ++ args.sDacload.ucDacType = ATOM_DAC_B; ++ ++ if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) ++ args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); ++ else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) ++ args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); ++ else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { ++ args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); ++ if (crev >= 3) ++ args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; ++ } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { ++ args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); ++ if (crev >= 3) ++ args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; ++ } ++ ++ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); ++ ++ return true; ++ } else ++ return false; ++} ++ ++static enum drm_connector_status ++radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t bios_0_scratch; ++ ++ if (!atombios_dac_load_detect(encoder)) { ++ DRM_DEBUG("detect returned false \n"); ++ return connector_status_unknown; ++ } ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ bios_0_scratch = RADEON_READ(R600_BIOS_0_SCRATCH); ++ else ++ bios_0_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH); ++ ++ DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch); ++ if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { ++ if (bios_0_scratch & ATOM_S0_CRT1_MASK) ++ return connector_status_connected; ++ } else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { ++ if (bios_0_scratch & ATOM_S0_CRT2_MASK) ++ return connector_status_connected; ++ } else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { ++ if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) ++ return connector_status_connected; ++ } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { ++ if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) ++ return connector_status_connected; /* CTV */ ++ else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) ++ return connector_status_connected; /* STV */ ++ } ++ return connector_status_disconnected; ++} ++ ++static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) ++{ ++ radeon_atom_output_lock(encoder, true); ++ radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); ++} ++ ++static void radeon_atom_encoder_commit(struct drm_encoder *encoder) ++{ ++ radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); ++ radeon_atom_output_lock(encoder, false); ++} ++ ++static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { ++ .dpms = radeon_atom_encoder_dpms, ++ .mode_fixup = radeon_atom_mode_fixup, ++ .prepare = radeon_atom_encoder_prepare, ++ .mode_set = radeon_atom_encoder_mode_set, ++ .commit = radeon_atom_encoder_commit, ++ /* no detect for TMDS/LVDS yet */ ++}; ++ ++static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = { ++ .dpms = radeon_atom_encoder_dpms, ++ .mode_fixup = radeon_atom_mode_fixup, ++ .prepare = radeon_atom_encoder_prepare, ++ .mode_set = radeon_atom_encoder_mode_set, ++ .commit = radeon_atom_encoder_commit, ++ .detect = radeon_atom_dac_detect, ++}; ++ ++void radeon_enc_destroy(struct drm_encoder *encoder) ++{ ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ kfree(radeon_encoder->enc_priv); ++ drm_encoder_cleanup(encoder); ++ kfree(radeon_encoder); ++} ++ ++static const struct drm_encoder_funcs radeon_atom_enc_funcs = { ++ .destroy = radeon_enc_destroy, ++}; ++ ++struct radeon_encoder_atom_dig * ++radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) ++{ ++ struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); ++ ++ if (!dig) ++ return NULL; ++ ++ /* coherent mode by default */ ++ dig->coherent_mode = true; ++ ++ return dig; ++} ++ ++void ++radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) ++{ ++ struct drm_encoder *encoder; ++ struct radeon_encoder *radeon_encoder; ++ ++ /* see if we already added it */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ radeon_encoder = to_radeon_encoder(encoder); ++ if (radeon_encoder->encoder_id == encoder_id) { ++ radeon_encoder->devices |= supported_device; ++ return; ++ } ++ ++ } ++ ++ /* add a new one */ ++ radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); ++ if (!radeon_encoder) ++ return; ++ ++ encoder = &radeon_encoder->base; ++ encoder->possible_crtcs = 0x3; ++ encoder->possible_clones = 0; ++ ++ radeon_encoder->enc_priv = NULL; ++ ++ radeon_encoder->encoder_id = encoder_id; ++ radeon_encoder->devices = supported_device; ++ ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_LVDS: ++ case ENCODER_OBJECT_ID_INTERNAL_TMDS1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: ++ case ENCODER_OBJECT_ID_INTERNAL_LVTM1: ++ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { ++ radeon_encoder->rmx_type = RMX_FULL; ++ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); ++ radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); ++ } else { ++ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); ++ radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); ++ } ++ drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC1: ++ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); ++ drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC2: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: ++ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); ++ drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DVO1: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: ++ case ENCODER_OBJECT_ID_INTERNAL_DDI: ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: ++ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: ++ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: ++ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); ++ radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); ++ drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); ++ break; ++ } ++} +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_fb.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_fb.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_fb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_fb.c 2009-04-26 03:01:05.285726014 +0200 +@@ -0,0 +1,928 @@ ++/* ++ * Copyright © 2007 David Airlie ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * David Airlie ++ */ ++ /* ++ * Modularization ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_crtc.h" ++#include "drm_crtc_helper.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++struct radeonfb_par { ++ struct drm_device *dev; ++ struct drm_display_mode *our_mode; ++ struct radeon_framebuffer *radeon_fb; ++ int crtc_count; ++ /* crtc currently bound to this */ ++ uint32_t crtc_ids[2]; ++}; ++/* ++static int ++var_to_refresh(const struct fb_var_screeninfo *var) ++{ ++ int xtot = var->xres + var->left_margin + var->right_margin + ++ var->hsync_len; ++ int ytot = var->yres + var->upper_margin + var->lower_margin + ++ var->vsync_len; ++ ++ return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot; ++}*/ ++ ++static int radeonfb_setcolreg(unsigned regno, unsigned red, unsigned green, ++ unsigned blue, unsigned transp, ++ struct fb_info *info) ++{ ++ struct radeonfb_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_crtc *crtc; ++ int i; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_mode_set *modeset = &radeon_crtc->mode_set; ++ struct drm_framebuffer *fb = modeset->fb; ++ ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ if (i == par->crtc_count) ++ continue; ++ ++ ++ if (regno > 255) ++ return 1; ++ ++ if (fb->depth == 8) { ++ radeon_crtc_fb_gamma_set(crtc, red, green, blue, regno); ++ return 0; ++ } ++ ++ if (regno < 16) { ++ switch (fb->depth) { ++ case 15: ++ fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | ++ ((green & 0xf800) >> 6) | ++ ((blue & 0xf800) >> 11); ++ break; ++ case 16: ++ fb->pseudo_palette[regno] = (red & 0xf800) | ++ ((green & 0xfc00) >> 5) | ++ ((blue & 0xf800) >> 11); ++ break; ++ case 24: ++ case 32: ++ fb->pseudo_palette[regno] = ((red & 0xff00) << 8) | ++ (green & 0xff00) | ++ ((blue & 0xff00) >> 8); ++ break; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int radeonfb_check_var(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ struct radeonfb_par *par = info->par; ++ struct radeon_framebuffer *radeon_fb = par->radeon_fb; ++ struct drm_framebuffer *fb = &radeon_fb->base; ++ int depth; ++ ++ if (var->pixclock == -1 || !var->pixclock) ++ return -EINVAL; ++ ++ /* Need to resize the fb object !!! */ ++ if (var->xres > fb->width || var->yres > fb->height) { ++ DRM_ERROR("Requested width/height is greater than current fb object %dx%d > %dx%d\n",var->xres,var->yres,fb->width,fb->height); ++ DRM_ERROR("Need resizing code.\n"); ++ return -EINVAL; ++ } ++ ++ switch (var->bits_per_pixel) { ++ case 16: ++ depth = (var->green.length == 6) ? 16 : 15; ++ break; ++ case 32: ++ depth = (var->transp.length > 0) ? 32 : 24; ++ break; ++ default: ++ depth = var->bits_per_pixel; ++ break; ++ } ++ ++ switch (depth) { ++ case 8: ++ var->red.offset = 0; ++ var->green.offset = 0; ++ var->blue.offset = 0; ++ var->red.length = 8; ++ var->green.length = 8; ++ var->blue.length = 8; ++ var->transp.length = 0; ++ var->transp.offset = 0; ++ break; ++ case 15: ++ var->red.offset = 10; ++ var->green.offset = 5; ++ var->blue.offset = 0; ++ var->red.length = 5; ++ var->green.length = 5; ++ var->blue.length = 5; ++ var->transp.length = 1; ++ var->transp.offset = 15; ++ break; ++ case 16: ++ var->red.offset = 11; ++ var->green.offset = 5; ++ var->blue.offset = 0; ++ var->red.length = 5; ++ var->green.length = 6; ++ var->blue.length = 5; ++ var->transp.length = 0; ++ var->transp.offset = 0; ++ break; ++ case 24: ++ var->red.offset = 16; ++ var->green.offset = 8; ++ var->blue.offset = 0; ++ var->red.length = 8; ++ var->green.length = 8; ++ var->blue.length = 8; ++ var->transp.length = 0; ++ var->transp.offset = 0; ++ break; ++ case 32: ++ var->red.offset = 16; ++ var->green.offset = 8; ++ var->blue.offset = 0; ++ var->red.length = 8; ++ var->green.length = 8; ++ var->blue.length = 8; ++ var->transp.length = 8; ++ var->transp.offset = 24; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* this will let fbcon do the mode init */ ++/* FIXME: take mode config lock? */ ++static int radeonfb_set_par(struct fb_info *info) ++{ ++ struct radeonfb_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct fb_var_screeninfo *var = &info->var; ++ int i; ++ ++ DRM_DEBUG("%d %d\n", var->xres, var->pixclock); ++ ++ if (var->pixclock != -1) { ++ ++ DRM_ERROR("PIXEL CLCOK SET\n"); ++ return -EINVAL; ++ } else { ++ struct drm_crtc *crtc; ++ int ret; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ if (i == par->crtc_count) ++ continue; ++ ++ if (crtc->fb == radeon_crtc->mode_set.fb) { ++ ret = crtc->funcs->set_config(&radeon_crtc->mode_set); ++ if (ret) ++ return ret; ++ } ++ } ++ return 0; ++ } ++} ++ ++static int radeonfb_pan_display(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ struct radeonfb_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_mode_set *modeset; ++ struct drm_crtc *crtc; ++ struct radeon_crtc *radeon_crtc; ++ int ret = 0; ++ int i; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ if (i == par->crtc_count) ++ continue; ++ ++ radeon_crtc = to_radeon_crtc(crtc); ++ modeset = &radeon_crtc->mode_set; ++ ++ modeset->x = var->xoffset; ++ modeset->y = var->yoffset; ++ ++ if (modeset->num_connectors) { ++ ret = crtc->funcs->set_config(modeset); ++ ++ if (!ret) { ++ info->var.xoffset = var->xoffset; ++ info->var.yoffset = var->yoffset; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++static void radeonfb_on(struct fb_info *info) ++{ ++ struct radeonfb_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_crtc *crtc; ++ struct drm_encoder *encoder; ++ int i; ++ ++ /* ++ * For each CRTC in this fb, find all associated encoders ++ * and turn them off, then turn off the CRTC. ++ */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; ++ ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); ++ ++ /* Found a CRTC on this fb, now find encoders */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ if (encoder->crtc == crtc) { ++ struct drm_encoder_helper_funcs *encoder_funcs; ++ encoder_funcs = encoder->helper_private; ++ encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); ++ } ++ } ++ } ++} ++ ++static void radeonfb_off(struct fb_info *info, int dpms_mode) ++{ ++ struct radeonfb_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_crtc *crtc; ++ struct drm_encoder *encoder; ++ int i; ++ ++ /* ++ * For each CRTC in this fb, find all associated encoders ++ * and turn them off, then turn off the CRTC. ++ */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; ++ ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ /* Found a CRTC on this fb, now find encoders */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ if (encoder->crtc == crtc) { ++ struct drm_encoder_helper_funcs *encoder_funcs; ++ encoder_funcs = encoder->helper_private; ++ encoder_funcs->dpms(encoder, dpms_mode); ++ } ++ } ++ if (dpms_mode == DRM_MODE_DPMS_OFF) ++ crtc_funcs->dpms(crtc, dpms_mode); ++ } ++} ++ ++int radeonfb_blank(int blank, struct fb_info *info) ++{ ++ switch (blank) { ++ case FB_BLANK_UNBLANK: ++ radeonfb_on(info); ++ break; ++ case FB_BLANK_NORMAL: ++ radeonfb_off(info, DRM_MODE_DPMS_STANDBY); ++ break; ++ case FB_BLANK_HSYNC_SUSPEND: ++ radeonfb_off(info, DRM_MODE_DPMS_STANDBY); ++ break; ++ case FB_BLANK_VSYNC_SUSPEND: ++ radeonfb_off(info, DRM_MODE_DPMS_SUSPEND); ++ break; ++ case FB_BLANK_POWERDOWN: ++ radeonfb_off(info, DRM_MODE_DPMS_OFF); ++ break; ++ } ++ return 0; ++} ++ ++static struct fb_ops radeonfb_ops = { ++ .owner = THIS_MODULE, ++ //.fb_open = radeonfb_open, ++ //.fb_read = radeonfb_read, ++ //.fb_write = radeonfb_write, ++ //.fb_release = radeonfb_release, ++ //.fb_ioctl = radeonfb_ioctl, ++ .fb_check_var = radeonfb_check_var, ++ .fb_set_par = radeonfb_set_par, ++ .fb_setcolreg = radeonfb_setcolreg, ++ .fb_fillrect = cfb_fillrect, ++ .fb_copyarea = cfb_copyarea, //radeonfb_copyarea, ++ .fb_imageblit = cfb_imageblit, //radeonfb_imageblit, ++ .fb_pan_display = radeonfb_pan_display, ++ .fb_blank = radeonfb_blank, ++}; ++ ++/** ++ * Curretly it is assumed that the old framebuffer is reused. ++ * ++ * LOCKING ++ * caller should hold the mode config lock. ++ * ++ */ ++int radeonfb_resize(struct drm_device *dev, struct drm_crtc *crtc) ++{ ++ struct fb_info *info; ++ struct drm_framebuffer *fb; ++ struct drm_display_mode *mode = crtc->desired_mode; ++ ++ fb = crtc->fb; ++ if (!fb) ++ return 1; ++ ++ info = fb->fbdev; ++ if (!info) ++ return 1; ++ ++ if (!mode) ++ return 1; ++ ++ info->var.xres = mode->hdisplay; ++ info->var.right_margin = mode->hsync_start - mode->hdisplay; ++ info->var.hsync_len = mode->hsync_end - mode->hsync_start; ++ info->var.left_margin = mode->htotal - mode->hsync_end; ++ info->var.yres = mode->vdisplay; ++ info->var.lower_margin = mode->vsync_start - mode->vdisplay; ++ info->var.vsync_len = mode->vsync_end - mode->vsync_start; ++ info->var.upper_margin = mode->vtotal - mode->vsync_end; ++ info->var.pixclock = 10000000 / mode->htotal * 1000 / mode->vtotal * 100; ++ /* avoid overflow */ ++ info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh; ++ ++ return 0; ++} ++EXPORT_SYMBOL(radeonfb_resize); ++ ++static struct drm_mode_set panic_mode; ++ ++int radeonfb_panic(struct notifier_block *n, unsigned long ununsed, ++ void *panic_str) ++{ ++ DRM_ERROR("panic occurred, switching back to text console\n"); ++ drm_crtc_helper_set_config(&panic_mode); ++ ++ return 0; ++} ++EXPORT_SYMBOL(radeonfb_panic); ++ ++static struct notifier_block paniced = { ++ .notifier_call = radeonfb_panic, ++}; ++ ++static int radeon_align_pitch(struct drm_device *dev, int width, int bpp) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int aligned = width; ++ int align_large = (radeon_is_avivo(dev_priv)); ++ int pitch_mask = 0; ++ ++ switch(bpp / 8) { ++ case 1: pitch_mask = align_large ? 255 : 127; break; ++ case 2: pitch_mask = align_large ? 127 : 31; break; ++ case 3: ++ case 4: pitch_mask = align_large ? 63 : 15; break; ++ } ++ ++ aligned += pitch_mask; ++ aligned &= ~pitch_mask; ++ return aligned; ++} ++ ++int radeonfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_height, ++ uint32_t surface_width, uint32_t surface_height, ++ struct radeon_framebuffer **radeon_fb_p) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct fb_info *info; ++ struct radeonfb_par *par; ++ struct drm_framebuffer *fb; ++ struct radeon_framebuffer *radeon_fb; ++ struct drm_mode_fb_cmd mode_cmd; ++ struct drm_gem_object *fbo = NULL; ++ struct drm_radeon_gem_object *obj_priv; ++ struct device *device = &dev->pdev->dev; ++ int size, aligned_size, ret; ++ ++ mode_cmd.width = surface_width;/* crtc->desired_mode->hdisplay; */ ++ mode_cmd.height = surface_height;/* crtc->desired_mode->vdisplay; */ ++ ++ mode_cmd.bpp = 32; ++ /* need to align pitch with crtc limits */ ++ mode_cmd.pitch = radeon_align_pitch(dev, mode_cmd.width, mode_cmd.bpp) * ((mode_cmd.bpp + 1) / 8); ++ mode_cmd.depth = 24; ++ ++ size = mode_cmd.pitch * mode_cmd.height; ++ aligned_size = ALIGN(size, PAGE_SIZE); ++ ++ fbo = radeon_gem_object_alloc(dev, aligned_size, 1, RADEON_GEM_DOMAIN_VRAM, 0); ++ if (!fbo) { ++ printk(KERN_ERR "failed to allocate framebuffer\n"); ++ ret = -ENOMEM; ++ goto out; ++ } ++ obj_priv = fbo->driver_private; ++ ++ ret = radeon_gem_object_pin(fbo, PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM); ++ if (ret) { ++ DRM_ERROR("failed to pin fb: %d\n", ret); ++ mutex_lock(&dev->struct_mutex); ++ goto out_unref; ++ } ++ ++ dev_priv->mm.vram_visible -= aligned_size; ++ ++ mutex_lock(&dev->struct_mutex); ++ fb = radeon_framebuffer_create(dev, &mode_cmd, fbo); ++ if (!fb) { ++ DRM_ERROR("failed to allocate fb.\n"); ++ ret = -ENOMEM; ++ goto out_unref; ++ } ++ ++ list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list); ++ ++ radeon_fb = to_radeon_framebuffer(fb); ++ *radeon_fb_p = radeon_fb; ++ ++ info = framebuffer_alloc(sizeof(struct radeonfb_par), device); ++ if (!info) { ++ ret = -ENOMEM; ++ goto out_unref; ++ } ++ ++ par = info->par; ++ ++ strcpy(info->fix.id, "radeondrmfb"); ++ info->fix.type = FB_TYPE_PACKED_PIXELS; ++ info->fix.visual = FB_VISUAL_TRUECOLOR; ++ info->fix.type_aux = 0; ++ info->fix.xpanstep = 1; /* doing it in hw */ ++ info->fix.ypanstep = 1; /* doing it in hw */ ++ info->fix.ywrapstep = 0; ++ info->fix.accel = FB_ACCEL_I830; ++ info->fix.type_aux = 0; ++ ++ info->flags = FBINFO_DEFAULT; ++ ++ info->fbops = &radeonfb_ops; ++ ++ info->fix.line_length = fb->pitch; ++ info->fix.smem_start = dev->mode_config.fb_base + obj_priv->bo->offset; ++ info->fix.smem_len = size; ++ ++ info->flags = FBINFO_DEFAULT; ++ ++ ret = drm_bo_kmap(obj_priv->bo, 0, PAGE_ALIGN(size) >> PAGE_SHIFT, ++ &radeon_fb->kmap_obj); ++ info->screen_base = radeon_fb->kmap_obj.virtual; ++ if (!info->screen_base) { ++ ret = -ENOSPC; ++ goto out_unref; ++ } ++ info->screen_size = size; ++ ++ memset(info->screen_base, 0, size); ++ ++ info->pseudo_palette = fb->pseudo_palette; ++ info->var.xres_virtual = fb->width; ++ info->var.yres_virtual = fb->height; ++ info->var.bits_per_pixel = fb->bits_per_pixel; ++ info->var.xoffset = 0; ++ info->var.yoffset = 0; ++ info->var.activate = FB_ACTIVATE_NOW; ++ info->var.height = -1; ++ info->var.width = -1; ++ ++ info->var.xres = fb_width; ++ info->var.yres = fb_height; ++ ++ info->fix.mmio_start = pci_resource_start(dev->pdev, 2); ++ info->fix.mmio_len = pci_resource_len(dev->pdev, 2); ++ ++ info->pixmap.size = 64*1024; ++ info->pixmap.buf_align = 8; ++ info->pixmap.access_align = 32; ++ info->pixmap.flags = FB_PIXMAP_SYSTEM; ++ info->pixmap.scan_align = 1; ++ ++ DRM_DEBUG("fb depth is %d\n", fb->depth); ++ DRM_DEBUG(" pitch is %d\n", fb->pitch); ++ switch(fb->depth) { ++ case 8: ++ info->var.red.offset = 0; ++ info->var.green.offset = 0; ++ info->var.blue.offset = 0; ++ info->var.red.length = 8; /* 8bit DAC */ ++ info->var.green.length = 8; ++ info->var.blue.length = 8; ++ info->var.transp.offset = 0; ++ info->var.transp.length = 0; ++ break; ++ case 15: ++ info->var.red.offset = 10; ++ info->var.green.offset = 5; ++ info->var.blue.offset = 0; ++ info->var.red.length = 5; ++ info->var.green.length = 5; ++ info->var.blue.length = 5; ++ info->var.transp.offset = 15; ++ info->var.transp.length = 1; ++ break; ++ case 16: ++ info->var.red.offset = 11; ++ info->var.green.offset = 5; ++ info->var.blue.offset = 0; ++ info->var.red.length = 5; ++ info->var.green.length = 6; ++ info->var.blue.length = 5; ++ info->var.transp.offset = 0; ++ break; ++ case 24: ++ info->var.red.offset = 16; ++ info->var.green.offset = 8; ++ info->var.blue.offset = 0; ++ info->var.red.length = 8; ++ info->var.green.length = 8; ++ info->var.blue.length = 8; ++ info->var.transp.offset = 0; ++ info->var.transp.length = 0; ++ break; ++ case 32: ++ info->var.red.offset = 16; ++ info->var.green.offset = 8; ++ info->var.blue.offset = 0; ++ info->var.red.length = 8; ++ info->var.green.length = 8; ++ info->var.blue.length = 8; ++ info->var.transp.offset = 24; ++ info->var.transp.length = 8; ++ break; ++ default: ++ break; ++ } ++ ++ fb->fbdev = info; ++ ++ par->radeon_fb = radeon_fb; ++ par->dev = dev; ++ ++ /* To allow resizeing without swapping buffers */ ++ printk("allocated %p %dx%d fb: 0x%08x, bo %p\n", dev, radeon_fb->base.width, ++ radeon_fb->base.height, obj_priv->bo->offset, fbo); ++ ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++ ++out_unref: ++ drm_gem_object_unreference(fbo); ++ mutex_unlock(&dev->struct_mutex); ++out: ++ return ret; ++} ++ ++static int radeonfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc *crtc) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct radeon_framebuffer *radeon_fb; ++ struct drm_framebuffer *fb; ++ struct drm_connector *connector; ++ struct fb_info *info; ++ struct radeonfb_par *par; ++ struct drm_mode_set *modeset; ++ unsigned int width, height; ++ int new_fb = 0; ++ int ret, i, conn_count; ++ ++ if (!drm_helper_crtc_in_use(crtc)) ++ return 0; ++ ++ if (!crtc->desired_mode) ++ return 0; ++ ++ width = crtc->desired_mode->hdisplay; ++ height = crtc->desired_mode->vdisplay; ++ ++ /* is there an fb bound to this crtc already */ ++ if (!radeon_crtc->mode_set.fb) { ++ ret = radeonfb_create(dev, width, height, width, height, &radeon_fb); ++ if (ret) ++ return -EINVAL; ++ new_fb = 1; ++ } else { ++ fb = radeon_crtc->mode_set.fb; ++ radeon_fb = to_radeon_framebuffer(fb); ++ if ((radeon_fb->base.width < width) || (radeon_fb->base.height < height)) ++ return -EINVAL; ++ } ++ ++ info = radeon_fb->base.fbdev; ++ par = info->par; ++ ++ modeset = &radeon_crtc->mode_set; ++ modeset->fb = &radeon_fb->base; ++ conn_count = 0; ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { ++ if (connector->encoder) ++ if (connector->encoder->crtc == modeset->crtc) { ++ modeset->connectors[conn_count] = connector; ++ conn_count++; ++ if (conn_count > RADEONFB_CONN_LIMIT) ++ BUG(); ++ } ++ } ++ ++ for (i = conn_count; i < RADEONFB_CONN_LIMIT; i++) ++ modeset->connectors[i] = NULL; ++ ++ par->crtc_ids[0] = crtc->base.id; ++ ++ modeset->num_connectors = conn_count; ++ if (modeset->mode != modeset->crtc->desired_mode) ++ modeset->mode = modeset->crtc->desired_mode; ++ ++ par->crtc_count = 1; ++ ++ if (new_fb) { ++ info->var.pixclock = -1; ++ if (register_framebuffer(info) < 0) ++ return -EINVAL; ++ } else ++ radeonfb_set_par(info); ++ ++ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, ++ info->fix.id); ++ ++ /* Switch back to kernel console on panic */ ++ panic_mode = *modeset; ++ atomic_notifier_chain_register(&panic_notifier_list, &paniced); ++ printk(KERN_INFO "registered panic notifier\n"); ++ ++ return 0; ++} ++ ++static int radeonfb_multi_fb_probe(struct drm_device *dev) ++{ ++ ++ struct drm_crtc *crtc; ++ int ret = 0; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ ret = radeonfb_multi_fb_probe_crtc(dev, crtc); ++ if (ret) ++ return ret; ++ } ++ return ret; ++} ++ ++static int radeonfb_single_fb_probe(struct drm_device *dev) ++{ ++ struct drm_crtc *crtc; ++ struct drm_connector *connector; ++ unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1; ++ unsigned int surface_width = 0, surface_height = 0; ++ int new_fb = 0; ++ int crtc_count = 0; ++ int ret, i, conn_count = 0; ++ struct radeon_framebuffer *radeon_fb; ++ struct fb_info *info; ++ struct radeonfb_par *par; ++ struct drm_mode_set *modeset = NULL; ++ ++ DRM_DEBUG("\n"); ++ /* first up get a count of crtcs now in use and new min/maxes width/heights */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ if (drm_helper_crtc_in_use(crtc)) { ++ if (crtc->desired_mode) { ++ if (crtc->desired_mode->hdisplay < fb_width) ++ fb_width = crtc->desired_mode->hdisplay; ++ ++ if (crtc->desired_mode->vdisplay < fb_height) ++ fb_height = crtc->desired_mode->vdisplay; ++ ++ if (crtc->desired_mode->hdisplay > surface_width) ++ surface_width = crtc->desired_mode->hdisplay; ++ ++ if (crtc->desired_mode->vdisplay > surface_height) ++ surface_height = crtc->desired_mode->vdisplay; ++ ++ } ++ crtc_count++; ++ } ++ } ++ ++ if (crtc_count == 0 || fb_width == -1 || fb_height == -1) { ++ /* hmm everyone went away - assume VGA cable just fell out ++ and will come back later. */ ++ return 0; ++ } ++ ++ /* do we have an fb already? */ ++ if (list_empty(&dev->mode_config.fb_kernel_list)) { ++ /* create an fb if we don't have one */ ++ ret = radeonfb_create(dev, fb_width, fb_height, surface_width, surface_height, &radeon_fb); ++ if (ret) ++ return -EINVAL; ++ new_fb = 1; ++ } else { ++ struct drm_framebuffer *fb; ++ fb = list_first_entry(&dev->mode_config.fb_kernel_list, struct drm_framebuffer, filp_head); ++ radeon_fb = to_radeon_framebuffer(fb); ++ ++ /* if someone hotplugs something bigger than we have already allocated, we are pwned. ++ As really we can't resize an fbdev that is in the wild currently due to fbdev ++ not really being designed for the lower layers moving stuff around under it. ++ - so in the grand style of things - punt. */ ++ if ((fb->width < surface_width) || (fb->height < surface_height)) { ++ DRM_ERROR("Framebuffer not large enough to scale console onto.\n"); ++ return -EINVAL; ++ } ++ } ++ ++ info = radeon_fb->base.fbdev; ++ par = info->par; ++ ++ crtc_count = 0; ++ /* okay we need to setup new connector sets in the crtcs */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ modeset = &radeon_crtc->mode_set; ++ modeset->fb = &radeon_fb->base; ++ conn_count = 0; ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { ++ if (connector->encoder) ++ if(connector->encoder->crtc == modeset->crtc) { ++ modeset->connectors[conn_count] = connector; ++ conn_count++; ++ if (conn_count > RADEONFB_CONN_LIMIT) ++ BUG(); ++ } ++ } ++ ++ for (i = conn_count; i < RADEONFB_CONN_LIMIT; i++) ++ modeset->connectors[i] = NULL; ++ ++ ++ par->crtc_ids[crtc_count++] = crtc->base.id; ++ ++ modeset->num_connectors = conn_count; ++ if (modeset->mode != modeset->crtc->desired_mode) ++ modeset->mode = modeset->crtc->desired_mode; ++ } ++ par->crtc_count = crtc_count; ++ ++ if (new_fb) { ++ info->var.pixclock = -1; ++ if (register_framebuffer(info) < 0) ++ return -EINVAL; ++ } else ++ radeonfb_set_par(info); ++ ++ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, ++ info->fix.id); ++ ++ /* Switch back to kernel console on panic */ ++ panic_mode = *modeset; ++ atomic_notifier_chain_register(&panic_notifier_list, &paniced); ++ printk(KERN_INFO "registered panic notifier\n"); ++ ++ return 0; ++} ++ ++int radeonfb_probe(struct drm_device *dev) ++{ ++ int ret; ++ ++ DRM_DEBUG("\n"); ++ ++ /* something has changed in the lower levels of hell - deal with it ++ here */ ++ ++ /* two modes : a) 1 fb to rule all crtcs. ++ b) one fb per crtc. ++ two actions 1) new connected device ++ 2) device removed. ++ case a/1 : if the fb surface isn't big enough - resize the surface fb. ++ if the fb size isn't big enough - resize fb into surface. ++ if everything big enough configure the new crtc/etc. ++ case a/2 : undo the configuration ++ possibly resize down the fb to fit the new configuration. ++ case b/1 : see if it is on a new crtc - setup a new fb and add it. ++ case b/2 : teardown the new fb. ++ */ ++ ++ /* mode a first */ ++ /* search for an fb */ ++ // if (radeon_fbpercrtc == 1) { ++ // ret = radeonfb_multi_fb_probe(dev); ++ // } else { ++ ret = radeonfb_single_fb_probe(dev); ++ // } ++ ++ return ret; ++} ++EXPORT_SYMBOL(radeonfb_probe); ++ ++int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct fb_info *info; ++ struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); ++ ++ if (!fb) ++ return -EINVAL; ++ ++ info = fb->fbdev; ++ ++ if (info) { ++ unregister_framebuffer(info); ++ drm_bo_kunmap(&radeon_fb->kmap_obj); ++ dev_priv->mm.vram_visible += radeon_fb->obj->size; ++ mutex_lock(&dev->struct_mutex); ++ radeon_gem_object_unpin(radeon_fb->obj); ++ drm_gem_object_unreference(radeon_fb->obj); ++ radeon_fb->obj = NULL; ++ mutex_unlock(&dev->struct_mutex); ++ framebuffer_release(info); ++ } ++ ++ atomic_notifier_chain_unregister(&panic_notifier_list, &paniced); ++ memset(&panic_mode, 0, sizeof(struct drm_mode_set)); ++ return 0; ++} ++EXPORT_SYMBOL(radeonfb_remove); ++MODULE_LICENSE("GPL"); +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_fence.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_fence.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_fence.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_fence.c 2009-04-26 03:01:09.883725564 +0200 +@@ -0,0 +1,99 @@ ++/************************************************************************** ++ * ++ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * ++ **************************************************************************/ ++/* ++ * Authors: Thomas Hellström ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class, ++ uint32_t flags, uint32_t *sequence, ++ uint32_t *native_type) ++{ ++ struct drm_radeon_private *dev_priv = (struct drm_radeon_private *) dev->dev_private; ++ ++ if (!dev_priv) ++ return -EINVAL; ++ ++ radeon_emit_irq(dev); ++ ++ DRM_DEBUG("emitting %d\n", dev_priv->counter); ++ *sequence = (uint32_t) dev_priv->counter; ++ *native_type = DRM_FENCE_TYPE_EXE; ++ ++ return 0; ++} ++ ++static void radeon_fence_poll(struct drm_device *dev, uint32_t fence_class, ++ uint32_t waiting_types) ++{ ++ struct drm_radeon_private *dev_priv = (struct drm_radeon_private *) dev->dev_private; ++ uint32_t sequence; ++ ++ sequence = RADEON_READ(RADEON_SCRATCH_REG3); ++ /* this used to be READ_BREADCRUMB(dev_priv); but it caused ++ * a race somewhere in the fencing irq ++ */ ++ ++ DRM_DEBUG("polling %d\n", sequence); ++ drm_fence_handler(dev, 0, sequence, ++ DRM_FENCE_TYPE_EXE, 0); ++} ++ ++void radeon_fence_handler(struct drm_device * dev) ++{ ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_class_manager *fc = &fm->fence_class[0]; ++ ++ write_lock(&fm->lock); ++ radeon_fence_poll(dev, 0, fc->waiting_types); ++ write_unlock(&fm->lock); ++} ++ ++int radeon_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags) ++{ ++ /* ++ * We have an irq that tells us when we have a new breadcrumb. ++ */ ++ return 1; ++} ++ ++ ++struct drm_fence_driver radeon_fence_driver = { ++ .num_classes = 1, ++ .wrap_diff = (1U << (BREADCRUMB_BITS -1)), ++ .flush_diff = (1U << (BREADCRUMB_BITS - 2)), ++ .sequence_mask = BREADCRUMB_MASK, ++ .emit = radeon_fence_emit_sequence, ++ .has_irq = radeon_fence_has_irq, ++ .poll = radeon_fence_poll, ++}; ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_fixed.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_fixed.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_fixed.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_fixed.h 2009-04-26 03:01:18.707990741 +0200 +@@ -0,0 +1,53 @@ ++/* ++ * Copyright 2009 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++#ifndef RADEON_FIXED_H ++#define RADEON_FIXED_H ++ ++typedef union rfixed { ++ u32 full; ++} fixed20_12; ++ ++ ++#define rfixed_const(A) (u32)((A<<12))// + ((B + 0.000122)*4096)) ++#define rfixed_const_half(A) (u32)((A<<12) + 2048) ++#define rfixed_const_666(A) (u32)((A<<12) + 2731) ++#define rfixed_const_8(A) (u32)((A<<12) + 3277) ++#define rfixed_mul(A,B) (u64)((u64)A.full*B.full+2048) >> 12 ++#define fixed_init(A) { .full = rfixed_const(A) } ++#define fixed_init_half(A) { .full = rfixed_const_half(A) } ++#define rfixed_trunc(A) (A.full >> 12) ++ ++static inline u32 rfixed_div(fixed20_12 A, fixed20_12 B) ++{ ++ u64 tmp = ((u64)A.full << 13); ++ ++ do_div(tmp, B.full); ++ tmp += 1; ++ tmp /= 2; ++ return (lower_32_bits(tmp)); ++} ++#endif +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_gem.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_gem.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_gem.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_gem.c 2009-04-26 03:01:28.600724478 +0200 +@@ -0,0 +1,1604 @@ ++/* ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Author: Dave Airlie ++ */ ++#include "drmP.h" ++#include "drm.h" ++ ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++static int radeon_gem_ib_init(struct drm_device *dev); ++static int radeon_gem_ib_destroy(struct drm_device *dev); ++ ++int radeon_gem_init_object(struct drm_gem_object *obj) ++{ ++ struct drm_radeon_gem_object *obj_priv; ++ ++ obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER); ++ if (!obj_priv) { ++ return -ENOMEM; ++ } ++ ++ obj->driver_private = obj_priv; ++ obj_priv->obj = obj; ++ return 0; ++} ++ ++void radeon_gem_free_object(struct drm_gem_object *obj) ++{ ++ ++ struct drm_radeon_gem_object *obj_priv = obj->driver_private; ++ ++ /* tear down the buffer object - gem holds struct mutex */ ++ drm_bo_takedown_vm_locked(obj_priv->bo); ++ drm_bo_usage_deref_locked(&obj_priv->bo); ++ drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); ++} ++ ++int radeon_gem_info_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_radeon_gem_info *args = data; ++ ++ args->vram_size = dev_priv->mm.vram_size; ++ args->vram_visible = dev_priv->mm.vram_visible; ++ args->gart_size = dev_priv->mm.gart_useable; ++ ++ return 0; ++} ++ ++struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment, ++ int initial_domain, bool discardable) ++{ ++ struct drm_gem_object *obj; ++ struct drm_radeon_gem_object *obj_priv; ++ struct drm_radeon_private *dev_priv; ++ int ret; ++ uint32_t flags; ++ uint32_t page_align; ++ uint32_t cached = 0; ++ ++ obj = drm_gem_object_alloc(dev, size); ++ if (!obj) ++ return NULL; ++ ++ obj_priv = obj->driver_private; ++ dev_priv = obj->dev->dev_private; ++ flags = DRM_BO_FLAG_MAPPABLE; ++ ++ if (!(dev_priv->flags & RADEON_IS_AGP)) ++ cached = DRM_BO_FLAG_CACHED; ++ if (initial_domain == RADEON_GEM_DOMAIN_VRAM) ++ flags |= DRM_BO_FLAG_MEM_VRAM | cached; ++ else if (initial_domain == RADEON_GEM_DOMAIN_GTT) ++ flags |= DRM_BO_FLAG_MEM_TT | cached; ++ else ++ flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; ++ ++ flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE; ++ ++ if (discardable) ++ flags |= DRM_BO_FLAG_DISCARDABLE; ++ ++ if (alignment == 0) ++ alignment = PAGE_SIZE; ++ ++ page_align = alignment >> PAGE_SHIFT; ++ /* create a TTM BO */ ++ ret = drm_buffer_object_create(dev, ++ size, drm_bo_type_device, ++ flags, 0, page_align, ++ 0, &obj_priv->bo); ++ if (ret) ++ goto fail; ++ ++ DRM_DEBUG("%p : size 0x%x, alignment %d, initial_domain %d\n", obj_priv->bo, size, alignment, initial_domain); ++ return obj; ++fail: ++ ++ return NULL; ++} ++ ++int radeon_gem_create_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_radeon_gem_create *args = data; ++ struct drm_radeon_gem_object *obj_priv; ++ struct drm_gem_object *obj; ++ int ret = 0; ++ int handle; ++ bool no_backing_store = !!(args->flags & RADEON_GEM_NO_BACKING_STORE); ++ ++ /* create a gem object to contain this object in */ ++ args->size = roundup(args->size, PAGE_SIZE); ++ ++ obj = radeon_gem_object_alloc(dev, args->size, args->alignment, args->initial_domain, no_backing_store); ++ if (!obj) ++ return -EINVAL; ++ ++ obj_priv = obj->driver_private; ++ DRM_DEBUG("obj is %p bo is %p, %ld\n", obj, obj_priv->bo, obj_priv->bo->num_pages); ++ ret = drm_gem_handle_create(file_priv, obj, &handle); ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_handle_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ ++ if (ret) ++ goto fail; ++ ++ args->handle = handle; ++ ++ return 0; ++fail: ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return ret; ++} ++ ++int radeon_gem_set_domain(struct drm_gem_object *obj, uint32_t read_domains, uint32_t write_domain, uint32_t *flags_p, bool unfenced) ++{ ++ struct drm_radeon_gem_object *obj_priv; ++ drm_radeon_private_t *dev_priv = obj->dev->dev_private; ++ uint32_t flags = 0; ++ int ret; ++ uint32_t cached = 0; ++ ++ obj_priv = obj->driver_private; ++ ++ if (!(dev_priv->flags & RADEON_IS_AGP)) ++ cached = DRM_BO_FLAG_CACHED; ++ ++ /* work out where to validate the buffer to */ ++ if (write_domain) { /* write domains always win */ ++ if (write_domain == RADEON_GEM_DOMAIN_VRAM) ++ flags = DRM_BO_FLAG_MEM_VRAM | cached; ++ else if (write_domain == RADEON_GEM_DOMAIN_GTT) ++ flags = DRM_BO_FLAG_MEM_TT | cached; // need a can write gart check ++ else ++ return -EINVAL; // we can't write to system RAM ++ } else { ++ /* okay for a read domain - prefer wherever the object is now or close enough */ ++ if (read_domains == 0) ++ return -EINVAL; ++ ++ /* if its already a local memory and CPU is valid do nothing */ ++ if (read_domains & RADEON_GEM_DOMAIN_CPU) { ++ if (obj_priv->bo->mem.mem_type == DRM_BO_MEM_LOCAL) ++ return 0; ++ if (read_domains == RADEON_GEM_DOMAIN_CPU) ++ return -EINVAL; ++ } ++ ++ /* simple case no choice in domains */ ++ if (read_domains == RADEON_GEM_DOMAIN_VRAM) ++ flags = DRM_BO_FLAG_MEM_VRAM | cached; ++ else if (read_domains == RADEON_GEM_DOMAIN_GTT) ++ flags = DRM_BO_FLAG_MEM_TT | cached; ++ else if ((obj_priv->bo->mem.mem_type == DRM_BO_MEM_VRAM) && (read_domains & RADEON_GEM_DOMAIN_VRAM)) ++ flags = DRM_BO_FLAG_MEM_VRAM | cached; ++ else if ((obj_priv->bo->mem.mem_type == DRM_BO_MEM_TT) && (read_domains & RADEON_GEM_DOMAIN_GTT)) ++ flags = DRM_BO_FLAG_MEM_TT | cached; ++ else if ((obj_priv->bo->mem.mem_type == DRM_BO_MEM_LOCAL) && (read_domains & RADEON_GEM_DOMAIN_GTT)) ++ flags = DRM_BO_FLAG_MEM_TT | cached; ++ ++ /* no idea here just set whatever we are input */ ++ if (flags == 0) { ++ if (read_domains & RADEON_GEM_DOMAIN_VRAM) ++ flags |= DRM_BO_FLAG_MEM_VRAM | cached; ++ if (read_domains & RADEON_GEM_DOMAIN_GTT) ++ flags |= DRM_BO_FLAG_MEM_TT | cached; ++ } ++ } ++ ++ /* if this BO is pinned then we ain't moving it anywhere */ ++ if (obj_priv->bo->pinned_mem_type && unfenced) ++ return 0; ++ ++ DRM_DEBUG("validating %p from %d into %x %d %d\n", obj_priv->bo, obj_priv->bo->mem.mem_type, flags, read_domains, write_domain); ++ ret = drm_bo_do_validate(obj_priv->bo, flags, DRM_BO_MASK_MEM | DRM_BO_FLAG_CACHED, ++ unfenced ? DRM_BO_HINT_DONT_FENCE : 0, 0); ++ if (ret) ++ return ret; ++ ++ flags &= ~cached; ++ if (flags_p) ++ *flags_p = flags; ++ return 0; ++ ++} ++ ++int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ /* transition the BO to a domain - just validate the BO into a certain domain */ ++ struct drm_radeon_gem_set_domain *args = data; ++ struct drm_gem_object *obj; ++ struct drm_radeon_gem_object *obj_priv; ++ int ret; ++ ++ /* for now if someone requests domain CPU - just make sure the buffer is finished with */ ++ ++ /* just do a BO wait for now */ ++ obj = drm_gem_object_lookup(dev, file_priv, args->handle); ++ if (obj == NULL) ++ return -EINVAL; ++ ++ obj_priv = obj->driver_private; ++ ++ ret = radeon_gem_set_domain(obj, args->read_domains, args->write_domain, NULL, true); ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++ ++int radeon_gem_pread_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENOSYS; ++} ++ ++int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_radeon_gem_pwrite *args = data; ++ struct drm_gem_object *obj; ++ struct drm_radeon_gem_object *obj_priv; ++ int ret; ++ ++ obj = drm_gem_object_lookup(dev, file_priv, args->handle); ++ if (obj == NULL) ++ return -EINVAL; ++ ++ obj_priv = obj->driver_private; ++ ++ /* check where the buffer is first - if not in VRAM ++ fallback to userspace copying for now */ ++ mutex_lock(&obj_priv->bo->mutex); ++ if (obj_priv->bo->mem.mem_type != DRM_BO_MEM_VRAM) { ++ ret = -EINVAL; ++ goto out_unlock; ++ } ++ ++ DRM_ERROR("pwriting data->size %lld %llx\n", args->size, args->offset); ++ ret = -EINVAL; ++ ++#if 0 ++ /* so need to grab an IB, copy the data into it in a loop ++ and send them to VRAM using HDB */ ++ while ((buf = radeon_host_data_blit(dev, cpp, w, dst_pitch_off, &buf_pitch, ++ x, &y, (unsigned int*)&h, &hpass)) != 0) { ++ radeon_host_data_blit_copy_pass(dev, cpp, buf, (uint8_t *)src, ++ hpass, buf_pitch, src_pitch); ++ src += hpass * src_pitch; ++ } ++#endif ++out_unlock: ++ mutex_unlock(&obj_priv->bo->mutex); ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++ ++int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_radeon_gem_mmap *args = data; ++ struct drm_gem_object *obj; ++ struct drm_radeon_gem_object *obj_priv; ++ loff_t offset; ++ ++ obj = drm_gem_object_lookup(dev, file_priv, args->handle); ++ if (obj == NULL) ++ return -EINVAL; ++ ++ offset = args->offset; ++ ++ obj_priv = obj->driver_private; ++ ++ if (!obj_priv->bo) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ return -EINVAL; ++ } ++ ++ args->addr_ptr = (uint64_t)obj_priv->bo->map_list.hash.key << PAGE_SHIFT; ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return 0; ++} ++ ++int radeon_gem_busy(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return 0; ++} ++ ++int radeon_gem_wait_rendering(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_radeon_gem_wait_idle *args = data; ++ struct drm_gem_object *obj; ++ struct drm_radeon_gem_object *obj_priv; ++ int ret; ++ ++ ++ obj = drm_gem_object_lookup(dev, file_priv, args->handle); ++ if (obj == NULL) ++ return -EINVAL; ++ ++ obj_priv = obj->driver_private; ++ ++ mutex_lock(&obj_priv->bo->mutex); ++ ret = drm_bo_wait(obj_priv->bo, 0, 1, 1, 0); ++ mutex_unlock(&obj_priv->bo->mutex); ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++ ++ ++ ++/* ++ * Depending on card genertation, chipset bugs, etc... the amount of vram ++ * accessible to the CPU can vary. This function is our best shot at figuring ++ * it out. Returns a value in KB. ++ */ ++static uint32_t radeon_get_accessible_vram(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t aper_size; ++ u8 byte; ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ aper_size = RADEON_READ(R600_CONFIG_APER_SIZE) / 1024; ++ else ++ aper_size = RADEON_READ(RADEON_CONFIG_APER_SIZE) / 1024; ++ ++ /* Set HDP_APER_CNTL only on cards that are known not to be broken, ++ * that is has the 2nd generation multifunction PCI interface ++ */ ++ if (dev_priv->chip_family == CHIP_RV280 || ++ dev_priv->chip_family == CHIP_RV350 || ++ dev_priv->chip_family == CHIP_RV380 || ++ dev_priv->chip_family == CHIP_R420 || ++ dev_priv->chip_family == CHIP_R423 || ++ dev_priv->chip_family == CHIP_RV410 || ++ (radeon_is_avivo(dev_priv) && ++ (dev_priv->chip_family < CHIP_R600))) { ++ uint32_t temp = RADEON_READ(RADEON_HOST_PATH_CNTL); ++ temp |= RADEON_HDP_APER_CNTL; ++ RADEON_WRITE(RADEON_HOST_PATH_CNTL, temp); ++ return aper_size * 2; ++ } ++ ++ /* Older cards have all sorts of funny issues to deal with. First ++ * check if it's a multifunction card by reading the PCI config ++ * header type... Limit those to one aperture size ++ */ ++ pci_read_config_byte(dev->pdev, 0xe, &byte); ++ if (byte & 0x80) ++ return aper_size; ++ ++ /* Single function older card. We read HDP_APER_CNTL to see how the BIOS ++ * have set it up. We don't write this as it's broken on some ASICs but ++ * we expect the BIOS to have done the right thing (might be too optimistic...) ++ */ ++ if (dev_priv->chip_family < CHIP_R600) { ++ if (RADEON_READ(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL) ++ return aper_size * 2; ++ } ++ ++ return aper_size; ++} ++ ++/* code from the DDX - do memory sizing */ ++void radeon_vram_setup(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t vram; ++ uint32_t accessible, bar_size; ++ ++ if (!radeon_is_avivo(dev_priv) && (dev_priv->flags & RADEON_IS_IGP)) { ++ uint32_t tom = RADEON_READ(RADEON_NB_TOM); ++ ++ vram = (((tom >> 16) - (tom & 0xffff) + 1) << 6); ++ RADEON_WRITE(RADEON_CONFIG_MEMSIZE, vram * 1024); ++ } else { ++ if (dev_priv->chip_family >= CHIP_R600) ++ vram = RADEON_READ(R600_CONFIG_MEMSIZE) / 1024; ++ else { ++ vram = RADEON_READ(RADEON_CONFIG_MEMSIZE) / 1024; ++ ++ /* Some production boards of m6 will return 0 if it's 8 MB */ ++ if (vram == 0) { ++ vram = 8192; ++ RADEON_WRITE(RADEON_CONFIG_MEMSIZE, 0x800000); ++ } ++ } ++ } ++ ++ accessible = radeon_get_accessible_vram(dev); ++ ++ bar_size = drm_get_resource_len(dev, 0) / 1024; ++ if (bar_size == 0) ++ bar_size = 0x20000; ++ if (accessible > bar_size) ++ accessible = bar_size; ++ ++ if (radeon_vram_limit > 0) { ++ if ((radeon_vram_limit * 1024) < vram) { ++ DRM_INFO("Forcing VRAM limit from %dK to %dK\n", ++ vram, radeon_vram_limit * 1024); ++ vram = radeon_vram_limit * 1024; ++ } ++ } ++ ++ if (accessible > vram) ++ accessible = vram; ++ ++ DRM_INFO("Detected VRAM RAM=%dK, accessible=%uK, BAR=%uK\n", ++ vram, accessible, bar_size); ++ ++ dev_priv->mm.vram_offset = dev_priv->fb_aper_offset; ++ dev_priv->mm.vram_size = vram * 1024; ++ dev_priv->mm.vram_visible = accessible * 1024; ++ ++ ++} ++ ++static int radeon_gart_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ int ret; ++ u32 base = 0; ++ ++ /* setup a 32MB GART */ ++ dev_priv->gart_size = dev_priv->mm.gart_size; ++ ++ /* work out table size from GART size - do the math for show ++ * table is one dword per 4k page. ++ */ ++ dev_priv->gart_info.table_size = (dev_priv->gart_size / 4096) * sizeof(uint32_t); ++ ++#if __OS_HAS_AGP ++ /* setup VRAM vs GART here */ ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ base = dev->agp->base; ++ if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && ++ base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { ++ DRM_INFO("Can't use agp base @0x%08lx, won't fit\n", ++ dev->agp->base); ++ base = 0; ++ } ++ } ++#endif ++ ++ if (base == 0) { ++ base = dev_priv->fb_location + dev_priv->fb_size; ++ if (base < dev_priv->fb_location || ++ ((base + dev_priv->gart_size) & 0xfffffffful) < base) ++ base = dev_priv->fb_location ++ - dev_priv->gart_size; ++ } ++ /* start on the card */ ++ dev_priv->gart_vm_start = base & 0xffc00000u; ++ if (dev_priv->gart_vm_start != base) ++ DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", ++ base, dev_priv->gart_vm_start); ++ ++ /* if on PCIE we need to allocate an fb object for the PCIE GART table */ ++ if (dev_priv->flags & RADEON_IS_PCIE) { ++ ret = drm_buffer_object_create(dev, dev_priv->gart_info.table_size, ++ drm_bo_type_kernel, ++ DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_NO_EVICT, ++ 0, 1, 0, &dev_priv->mm.pcie_table.bo); ++ if (ret) ++ return -EINVAL; ++ ++ /* subtract from VRAM value reporting to userspace */ ++ dev_priv->mm.vram_visible -= dev_priv->gart_info.table_size; ++ ++ dev_priv->mm.pcie_table_backup = kzalloc(dev_priv->gart_info.table_size, GFP_KERNEL); ++ if (!dev_priv->mm.pcie_table_backup) ++ return -EINVAL; ++ ++ ret = drm_bo_kmap(dev_priv->mm.pcie_table.bo, 0, dev_priv->gart_info.table_size >> PAGE_SHIFT, ++ &dev_priv->mm.pcie_table.kmap); ++ if (ret) ++ return -EINVAL; ++ ++ dev_priv->pcigart_offset_set = 2; ++ dev_priv->gart_info.bus_addr = dev_priv->fb_location + dev_priv->mm.pcie_table.bo->offset; ++ dev_priv->gart_info.addr = dev_priv->mm.pcie_table.kmap.virtual; ++ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; ++ dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; ++ memset(dev_priv->gart_info.addr, 0, dev_priv->gart_info.table_size); ++ } else if (!(dev_priv->flags & RADEON_IS_AGP)) { ++ /* allocate PCI GART table */ ++ dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); ++ dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; ++ if (dev_priv->flags & RADEON_IS_IGPGART) ++ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; ++ else ++ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; ++ ++ ret = drm_ati_alloc_pcigart_table(dev, &dev_priv->gart_info); ++ if (ret) { ++ DRM_ERROR("cannot allocate PCI GART page!\n"); ++ return -EINVAL; ++ } ++ ++ dev_priv->gart_info.addr = dev_priv->gart_info.table_handle->vaddr; ++ dev_priv->gart_info.bus_addr = dev_priv->gart_info.table_handle->busaddr; ++ } ++ ++ /* gart values setup - start the GART */ ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ radeon_set_pcigart(dev_priv, 0); ++ /* enable AGP GART bits */ ++ ++ DRM_INFO("setting agp_base to %lx\n", dev->agp->base); ++ radeon_write_agp_base(dev_priv, dev->agp->base); ++ ++ DRM_INFO("setting agp_location to %x\n", dev_priv->gart_vm_start); ++ radeon_write_agp_location(dev_priv, ++ (((dev_priv->gart_vm_start - 1 + ++ dev_priv->gart_size) & 0xffff0000) | ++ (dev_priv->gart_vm_start >> 16)), 0); ++ ++ } else { ++ radeon_set_pcigart(dev_priv, 1); ++ } ++ ++ return 0; ++} ++ ++int radeon_alloc_gart_objects(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ int ret; ++ int cached = 0; ++ ++ if (!(dev_priv->flags & RADEON_IS_AGP)) ++ cached = DRM_BO_FLAG_CACHED; ++ ++ ret = drm_buffer_object_create(dev, RADEON_DEFAULT_RING_SIZE, ++ drm_bo_type_kernel, ++ DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT | ++ DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_NO_EVICT | cached, ++ 0, 1, 0, &dev_priv->mm.ring.bo); ++ if (ret) { ++ if (dev_priv->flags & RADEON_IS_AGP) ++ DRM_ERROR("failed to allocate ring - most likely an AGP driver bug\n"); ++ else ++ DRM_ERROR("failed to allocate ring\n"); ++ return -EINVAL; ++ } ++ ++ ret = drm_bo_kmap(dev_priv->mm.ring.bo, 0, RADEON_DEFAULT_RING_SIZE >> PAGE_SHIFT, ++ &dev_priv->mm.ring.kmap); ++ if (ret) { ++ DRM_ERROR("failed to map ring\n"); ++ return -EINVAL; ++ } ++ ++ ret = drm_buffer_object_create(dev, PAGE_SIZE, ++ drm_bo_type_kernel, ++ DRM_BO_FLAG_WRITE |DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT | ++ DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_NO_EVICT | cached, ++ 0, 1, 0, &dev_priv->mm.ring_read.bo); ++ if (ret) { ++ DRM_ERROR("failed to allocate ring read\n"); ++ return -EINVAL; ++ } ++ ++ ret = drm_bo_kmap(dev_priv->mm.ring_read.bo, 0, ++ PAGE_SIZE >> PAGE_SHIFT, ++ &dev_priv->mm.ring_read.kmap); ++ if (ret) { ++ DRM_ERROR("failed to map ring read\n"); ++ return -EINVAL; ++ } ++ ++ DRM_DEBUG("Ring ptr %p mapped at %ld %p, read ptr %p maped at %ld %p\n", ++ dev_priv->mm.ring.bo, dev_priv->mm.ring.bo->offset, dev_priv->mm.ring.kmap.virtual, ++ dev_priv->mm.ring_read.bo, dev_priv->mm.ring_read.bo->offset, dev_priv->mm.ring_read.kmap.virtual); ++ ++ dev_priv->mm.gart_useable -= RADEON_DEFAULT_RING_SIZE + PAGE_SIZE; ++ ++ /* init the indirect buffers */ ++ radeon_gem_ib_init(dev); ++ return 0; ++ ++} ++ ++static bool avivo_get_mc_idle(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ if (dev_priv->chip_family >= CHIP_R600) { ++ if (RADEON_READ(R600_SRBM_STATUS) & 0x3f00) ++ return false; ++ else ++ return true; ++ } else if (dev_priv->chip_family == CHIP_RV515) { ++ if (RADEON_READ_MCIND(dev_priv, RV515_MC_STATUS) & RV515_MC_STATUS_IDLE) ++ return true; ++ else ++ return false; ++ } else if (dev_priv->chip_family == CHIP_RS600) { ++ if (RADEON_READ_MCIND(dev_priv, RS600_MC_STATUS) & RS600_MC_IDLE) ++ return true; ++ else ++ return false; ++ } else if ((dev_priv->chip_family == CHIP_RS690) || ++ (dev_priv->chip_family == CHIP_RS740)) { ++ if (RADEON_READ_MCIND(dev_priv, RS690_MC_STATUS) & RS690_MC_STATUS_IDLE) ++ return true; ++ else ++ return false; ++ } else { ++ if (RADEON_READ_MCIND(dev_priv, R520_MC_STATUS) & R520_MC_STATUS_IDLE) ++ return true; ++ else ++ return false; ++ } ++} ++ ++ ++static void avivo_disable_mc_clients(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ int timeout; ++ ++ radeon_do_wait_for_idle(dev_priv); ++ ++ RADEON_WRITE(AVIVO_D1VGA_CONTROL, RADEON_READ(AVIVO_D1VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE); ++ RADEON_WRITE(AVIVO_D2VGA_CONTROL, RADEON_READ(AVIVO_D2VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE); ++ ++ tmp = RADEON_READ(AVIVO_D1CRTC_CONTROL); ++ RADEON_WRITE(AVIVO_D1CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN); ++ ++ tmp = RADEON_READ(AVIVO_D2CRTC_CONTROL); ++ RADEON_WRITE(AVIVO_D2CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN); ++ ++ tmp = RADEON_READ(AVIVO_D2CRTC_CONTROL); ++ ++ udelay(1000); ++ ++ timeout = 0; ++ while (!(avivo_get_mc_idle(dev))) { ++ if (++timeout > 100000) { ++ DRM_ERROR("Timeout waiting for memory controller to update settings\n"); ++ DRM_ERROR("Bad things may or may not happen\n"); ++ } ++ udelay(10); ++ } ++} ++ ++static inline u32 radeon_busy_wait(struct drm_device *dev, uint32_t reg, uint32_t bits, ++ unsigned int timeout) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ u32 status; ++ ++ do { ++ udelay(10); ++ status = RADEON_READ(reg); ++ timeout--; ++ } while(status != 0xffffffff && (status & bits) && (timeout > 0)); ++ ++ if (timeout == 0) ++ status = 0xffffffff; ++ ++ return status; ++} ++ ++/* Wait for vertical sync on primary CRTC */ ++static void radeon_wait_for_vsync(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t crtc_gen_cntl; ++ ++ crtc_gen_cntl = RADEON_READ(RADEON_CRTC_GEN_CNTL); ++ if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) || ++ !(crtc_gen_cntl & RADEON_CRTC_EN)) ++ return; ++ ++ /* Clear the CRTC_VBLANK_SAVE bit */ ++ RADEON_WRITE(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR); ++ ++ radeon_busy_wait(dev, RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE, 2000); ++ ++} ++ ++/* Wait for vertical sync on primary CRTC */ ++static void radeon_wait_for_vsync2(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t crtc2_gen_cntl; ++ ++ crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL); ++ if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) || ++ !(crtc2_gen_cntl & RADEON_CRTC2_EN)) ++ return; ++ ++ /* Clear the CRTC_VBLANK_SAVE bit */ ++ RADEON_WRITE(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR); ++ ++ radeon_busy_wait(dev, RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE, 2000); ++} ++ ++static void legacy_disable_mc_clients(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t old_mc_status, status_idle; ++ uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl; ++ uint32_t status; ++ ++ radeon_do_wait_for_idle(dev_priv); ++ ++ if (dev_priv->flags & RADEON_IS_IGP) ++ return; ++ ++ old_mc_status = RADEON_READ(RADEON_MC_STATUS); ++ ++ /* stop display and memory access */ ++ ov0_scale_cntl = RADEON_READ(RADEON_OV0_SCALE_CNTL); ++ RADEON_WRITE(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE); ++ crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL); ++ RADEON_WRITE(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS); ++ crtc_gen_cntl = RADEON_READ(RADEON_CRTC_GEN_CNTL); ++ ++ radeon_wait_for_vsync(dev); ++ ++ RADEON_WRITE(RADEON_CRTC_GEN_CNTL, ++ (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) | ++ RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN); ++ ++ if (!(dev_priv->flags & RADEON_SINGLE_CRTC)) { ++ crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL); ++ ++ radeon_wait_for_vsync2(dev); ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, ++ (crtc2_gen_cntl & ++ ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) | ++ RADEON_CRTC2_DISP_REQ_EN_B); ++ } ++ ++ udelay(500); ++ ++ if (radeon_is_r300(dev_priv)) ++ status_idle = R300_MC_IDLE; ++ else ++ status_idle = RADEON_MC_IDLE; ++ ++ status = radeon_busy_wait(dev, RADEON_MC_STATUS, status_idle, 200000); ++ if (status == 0xffffffff) { ++ DRM_ERROR("Timeout waiting for memory controller to update settings\n"); ++ DRM_ERROR("Bad things may or may not happen\n"); ++ } ++} ++ ++ ++void radeon_init_memory_map(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ u32 mem_size, aper_size; ++ ++ dev_priv->mc_fb_location = radeon_read_fb_location(dev_priv); ++ radeon_read_agp_location(dev_priv, &dev_priv->mc_agp_loc_lo, &dev_priv->mc_agp_loc_hi); ++ ++ if (dev_priv->chip_family >= CHIP_R600) { ++ mem_size = RADEON_READ(R600_CONFIG_MEMSIZE); ++ aper_size = RADEON_READ(R600_CONFIG_APER_SIZE); ++ } else { ++ mem_size = RADEON_READ(RADEON_CONFIG_MEMSIZE); ++ aper_size = RADEON_READ(RADEON_CONFIG_APER_SIZE); ++ } ++ ++ /* M6s report illegal memory size */ ++ if (mem_size == 0) ++ mem_size = 8 * 1024 * 1024; ++ ++ /* for RN50/M6/M7 - Novell bug 204882 */ ++ if (aper_size > mem_size) ++ mem_size = aper_size; ++ ++ if ((dev_priv->chip_family != CHIP_RS600) && ++ (dev_priv->chip_family != CHIP_RS690) && ++ (dev_priv->chip_family != CHIP_RS740) && ++ (dev_priv->chip_family != CHIP_RS780)) { ++ if (dev_priv->flags & RADEON_IS_IGP) ++ dev_priv->mc_fb_location = RADEON_READ(RADEON_NB_TOM); ++ else { ++ uint64_t aper0_base; ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ aper0_base = RADEON_READ(R600_CONFIG_F0_BASE); ++ else ++ aper0_base = RADEON_READ(RADEON_CONFIG_APER_0_BASE); ++ ++ ++ /* Some chips have an "issue" with the memory controller, the ++ * location must be aligned to the size. We just align it down, ++ * too bad if we walk over the top of system memory, we don't ++ * use DMA without a remapped anyway. ++ * Affected chips are rv280, all r3xx, and all r4xx, but not IGP ++ */ ++ if (dev_priv->chip_family == CHIP_RV280 || ++ dev_priv->chip_family == CHIP_R300 || ++ dev_priv->chip_family == CHIP_R350 || ++ dev_priv->chip_family == CHIP_RV350 || ++ dev_priv->chip_family == CHIP_RV380 || ++ dev_priv->chip_family == CHIP_R420 || ++ dev_priv->chip_family == CHIP_R423 || ++ dev_priv->chip_family == CHIP_RV410) ++ aper0_base &= ~(mem_size - 1); ++ ++ if (dev_priv->chip_family >= CHIP_R600) { ++ uint64_t mc_fb = ((aper0_base >> 24) & 0xffff) | ++ (((aper0_base + mem_size - 1) >> 8) & 0xffff0000); ++ dev_priv->mc_fb_location = mc_fb & 0xffffffff; ++ } else { ++ uint64_t mc_fb = ((aper0_base >> 16) & 0xffff) | ++ ((aper0_base + mem_size - 1) & 0xffff0000U); ++ dev_priv->mc_fb_location = mc_fb & 0xffffffff; ++ } ++ } ++ } ++ ++ if (dev_priv->chip_family >= CHIP_R600) ++ dev_priv->fb_location = (dev_priv->mc_fb_location & 0xffff) << 24; ++ else ++ dev_priv->fb_location = (dev_priv->mc_fb_location & 0xffff) << 16; ++ ++ /* updating mc regs here */ ++ if (radeon_is_avivo(dev_priv)) ++ avivo_disable_mc_clients(dev); ++ else ++ legacy_disable_mc_clients(dev); ++ ++ radeon_write_fb_location(dev_priv, dev_priv->mc_fb_location); ++ ++ if (radeon_is_avivo(dev_priv)) { ++ if (dev_priv->chip_family >= CHIP_R600) ++ RADEON_WRITE(R600_HDP_NONSURFACE_BASE, (dev_priv->mc_fb_location << 16) & 0xff0000); ++ else ++ RADEON_WRITE(AVIVO_HDP_FB_LOCATION, dev_priv->mc_fb_location); ++ } ++ ++ if (dev_priv->chip_family >= CHIP_R600) { ++ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffffff) << 24; ++ dev_priv->fb_size = ((radeon_read_fb_location(dev_priv) & 0xff000000u) + 0x1000000) ++ - dev_priv->fb_location; ++ } else { ++ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; ++ dev_priv->fb_size = ++ ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) ++ - dev_priv->fb_location; ++ } ++ ++ /* add an MTRR for the VRAM */ ++ dev_priv->aper_size = aper_size; ++ dev_priv->vram_mtrr = mtrr_add(dev_priv->fb_aper_offset, dev_priv->aper_size, MTRR_TYPE_WRCOMB, 1); ++ ++} ++ ++#if __OS_HAS_AGP ++ ++struct radeon_agpmode_quirk { ++ u32 hostbridge_vendor; ++ u32 hostbridge_device; ++ u32 chip_vendor; ++ u32 chip_device; ++ u32 subsys_vendor; ++ u32 subsys_device; ++ u32 default_mode; ++}; ++ ++static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { ++ /* Intel E7505 Memory Controller Hub / RV350 AR [Radeon 9600XT] Needs AGPMode 4 (deb #515326) */ ++ { PCI_VENDOR_ID_INTEL,0x2550, PCI_VENDOR_ID_ATI, 0x4152, ++ 0x1458,0x4038, 4}, ++ /* Intel 82865G/PE/P DRAM Controller/Host-Hub / Mobility 9800 Needs AGPMode 4 (deb #462590) */ ++ { PCI_VENDOR_ID_INTEL, 0x2570, PCI_VENDOR_ID_ATI, 0x4a4e, ++ PCI_VENDOR_ID_DELL, 0x5106, 4}, ++ /* Intel 82865G/PE/P DRAM Controller/Host-Hub / RV280 [Radeon 9200 SE] Needs AGPMode 4 (lp #300304) */ ++ { PCI_VENDOR_ID_INTEL, 0x2570, PCI_VENDOR_ID_ATI, 0x5964, ++ 0x148c, 0x2073, 4}, ++ /* Intel 82855PM Processor to I/O Controller / Mobility M6 LY Needs AGPMode 1 (deb #467235) */ ++ { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c59, ++ PCI_VENDOR_ID_IBM, 0x052f, 1}, ++ /* Intel 82855PM host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #195051) */ ++ { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4e50, ++ PCI_VENDOR_ID_IBM, 0x0550, 1}, ++ /* Intel 82855PM host bridge / Mobility M7 needs AGPMode 1 */ ++ { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c57, ++ PCI_VENDOR_ID_IBM, 0x0530, 1}, ++ /* Intel 82855PM host bridge / FireGL Mobility T2 RV350 Needs AGPMode 2 (fdo #20647) */ ++ { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4e54, ++ PCI_VENDOR_ID_IBM, 0x054f, 2}, ++ /* Intel 82855PM host bridge / Mobility M9+ / VaioPCG-V505DX Needs AGPMode 2 (fdo #17928) */ ++ { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x5c61, ++ PCI_VENDOR_ID_SONY, 0x816b, 2}, ++ /* Intel 82855PM Processor to I/O Controller / Mobility M9+ Needs AGPMode 8 (phoronix forum) */ ++ { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x5c61, ++ PCI_VENDOR_ID_SONY, 0x8195, 8}, ++ /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ ++ { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, ++ PCI_VENDOR_ID_DELL, 0x00e3, 2}, ++ /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ ++ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, ++ PCI_VENDOR_ID_DELL, 0x0149, 1}, ++ /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ ++ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, ++ 0x1025, 0x0061, 1}, ++ /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #203007) */ ++ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, ++ 0x1025, 0x0064, 1}, ++ /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #141551) */ ++ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, ++ PCI_VENDOR_ID_ASUSTEK, 0x1942, 1}, ++ /* Intel 82852/82855 host bridge / Mobility 9600/9700 Needs AGPMode 1 (deb #510208) */ ++ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, ++ 0x10cf, 0x127f, 1}, ++ /* ASRock K7VT4A+ AGP 8x / ATI Radeon 9250 AGP Needs AGPMode 4 (lp #133192) */ ++ { 0x1849, 0x3189, PCI_VENDOR_ID_ATI, 0x5960, ++ 0x1787, 0x5960, 4}, ++ /* VIA K8M800 Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 4 (fdo #12544) */ ++ { PCI_VENDOR_ID_VIA, 0x0204, PCI_VENDOR_ID_ATI, 0x5960, ++ 0x17af, 0x2020, 4}, ++ /* VIA KT880 Host Bridge / RV350 [Radeon 9550] Needs AGPMode 4 (fdo #19981) */ ++ { PCI_VENDOR_ID_VIA, 0x0269, PCI_VENDOR_ID_ATI, 0x4153, ++ PCI_VENDOR_ID_ASUSTEK, 0x003c, 4}, ++ /* VIA VT8363 Host Bridge / R200 QL [Radeon 8500] Needs AGPMode 2 (lp #141551) */ ++ { PCI_VENDOR_ID_VIA, 0x0305, PCI_VENDOR_ID_ATI, 0x514c, ++ PCI_VENDOR_ID_ATI, 0x013a, 2}, ++ /* VIA VT82C693A Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 2 (deb #515512) */ ++ { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_ATI, 0x5960, ++ PCI_VENDOR_ID_ASUSTEK, 0x004c, 2}, ++ /* VIA VT82C693A Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 2 */ ++ { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_ATI, 0x5960, ++ PCI_VENDOR_ID_ASUSTEK, 0x0054, 2}, ++ /* VIA VT8377 Host Bridge / R200 QM [Radeon 9100] Needs AGPMode 4 (deb #461144) */ ++ { PCI_VENDOR_ID_VIA, 0x3189, PCI_VENDOR_ID_ATI, 0x514d, ++ 0x174b, 0x7149, 4}, ++ /* VIA VT8377 Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 4 (lp #312693) */ ++ { PCI_VENDOR_ID_VIA, 0x3189, PCI_VENDOR_ID_ATI, 0x5960, ++ 0x1462, 0x0380, 4}, ++ /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (ati ML) */ ++ { PCI_VENDOR_ID_VIA, 0x3189, PCI_VENDOR_ID_ATI, 0x5964, ++ 0x148c, 0x2073, 4}, ++ /* ATI Host Bridge / RV280 [M9+] Needs AGPMode 1 (phoronix forum) */ ++ { PCI_VENDOR_ID_ATI, 0xcbb2, PCI_VENDOR_ID_ATI, 0x5c61, ++ PCI_VENDOR_ID_SONY, 0x8175, 1}, ++ /* HP Host Bridge / R300 [FireGL X1] Needs AGPMode 2 (fdo #7770) */ ++ { PCI_VENDOR_ID_HP, 0x122e, PCI_VENDOR_ID_ATI, 0x4e47, ++ PCI_VENDOR_ID_ATI, 0x0152, 2}, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++}; ++ ++int radeon_modeset_agp_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct drm_agp_mode mode; ++ struct drm_agp_info info; ++ int ret; ++ int default_mode; ++ uint32_t agp_status; ++ bool is_v3; ++ struct radeon_agpmode_quirk *p = radeon_agpmode_quirk_list; ++ ++ /* Acquire AGP. */ ++ ret = drm_agp_acquire(dev); ++ if (ret) { ++ DRM_ERROR("Unable to acquire AGP: %d\n", ret); ++ return ret; ++ } ++ ++ ret = drm_agp_info(dev, &info); ++ if (ret) { ++ DRM_ERROR("Unable to get AGP info: %d\n", ret); ++ return ret; ++ } ++ ++ mode.mode = info.mode; ++ ++ agp_status = (RADEON_READ(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; ++ is_v3 = !!(agp_status & RADEON_AGPv3_MODE); ++ ++ if (is_v3) { ++ default_mode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4; ++ } else { ++ if (agp_status & RADEON_AGP_4X_MODE) default_mode = 4; ++ else if (agp_status & RADEON_AGP_2X_MODE) default_mode = 2; ++ else default_mode = 1; ++ } ++ ++ /* Apply AGPMode Quirks */ ++ while (p && p->chip_device != 0) { ++ if (info.id_vendor == p->hostbridge_vendor && ++ info.id_device == p->hostbridge_device && ++ dev->pdev->vendor == p->chip_vendor && ++ dev->pdev->device == p->chip_device && ++ dev->pdev->subsystem_vendor == p->subsys_vendor && ++ dev->pdev->subsystem_device == p->subsys_device) ++ { ++ default_mode = p->default_mode; ++ } ++ ++p; ++ } ++ ++ if (radeon_agpmode > 0) { ++ if ((radeon_agpmode < (is_v3 ? 4 : 1)) || ++ (radeon_agpmode > (is_v3 ? 8 : 4)) || ++ (radeon_agpmode & (radeon_agpmode - 1))) { ++ DRM_ERROR("Illegal AGP Mode: %d (valid %s), leaving at %d\n", ++ radeon_agpmode, is_v3 ? "4, 8" : "1, 2, 4", ++ default_mode); ++ radeon_agpmode = default_mode; ++ } ++ else ++ DRM_INFO("AGP mode requested: %d\n", radeon_agpmode); ++ } else ++ radeon_agpmode = default_mode; ++ ++ mode.mode &= ~RADEON_AGP_MODE_MASK; ++ if (is_v3) { ++ switch(radeon_agpmode) { ++ case 8: ++ mode.mode |= RADEON_AGPv3_8X_MODE; ++ break; ++ case 4: ++ default: ++ mode.mode |= RADEON_AGPv3_4X_MODE; ++ break; ++ } ++ } else { ++ switch(radeon_agpmode) { ++ case 4: mode.mode |= RADEON_AGP_4X_MODE; ++ case 2: mode.mode |= RADEON_AGP_2X_MODE; ++ case 1: ++ default: ++ mode.mode |= RADEON_AGP_1X_MODE; ++ break; ++ } ++ } ++ ++ mode.mode &= ~RADEON_AGP_FW_MODE; /* disable fw */ ++ ++ ret = drm_agp_enable(dev, mode); ++ if (ret) { ++ DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); ++ return ret; ++ } ++ ++ /* workaround some hw issues */ ++ if (dev_priv->chip_family < CHIP_R200) { ++ RADEON_WRITE(RADEON_AGP_CNTL, RADEON_READ(RADEON_AGP_CNTL) | 0x000e0000); ++ } ++ return 0; ++} ++ ++void radeon_modeset_agp_destroy(struct drm_device *dev) ++{ ++ if (dev->agp->acquired) ++ drm_agp_release(dev); ++} ++#endif ++ ++/* init memory manager - start with all of VRAM and a 32MB GART aperture for now */ ++int radeon_gem_mm_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ int ret; ++ u32 pg_offset; ++ ++ /* init TTM underneath */ ++ drm_bo_driver_init(dev); ++ ++ /* size the mappable VRAM memory for now */ ++ radeon_vram_setup(dev); ++ ++ radeon_init_memory_map(dev); ++ ++#define VRAM_RESERVE_TEXT (256*1024) /* need to reserve 256 for text mode for now */ ++ dev_priv->mm.vram_visible -= VRAM_RESERVE_TEXT; ++ pg_offset = VRAM_RESERVE_TEXT >> PAGE_SHIFT; ++ drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, pg_offset, /*dev_priv->mm.vram_offset >> PAGE_SHIFT,*/ ++ ((dev_priv->mm.vram_visible) >> PAGE_SHIFT) - 16, ++ 0); ++ ++ /* need AGP to work out sizes */ ++#if __OS_HAS_AGP ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ radeon_modeset_agp_init(dev); ++ ++ if (dev->agp->agp_info.aper_size < radeon_gart_size) ++ radeon_gart_size = dev->agp->agp_info.aper_size; ++ } ++#endif ++ ++ if (dev_priv->chip_family > CHIP_R600) { ++ dev_priv->mm_enabled = true; ++ return 0; ++ } ++ ++ dev_priv->mm.gart_size = (radeon_gart_size * 1024 * 1024); ++ dev_priv->mm.gart_start = 0; ++ dev_priv->mm.gart_useable = dev_priv->mm.gart_size; ++ ret = radeon_gart_init(dev); ++ if (ret) ++ return -EINVAL; ++ ++ drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0, ++ dev_priv->mm.gart_size >> PAGE_SHIFT, ++ 0); ++ ++ /* need to allocate some objects in the GART */ ++ /* ring + ring read ptr */ ++ ret = radeon_alloc_gart_objects(dev); ++ if (ret) { ++ radeon_gem_mm_fini(dev); ++ return -EINVAL; ++ } ++ ++ dev_priv->mm_enabled = true; ++ return 0; ++} ++ ++void radeon_gem_mm_fini(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ radeon_gem_ib_destroy(dev); ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ if (dev_priv->mm.ring_read.bo) { ++ drm_bo_kunmap(&dev_priv->mm.ring_read.kmap); ++ drm_bo_usage_deref_locked(&dev_priv->mm.ring_read.bo); ++ } ++ ++ if (dev_priv->mm.ring.bo) { ++ drm_bo_kunmap(&dev_priv->mm.ring.kmap); ++ drm_bo_usage_deref_locked(&dev_priv->mm.ring.bo); ++ } ++ ++ if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1)) { ++ DRM_DEBUG("delaying takedown of TTM memory\n"); ++ } ++ ++ if (dev_priv->flags & RADEON_IS_PCIE) { ++ if (dev_priv->mm.pcie_table_backup) { ++ kfree(dev_priv->mm.pcie_table_backup); ++ dev_priv->mm.pcie_table_backup = NULL; ++ } ++ if (dev_priv->mm.pcie_table.bo) { ++ drm_bo_kunmap(&dev_priv->mm.pcie_table.kmap); ++ drm_bo_usage_deref_locked(&dev_priv->mm.pcie_table.bo); ++ } ++ } ++ ++#if __OS_HAS_AGP ++ if (dev_priv->flags & RADEON_IS_AGP) ++ radeon_modeset_agp_destroy(dev); ++#endif ++ ++ if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) { ++ DRM_DEBUG("delaying takedown of VRAM memory\n"); ++ } ++ ++ if (dev_priv->vram_mtrr) ++ mtrr_del(dev_priv->vram_mtrr, dev_priv->fb_aper_offset, dev_priv->aper_size); ++ mutex_unlock(&dev->struct_mutex); ++ ++ drm_bo_driver_finish(dev); ++ dev_priv->mm_enabled = false; ++} ++ ++int radeon_gem_object_pin(struct drm_gem_object *obj, ++ uint32_t alignment, uint32_t pin_domain) ++{ ++ struct drm_radeon_gem_object *obj_priv; ++ int ret; ++ uint32_t flags = DRM_BO_FLAG_NO_EVICT; ++ uint32_t mask = DRM_BO_FLAG_NO_EVICT; ++ ++ obj_priv = obj->driver_private; ++ ++ obj_priv->pin_count++; ++ if (obj_priv->pin_count != 1) ++ return 0; ++ ++ if (pin_domain) { ++ mask |= DRM_BO_MASK_MEM; ++ if (pin_domain == RADEON_GEM_DOMAIN_GTT) ++ flags |= DRM_BO_FLAG_MEM_TT; ++ else if (pin_domain == RADEON_GEM_DOMAIN_VRAM) ++ flags |= DRM_BO_FLAG_MEM_VRAM; ++ else ++ return -EINVAL; ++ } ++ ret = drm_bo_do_validate(obj_priv->bo, flags, mask, ++ DRM_BO_HINT_DONT_FENCE, 0); ++ ++ return ret; ++} ++ ++int radeon_gem_object_unpin(struct drm_gem_object *obj) ++{ ++ struct drm_radeon_gem_object *obj_priv; ++ int ret; ++ ++ obj_priv = obj->driver_private; ++ ++ obj_priv->pin_count--; ++ if (obj_priv->pin_count != 0) ++ return 0; ++ ++ ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT, ++ DRM_BO_HINT_DONT_FENCE, 0); ++ ++ return ret; ++} ++ ++/* check the free list - if nothing update the free list without waiting ++ * if still nothing block until we get something */ ++int radeon_gem_ib_get(struct drm_radeon_cs_parser *parser) ++{ ++ int i, index = -1; ++ int ret; ++ int no_wait = 1; ++ drm_radeon_private_t *dev_priv = parser->dev->dev_private; ++ int pass = 0; ++ ++restart_find: ++ if (pass == 1) ++ no_wait = 0; ++ ++ for (i = 0; i < RADEON_NUM_IB; i++) { ++ if (!(dev_priv->ib_alloc_bitmap & (1 << i))){ ++ index = i; ++ break; ++ } ++ } ++ ++ if (index == -1) { ++ /* if all in use do a first pass over them - non waiting */ ++ for (i = 0; i < RADEON_NUM_IB; i++) { ++ if (dev_priv->ib_alloc_bitmap & (1 << i)) { ++ mutex_lock(&dev_priv->ib_objs[i]->bo->mutex); ++ ret = drm_bo_wait(dev_priv->ib_objs[i]->bo, 0, 1, no_wait, 0); ++ mutex_unlock(&dev_priv->ib_objs[i]->bo->mutex); ++ if (ret == -EAGAIN) ++ goto restart_find; ++ if (ret) ++ continue; ++ dev_priv->ib_alloc_bitmap &= ~(1 << i); ++ if (pass == 1) { ++ index = i; ++ break; ++ } ++ } ++ } ++ pass++; ++ if (pass < 2) ++ goto restart_find; ++ } ++ ++ if (index == -1) { ++ DRM_ERROR("Major case fail to allocate IB from freelist %llx\n", dev_priv->ib_alloc_bitmap); ++ return -EINVAL; ++ } ++ ++ if (parser->chunks[parser->ib_index].length_dw > RADEON_IB_SIZE / sizeof(uint32_t)) ++ return -EINVAL; ++ ++ ret = drm_bo_do_validate(dev_priv->ib_objs[index]->bo, 0, ++ DRM_BO_FLAG_NO_EVICT, ++ 0, 0); ++ if (ret) { ++ DRM_ERROR("Failed to validate IB %d\n", index); ++ return -EINVAL; ++ } ++ ++ parser->ib = dev_priv->ib_objs[index]->kmap.virtual; ++ parser->card_offset = dev_priv->gart_vm_start + dev_priv->ib_objs[index]->bo->offset; ++ dev_priv->ib_alloc_bitmap |= (1 << index); ++ return 0; ++} ++ ++static void radeon_gem_ib_free(struct drm_radeon_cs_parser *parser, int error) ++{ ++ struct drm_device *dev = parser->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct drm_fence_object *fence; ++ int ret; ++ int i; ++ ++ for (i = 0; i < RADEON_NUM_IB; i++) { ++ if (dev_priv->ib_objs[i]->kmap.virtual == parser->ib) { ++ ++ if (error) { ++ drm_putback_buffer_objects(dev); ++ dev_priv->ib_alloc_bitmap &= ~(1 << i); ++ parser->ib = NULL; ++ parser->card_offset = 0; ++ break; ++ } else { ++ /* emit a fence object */ ++ ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence); ++ dev_priv->irq_emitted = 0; ++ if (ret) { ++ drm_putback_buffer_objects(dev); ++ } ++ /* dereference the fence object */ ++ if (fence) ++ drm_fence_usage_deref_unlocked(&fence); ++ break; ++ } ++ } ++ } ++} ++ ++static int radeon_gem_ib_destroy(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ int i; ++ ++ if (dev_priv->ib_objs) { ++ for (i = 0; i < RADEON_NUM_IB; i++) { ++ if (dev_priv->ib_objs[i]) { ++ drm_bo_kunmap(&dev_priv->ib_objs[i]->kmap); ++ drm_bo_usage_deref_unlocked(&dev_priv->ib_objs[i]->bo); ++ } ++ drm_free(dev_priv->ib_objs[i], sizeof(struct radeon_mm_obj), DRM_MEM_DRIVER); ++ } ++ drm_free(dev_priv->ib_objs, RADEON_NUM_IB*sizeof(struct radeon_mm_obj *), DRM_MEM_DRIVER); ++ } ++ dev_priv->ib_objs = NULL; ++ return 0; ++} ++ ++static int radeon_gem_find_reloc(struct drm_radeon_cs_parser *parser, ++ uint32_t offset, uint32_t *handle, ++ uint32_t *retval) ++{ ++ struct drm_radeon_kernel_chunk *reloc_chunk = &parser->chunks[parser->reloc_index]; ++ ++ if (!reloc_chunk->kdata) ++ return -EINVAL; ++ ++ if (offset > reloc_chunk->length_dw){ ++ DRM_ERROR("Offset larger than chunk %d %d\n", offset, reloc_chunk->length_dw); ++ return -EINVAL; ++ } ++ ++ *handle = reloc_chunk->kdata[offset]; ++ *retval = reloc_chunk->kdata[offset + 3]; ++ return 0; ++} ++ ++static int radeon_gem_do_relocate(struct drm_gem_object *obj, uint32_t read_domains, ++ uint32_t write_domain, uint32_t *offset) ++{ ++ struct drm_device *dev = obj->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct drm_radeon_gem_object *obj_priv; ++ uint32_t flags; ++ int ret; ++ ++ obj_priv = obj->driver_private; ++ ret = radeon_gem_set_domain(obj, read_domains, write_domain, &flags, false); ++ if (ret) { ++ DRM_ERROR("radeon gem set domain %d failed %x %x\n", ret, read_domains, write_domain); ++ return ret; ++ } ++ ++ obj_priv->bo->mem.flags &= ~DRM_BO_FLAG_CLEAN; ++ obj_priv->bo->mem.proposed_flags &= ~DRM_BO_FLAG_CLEAN; ++ ++ if (offset) { ++ if (flags == DRM_BO_FLAG_MEM_VRAM) ++ *offset = obj_priv->bo->offset + dev_priv->fb_location; ++ else if (flags == DRM_BO_FLAG_MEM_TT) ++ *offset = obj_priv->bo->offset + dev_priv->gart_vm_start; ++ } ++ ++ return 0; ++} ++ ++static int radeon_gem_relocate(struct drm_radeon_cs_parser *parser, ++ uint32_t *reloc, uint32_t *offset) ++{ ++ struct drm_device *dev = parser->dev; ++ /* relocate the handle */ ++ uint32_t read_domains, write_domain; ++ struct drm_gem_object *obj; ++ int ret = 0; ++ struct drm_radeon_gem_object *obj_priv; ++ ++ if (parser->reloc_index == -1) { ++ obj = drm_gem_object_lookup(dev, parser->file_priv, reloc[1]); ++ if (!obj) ++ return -EINVAL; ++ obj_priv = obj->driver_private; ++ if (obj_priv->bo->mem.flags & DRM_BO_FLAG_CLEAN) ++ DRM_ERROR("clean on relocate for %d\n", reloc[1]); ++ read_domains = reloc[2]; ++ write_domain = reloc[3]; ++ ++ ret = radeon_gem_do_relocate(obj, read_domains, write_domain, offset); ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ ++ } else { ++ uint32_t handle; ++ /* have to lookup handle in other chunk */ ++ ret = radeon_gem_find_reloc(parser, reloc[1], &handle, offset); ++ } ++ return ret; ++} ++ ++ ++int radeon_gem_prelocate(struct drm_radeon_cs_parser *parser) ++{ ++ struct drm_device *dev = parser->dev; ++ struct drm_radeon_kernel_chunk *reloc_chunk = &parser->chunks[parser->reloc_index]; ++ struct drm_gem_object *obj; ++ int pass_id; ++ int i; ++ int ret; ++ ++ /* no relocs - return now */ ++ if (!reloc_chunk->kdata) ++ return 0; ++ ++ for (pass_id = 0; pass_id < 2; pass_id++) { ++ /* traverse the reloc chunk */ ++ for (i = 0; i < reloc_chunk->length_dw; i += 4) { ++ ++ if (pass_id == 0) ++ reloc_chunk->kdata[i + 3] = 0; ++ ++ if (pass_id == 1 && reloc_chunk->kdata[i + 3]) ++ continue; ++ ++ /* first pass get all write domains */ ++ if (((pass_id == 0) && reloc_chunk->kdata[i + 2]) || ++ ((pass_id == 1) && reloc_chunk->kdata[i + 1])) { ++ obj = drm_gem_object_lookup(dev, parser->file_priv, reloc_chunk->kdata[i]); ++ if (!obj) { ++ DRM_ERROR("gem object lookup failed 0x%x\n", reloc_chunk->kdata[i]); ++ return -EINVAL; ++ } ++ ret = radeon_gem_do_relocate(obj, reloc_chunk->kdata[i + 1], reloc_chunk->kdata[i + 2], ++ &reloc_chunk->kdata[i + 3]); ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ if (ret) ++ return ret; ++ } ++ } ++ } ++ return 0; ++} ++ ++/* allocate 1MB of 64k IBs the the kernel can keep mapped */ ++static int radeon_gem_ib_init(struct drm_device *dev) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ int i; ++ int ret; ++ int cached = 0; ++ ++ if (!(dev_priv->flags & RADEON_IS_AGP)) ++ cached = DRM_BO_FLAG_CACHED; ++ ++ dev_priv->ib_objs = drm_calloc(RADEON_NUM_IB, sizeof(struct radeon_mm_obj *), DRM_MEM_DRIVER); ++ if (!dev_priv->ib_objs) ++ goto free_all; ++ ++ for (i = 0; i < RADEON_NUM_IB; i++) { ++ dev_priv->ib_objs[i] = drm_calloc(1, sizeof(struct radeon_mm_obj), DRM_MEM_DRIVER); ++ if (!dev_priv->ib_objs[i]) ++ goto free_all; ++ ++ ret = drm_buffer_object_create(dev, RADEON_IB_SIZE, ++ drm_bo_type_kernel, ++ DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT | cached | ++ DRM_BO_FLAG_MAPPABLE, 0, ++ 0, 0, &dev_priv->ib_objs[i]->bo); ++ if (ret) ++ goto free_all; ++ ++ ret = drm_bo_kmap(dev_priv->ib_objs[i]->bo, 0, RADEON_IB_SIZE >> PAGE_SHIFT, ++ &dev_priv->ib_objs[i]->kmap); ++ ++ if (ret) ++ goto free_all; ++ } ++ ++ dev_priv->mm.gart_useable -= RADEON_IB_SIZE * RADEON_NUM_IB; ++ dev_priv->ib_alloc_bitmap = 0; ++ ++ dev_priv->cs.ib_get = radeon_gem_ib_get; ++ dev_priv->cs.ib_free = radeon_gem_ib_free; ++ ++ radeon_cs_init(dev); ++ dev_priv->cs.relocate = radeon_gem_relocate; ++ return 0; ++ ++free_all: ++ radeon_gem_ib_destroy(dev); ++ return -ENOMEM; ++} ++ ++/* ++ * * Userspace get informations ioctl ++ * */ ++int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ struct drm_radeon_info *info; ++ uint32_t *value_ptr; ++ uint32_t value; ++ ++ info = data; ++ value_ptr = (uint32_t*)(unsigned long)info->value; ++ switch (info->request) { ++ case RADEON_INFO_DEVICE_ID: ++ value = dev->pci_device; ++ break; ++ case RADEON_INFO_NUM_GB_PIPES: ++ value = dev_priv->num_gb_pipes; ++ break; ++ default: ++ DRM_DEBUG("Invalid request %d\n", info->request); ++ return -EINVAL; ++ } ++ if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { ++ DRM_ERROR("copy_to_user\n"); ++ return -EFAULT; ++ } ++ return 0; ++} ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_gem_debugfs.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_gem_debugfs.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_gem_debugfs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_gem_debugfs.c 2009-04-26 03:01:41.636976096 +0200 +@@ -0,0 +1,179 @@ ++/* ++ * Copyright © 2008 Intel Corporation ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ * ++ * Authors: ++ * Eric Anholt ++ * Keith Packard ++ * ++ */ ++ ++#include ++#include "drmP.h" ++#include "drm.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++#if defined(CONFIG_DEBUG_FS) ++static int radeon_ring_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t rdp, wdp; ++ ++ rdp = RADEON_READ(RADEON_CP_RB_RPTR); ++ wdp = RADEON_READ(RADEON_CP_RB_WPTR); ++ seq_printf(m, "RADEON_CP_RB_WPTR %08x\n", wdp); ++ seq_printf(m, "RADEON_CP_RB_RPTR %08x\n", rdp); ++ ++ if (rdp != wdp) { ++ uint32_t *start, *end; ++ uint32_t *ptr; ++ rdp = (rdp + 15) & ~15; ++ if (rdp > 128) ++ rdp -= 128; ++ else ++ rdp = 0; ++ start = dev_priv->ring.start + rdp; ++ if (rdp > wdp) { ++ /* dump the ring until the end */ ++ end = dev_priv->ring.start + dev_priv->ring.size; ++ } else ++ end = dev_priv->ring.start + wdp; ++ ++ for (ptr = start; ptr < end; ptr += 4) { ++ seq_printf(m, "%x: %08x %08x %08x %08x\n", ptr - dev_priv->ring.start, ++ ptr[0], ptr[1], ptr[2], ptr[3]); ++ } ++ } ++ return 0; ++} ++ ++static int radeon_ib_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t ib_base, ib_size, csq_stat; ++ uint32_t rdp, wdp; ++ ++ rdp = RADEON_READ(RADEON_CP_RB_RPTR); ++ wdp = RADEON_READ(RADEON_CP_RB_WPTR); ++ ++ if (rdp == wdp) ++ return 0; ++ ++ /* find the IB that is being processed */ ++ ib_base = RADEON_READ(RADEON_CP_IB_BASE); ++ ib_size = RADEON_READ(RADEON_CP_IB_BUFSZ); ++ csq_stat = RADEON_READ(RADEON_CP_CSQ_STAT); ++ ++ seq_printf(m, "RADEON_CP_IB_BASE/BUFSZ %08x/%08x\n", ib_base, ib_size); ++ seq_printf(m, "RADEON_CP_CSQ_STAT %08x/indrptr %08x\n", csq_stat, csq_stat >> 20); ++ if (ib_base && ib_size) { ++ int i; ++ ++ for (i = 0; i < RADEON_NUM_IB; i++) ++ if ((dev_priv->ib_objs[i]->bo->offset + dev_priv->gart_vm_start) == ib_base) ++ break; ++ if (i < RADEON_NUM_IB) { ++ uint32_t offset; ++ uint32_t *start, *end; ++ uint32_t *ptr; ++ offset = csq_stat >> 20; ++ if (offset > 32) ++ offset -= 32; ++ else ++ offset = 0; ++ offset = (offset + 15) & ~15; ++ start = dev_priv->ib_objs[i]->kmap.virtual + (offset * sizeof(u32)); ++ end = dev_priv->ib_objs[i]->kmap.virtual + (ib_size * sizeof(u32)); ++ for (ptr = start; ptr < end; ptr += 4) { ++ seq_printf(m, "%x: %08x %08x %08x %08x\n", ptr - (uint32_t *)dev_priv->ib_objs[i]->kmap.virtual, ++ ptr[0], ptr[1], ptr[2], ptr[3]); ++ } ++ } ++ } ++ return 0; ++} ++ ++static int radeon_interrupt_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ ++ seq_printf(m, "Interrupt enable: %08x\n", ++ RADEON_READ(RADEON_GEN_INT_CNTL)); ++ ++ if (dev_priv->chip_family >= CHIP_RS600) { ++ seq_printf(m, "DxMODE_INT_MASK: %08x\n", ++ RADEON_READ(R500_DxMODE_INT_MASK)); ++ } ++ seq_printf(m, "Interrupts received: %d\n", ++ atomic_read(&dev_priv->irq_received)); ++ seq_printf(m, "Current sequence: %d %d\n", ++ READ_BREADCRUMB(dev_priv), RADEON_READ(RADEON_SCRATCH_REG3)); ++ seq_printf(m, "Counter sequence: %d\n", ++ dev_priv->counter); ++ if (dev_priv->chip_family >= CHIP_R300) ++ seq_printf(m, "CS: %d\n", GET_SCRATCH(dev_priv, 6)); ++ ++ return 0; ++} ++ ++static int radeon_suspend_test(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ pm_message_t msg; ++ ++ msg.event = PM_EVENT_USER_SUSPEND; ++ radeon_suspend(dev, msg); ++ radeon_resume(dev); ++ ++ return 0; ++} ++ ++static struct drm_info_list radeon_gem_debugfs_list[] = { ++ {"radeon_gem_interrupt", radeon_interrupt_info, 0, NULL}, ++ {"radeon_gem_ring", radeon_ring_info, 0, NULL}, ++ {"radeon_gem_ib", radeon_ib_info, 0, NULL}, ++ {"radeon_suspend_test", radeon_suspend_test, 0, NULL}, ++}; ++ ++ ++#define RADEON_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(radeon_gem_debugfs_list) ++ ++int radeon_gem_debugfs_init(struct drm_minor *minor) ++{ ++ return drm_debugfs_create_files(radeon_gem_debugfs_list, ++ RADEON_GEM_DEBUGFS_ENTRIES, ++ minor->debugfs_root, minor); ++} ++ ++void radeon_gem_debugfs_cleanup(struct drm_minor *minor) ++{ ++ drm_debugfs_remove_files(radeon_gem_debugfs_list, ++ RADEON_GEM_DEBUGFS_ENTRIES, minor); ++} ++#endif +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_i2c.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_i2c.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_i2c.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_i2c.c 2009-04-26 03:01:46.314975520 +0200 +@@ -0,0 +1,205 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++/** ++ * radeon_ddc_probe ++ * ++ */ ++bool radeon_ddc_probe(struct radeon_connector *radeon_connector) ++{ ++ u8 out_buf[] = { 0x0, 0x0}; ++ u8 buf[2]; ++ int ret; ++ struct i2c_msg msgs[] = { ++ { ++ .addr = 0x50, ++ .flags = 0, ++ .len = 1, ++ .buf = out_buf, ++ }, ++ { ++ .addr = 0x50, ++ .flags = I2C_M_RD, ++ .len = 1, ++ .buf = buf, ++ } ++ }; ++ ++ ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); ++ if (ret == 2) ++ return true; ++ ++ return false; ++} ++ ++ ++void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state) ++{ ++ struct drm_radeon_private *dev_priv = radeon_connector->base.dev->dev_private; ++ uint32_t temp; ++ struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec; ++ ++ /* ++ * on certain r3xx/rv4xx the hw i2c block appears to hold the ++ * gpio lines in reset, select different gpios to avoid this ++ */ ++ if (radeon_is_r300(dev_priv)) { ++ if (rec->a_clk_reg == RADEON_GPIO_VGA_DDC) ++ RADEON_WRITE(RADEON_DVI_I2C_CNTL_0, 0x30); ++ else ++ RADEON_WRITE(RADEON_DVI_I2C_CNTL_0, 0x20); ++ } ++ if (lock_state) { ++ temp = RADEON_READ(rec->a_clk_reg); ++ temp &= ~(rec->a_clk_mask); ++ RADEON_WRITE(rec->a_clk_reg, temp); ++ ++ temp = RADEON_READ(rec->a_data_reg); ++ temp &= ~(rec->a_data_mask); ++ RADEON_WRITE(rec->a_data_reg, temp); ++ } ++ ++ temp = RADEON_READ(rec->mask_clk_reg); ++ if (lock_state) ++ temp |= rec->mask_clk_mask; ++ else ++ temp &= ~rec->mask_clk_mask; ++ RADEON_WRITE(rec->mask_clk_reg, temp); ++ temp = RADEON_READ(rec->mask_clk_reg); ++ ++ temp = RADEON_READ(rec->mask_data_reg); ++ if (lock_state) ++ temp |= rec->mask_data_mask; ++ else ++ temp &= ~rec->mask_data_mask; ++ RADEON_WRITE(rec->mask_data_reg, temp); ++ temp = RADEON_READ(rec->mask_data_reg); ++} ++ ++static int get_clock(void *i2c_priv) ++{ ++ struct radeon_i2c_chan *i2c = i2c_priv; ++ struct drm_radeon_private *dev_priv = i2c->dev->dev_private; ++ struct radeon_i2c_bus_rec *rec = &i2c->rec; ++ uint32_t val; ++ ++ val = RADEON_READ(rec->get_clk_reg); ++ val &= rec->get_clk_mask; ++ ++ return (val != 0); ++} ++ ++ ++static int get_data(void *i2c_priv) ++{ ++ struct radeon_i2c_chan *i2c = i2c_priv; ++ struct drm_radeon_private *dev_priv = i2c->dev->dev_private; ++ struct radeon_i2c_bus_rec *rec = &i2c->rec; ++ uint32_t val; ++ ++ val = RADEON_READ(rec->get_data_reg); ++ val &= rec->get_data_mask; ++ return (val != 0); ++} ++ ++static void set_clock(void *i2c_priv, int clock) ++{ ++ struct radeon_i2c_chan *i2c = i2c_priv; ++ struct drm_radeon_private *dev_priv = i2c->dev->dev_private; ++ struct radeon_i2c_bus_rec *rec = &i2c->rec; ++ uint32_t val; ++ ++ val = RADEON_READ(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask); ++ val |= clock ? 0 : rec->put_clk_mask; ++ RADEON_WRITE(rec->put_clk_reg, val); ++} ++ ++static void set_data(void *i2c_priv, int data) ++{ ++ struct radeon_i2c_chan *i2c = i2c_priv; ++ struct drm_radeon_private *dev_priv = i2c->dev->dev_private; ++ struct radeon_i2c_bus_rec *rec = &i2c->rec; ++ uint32_t val; ++ ++ val = RADEON_READ(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask); ++ val |= data ? 0 : rec->put_data_mask; ++ RADEON_WRITE(rec->put_data_reg, val); ++} ++ ++struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, ++ struct radeon_i2c_bus_rec *rec, ++ const char *name) ++{ ++ struct radeon_i2c_chan *i2c; ++ int ret; ++ ++ i2c = drm_calloc(1, sizeof(struct radeon_i2c_chan), DRM_MEM_DRIVER); ++ if (i2c == NULL) ++ return NULL; ++ ++ i2c->adapter.owner = THIS_MODULE; ++ i2c->adapter.algo_data = &i2c->algo; ++ i2c->dev = dev; ++ i2c->algo.setsda = set_data; ++ i2c->algo.setscl = set_clock; ++ i2c->algo.getsda = get_data; ++ i2c->algo.getscl = get_clock; ++ i2c->algo.udelay = 20; ++ i2c->algo.timeout = usecs_to_jiffies(2200); ++ i2c->algo.data = i2c; ++ i2c->rec = *rec; ++ i2c_set_adapdata(&i2c->adapter, i2c); ++ ++ ret = i2c_bit_add_bus(&i2c->adapter); ++ if (ret) { ++ DRM_INFO("Failed to register i2c %s\n", name); ++ goto out_free; ++ } ++ ++ return i2c; ++out_free: ++ drm_free(i2c, sizeof(struct radeon_i2c_chan), DRM_MEM_DRIVER); ++ return NULL; ++ ++} ++ ++void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) ++{ ++ if (!i2c) ++ return; ++ ++ i2c_del_adapter(&i2c->adapter); ++ drm_free(i2c, sizeof(struct radeon_i2c_chan), DRM_MEM_DRIVER); ++} ++ ++struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) ++{ ++ return NULL; ++} ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_irq.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_irq.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_irq.c 2009-04-26 02:52:17.309735936 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_irq.c 2009-04-26 02:56:52.448725786 +0200 +@@ -129,7 +129,7 @@ + } + } + +-static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int) ++u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int) + { + u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS); + u32 irq_mask = RADEON_SW_INT_TEST; +@@ -154,11 +154,10 @@ + } else + irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT; + +- irqs &= irq_mask; +- + if (irqs) + RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); + ++ irqs &= irq_mask; + return irqs; + } + +@@ -195,41 +194,49 @@ + if (!stat) + return IRQ_NONE; + +- stat &= dev_priv->irq_enable_reg; +- +- /* SW interrupt */ +- if (stat & RADEON_SW_INT_TEST) +- DRM_WAKEUP(&dev_priv->swi_queue); ++ while (stat) { ++ atomic_inc(&dev_priv->irq_received); ++ stat &= dev_priv->irq_enable_reg; ++ ++ /* SW interrupt */ ++ if (stat & RADEON_SW_INT_TEST) { ++ DRM_WAKEUP(&dev_priv->swi_queue); ++ radeon_fence_handler(dev); ++ } + +- /* VBLANK interrupt */ +- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { +- if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) +- drm_handle_vblank(dev, 0); +- if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) +- drm_handle_vblank(dev, 1); +- } else { +- if (stat & RADEON_CRTC_VBLANK_STAT) +- drm_handle_vblank(dev, 0); +- if (stat & RADEON_CRTC2_VBLANK_STAT) +- drm_handle_vblank(dev, 1); ++ /* VBLANK interrupt */ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { ++ if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) ++ drm_handle_vblank(dev, 0); ++ if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) ++ drm_handle_vblank(dev, 1); ++ } else { ++ if (stat & RADEON_CRTC_VBLANK_STAT) ++ drm_handle_vblank(dev, 0); ++ if (stat & RADEON_CRTC2_VBLANK_STAT) ++ drm_handle_vblank(dev, 1); ++ } ++ stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int); + } + return IRQ_HANDLED; + } + +-static int radeon_emit_irq(struct drm_device * dev) ++int radeon_emit_irq(struct drm_device * dev) + { + drm_radeon_private_t *dev_priv = dev->dev_private; + unsigned int ret; + RING_LOCALS; + +- atomic_inc(&dev_priv->swi_emitted); +- ret = atomic_read(&dev_priv->swi_emitted); ++ if (!dev_priv->irq_emitted) { ++ ret = radeon_update_breadcrumb(dev); + +- BEGIN_RING(4); +- OUT_RING_REG(RADEON_LAST_SWI_REG, ret); +- OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); +- ADVANCE_RING(); +- COMMIT_RING(); ++ BEGIN_RING(4); ++ OUT_RING_REG(RADEON_LAST_SWI_REG, ret); ++ OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); ++ ADVANCE_RING(); ++ COMMIT_RING(); ++ } else ++ ret = dev_priv->irq_emitted; + + return ret; + } +@@ -240,13 +247,13 @@ + (drm_radeon_private_t *) dev->dev_private; + int ret = 0; + +- if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) ++ if (READ_BREADCRUMB(dev_priv) >= swi_nr) + return 0; + + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + + DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, +- RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); ++ READ_BREADCRUMB(dev_priv) >= swi_nr); + + return ret; + } +@@ -340,7 +347,6 @@ + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *) dev->dev_private; + +- atomic_set(&dev_priv->swi_emitted, 0); + DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); + + dev->max_vblank_count = 0x001fffff; +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_legacy_crtc.c 2009-04-26 03:01:52.975974690 +0200 +@@ -0,0 +1,1600 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++#include "radeon_fixed.h" ++#include "drm_crtc_helper.h" ++ ++void radeon_restore_common_regs(struct drm_device *dev) ++{ ++ /* don't need this yet */ ++} ++ ++static void radeon_pll_wait_for_read_update_complete(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int i = 0; ++ ++ /* FIXME: Certain revisions of R300 can't recover here. Not sure of ++ the cause yet, but this workaround will mask the problem for now. ++ Other chips usually will pass at the very first test, so the ++ workaround shouldn't have any effect on them. */ ++ for (i = 0; ++ (i < 10000 && ++ RADEON_READ_PLL(dev_priv, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R); ++ i++); ++} ++ ++static void radeon_pll_write_update(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ ++ while (RADEON_READ_PLL(dev_priv, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R); ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PPLL_REF_DIV, ++ RADEON_PPLL_ATOMIC_UPDATE_W, ++ ~(RADEON_PPLL_ATOMIC_UPDATE_W)); ++} ++ ++static void radeon_pll2_wait_for_read_update_complete(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int i = 0; ++ ++ ++ /* FIXME: Certain revisions of R300 can't recover here. Not sure of ++ the cause yet, but this workaround will mask the problem for now. ++ Other chips usually will pass at the very first test, so the ++ workaround shouldn't have any effect on them. */ ++ for (i = 0; ++ (i < 10000 && ++ RADEON_READ_PLL(dev_priv, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R); ++ i++); ++} ++ ++static void radeon_pll2_write_update(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ ++ while (RADEON_READ_PLL(dev_priv, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R); ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_P2PLL_REF_DIV, ++ RADEON_P2PLL_ATOMIC_UPDATE_W, ++ ~(RADEON_P2PLL_ATOMIC_UPDATE_W)); ++} ++ ++static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div, ++ uint16_t fb_div) ++{ ++ unsigned int vcoFreq; ++ ++ if (!ref_div) ++ return 1; ++ ++ vcoFreq = ((unsigned)ref_freq & fb_div) / ref_div; ++ ++ /* ++ * This is horribly crude: the VCO frequency range is divided into ++ * 3 parts, each part having a fixed PLL gain value. ++ */ ++ if (vcoFreq >= 30000) ++ /* ++ * [300..max] MHz : 7 ++ */ ++ return 7; ++ else if (vcoFreq >= 18000) ++ /* ++ * [180..300) MHz : 4 ++ */ ++ return 4; ++ else ++ /* ++ * [0..180) MHz : 1 ++ */ ++ return 1; ++} ++ ++void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t mask; ++ ++ DRM_DEBUG("\n"); ++ ++ mask = radeon_crtc->crtc_id ? ++ (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_REQ_EN_B) : ++ (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS); ++ ++ switch(mode) { ++ case DRM_MODE_DPMS_ON: ++ if (radeon_crtc->crtc_id) ++ RADEON_WRITE_P(RADEON_CRTC2_GEN_CNTL, 0, ~mask); ++ else { ++ RADEON_WRITE_P(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B); ++ RADEON_WRITE_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); ++ } ++ break; ++ case DRM_MODE_DPMS_STANDBY: ++ if (radeon_crtc->crtc_id) ++ RADEON_WRITE_P(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask); ++ else { ++ RADEON_WRITE_P(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B); ++ RADEON_WRITE_P(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask); ++ } ++ break; ++ case DRM_MODE_DPMS_SUSPEND: ++ if (radeon_crtc->crtc_id) ++ RADEON_WRITE_P(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask); ++ else { ++ RADEON_WRITE_P(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B); ++ RADEON_WRITE_P(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask); ++ } ++ break; ++ case DRM_MODE_DPMS_OFF: ++ if (radeon_crtc->crtc_id) ++ RADEON_WRITE_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); ++ else { ++ RADEON_WRITE_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~RADEON_CRTC_DISP_REQ_EN_B); ++ RADEON_WRITE_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); ++ } ++ break; ++ } ++ ++ if (mode != DRM_MODE_DPMS_OFF) { ++ radeon_crtc_load_lut(crtc); ++ } ++} ++ ++/* properly set crtc bpp when using atombios */ ++void radeon_legacy_atom_set_surface(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ int format; ++ uint32_t crtc_gen_cntl; ++ uint32_t disp_merge_cntl; ++ uint32_t crtc_pitch; ++ ++ switch (crtc->fb->bits_per_pixel) { ++ case 15: /* 555 */ ++ format = 3; ++ break; ++ case 16: /* 565 */ ++ format = 4; ++ break; ++ case 24: /* RGB */ ++ format = 5; ++ break; ++ case 32: /* xRGB */ ++ format = 6; ++ break; ++ default: ++ return; ++ } ++ ++ crtc_pitch = ((((crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8)) * crtc->fb->bits_per_pixel) + ++ ((crtc->fb->bits_per_pixel * 8) - 1)) / ++ (crtc->fb->bits_per_pixel * 8)); ++ crtc_pitch |= crtc_pitch << 16; ++ ++ switch (radeon_crtc->crtc_id) { ++ case 0: ++ disp_merge_cntl = RADEON_READ(RADEON_DISP_MERGE_CNTL); ++ disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN; ++ RADEON_WRITE(RADEON_DISP_MERGE_CNTL, disp_merge_cntl); ++ ++ RADEON_WRITE(RADEON_CRTC_PITCH, crtc_pitch); ++ ++ crtc_gen_cntl = RADEON_READ(RADEON_CRTC_GEN_CNTL) & 0xfffff0ff; ++ crtc_gen_cntl |= (format << 8); ++ crtc_gen_cntl |= RADEON_CRTC_EXT_DISP_EN; ++ RADEON_WRITE(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); ++ break; ++ case 1: ++ disp_merge_cntl = RADEON_READ(RADEON_DISP2_MERGE_CNTL); ++ disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN; ++ RADEON_WRITE(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl); ++ ++ RADEON_WRITE(RADEON_CRTC2_PITCH, crtc_pitch); ++ ++ crtc_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL) & 0xfffff0ff; ++ crtc_gen_cntl |= (format << 8); ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, crtc_gen_cntl); ++ RADEON_WRITE(RADEON_FP_H2_SYNC_STRT_WID, RADEON_READ(RADEON_CRTC2_H_SYNC_STRT_WID)); ++ RADEON_WRITE(RADEON_FP_V2_SYNC_STRT_WID, RADEON_READ(RADEON_CRTC2_V_SYNC_STRT_WID)); ++ break; ++ } ++} ++ ++static bool radeon_set_crtc1_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_framebuffer *radeon_fb; ++ struct drm_gem_object *obj; ++ struct drm_radeon_gem_object *obj_priv; ++ uint32_t base; ++ uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0; ++ ++ DRM_DEBUG("\n"); ++ ++ radeon_fb = to_radeon_framebuffer(crtc->fb); ++ ++ obj = radeon_fb->obj; ++ obj_priv = obj->driver_private; ++ ++ if (radeon_gem_object_pin(obj, 0, RADEON_GEM_DOMAIN_VRAM)) ++ return -EINVAL; ++ ++ crtc_offset = obj_priv->bo->offset; ++ ++ crtc_offset_cntl = 0; ++ ++ /* TODO tiling */ ++ if (0) { ++ if (radeon_is_r300(dev_priv)) ++ crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN | ++ R300_CRTC_MICRO_TILE_BUFFER_DIS | ++ R300_CRTC_MACRO_TILE_EN); ++ else ++ crtc_offset_cntl |= RADEON_CRTC_TILE_EN; ++ } else { ++ if (radeon_is_r300(dev_priv)) ++ crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN | ++ R300_CRTC_MICRO_TILE_BUFFER_DIS | ++ R300_CRTC_MACRO_TILE_EN); ++ else ++ crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN; ++ } ++ ++ base = obj_priv->bo->offset; ++ ++ /* TODO more tiling */ ++ if (0) { ++ if (radeon_is_r300(dev_priv)) { ++ crtc_tile_x0_y0 = x | (y << 16); ++ base &= ~0x7ff; ++ } else { ++ int byteshift = crtc->fb->bits_per_pixel >> 4; ++ int tile_addr = (((y >> 3) * crtc->fb->width + x) >> (8 - byteshift)) << 11; ++ base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8); ++ crtc_offset_cntl |= (y % 16); ++ } ++ } else { ++ int offset = y * crtc->fb->pitch + x; ++ switch (crtc->fb->bits_per_pixel) { ++ case 15: ++ case 16: ++ offset *= 2; ++ break; ++ case 24: ++ offset *= 3; ++ break; ++ case 32: ++ offset *= 4; ++ break; ++ default: ++ return false; ++ } ++ base += offset; ++ } ++ ++ base &= ~7; ++ ++ /* update sarea TODO */ ++ ++ crtc_offset = base; ++ ++ DRM_DEBUG("mc_fb_location: 0x%x\n", dev_priv->fb_location); ++ ++ RADEON_WRITE(RADEON_DISPLAY_BASE_ADDR, dev_priv->fb_location); ++ ++ if (radeon_is_r300(dev_priv)) ++ RADEON_WRITE(R300_CRTC_TILE_X0_Y0, crtc_tile_x0_y0); ++ RADEON_WRITE(RADEON_CRTC_OFFSET_CNTL, crtc_offset_cntl); ++ RADEON_WRITE(RADEON_CRTC_OFFSET, crtc_offset); ++ ++ if (old_fb) { ++ radeon_fb = to_radeon_framebuffer(old_fb); ++ radeon_gem_object_unpin(radeon_fb->obj); ++ } ++ ++ return true; ++} ++ ++static bool radeon_set_crtc1_timing(struct drm_crtc *crtc, struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int format; ++ int hsync_start; ++ int hsync_wid; ++ int vsync_wid; ++ uint32_t crtc_gen_cntl; ++ uint32_t crtc_ext_cntl; ++ uint32_t crtc_h_total_disp; ++ uint32_t crtc_h_sync_strt_wid; ++ uint32_t crtc_v_total_disp; ++ uint32_t crtc_v_sync_strt_wid; ++ uint32_t crtc_pitch; ++ uint32_t disp_merge_cntl; ++ ++ DRM_DEBUG("\n"); ++ ++ switch (crtc->fb->bits_per_pixel) { ++ case 15: /* 555 */ ++ format = 3; ++ break; ++ case 16: /* 565 */ ++ format = 4; ++ break; ++ case 24: /* RGB */ ++ format = 5; ++ break; ++ case 32: /* xRGB */ ++ format = 6; ++ break; ++ default: ++ return false; ++ } ++ ++ crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN ++ | RADEON_CRTC_EN ++ | (format << 8) ++ | ((mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ ? RADEON_CRTC_DBL_SCAN_EN ++ : 0) ++ | ((mode->flags & DRM_MODE_FLAG_CSYNC) ++ ? RADEON_CRTC_CSYNC_EN ++ : 0) ++ | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ++ ? RADEON_CRTC_INTERLACE_EN ++ : 0)); ++ ++ crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL); ++ crtc_ext_cntl |= (RADEON_XCRT_CNT_EN | ++ RADEON_CRTC_VSYNC_DIS | ++ RADEON_CRTC_HSYNC_DIS | ++ RADEON_CRTC_DISPLAY_DIS); ++ ++ crtc_h_total_disp = ((((mode->crtc_htotal / 8) - 1) & 0x3ff) ++ | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16)); ++ ++ hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8; ++ if (!hsync_wid) ++ hsync_wid = 1; ++ hsync_start = mode->crtc_hsync_start - 8; ++ ++ crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) ++ | ((hsync_wid & 0x3f) << 16) ++ | ((mode->flags & DRM_MODE_FLAG_NHSYNC) ++ ? RADEON_CRTC_H_SYNC_POL ++ : 0)); ++ ++ /* This works for double scan mode. */ ++ crtc_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff) ++ | ((mode->crtc_vdisplay - 1) << 16)); ++ ++ vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start; ++ if (!vsync_wid) ++ vsync_wid = 1; ++ ++ crtc_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff) ++ | ((vsync_wid & 0x1f) << 16) ++ | ((mode->flags & DRM_MODE_FLAG_NVSYNC) ++ ? RADEON_CRTC_V_SYNC_POL ++ : 0)); ++ ++ crtc_pitch = ((((crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8)) * crtc->fb->bits_per_pixel) + ++ ((crtc->fb->bits_per_pixel * 8) - 1)) / ++ (crtc->fb->bits_per_pixel * 8)); ++ crtc_pitch |= crtc_pitch << 16; ++ ++ /* TODO -> Dell Server */ ++ if (0) { ++ uint32_t disp_hw_debug = RADEON_READ(RADEON_DISP_HW_DEBUG); ++ uint32_t tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL); ++ uint32_t dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2); ++ uint32_t crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL); ++ ++ dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL; ++ dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL; ++ ++ /* For CRT on DAC2, don't turn it on if BIOS didn't ++ enable it, even it's detected. ++ */ ++ disp_hw_debug |= RADEON_CRT2_DISP1_SEL; ++ tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16)); ++ tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16)); ++ ++ RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl); ++ RADEON_WRITE(RADEON_DISP_HW_DEBUG, disp_hw_debug); ++ RADEON_WRITE(RADEON_DAC_CNTL2, dac2_cntl); ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); ++ } ++ ++ disp_merge_cntl = RADEON_READ(RADEON_DISP_MERGE_CNTL); ++ disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN; ++ RADEON_WRITE(RADEON_DISP_MERGE_CNTL, disp_merge_cntl); ++ ++ RADEON_WRITE(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl | ++ RADEON_CRTC_DISP_REQ_EN_B); ++ ++ RADEON_WRITE_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ++ RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_DISPLAY_DIS); ++ ++ RADEON_WRITE(RADEON_CRTC_H_TOTAL_DISP, crtc_h_total_disp); ++ RADEON_WRITE(RADEON_CRTC_H_SYNC_STRT_WID, crtc_h_sync_strt_wid); ++ RADEON_WRITE(RADEON_CRTC_V_TOTAL_DISP, crtc_v_total_disp); ++ RADEON_WRITE(RADEON_CRTC_V_SYNC_STRT_WID, crtc_v_sync_strt_wid); ++ ++ RADEON_WRITE(RADEON_CRTC_PITCH, crtc_pitch); ++ ++ RADEON_WRITE(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); ++ ++ return true; ++} ++ ++static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_encoder *encoder; ++ uint32_t feedback_div = 0; ++ uint32_t reference_div = 0; ++ uint32_t post_divider = 0; ++ uint32_t freq = 0; ++ uint8_t pll_gain; ++ int pll_flags = RADEON_PLL_LEGACY; ++ bool use_bios_divs = false; ++ /* PLL registers */ ++ uint32_t ppll_ref_div = 0; ++ uint32_t ppll_div_3 = 0; ++ uint32_t htotal_cntl = 0; ++ uint32_t vclk_ecp_cntl; ++ ++ struct radeon_pll *pll = &dev_priv->mode_info.p1pll; ++ ++ struct { ++ int divider; ++ int bitvalue; ++ } *post_div, post_divs[] = { ++ /* From RAGE 128 VR/RAGE 128 GL Register ++ * Reference Manual (Technical Reference ++ * Manual P/N RRG-G04100-C Rev. 0.04), page ++ * 3-17 (PLL_DIV_[3:0]). ++ */ ++ { 1, 0 }, /* VCLK_SRC */ ++ { 2, 1 }, /* VCLK_SRC/2 */ ++ { 4, 2 }, /* VCLK_SRC/4 */ ++ { 8, 3 }, /* VCLK_SRC/8 */ ++ { 3, 4 }, /* VCLK_SRC/3 */ ++ { 16, 5 }, /* VCLK_SRC/16 */ ++ { 6, 6 }, /* VCLK_SRC/6 */ ++ { 12, 7 }, /* VCLK_SRC/12 */ ++ { 0, 0 } ++ }; ++ ++ if (mode->clock > 200000) /* range limits??? */ ++ pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; ++ else ++ pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; ++ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ if (encoder->crtc == crtc) { ++ if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) ++ pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; ++ if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; ++ if (lvds) { ++ if (lvds->use_bios_dividers) { ++ ppll_ref_div = lvds->panel_ref_divider; ++ ppll_div_3 = (lvds->panel_fb_divider | ++ (lvds->panel_post_divider << 16)); ++ htotal_cntl = 0; ++ use_bios_divs = true; ++ } ++ } ++ pll_flags |= RADEON_PLL_USE_REF_DIV; ++ } ++ } ++ } ++ ++ DRM_DEBUG("\n"); ++ ++ if (!use_bios_divs) { ++ radeon_compute_pll(pll, mode->clock, &freq, &feedback_div, &reference_div, &post_divider, pll_flags); ++ ++ for (post_div = &post_divs[0]; post_div->divider; ++post_div) { ++ if (post_div->divider == post_divider) ++ break; ++ } ++ ++ if (!post_div->divider) { ++ post_div = &post_divs[0]; ++ } ++ ++ DRM_DEBUG("dc=%u, fd=%d, rd=%d, pd=%d\n", ++ (unsigned)freq, ++ feedback_div, ++ reference_div, ++ post_divider); ++ ++ ppll_ref_div = reference_div; ++#if defined(__powerpc__) && (0) /* TODO */ ++ /* apparently programming this otherwise causes a hang??? */ ++ if (info->MacModel == RADEON_MAC_IBOOK) ++ state->ppll_div_3 = 0x000600ad; ++ else ++#endif ++ ppll_div_3 = (feedback_div | (post_div->bitvalue << 16)); ++ htotal_cntl = mode->htotal & 0x7; ++ ++ } ++ ++ vclk_ecp_cntl = (RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL) & ++ ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK; ++ ++ pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.p1pll.reference_freq, ++ ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, ++ ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK); ++ ++ if (dev_priv->flags & RADEON_IS_MOBILITY) { ++ /* A temporal workaround for the occational blanking on certain laptop panels. ++ This appears to related to the PLL divider registers (fail to lock?). ++ It occurs even when all dividers are the same with their old settings. ++ In this case we really don't need to fiddle with PLL registers. ++ By doing this we can avoid the blanking problem with some panels. ++ */ ++ if ((ppll_ref_div == (RADEON_READ_PLL(dev_priv, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) && ++ (ppll_div_3 == (RADEON_READ_PLL(dev_priv, RADEON_PPLL_DIV_3) & ++ (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) { ++ RADEON_WRITE_P(RADEON_CLOCK_CNTL_INDEX, ++ RADEON_PLL_DIV_SEL, ++ ~(RADEON_PLL_DIV_SEL)); ++ radeon_pll_errata_after_index(dev_priv); ++ return; ++ } ++ } ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_VCLK_ECP_CNTL, ++ RADEON_VCLK_SRC_SEL_CPUCLK, ++ ~(RADEON_VCLK_SRC_SEL_MASK)); ++ RADEON_WRITE_PLL_P(dev_priv, ++ RADEON_PPLL_CNTL, ++ RADEON_PPLL_RESET ++ | RADEON_PPLL_ATOMIC_UPDATE_EN ++ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN ++ | ((uint32_t)pll_gain << RADEON_PPLL_PVG_SHIFT), ++ ~(RADEON_PPLL_RESET ++ | RADEON_PPLL_ATOMIC_UPDATE_EN ++ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN ++ | RADEON_PPLL_PVG_MASK)); ++ ++ RADEON_WRITE_P(RADEON_CLOCK_CNTL_INDEX, ++ RADEON_PLL_DIV_SEL, ++ ~(RADEON_PLL_DIV_SEL)); ++ radeon_pll_errata_after_index(dev_priv); ++ ++ if (radeon_is_r300(dev_priv) || ++ (dev_priv->chip_family == CHIP_RS300) || ++ (dev_priv->chip_family == CHIP_RS400) || ++ (dev_priv->chip_family == CHIP_RS480)) { ++ if (ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { ++ /* When restoring console mode, use saved PPLL_REF_DIV ++ * setting. ++ */ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PPLL_REF_DIV, ++ ppll_ref_div, ++ 0); ++ } else { ++ /* R300 uses ref_div_acc field as real ref divider */ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PPLL_REF_DIV, ++ (ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT), ++ ~R300_PPLL_REF_DIV_ACC_MASK); ++ } ++ } else { ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PPLL_REF_DIV, ++ ppll_ref_div, ++ ~RADEON_PPLL_REF_DIV_MASK); ++ } ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PPLL_DIV_3, ++ ppll_div_3, ++ ~RADEON_PPLL_FB3_DIV_MASK); ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PPLL_DIV_3, ++ ppll_div_3, ++ ~RADEON_PPLL_POST3_DIV_MASK); ++ ++ radeon_pll_write_update(dev); ++ radeon_pll_wait_for_read_update_complete(dev); ++ ++ RADEON_WRITE_PLL(dev_priv, RADEON_HTOTAL_CNTL, htotal_cntl); ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PPLL_CNTL, ++ 0, ++ ~(RADEON_PPLL_RESET ++ | RADEON_PPLL_SLEEP ++ | RADEON_PPLL_ATOMIC_UPDATE_EN ++ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); ++ ++ DRM_DEBUG("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", ++ ppll_ref_div, ++ ppll_div_3, ++ (unsigned)htotal_cntl, ++ RADEON_READ_PLL(dev_priv, RADEON_PPLL_CNTL)); ++ DRM_DEBUG("Wrote: rd=%d, fd=%d, pd=%d\n", ++ ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, ++ ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK, ++ (ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16); ++ ++ mdelay(50); /* Let the clock to lock */ ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_VCLK_ECP_CNTL, ++ RADEON_VCLK_SRC_SEL_PPLLCLK, ++ ~(RADEON_VCLK_SRC_SEL_MASK)); ++ ++ /*RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);*/ ++ ++} ++ ++static bool radeon_set_crtc2_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_framebuffer *radeon_fb; ++ struct drm_gem_object *obj; ++ struct drm_radeon_gem_object *obj_priv; ++ uint32_t base; ++ uint32_t crtc2_offset, crtc2_offset_cntl, crtc2_tile_x0_y0 = 0; ++ ++ DRM_DEBUG("\n"); ++ ++ radeon_fb = to_radeon_framebuffer(crtc->fb); ++ ++ obj = radeon_fb->obj; ++ obj_priv = obj->driver_private; ++ ++ if (radeon_gem_object_pin(obj, 0, RADEON_GEM_DOMAIN_VRAM)) ++ return -EINVAL; ++ ++ crtc2_offset = obj_priv->bo->offset; ++ ++ crtc2_offset_cntl = 0; ++ ++ /* TODO tiling */ ++ if (0) { ++ if (radeon_is_r300(dev_priv)) ++ crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN | ++ R300_CRTC_MICRO_TILE_BUFFER_DIS | ++ R300_CRTC_MACRO_TILE_EN); ++ else ++ crtc2_offset_cntl |= RADEON_CRTC_TILE_EN; ++ } else { ++ if (radeon_is_r300(dev_priv)) ++ crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN | ++ R300_CRTC_MICRO_TILE_BUFFER_DIS | ++ R300_CRTC_MACRO_TILE_EN); ++ else ++ crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN; ++ } ++ ++ base = obj_priv->bo->offset; ++ ++ /* TODO more tiling */ ++ if (0) { ++ if (radeon_is_r300(dev_priv)) { ++ crtc2_tile_x0_y0 = x | (y << 16); ++ base &= ~0x7ff; ++ } else { ++ int byteshift = crtc->fb->bits_per_pixel >> 4; ++ int tile_addr = (((y >> 3) * crtc->fb->width + x) >> (8 - byteshift)) << 11; ++ base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8); ++ crtc2_offset_cntl |= (y % 16); ++ } ++ } else { ++ int offset = y * crtc->fb->pitch + x; ++ switch (crtc->fb->bits_per_pixel) { ++ case 15: ++ case 16: ++ offset *= 2; ++ break; ++ case 24: ++ offset *= 3; ++ break; ++ case 32: ++ offset *= 4; ++ break; ++ default: ++ goto out; ++ } ++ base += offset; ++ } ++ ++ base &= ~7; ++ ++ /* update sarea TODO */ ++ ++ crtc2_offset = base; ++ ++ RADEON_WRITE(RADEON_DISPLAY2_BASE_ADDR, dev_priv->fb_location); ++ ++ if (radeon_is_r300(dev_priv)) ++ RADEON_WRITE(R300_CRTC2_TILE_X0_Y0, crtc2_tile_x0_y0); ++ RADEON_WRITE(RADEON_CRTC2_OFFSET_CNTL, crtc2_offset_cntl); ++ RADEON_WRITE(RADEON_CRTC2_OFFSET, crtc2_offset); ++ ++ out: ++ if (old_fb) { ++ radeon_fb = to_radeon_framebuffer(old_fb); ++ radeon_gem_object_unpin(radeon_fb->obj); ++ } ++ ++ return true; ++} ++ ++static bool radeon_set_crtc2_timing(struct drm_crtc *crtc, struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ int format; ++ int hsync_start; ++ int hsync_wid; ++ int vsync_wid; ++ uint32_t crtc2_gen_cntl; ++ uint32_t crtc2_h_total_disp; ++ uint32_t crtc2_h_sync_strt_wid; ++ uint32_t crtc2_v_total_disp; ++ uint32_t crtc2_v_sync_strt_wid; ++ uint32_t fp_h2_sync_strt_wid; ++ uint32_t fp_v2_sync_strt_wid; ++ uint32_t crtc2_pitch; ++ uint32_t disp2_merge_cntl; ++ ++ DRM_DEBUG("\n"); ++ ++ switch (crtc->fb->bits_per_pixel) { ++ ++ case 15: /* 555 */ ++ format = 3; ++ break; ++ case 16: /* 565 */ ++ format = 4; ++ break; ++ case 24: /* RGB */ ++ format = 5; ++ break; ++ case 32: /* xRGB */ ++ format = 6; ++ break; ++ default: ++ return false; ++ } ++ ++ crtc2_h_total_disp = ++ ((((mode->crtc_htotal / 8) - 1) & 0x3ff) ++ | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16)); ++ ++ hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8; ++ if (!hsync_wid) ++ hsync_wid = 1; ++ hsync_start = mode->crtc_hsync_start - 8; ++ ++ crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff) ++ | ((hsync_wid & 0x3f) << 16) ++ | ((mode->flags & DRM_MODE_FLAG_NHSYNC) ++ ? RADEON_CRTC_H_SYNC_POL ++ : 0)); ++ ++ /* This works for double scan mode. */ ++ crtc2_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff) ++ | ((mode->crtc_vdisplay - 1) << 16)); ++ ++ vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start; ++ if (!vsync_wid) ++ vsync_wid = 1; ++ ++ crtc2_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff) ++ | ((vsync_wid & 0x1f) << 16) ++ | ((mode->flags & DRM_MODE_FLAG_NVSYNC) ++ ? RADEON_CRTC2_V_SYNC_POL ++ : 0)); ++ ++ /* check to see if TV DAC is enabled for another crtc and keep it enabled */ ++ if (RADEON_READ(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_CRT2_ON) ++ crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON; ++ else ++ crtc2_gen_cntl = 0; ++ ++ crtc2_gen_cntl |= (RADEON_CRTC2_EN ++ | (format << 8) ++ | RADEON_CRTC2_VSYNC_DIS ++ | RADEON_CRTC2_HSYNC_DIS ++ | RADEON_CRTC2_DISP_DIS ++ | ((mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ ? RADEON_CRTC2_DBL_SCAN_EN ++ : 0) ++ | ((mode->flags & DRM_MODE_FLAG_CSYNC) ++ ? RADEON_CRTC2_CSYNC_EN ++ : 0) ++ | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ++ ? RADEON_CRTC2_INTERLACE_EN ++ : 0)); ++ ++ fp_h2_sync_strt_wid = crtc2_h_sync_strt_wid; ++ fp_v2_sync_strt_wid = crtc2_v_sync_strt_wid; ++ ++ crtc2_pitch = ((((crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8)) * crtc->fb->bits_per_pixel) + ++ ((crtc->fb->bits_per_pixel * 8) - 1)) / ++ (crtc->fb->bits_per_pixel * 8)); ++ crtc2_pitch |= crtc2_pitch << 16; ++ ++ disp2_merge_cntl = RADEON_READ(RADEON_DISP2_MERGE_CNTL); ++ disp2_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN; ++ RADEON_WRITE(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl); ++ ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, ++ crtc2_gen_cntl | RADEON_CRTC2_VSYNC_DIS | ++ RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_DIS | ++ RADEON_CRTC2_DISP_REQ_EN_B); ++ ++ RADEON_WRITE(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); ++ RADEON_WRITE(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); ++ RADEON_WRITE(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); ++ RADEON_WRITE(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); ++ ++ RADEON_WRITE(RADEON_FP_H2_SYNC_STRT_WID, fp_h2_sync_strt_wid); ++ RADEON_WRITE(RADEON_FP_V2_SYNC_STRT_WID, fp_v2_sync_strt_wid); ++ ++ RADEON_WRITE(RADEON_CRTC2_PITCH, crtc2_pitch); ++ ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); ++ ++ return true; ++ ++} ++ ++static void radeon_set_pll2(struct drm_crtc *crtc, struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_encoder *encoder; ++ uint32_t feedback_div = 0; ++ uint32_t reference_div = 0; ++ uint32_t post_divider = 0; ++ uint32_t freq = 0; ++ uint8_t pll_gain; ++ int pll_flags = RADEON_PLL_LEGACY; ++ bool use_bios_divs = false; ++ /* PLL2 registers */ ++ uint32_t p2pll_ref_div = 0; ++ uint32_t p2pll_div_0 = 0; ++ uint32_t htotal_cntl2 = 0; ++ uint32_t pixclks_cntl; ++ ++ struct radeon_pll *pll = &dev_priv->mode_info.p2pll; ++ ++ struct { ++ int divider; ++ int bitvalue; ++ } *post_div, post_divs[] = { ++ /* From RAGE 128 VR/RAGE 128 GL Register ++ * Reference Manual (Technical Reference ++ * Manual P/N RRG-G04100-C Rev. 0.04), page ++ * 3-17 (PLL_DIV_[3:0]). ++ */ ++ { 1, 0 }, /* VCLK_SRC */ ++ { 2, 1 }, /* VCLK_SRC/2 */ ++ { 4, 2 }, /* VCLK_SRC/4 */ ++ { 8, 3 }, /* VCLK_SRC/8 */ ++ { 3, 4 }, /* VCLK_SRC/3 */ ++ { 6, 6 }, /* VCLK_SRC/6 */ ++ { 12, 7 }, /* VCLK_SRC/12 */ ++ { 0, 0 } ++ }; ++ ++ if (mode->clock > 200000) /* range limits??? */ ++ pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; ++ else ++ pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; ++ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ if (encoder->crtc == crtc) { ++ if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) ++ pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; ++ if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; ++ if (lvds) { ++ if (lvds->use_bios_dividers) { ++ p2pll_ref_div = lvds->panel_ref_divider; ++ p2pll_div_0 = (lvds->panel_fb_divider | ++ (lvds->panel_post_divider << 16)); ++ htotal_cntl2 = 0; ++ use_bios_divs = true; ++ } ++ } ++ pll_flags |= RADEON_PLL_USE_REF_DIV; ++ } ++ } ++ } ++ ++ DRM_DEBUG("\n"); ++ ++ if (!use_bios_divs) { ++ radeon_compute_pll(pll, mode->clock, &freq, &feedback_div, &reference_div, &post_divider, pll_flags); ++ ++ for (post_div = &post_divs[0]; post_div->divider; ++post_div) { ++ if (post_div->divider == post_divider) ++ break; ++ } ++ ++ if (!post_div->divider) { ++ post_div = &post_divs[0]; ++ } ++ ++ DRM_DEBUG("dc=%u, fd=%d, rd=%d, pd=%d\n", ++ (unsigned)freq, ++ feedback_div, ++ reference_div, ++ post_divider); ++ ++ p2pll_ref_div = reference_div; ++ p2pll_div_0 = (feedback_div | (post_div->bitvalue << 16)); ++ htotal_cntl2 = mode->htotal & 0x7; ++ ++ } ++ ++ pixclks_cntl = ((RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL) & ++ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | ++ RADEON_PIX2CLK_SRC_SEL_P2PLLCLK); ++ ++ pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.p2pll.reference_freq, ++ p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, ++ p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK); ++ ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PIXCLKS_CNTL, ++ RADEON_PIX2CLK_SRC_SEL_CPUCLK, ++ ~(RADEON_PIX2CLK_SRC_SEL_MASK)); ++ ++ RADEON_WRITE_PLL_P(dev_priv, ++ RADEON_P2PLL_CNTL, ++ RADEON_P2PLL_RESET ++ | RADEON_P2PLL_ATOMIC_UPDATE_EN ++ | ((uint32_t)pll_gain << RADEON_P2PLL_PVG_SHIFT), ++ ~(RADEON_P2PLL_RESET ++ | RADEON_P2PLL_ATOMIC_UPDATE_EN ++ | RADEON_P2PLL_PVG_MASK)); ++ ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_P2PLL_REF_DIV, ++ p2pll_ref_div, ++ ~RADEON_P2PLL_REF_DIV_MASK); ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_P2PLL_DIV_0, ++ p2pll_div_0, ++ ~RADEON_P2PLL_FB0_DIV_MASK); ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_P2PLL_DIV_0, ++ p2pll_div_0, ++ ~RADEON_P2PLL_POST0_DIV_MASK); ++ ++ radeon_pll2_write_update(dev); ++ radeon_pll2_wait_for_read_update_complete(dev); ++ ++ RADEON_WRITE_PLL(dev_priv, RADEON_HTOTAL2_CNTL, htotal_cntl2); ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_P2PLL_CNTL, ++ 0, ++ ~(RADEON_P2PLL_RESET ++ | RADEON_P2PLL_SLEEP ++ | RADEON_P2PLL_ATOMIC_UPDATE_EN)); ++ ++ DRM_DEBUG("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n", ++ (unsigned)p2pll_ref_div, ++ (unsigned)p2pll_div_0, ++ (unsigned)htotal_cntl2, ++ RADEON_READ_PLL(dev_priv, RADEON_P2PLL_CNTL)); ++ DRM_DEBUG("Wrote2: rd=%u, fd=%u, pd=%u\n", ++ (unsigned)p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, ++ (unsigned)p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK, ++ (unsigned)((p2pll_div_0 & ++ RADEON_P2PLL_POST0_DIV_MASK) >>16)); ++ ++ mdelay(50); /* Let the clock to lock */ ++ ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PIXCLKS_CNTL, ++ RADEON_PIX2CLK_SRC_SEL_P2PLLCLK, ++ ~(RADEON_PIX2CLK_SRC_SEL_MASK)); ++ ++ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, pixclks_cntl); ++ ++} ++ ++static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ return true; ++} ++ ++int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ ++ switch(radeon_crtc->crtc_id) { ++ case 0: ++ radeon_set_crtc1_base(crtc, x, y, old_fb); ++ break; ++ case 1: ++ radeon_set_crtc2_base(crtc, x, y, old_fb); ++ break; ++ ++ } ++ return 0; ++} ++ ++static int radeon_crtc_mode_set(struct drm_crtc *crtc, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode, ++ int x, int y, struct drm_framebuffer *old_fb) ++{ ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ ++ DRM_DEBUG("\n"); ++ ++ /* TODO TV */ ++ ++ radeon_crtc_set_base(crtc, x, y, old_fb); ++ ++ switch(radeon_crtc->crtc_id) { ++ case 0: ++ radeon_set_crtc1_timing(crtc, adjusted_mode); ++ radeon_set_pll1(crtc, adjusted_mode); ++ break; ++ case 1: ++ radeon_set_crtc2_timing(crtc, adjusted_mode); ++ radeon_set_pll2(crtc, adjusted_mode); ++ break; ++ ++ } ++ radeon_init_disp_bandwidth(crtc->dev); ++ return 0; ++} ++ ++static void radeon_crtc_prepare(struct drm_crtc *crtc) ++{ ++ radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); ++} ++ ++static void radeon_crtc_commit(struct drm_crtc *crtc) ++{ ++ radeon_crtc_dpms(crtc, DRM_MODE_DPMS_ON); ++} ++ ++static const struct drm_crtc_helper_funcs legacy_helper_funcs = { ++ .dpms = radeon_crtc_dpms, ++ .mode_fixup = radeon_crtc_mode_fixup, ++ .mode_set = radeon_crtc_mode_set, ++ .mode_set_base = radeon_crtc_set_base, ++ .prepare = radeon_crtc_prepare, ++ .commit = radeon_crtc_commit, ++}; ++ ++ ++void radeon_legacy_init_crtc(struct drm_device *dev, ++ struct radeon_crtc *radeon_crtc) ++{ ++ drm_crtc_helper_add(&radeon_crtc->base, &legacy_helper_funcs); ++} ++ ++void radeon_init_disp_bw_legacy(struct drm_device *dev, ++ struct drm_display_mode *mode1, ++ uint32_t pixel_bytes1, ++ struct drm_display_mode *mode2, ++ uint32_t pixel_bytes2) ++ ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ fixed20_12 trcd_ff, trp_ff, tras_ff, trbs_ff, tcas_ff; ++ fixed20_12 sclk_ff, mclk_ff, sclk_eff_ff, sclk_delay_ff; ++ fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff; ++ uint32_t temp, data, mem_trcd, mem_trp, mem_tras; ++ fixed20_12 memtcas_ff[8] = { ++ fixed_init(1), ++ fixed_init(2), ++ fixed_init(3), ++ fixed_init(0), ++ fixed_init_half(1), ++ fixed_init_half(2), ++ fixed_init(0), ++ }; ++ fixed20_12 memtcas_rs480_ff[8] = { ++ fixed_init(0), ++ fixed_init(1), ++ fixed_init(2), ++ fixed_init(3), ++ fixed_init(0), ++ fixed_init_half(1), ++ fixed_init_half(2), ++ fixed_init_half(3), ++ }; ++ fixed20_12 memtcas2_ff[8] = { ++ fixed_init(0), ++ fixed_init(1), ++ fixed_init(2), ++ fixed_init(3), ++ fixed_init(4), ++ fixed_init(5), ++ fixed_init(6), ++ fixed_init(7), ++ }; ++ fixed20_12 memtrbs[8] = { ++ fixed_init(1), ++ fixed_init_half(1), ++ fixed_init(2), ++ fixed_init_half(2), ++ fixed_init(3), ++ fixed_init_half(3), ++ fixed_init(4), ++ fixed_init_half(4) ++ }; ++ fixed20_12 memtrbs_r4xx[8] = { ++ fixed_init(4), ++ fixed_init(5), ++ fixed_init(6), ++ fixed_init(7), ++ fixed_init(8), ++ fixed_init(9), ++ fixed_init(10), ++ fixed_init(11) ++ }; ++ fixed20_12 min_mem_eff; ++ fixed20_12 mc_latency_sclk, mc_latency_mclk, k1; ++ fixed20_12 cur_latency_mclk, cur_latency_sclk; ++ fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate, ++ disp_drain_rate2, read_return_rate; ++ fixed20_12 time_disp1_drop_priority; ++ int c; ++ int cur_size = 16; /* in octawords */ ++ int critical_point = 0, critical_point2; ++// uint32_t read_return_rate, time_disp1_drop_priority; ++ int stop_req, max_stop_req; ++ ++ min_mem_eff.full = rfixed_const_8(0); ++ /* get modes */ ++ if ((dev_priv->disp_priority == 2) && radeon_is_r300(dev_priv)) { ++ uint32_t mc_init_misc_lat_timer = RADEON_READ(R300_MC_INIT_MISC_LAT_TIMER); ++ mc_init_misc_lat_timer &= ~(R300_MC_DISP1R_INIT_LAT_MASK << R300_MC_DISP1R_INIT_LAT_SHIFT); ++ mc_init_misc_lat_timer &= ~(R300_MC_DISP0R_INIT_LAT_MASK << R300_MC_DISP0R_INIT_LAT_SHIFT); ++ /* check crtc enables */ ++ if (mode2) ++ mc_init_misc_lat_timer |= (1 << R300_MC_DISP1R_INIT_LAT_SHIFT); ++ if (mode1) ++ mc_init_misc_lat_timer |= (1 << R300_MC_DISP0R_INIT_LAT_SHIFT); ++ RADEON_WRITE(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer); ++ } ++ ++ /* ++ * determine is there is enough bw for current mode ++ */ ++ mclk_ff.full = rfixed_const(dev_priv->mode_info.mclk); ++ temp_ff.full = rfixed_const(100); ++ mclk_ff.full = rfixed_div(mclk_ff, temp_ff); ++ sclk_ff.full = rfixed_const(dev_priv->mode_info.sclk); ++ sclk_ff.full = rfixed_div(sclk_ff, temp_ff); ++ ++ temp = (dev_priv->ram_width / 8) * (dev_priv->is_ddr ? 2 : 1); ++ temp_ff.full = rfixed_const(temp); ++ mem_bw.full = rfixed_mul(mclk_ff, temp_ff); ++ ++ pix_clk.full = 0; ++ pix_clk2.full = 0; ++ peak_disp_bw.full = 0; ++ if (mode1) { ++ temp_ff.full = rfixed_const(1000); ++ pix_clk.full = rfixed_const(mode1->clock); /* convert to fixed point */ ++ pix_clk.full = rfixed_div(pix_clk, temp_ff); ++ temp_ff.full = rfixed_const(pixel_bytes1); ++ peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff); ++ } ++ if (mode2) { ++ temp_ff.full = rfixed_const(1000); ++ pix_clk2.full = rfixed_const(mode2->clock); /* convert to fixed point */ ++ pix_clk2.full = rfixed_div(pix_clk2, temp_ff); ++ temp_ff.full = rfixed_const(pixel_bytes2); ++ peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff); ++ } ++ ++ mem_bw.full = rfixed_mul(mem_bw, min_mem_eff); ++ if (peak_disp_bw.full >= mem_bw.full) { ++ DRM_ERROR("You may not have enough display bandwidth for current mode\n" ++ "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n"); ++ } ++ ++ /* Get values from the EXT_MEM_CNTL register...converting its contents. */ ++ temp = RADEON_READ(RADEON_MEM_TIMING_CNTL); ++ if ((dev_priv->chip_family == CHIP_RV100) || (dev_priv->flags & RADEON_IS_IGP)) { /* RV100, M6, IGPs */ ++ mem_trcd = ((temp >> 2) & 0x3) + 1; ++ mem_trp = ((temp & 0x3)) + 1; ++ mem_tras = ((temp & 0x70) >> 4) + 1; ++ } else if (dev_priv->chip_family == CHIP_R300 || ++ dev_priv->chip_family == CHIP_R350) { /* r300, r350 */ ++ mem_trcd = (temp & 0x7) + 1; ++ mem_trp = ((temp >> 8) & 0x7) + 1; ++ mem_tras = ((temp >> 11) & 0xf) + 4; ++ } else if (dev_priv->chip_family == CHIP_RV350 || ++ dev_priv->chip_family <= CHIP_RV380) { ++ /* rv3x0 */ ++ mem_trcd = (temp & 0x7) + 3; ++ mem_trp = ((temp >> 8) & 0x7) + 3; ++ mem_tras = ((temp >> 11) & 0xf) + 6; ++ } else if (dev_priv->chip_family == CHIP_R420 || ++ dev_priv->chip_family == CHIP_R423 || ++ dev_priv->chip_family == CHIP_RV410) { ++ /* r4xx */ ++ mem_trcd = (temp & 0xf) + 3; ++ if (mem_trcd > 15) ++ mem_trcd = 15; ++ mem_trp = ((temp >> 8) & 0xf) + 3; ++ if (mem_trp > 15) ++ mem_trp = 15; ++ mem_tras = ((temp >> 12) & 0x1f) + 6; ++ if (mem_tras > 31) ++ mem_tras = 31; ++ } else { /* RV200, R200 */ ++ mem_trcd = (temp & 0x7) + 1; ++ mem_trp = ((temp >> 8) & 0x7) + 1; ++ mem_tras = ((temp >> 12) & 0xf) + 4; ++ } ++ /* convert to FF */ ++ trcd_ff.full = rfixed_const(mem_trcd); ++ trp_ff.full = rfixed_const(mem_trp); ++ tras_ff.full = rfixed_const(mem_tras); ++ ++ /* Get values from the MEM_SDRAM_MODE_REG register...converting its */ ++ temp = RADEON_READ(RADEON_MEM_SDRAM_MODE_REG); ++ data = (temp & (7 << 20)) >> 20; ++ if ((dev_priv->chip_family == CHIP_RV100) || dev_priv->flags & RADEON_IS_IGP) { ++ if (dev_priv->chip_family == CHIP_RS480) /* don't think rs400 */ ++ tcas_ff = memtcas_rs480_ff[data]; ++ else ++ tcas_ff = memtcas_ff[data]; ++ } else ++ tcas_ff = memtcas2_ff[data]; ++ ++ if (dev_priv->chip_family == CHIP_RS400 || ++ dev_priv->chip_family == CHIP_RS480) { ++ /* extra cas latency stored in bits 23-25 0-4 clocks */ ++ data = (temp >> 23) & 0x7; ++ if (data < 5) ++ tcas_ff.full += rfixed_const(data); ++ } ++ ++ if (radeon_is_r300(dev_priv) && !(dev_priv->flags & RADEON_IS_IGP)) { ++ /* on the R300, Tcas is included in Trbs. ++ */ ++ temp = RADEON_READ(RADEON_MEM_CNTL); ++ data = (R300_MEM_NUM_CHANNELS_MASK & temp); ++ if (data == 1) { ++ if (R300_MEM_USE_CD_CH_ONLY & temp) { ++ temp = RADEON_READ(R300_MC_IND_INDEX); ++ temp &= ~R300_MC_IND_ADDR_MASK; ++ temp |= R300_MC_READ_CNTL_CD_mcind; ++ RADEON_WRITE(R300_MC_IND_INDEX, temp); ++ temp = RADEON_READ(R300_MC_IND_DATA); ++ data = (R300_MEM_RBS_POSITION_C_MASK & temp); ++ } else { ++ temp = RADEON_READ(R300_MC_READ_CNTL_AB); ++ data = (R300_MEM_RBS_POSITION_A_MASK & temp); ++ } ++ } else { ++ temp = RADEON_READ(R300_MC_READ_CNTL_AB); ++ data = (R300_MEM_RBS_POSITION_A_MASK & temp); ++ } ++ if (dev_priv->chip_family == CHIP_RV410 || ++ dev_priv->chip_family == CHIP_R420 || ++ dev_priv->chip_family == CHIP_R423) ++ trbs_ff = memtrbs_r4xx[data]; ++ else ++ trbs_ff = memtrbs[data]; ++ tcas_ff.full += trbs_ff.full; ++ } ++ ++ sclk_eff_ff.full = sclk_ff.full; ++ ++ if (dev_priv->flags & RADEON_IS_AGP) { ++ fixed20_12 agpmode_ff; ++ agpmode_ff.full = rfixed_const(radeon_agpmode); ++ temp_ff.full = rfixed_const_666(16); ++ sclk_eff_ff.full -= rfixed_mul(agpmode_ff, temp_ff); ++ } ++ /* TODO PCIE lanes may affect this - agpmode == 16?? */ ++ ++ if (radeon_is_r300(dev_priv)) { ++ sclk_delay_ff.full = rfixed_const(250); ++ } else { ++ if ((dev_priv->chip_family == CHIP_RV100) || ++ dev_priv->flags & RADEON_IS_IGP) { ++ if (dev_priv->is_ddr) ++ sclk_delay_ff.full = rfixed_const(41); ++ else ++ sclk_delay_ff.full = rfixed_const(33); ++ } else { ++ if (dev_priv->ram_width == 128) ++ sclk_delay_ff.full = rfixed_const(57); ++ else ++ sclk_delay_ff.full = rfixed_const(41); ++ } ++ } ++ ++ mc_latency_sclk.full = rfixed_div(sclk_delay_ff, sclk_eff_ff); ++ ++ if (dev_priv->is_ddr) { ++ if (dev_priv->ram_width == 32) { ++ k1.full = rfixed_const(40); ++ c = 3; ++ } else { ++ k1.full = rfixed_const(20); ++ c = 1; ++ } ++ } else { ++ k1.full = rfixed_const(40); ++ c = 3; ++ } ++ ++ temp_ff.full = rfixed_const(2); ++ mc_latency_mclk.full = rfixed_mul(trcd_ff, temp_ff); ++ temp_ff.full = rfixed_const(c); ++ mc_latency_mclk.full += rfixed_mul(tcas_ff, temp_ff); ++ temp_ff.full = rfixed_const(4); ++ mc_latency_mclk.full += rfixed_mul(tras_ff, temp_ff); ++ mc_latency_mclk.full += rfixed_mul(trp_ff, temp_ff); ++ mc_latency_mclk.full += k1.full; ++ ++ mc_latency_mclk.full = rfixed_div(mc_latency_mclk, mclk_ff); ++ mc_latency_mclk.full += rfixed_div(temp_ff, sclk_eff_ff); ++ ++ /* ++ HW cursor time assuming worst case of full size colour cursor. ++ */ ++ temp_ff.full = rfixed_const((2 * (cur_size - (dev_priv->is_ddr + 1)))); ++ temp_ff.full += trcd_ff.full; ++ if (temp_ff.full < tras_ff.full) ++ temp_ff.full = tras_ff.full; ++ cur_latency_mclk.full = rfixed_div(temp_ff, mclk_ff); ++ ++ temp_ff.full = rfixed_const(cur_size); ++ cur_latency_sclk.full = rfixed_div(temp_ff, sclk_eff_ff); ++ /* ++ Find the total latency for the display data. ++ */ ++ disp_latency_overhead.full = rfixed_const(80); ++ disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff); ++ mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full; ++ mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full; ++ ++ if (mc_latency_mclk.full > mc_latency_sclk.full) ++ disp_latency.full = mc_latency_mclk.full; ++ else ++ disp_latency.full = mc_latency_sclk.full; ++ ++ /* setup Max GRPH_STOP_REQ default value */ ++ if (radeon_is_rv100(dev_priv)) ++ max_stop_req = 0x5c; ++ else ++ max_stop_req = 0x7c; ++ ++ if (mode1) { ++ /* CRTC1 ++ Set GRPH_BUFFER_CNTL register using h/w defined optimal values. ++ GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ] ++ */ ++ stop_req = mode1->hdisplay * pixel_bytes1 / 16; ++ ++ if (stop_req > max_stop_req) ++ stop_req = max_stop_req; ++ ++ /* ++ Find the drain rate of the display buffer. ++ */ ++ temp_ff.full = rfixed_const((16/pixel_bytes1)); ++ disp_drain_rate.full = rfixed_div(pix_clk, temp_ff); ++ ++ /* ++ Find the critical point of the display buffer. ++ */ ++ crit_point_ff.full = rfixed_mul(disp_drain_rate, disp_latency); ++ crit_point_ff.full += rfixed_const_half(0); ++ ++ critical_point = rfixed_trunc(crit_point_ff); ++ ++ if (dev_priv->disp_priority == 2) { ++ critical_point = 0; ++ } ++ ++ /* ++ The critical point should never be above max_stop_req-4. Setting ++ GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time. ++ */ ++ if (max_stop_req - critical_point < 4) ++ critical_point = 0; ++ ++ if (critical_point == 0 && mode2 && dev_priv->chip_family == CHIP_R300) { ++ /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/ ++ critical_point = 0x10; ++ } ++ ++ temp = RADEON_READ(RADEON_GRPH_BUFFER_CNTL); ++ temp &= ~(RADEON_GRPH_STOP_REQ_MASK); ++ temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT); ++ temp &= ~(RADEON_GRPH_START_REQ_MASK); ++ if ((dev_priv->chip_family == CHIP_R350) && ++ (stop_req > 0x15)) { ++ stop_req -= 0x10; ++ } ++ temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT); ++ temp |= RADEON_GRPH_BUFFER_SIZE; ++ temp &= ~(RADEON_GRPH_CRITICAL_CNTL | ++ RADEON_GRPH_CRITICAL_AT_SOF | ++ RADEON_GRPH_STOP_CNTL); ++ /* ++ Write the result into the register. ++ */ ++ RADEON_WRITE(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) | ++ (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT))); ++ ++#if 0 ++ if ((dev_priv->chip_family == CHIP_RS400) || ++ (dev_priv->chip_family == CHIP_RS480)) { ++ /* attempt to program RS400 disp regs correctly ??? */ ++ temp = RADEON_READ(RS400_DISP1_REG_CNTL); ++ temp &= ~(RS400_DISP1_START_REQ_LEVEL_MASK | ++ RS400_DISP1_STOP_REQ_LEVEL_MASK); ++ RADEON_WRITE(RS400_DISP1_REQ_CNTL1, (temp | ++ (critical_point << RS400_DISP1_START_REQ_LEVEL_SHIFT) | ++ (critical_point << RS400_DISP1_STOP_REQ_LEVEL_SHIFT))); ++ temp = RADEON_READ(RS400_DMIF_MEM_CNTL1); ++ temp &= ~(RS400_DISP1_CRITICAL_POINT_START_MASK | ++ RS400_DISP1_CRITICAL_POINT_STOP_MASK); ++ RADEON_WRITE(RS400_DMIF_MEM_CNTL1, (temp | ++ (critical_point << RS400_DISP1_CRITICAL_POINT_START_SHIFT) | ++ (critical_point << RS400_DISP1_CRITICAL_POINT_STOP_SHIFT))); ++ } ++#endif ++ ++ DRM_DEBUG("GRPH_BUFFER_CNTL from to %x\n", ++ // (unsigned int)info->SavedReg->grph_buffer_cntl, ++ (unsigned int)RADEON_READ(RADEON_GRPH_BUFFER_CNTL)); ++ } ++ ++ if (mode2) { ++ stop_req = mode2->hdisplay * pixel_bytes2 / 16; ++ ++ if (stop_req > max_stop_req) ++ stop_req = max_stop_req; ++ ++ /* ++ Find the drain rate of the display buffer. ++ */ ++ temp_ff.full = rfixed_const((16/pixel_bytes2)); ++ disp_drain_rate2.full = rfixed_div(pix_clk2, temp_ff); ++ ++ temp = RADEON_READ(RADEON_GRPH2_BUFFER_CNTL); ++ temp &= ~(RADEON_GRPH_STOP_REQ_MASK); ++ temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT); ++ temp &= ~(RADEON_GRPH_START_REQ_MASK); ++ if ((dev_priv->chip_family == CHIP_R350) && ++ (stop_req > 0x15)) { ++ stop_req -= 0x10; ++ } ++ temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT); ++ temp |= RADEON_GRPH_BUFFER_SIZE; ++ temp &= ~(RADEON_GRPH_CRITICAL_CNTL | ++ RADEON_GRPH_CRITICAL_AT_SOF | ++ RADEON_GRPH_STOP_CNTL); ++ ++ if ((dev_priv->chip_family == CHIP_RS100) || ++ (dev_priv->chip_family == CHIP_RS200)) ++ critical_point2 = 0; ++ else { ++ temp = (dev_priv->ram_width * dev_priv->is_ddr + 1)/128; ++ temp_ff.full = rfixed_const(temp); ++ temp_ff.full = rfixed_mul(mclk_ff, temp_ff); ++ if (sclk_ff.full < temp_ff.full) ++ temp_ff.full = sclk_ff.full; ++ ++ read_return_rate.full = temp_ff.full; ++ ++ if (mode1) { ++ temp_ff.full = read_return_rate.full - disp_drain_rate.full; ++ time_disp1_drop_priority.full = rfixed_div(crit_point_ff, temp_ff); ++ } else ++ time_disp1_drop_priority.full = 0; ++ ++ crit_point_ff.full = disp_latency.full + time_disp1_drop_priority.full + disp_latency.full; ++ crit_point_ff.full = rfixed_mul(crit_point_ff, disp_drain_rate2); ++ crit_point_ff.full += rfixed_const_half(0); ++ ++ critical_point2 = rfixed_trunc(crit_point_ff); ++ ++ if (dev_priv->disp_priority == 2) { ++ critical_point2 = 0; ++ } ++ ++ if (max_stop_req - critical_point2 < 4) ++ critical_point2 = 0; ++ ++ } ++ ++ if (critical_point2 == 0 && dev_priv->chip_family == CHIP_R300) { ++ /* some R300 cards have problem with this set to 0 */ ++ critical_point2 = 0x10; ++ } ++ ++ RADEON_WRITE(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) | ++ (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT))); ++ ++ if ((dev_priv->chip_family == CHIP_RS400) || ++ (dev_priv->chip_family == CHIP_RS480)) { ++#if 0 ++ /* attempt to program RS400 disp2 regs correctly ??? */ ++ temp = RADEON_READ(RS400_DISP2_REQ_CNTL1); ++ temp &= ~(RS400_DISP2_START_REQ_LEVEL_MASK | ++ RS400_DISP2_STOP_REQ_LEVEL_MASK); ++ RADEON_WRITE(RS400_DISP2_REQ_CNTL1, (temp | ++ (critical_point2 << RS400_DISP1_START_REQ_LEVEL_SHIFT) | ++ (critical_point2 << RS400_DISP1_STOP_REQ_LEVEL_SHIFT))); ++ temp = RADEON_READ(RS400_DISP2_REQ_CNTL2); ++ temp &= ~(RS400_DISP2_CRITICAL_POINT_START_MASK | ++ RS400_DISP2_CRITICAL_POINT_STOP_MASK); ++ RADEON_WRITE(RS400_DISP2_REQ_CNTL2, (temp | ++ (critical_point2 << RS400_DISP2_CRITICAL_POINT_START_SHIFT) | ++ (critical_point2 << RS400_DISP2_CRITICAL_POINT_STOP_SHIFT))); ++#endif ++ RADEON_WRITE(RS400_DISP2_REQ_CNTL1, 0x105DC1CC); ++ RADEON_WRITE(RS400_DISP2_REQ_CNTL2, 0x2749D000); ++ RADEON_WRITE(RS400_DMIF_MEM_CNTL1, 0x29CA71DC); ++ RADEON_WRITE(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC); ++ } ++ ++ DRM_DEBUG("GRPH2_BUFFER_CNTL from to %x\n", ++// (unsigned int)info->SavedReg->grph2_buffer_cntl, ++ (unsigned int)RADEON_READ(RADEON_GRPH2_BUFFER_CNTL)); ++ } ++} ++ ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_legacy_encoders.c 2009-04-26 03:01:57.163975160 +0200 +@@ -0,0 +1,1284 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "drm_crtc_helper.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++ ++static void radeon_legacy_rmx_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ int xres = mode->hdisplay; ++ int yres = mode->vdisplay; ++ bool hscale = true, vscale = true; ++ int hsync_wid; ++ int vsync_wid; ++ int hsync_start; ++ uint32_t scale, inc; ++ uint32_t fp_horz_stretch, fp_vert_stretch, crtc_more_cntl, fp_horz_vert_active; ++ uint32_t fp_h_sync_strt_wid, fp_v_sync_strt_wid, fp_crtc_h_total_disp, fp_crtc_v_total_disp; ++ struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; ++ ++ DRM_DEBUG("\n"); ++ ++ fp_vert_stretch = RADEON_READ(RADEON_FP_VERT_STRETCH) & ++ (RADEON_VERT_STRETCH_RESERVED | ++ RADEON_VERT_AUTO_RATIO_INC); ++ fp_horz_stretch = RADEON_READ(RADEON_FP_HORZ_STRETCH) & ++ (RADEON_HORZ_FP_LOOP_STRETCH | ++ RADEON_HORZ_AUTO_RATIO_INC); ++ ++ crtc_more_cntl = 0; ++ if ((dev_priv->chip_family == CHIP_RS100) || ++ (dev_priv->chip_family == CHIP_RS200)) { ++ /* This is to workaround the asic bug for RMX, some versions ++ of BIOS dosen't have this register initialized correctly. */ ++ crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN; ++ } ++ ++ ++ fp_crtc_h_total_disp = ((((mode->crtc_htotal / 8) - 1) & 0x3ff) ++ | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16)); ++ ++ hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8; ++ if (!hsync_wid) ++ hsync_wid = 1; ++ hsync_start = mode->crtc_hsync_start - 8; ++ ++ fp_h_sync_strt_wid = ((hsync_start & 0x1fff) ++ | ((hsync_wid & 0x3f) << 16) ++ | ((mode->flags & DRM_MODE_FLAG_NHSYNC) ++ ? RADEON_CRTC_H_SYNC_POL ++ : 0)); ++ ++ fp_crtc_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff) ++ | ((mode->crtc_vdisplay - 1) << 16)); ++ ++ vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start; ++ if (!vsync_wid) ++ vsync_wid = 1; ++ ++ fp_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff) ++ | ((vsync_wid & 0x1f) << 16) ++ | ((mode->flags & DRM_MODE_FLAG_NVSYNC) ++ ? RADEON_CRTC_V_SYNC_POL ++ : 0)); ++ ++ fp_horz_vert_active = 0; ++ ++ if (native_mode->panel_xres == 0 || ++ native_mode->panel_yres == 0) { ++ hscale = false; ++ vscale = false; ++ } else { ++ if (xres > native_mode->panel_xres) ++ xres = native_mode->panel_xres; ++ if (yres > native_mode->panel_yres) ++ yres = native_mode->panel_yres; ++ ++ if (xres == native_mode->panel_xres) ++ hscale = false; ++ if (yres == native_mode->panel_yres) ++ vscale = false; ++ } ++ ++ if (radeon_encoder->flags & RADEON_USE_RMX) { ++ if (radeon_encoder->rmx_type != RMX_CENTER) { ++ if (!hscale) ++ fp_horz_stretch |= ((xres/8-1) << 16); ++ else { ++ inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0; ++ scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX) ++ / native_mode->panel_xres + 1; ++ fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) | ++ RADEON_HORZ_STRETCH_BLEND | ++ RADEON_HORZ_STRETCH_ENABLE | ++ ((native_mode->panel_xres/8-1) << 16)); ++ } ++ ++ if (!vscale) ++ fp_vert_stretch |= ((yres-1) << 12); ++ else { ++ inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0; ++ scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX) ++ / native_mode->panel_yres + 1; ++ fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) | ++ RADEON_VERT_STRETCH_ENABLE | ++ RADEON_VERT_STRETCH_BLEND | ++ ((native_mode->panel_yres-1) << 12)); ++ } ++ } else if (radeon_encoder->rmx_type == RMX_CENTER) { ++ int blank_width; ++ ++ fp_horz_stretch |= ((xres/8-1) << 16); ++ fp_vert_stretch |= ((yres-1) << 12); ++ ++ crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN | ++ RADEON_CRTC_AUTO_VERT_CENTER_EN); ++ ++ blank_width = (mode->crtc_hblank_end - mode->crtc_hblank_start) / 8; ++ if (blank_width > 110) ++ blank_width = 110; ++ ++ fp_crtc_h_total_disp = (((blank_width) & 0x3ff) ++ | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16)); ++ ++ hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8; ++ if (!hsync_wid) ++ hsync_wid = 1; ++ ++ fp_h_sync_strt_wid = ((((mode->crtc_hsync_start - mode->crtc_hblank_start) / 8) & 0x1fff) ++ | ((hsync_wid & 0x3f) << 16) ++ | ((mode->flags & DRM_MODE_FLAG_NHSYNC) ++ ? RADEON_CRTC_H_SYNC_POL ++ : 0)); ++ ++ fp_crtc_v_total_disp = (((mode->crtc_vblank_end - mode->crtc_vblank_start) & 0xffff) ++ | ((mode->crtc_vdisplay - 1) << 16)); ++ ++ vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start; ++ if (!vsync_wid) ++ vsync_wid = 1; ++ ++ fp_v_sync_strt_wid = ((((mode->crtc_vsync_start - mode->crtc_vblank_start) & 0xfff) ++ | ((vsync_wid & 0x1f) << 16) ++ | ((mode->flags & DRM_MODE_FLAG_NVSYNC) ++ ? RADEON_CRTC_V_SYNC_POL ++ : 0))); ++ ++ fp_horz_vert_active = (((native_mode->panel_yres) & 0xfff) | ++ (((native_mode->panel_xres / 8) & 0x1ff) << 16)); ++ } ++ } else { ++ fp_horz_stretch |= ((xres/8-1) << 16); ++ fp_vert_stretch |= ((yres-1) << 12); ++ } ++ ++ RADEON_WRITE(RADEON_FP_HORZ_STRETCH, fp_horz_stretch); ++ RADEON_WRITE(RADEON_FP_VERT_STRETCH, fp_vert_stretch); ++ RADEON_WRITE(RADEON_CRTC_MORE_CNTL, crtc_more_cntl); ++ RADEON_WRITE(RADEON_FP_HORZ_VERT_ACTIVE, fp_horz_vert_active); ++ RADEON_WRITE(RADEON_FP_H_SYNC_STRT_WID, fp_h_sync_strt_wid); ++ RADEON_WRITE(RADEON_FP_V_SYNC_STRT_WID, fp_v_sync_strt_wid); ++ RADEON_WRITE(RADEON_FP_CRTC_H_TOTAL_DISP, fp_crtc_h_total_disp); ++ RADEON_WRITE(RADEON_FP_CRTC_V_TOTAL_DISP, fp_crtc_v_total_disp); ++ ++} ++ ++static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; ++ int panel_pwr_delay = 2000; ++ DRM_DEBUG("\n"); ++ ++ if (radeon_encoder->enc_priv) { ++ if (dev_priv->is_atom_bios) { ++ struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; ++ panel_pwr_delay = lvds->panel_pwr_delay; ++ } else { ++ struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; ++ panel_pwr_delay = lvds->panel_pwr_delay; ++ } ++ } ++ ++ switch (mode) { ++ case DRM_MODE_DPMS_ON: ++ disp_pwr_man = RADEON_READ(RADEON_DISP_PWR_MAN); ++ disp_pwr_man |= RADEON_AUTO_PWRUP_EN; ++ RADEON_WRITE(RADEON_DISP_PWR_MAN, disp_pwr_man); ++ lvds_pll_cntl = RADEON_READ(RADEON_LVDS_PLL_CNTL); ++ lvds_pll_cntl |= RADEON_LVDS_PLL_EN; ++ RADEON_WRITE(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); ++ udelay(1000); ++ ++ lvds_pll_cntl = RADEON_READ(RADEON_LVDS_PLL_CNTL); ++ lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; ++ RADEON_WRITE(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); ++ ++ lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL); ++ lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | RADEON_LVDS_DIGON | RADEON_LVDS_BLON); ++ lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); ++ udelay(panel_pwr_delay * 1000); ++ RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); ++ break; ++ case DRM_MODE_DPMS_STANDBY: ++ case DRM_MODE_DPMS_SUSPEND: ++ case DRM_MODE_DPMS_OFF: ++ pixclks_cntl = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); ++ RADEON_WRITE_PLL_P(dev_priv, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); ++ lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL); ++ lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; ++ lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); ++ udelay(panel_pwr_delay * 1000); ++ RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); ++ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, pixclks_cntl); ++ break; ++ } ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++ else ++ radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++} ++ ++static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, true); ++ else ++ radeon_combios_output_lock(encoder, true); ++ radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); ++} ++ ++static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ ++ radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON); ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, false); ++ else ++ radeon_combios_output_lock(encoder, false); ++} ++ ++static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl; ++ ++ DRM_DEBUG("\n"); ++ ++ if (radeon_crtc->crtc_id == 0) ++ radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode); ++ ++ lvds_pll_cntl = RADEON_READ(RADEON_LVDS_PLL_CNTL); ++ lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; ++ ++ lvds_ss_gen_cntl = RADEON_READ(RADEON_LVDS_SS_GEN_CNTL); ++ if ((!dev_priv->is_atom_bios)) { ++ struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; ++ if (lvds) { ++ DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); ++ lvds_gen_cntl = lvds->lvds_gen_cntl; ++ lvds_ss_gen_cntl &= ~((0xf << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) | ++ (0xf << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); ++ lvds_ss_gen_cntl |= ((lvds->panel_digon_delay << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) | ++ (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); ++ } else ++ lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL); ++ } else ++ lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL); ++ lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; ++ lvds_gen_cntl &= ~(RADEON_LVDS_ON | ++ RADEON_LVDS_BLON | ++ RADEON_LVDS_EN | ++ RADEON_LVDS_RST_FM); ++ ++ if (radeon_is_r300(dev_priv)) ++ lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK); ++ ++ if (radeon_crtc->crtc_id == 0) { ++ if (radeon_is_r300(dev_priv)) { ++ if (radeon_encoder->flags & RADEON_USE_RMX) ++ lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX; ++ } else ++ lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2; ++ } else { ++ if (radeon_is_r300(dev_priv)) ++ lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2; ++ else ++ lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2; ++ } ++ ++ RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); ++ RADEON_WRITE(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); ++ RADEON_WRITE(RADEON_LVDS_SS_GEN_CNTL, lvds_ss_gen_cntl); ++ ++ if (dev_priv->chip_family == CHIP_RV410) ++ RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, 0); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++ else ++ radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++} ++ ++static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ ++ drm_mode_set_crtcinfo(adjusted_mode, 0); ++ ++ radeon_encoder->flags &= ~RADEON_USE_RMX; ++ ++ if (radeon_encoder->rmx_type != RMX_OFF) ++ radeon_rmx_mode_fixup(encoder, mode, adjusted_mode); ++ ++ return true; ++} ++ ++static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { ++ .dpms = radeon_legacy_lvds_dpms, ++ .mode_fixup = radeon_legacy_lvds_mode_fixup, ++ .prepare = radeon_legacy_lvds_prepare, ++ .mode_set = radeon_legacy_lvds_mode_set, ++ .commit = radeon_legacy_lvds_commit, ++}; ++ ++ ++static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = { ++ .destroy = radeon_enc_destroy, ++}; ++ ++static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ ++ drm_mode_set_crtcinfo(adjusted_mode, 0); ++ ++ return true; ++} ++ ++static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL); ++ uint32_t dac_cntl = RADEON_READ(RADEON_DAC_CNTL); ++ uint32_t dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL); ++ ++ DRM_DEBUG("\n"); ++ ++ switch(mode) { ++ case DRM_MODE_DPMS_ON: ++ crtc_ext_cntl |= RADEON_CRTC_CRT_ON; ++ dac_cntl &= ~RADEON_DAC_PDWN; ++ dac_macro_cntl &= ~(RADEON_DAC_PDWN_R | ++ RADEON_DAC_PDWN_G | ++ RADEON_DAC_PDWN_B); ++ break; ++ case DRM_MODE_DPMS_STANDBY: ++ case DRM_MODE_DPMS_SUSPEND: ++ case DRM_MODE_DPMS_OFF: ++ crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; ++ dac_cntl |= RADEON_DAC_PDWN; ++ dac_macro_cntl |= (RADEON_DAC_PDWN_R | ++ RADEON_DAC_PDWN_G | ++ RADEON_DAC_PDWN_B); ++ break; ++ } ++ ++ RADEON_WRITE(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); ++ RADEON_WRITE(RADEON_DAC_CNTL, dac_cntl); ++ RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++ else ++ radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++} ++ ++static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, true); ++ else ++ radeon_combios_output_lock(encoder, true); ++ radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); ++} ++ ++static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ ++ radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, false); ++ else ++ radeon_combios_output_lock(encoder, false); ++} ++ ++static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl; ++ ++ DRM_DEBUG("\n"); ++ ++ if (radeon_crtc->crtc_id == 0) ++ radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode); ++ ++ if (radeon_crtc->crtc_id == 0) { ++ if (dev_priv->chip_family == CHIP_R200 || radeon_is_r300(dev_priv)) { ++ disp_output_cntl = RADEON_READ(RADEON_DISP_OUTPUT_CNTL) & ++ ~(RADEON_DISP_DAC_SOURCE_MASK); ++ RADEON_WRITE(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); ++ } else { ++ dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2) & ~(RADEON_DAC2_DAC_CLK_SEL); ++ RADEON_WRITE(RADEON_DAC_CNTL2, dac2_cntl); ++ } ++ } else { ++ if (dev_priv->chip_family == CHIP_R200 || radeon_is_r300(dev_priv)) { ++ disp_output_cntl = RADEON_READ(RADEON_DISP_OUTPUT_CNTL) & ++ ~(RADEON_DISP_DAC_SOURCE_MASK); ++ disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2; ++ RADEON_WRITE(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); ++ } else { ++ dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC_CLK_SEL; ++ RADEON_WRITE(RADEON_DAC_CNTL2, dac2_cntl); ++ } ++ } ++ ++ dac_cntl = (RADEON_DAC_MASK_ALL | ++ RADEON_DAC_VGA_ADR_EN | ++ /* TODO 6-bits */ ++ RADEON_DAC_8BIT_EN); ++ ++ RADEON_WRITE_P(RADEON_DAC_CNTL, ++ dac_cntl, ++ RADEON_DAC_RANGE_CNTL | ++ RADEON_DAC_BLANKING); ++ ++ if (radeon_encoder->enc_priv) { ++ struct radeon_encoder_primary_dac *p_dac = (struct radeon_encoder_primary_dac *)radeon_encoder->enc_priv; ++ dac_macro_cntl = p_dac->ps2_pdac_adj; ++ } else ++ dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL); ++ dac_macro_cntl |= RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B; ++ RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++ else ++ radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++} ++ ++static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t vclk_ecp_cntl, crtc_ext_cntl; ++ uint32_t dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp; ++ enum drm_connector_status found = connector_status_disconnected; ++ bool color = true; ++ ++ /* save the regs we need */ ++ vclk_ecp_cntl = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); ++ crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL); ++ dac_ext_cntl = RADEON_READ(RADEON_DAC_EXT_CNTL); ++ dac_cntl = RADEON_READ(RADEON_DAC_CNTL); ++ dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL); ++ ++ tmp = vclk_ecp_cntl & ++ ~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb); ++ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); ++ ++ tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; ++ RADEON_WRITE(RADEON_CRTC_EXT_CNTL, tmp); ++ ++ tmp = RADEON_DAC_FORCE_BLANK_OFF_EN | ++ RADEON_DAC_FORCE_DATA_EN; ++ ++ if (color) ++ tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB; ++ else ++ tmp |= RADEON_DAC_FORCE_DATA_SEL_G; ++ ++ if (radeon_is_r300(dev_priv)) ++ tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); ++ else ++ tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); ++ ++ RADEON_WRITE(RADEON_DAC_EXT_CNTL, tmp); ++ ++ tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN); ++ tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; ++ RADEON_WRITE(RADEON_DAC_CNTL, tmp); ++ ++ tmp &= ~(RADEON_DAC_PDWN_R | ++ RADEON_DAC_PDWN_G | ++ RADEON_DAC_PDWN_B); ++ ++ RADEON_WRITE(RADEON_DAC_MACRO_CNTL, tmp); ++ ++ udelay(2000); ++ ++ if (RADEON_READ(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) ++ found = connector_status_connected; ++ ++ /* restore the regs we used */ ++ RADEON_WRITE(RADEON_DAC_CNTL, dac_cntl); ++ RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); ++ RADEON_WRITE(RADEON_DAC_EXT_CNTL, dac_ext_cntl); ++ RADEON_WRITE(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); ++ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl); ++ ++ return found; ++} ++ ++static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = { ++ .dpms = radeon_legacy_primary_dac_dpms, ++ .mode_fixup = radeon_legacy_primary_dac_mode_fixup, ++ .prepare = radeon_legacy_primary_dac_prepare, ++ .mode_set = radeon_legacy_primary_dac_mode_set, ++ .commit = radeon_legacy_primary_dac_commit, ++ .detect = radeon_legacy_primary_dac_detect, ++}; ++ ++ ++static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = { ++ .destroy = radeon_enc_destroy, ++}; ++ ++static bool radeon_legacy_tmds_int_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ ++ drm_mode_set_crtcinfo(adjusted_mode, 0); ++ ++ return true; ++} ++ ++static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t fp_gen_cntl = RADEON_READ(RADEON_FP_GEN_CNTL); ++ DRM_DEBUG("\n"); ++ ++ switch(mode) { ++ case DRM_MODE_DPMS_ON: ++ fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); ++ break; ++ case DRM_MODE_DPMS_STANDBY: ++ case DRM_MODE_DPMS_SUSPEND: ++ case DRM_MODE_DPMS_OFF: ++ fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); ++ break; ++ } ++ ++ RADEON_WRITE(RADEON_FP_GEN_CNTL, fp_gen_cntl); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++ else ++ radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++} ++ ++static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, true); ++ else ++ radeon_combios_output_lock(encoder, true); ++ radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); ++} ++ ++static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ ++ radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, true); ++ else ++ radeon_combios_output_lock(encoder, true); ++} ++ ++static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl; ++ int i; ++ ++ DRM_DEBUG("\n"); ++ ++ if (radeon_crtc->crtc_id == 0) ++ radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode); ++ ++ tmp = tmds_pll_cntl = RADEON_READ(RADEON_TMDS_PLL_CNTL); ++ tmp &= 0xfffff; ++ if (dev_priv->chip_family == CHIP_RV280) { ++ /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ ++ tmp ^= (1 << 22); ++ tmds_pll_cntl ^= (1 << 22); ++ } ++ ++ if (radeon_encoder->enc_priv) { ++ struct radeon_encoder_int_tmds *tmds = (struct radeon_encoder_int_tmds *)radeon_encoder->enc_priv; ++ ++ for (i = 0; i < 4; i++) { ++ if (tmds->tmds_pll[i].freq == 0) ++ break; ++ if ((uint32_t)(mode->clock / 10) < tmds->tmds_pll[i].freq) { ++ tmp = tmds->tmds_pll[i].value ; ++ break; ++ } ++ } ++ } ++ ++ if (radeon_is_r300(dev_priv) || (dev_priv->chip_family == CHIP_RV280)) { ++ if (tmp & 0xfff00000) ++ tmds_pll_cntl = tmp; ++ else { ++ tmds_pll_cntl &= 0xfff00000; ++ tmds_pll_cntl |= tmp; ++ } ++ } else ++ tmds_pll_cntl = tmp; ++ ++ tmds_transmitter_cntl = RADEON_READ(RADEON_TMDS_TRANSMITTER_CNTL) & ++ ~(RADEON_TMDS_TRANSMITTER_PLLRST); ++ ++ if (dev_priv->chip_family == CHIP_R200 || ++ dev_priv->chip_family == CHIP_R100 || ++ radeon_is_r300(dev_priv)) ++ tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN); ++ else /* RV chips got this bit reversed */ ++ tmds_transmitter_cntl |= RADEON_TMDS_TRANSMITTER_PLLEN; ++ ++ fp_gen_cntl = (RADEON_READ(RADEON_FP_GEN_CNTL) | ++ (RADEON_FP_CRTC_DONT_SHADOW_VPAR | ++ RADEON_FP_CRTC_DONT_SHADOW_HEND)); ++ ++ fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); ++ ++ if (1) // FIXME rgbBits == 8 ++ fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ ++ else ++ fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */ ++ ++ if (radeon_crtc->crtc_id == 0) { ++ if (radeon_is_r300(dev_priv) || dev_priv->chip_family == CHIP_R200) { ++ fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; ++ if (radeon_encoder->flags & RADEON_USE_RMX) ++ fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX; ++ else ++ fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; ++ } else ++ fp_gen_cntl |= RADEON_FP_SEL_CRTC1; ++ } else { ++ if (radeon_is_r300(dev_priv) || dev_priv->chip_family == CHIP_R200) { ++ fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; ++ fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2; ++ } else ++ fp_gen_cntl |= RADEON_FP_SEL_CRTC2; ++ } ++ ++ RADEON_WRITE(RADEON_TMDS_PLL_CNTL, tmds_pll_cntl); ++ RADEON_WRITE(RADEON_TMDS_TRANSMITTER_CNTL, tmds_transmitter_cntl); ++ RADEON_WRITE(RADEON_FP_GEN_CNTL, fp_gen_cntl); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++ else ++ radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++} ++ ++static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = { ++ .dpms = radeon_legacy_tmds_int_dpms, ++ .mode_fixup = radeon_legacy_tmds_int_mode_fixup, ++ .prepare = radeon_legacy_tmds_int_prepare, ++ .mode_set = radeon_legacy_tmds_int_mode_set, ++ .commit = radeon_legacy_tmds_int_commit, ++}; ++ ++ ++static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = { ++ .destroy = radeon_enc_destroy, ++}; ++ ++static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ ++ drm_mode_set_crtcinfo(adjusted_mode, 0); ++ ++ return true; ++} ++ ++static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL); ++ DRM_DEBUG("\n"); ++ ++ switch(mode) { ++ case DRM_MODE_DPMS_ON: ++ fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; ++ fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); ++ break; ++ case DRM_MODE_DPMS_STANDBY: ++ case DRM_MODE_DPMS_SUSPEND: ++ case DRM_MODE_DPMS_OFF: ++ fp2_gen_cntl |= RADEON_FP2_BLANK_EN; ++ fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); ++ break; ++ } ++ ++ RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++ else ++ radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++} ++ ++static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, true); ++ else ++ radeon_combios_output_lock(encoder, true); ++ radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); ++} ++ ++static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, false); ++ else ++ radeon_combios_output_lock(encoder, false); ++} ++ ++static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t fp2_gen_cntl; ++ ++ DRM_DEBUG("\n"); ++ ++ if (radeon_crtc->crtc_id == 0) ++ radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode); ++ ++ if (dev_priv->is_atom_bios) { ++ radeon_encoder->pixel_clock = adjusted_mode->clock; ++ atombios_external_tmds_setup(encoder, ATOM_ENABLE); ++ fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL); ++ } else { ++ fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL); ++ ++ if (1) // FIXME rgbBits == 8 ++ fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */ ++ else ++ fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */ ++ ++ fp2_gen_cntl &= ~(RADEON_FP2_ON | ++ RADEON_FP2_DVO_EN | ++ RADEON_FP2_DVO_RATE_SEL_SDR); ++ ++ /* XXX: these are oem specific */ ++ if (radeon_is_r300(dev_priv)) { ++ if ((dev->pdev->device == 0x4850) && ++ (dev->pdev->subsystem_vendor == 0x1028) && ++ (dev->pdev->subsystem_device == 0x2001)) /* Dell Inspiron 8600 */ ++ fp2_gen_cntl |= R300_FP2_DVO_CLOCK_MODE_SINGLE; ++ else ++ fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE; ++ ++ /*if (mode->clock > 165000) ++ fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/ ++ } ++ } ++ ++ if (radeon_crtc->crtc_id == 0) { ++ if ((dev_priv->chip_family == CHIP_R200) || radeon_is_r300(dev_priv)) { ++ fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK; ++ if (radeon_encoder->flags & RADEON_USE_RMX) ++ fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; ++ else ++ fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1; ++ } else ++ fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2; ++ } else { ++ if ((dev_priv->chip_family == CHIP_R200) || radeon_is_r300(dev_priv)) { ++ fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK; ++ fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; ++ } else ++ fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2; ++ } ++ ++ RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++ else ++ radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++} ++ ++static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = { ++ .dpms = radeon_legacy_tmds_ext_dpms, ++ .mode_fixup = radeon_legacy_tmds_ext_mode_fixup, ++ .prepare = radeon_legacy_tmds_ext_prepare, ++ .mode_set = radeon_legacy_tmds_ext_mode_set, ++ .commit = radeon_legacy_tmds_ext_commit, ++}; ++ ++ ++static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = { ++ .destroy = radeon_enc_destroy, ++}; ++ ++static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ ++ drm_mode_set_crtcinfo(adjusted_mode, 0); ++ ++ return true; ++} ++ ++static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; ++ //uint32_t tv_master_cntl = 0; ++ ++ DRM_DEBUG("\n"); ++ ++ if (dev_priv->chip_family == CHIP_R200) ++ fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL); ++ else { ++ crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL); ++ // FIXME TV ++ //tv_master_cntl = RADEON_READ(RADEON_TV_MASTER_CNTL); ++ tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL); ++ } ++ ++ switch(mode) { ++ case DRM_MODE_DPMS_ON: ++ if (dev_priv->chip_family == CHIP_R200) ++ fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); ++ else { ++ crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; ++ //tv_master_cntl |= RADEON_TV_ON; ++ if (dev_priv->chip_family == CHIP_R420 || ++ dev_priv->chip_family == CHIP_R423 || ++ dev_priv->chip_family == CHIP_RV410) ++ tv_dac_cntl &= ~(R420_TV_DAC_RDACPD | ++ R420_TV_DAC_GDACPD | ++ R420_TV_DAC_BDACPD | ++ RADEON_TV_DAC_BGSLEEP); ++ else ++ tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD | ++ RADEON_TV_DAC_GDACPD | ++ RADEON_TV_DAC_BDACPD | ++ RADEON_TV_DAC_BGSLEEP); ++ } ++ break; ++ case DRM_MODE_DPMS_STANDBY: ++ case DRM_MODE_DPMS_SUSPEND: ++ case DRM_MODE_DPMS_OFF: ++ if (dev_priv->chip_family == CHIP_R200) ++ fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); ++ else { ++ crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; ++ //tv_master_cntl &= ~RADEON_TV_ON; ++ if (dev_priv->chip_family == CHIP_R420 || ++ dev_priv->chip_family == CHIP_R423 || ++ dev_priv->chip_family == CHIP_RV410) ++ tv_dac_cntl |= (R420_TV_DAC_RDACPD | ++ R420_TV_DAC_GDACPD | ++ R420_TV_DAC_BDACPD | ++ RADEON_TV_DAC_BGSLEEP); ++ else ++ tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | ++ RADEON_TV_DAC_GDACPD | ++ RADEON_TV_DAC_BDACPD | ++ RADEON_TV_DAC_BGSLEEP); ++ } ++ break; ++ } ++ ++ if (dev_priv->chip_family == CHIP_R200) ++ RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); ++ else { ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); ++ //RADEON_WRITE(RADEON_TV_MASTER_CNTL, tv_master_cntl); ++ RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl); ++ } ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++ else ++ radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); ++} ++ ++static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, true); ++ else ++ radeon_combios_output_lock(encoder, true); ++ radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); ++} ++ ++static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) ++{ ++ struct drm_radeon_private *dev_priv = encoder->dev->dev_private; ++ ++ radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atom_output_lock(encoder, true); ++ else ++ radeon_combios_output_lock(encoder, true); ++} ++ ++static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); ++ uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0; ++ uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0; ++ ++ DRM_DEBUG("\n"); ++ ++ if (radeon_crtc->crtc_id == 0) ++ radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode); ++ ++ if (dev_priv->chip_family != CHIP_R200) { ++ tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL); ++ if (dev_priv->chip_family == CHIP_R420 || ++ dev_priv->chip_family == CHIP_R423 || ++ dev_priv->chip_family == CHIP_RV410) { ++ tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | ++ RADEON_TV_DAC_BGADJ_MASK | ++ R420_TV_DAC_DACADJ_MASK | ++ R420_TV_DAC_RDACPD | ++ R420_TV_DAC_GDACPD | ++ R420_TV_DAC_GDACPD | ++ R420_TV_DAC_TVENABLE); ++ } else { ++ tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | ++ RADEON_TV_DAC_BGADJ_MASK | ++ RADEON_TV_DAC_DACADJ_MASK | ++ RADEON_TV_DAC_RDACPD | ++ RADEON_TV_DAC_GDACPD | ++ RADEON_TV_DAC_GDACPD); ++ } ++ ++ // FIXME TV ++ if (radeon_encoder->enc_priv) { ++ struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; ++ tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | ++ RADEON_TV_DAC_NHOLD | ++ RADEON_TV_DAC_STD_PS2 | ++ tv_dac->ps2_tvdac_adj); ++ } else ++ tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | ++ RADEON_TV_DAC_NHOLD | ++ RADEON_TV_DAC_STD_PS2); ++ ++ RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl); ++ } ++ ++ if (radeon_is_r300(dev_priv)) { ++ gpiopad_a = RADEON_READ(RADEON_GPIOPAD_A) | 1; ++ disp_output_cntl = RADEON_READ(RADEON_DISP_OUTPUT_CNTL); ++ } else if (dev_priv->chip_family == CHIP_R200) ++ fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL); ++ else ++ disp_hw_debug = RADEON_READ(RADEON_DISP_HW_DEBUG); ++ ++ dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL; ++ ++ if (radeon_crtc->crtc_id == 0) { ++ if (radeon_is_r300(dev_priv)) { ++ disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; ++ disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC; ++ } else if (dev_priv->chip_family == CHIP_R200) { ++ fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | ++ RADEON_FP2_DVO_RATE_SEL_SDR); ++ } else ++ disp_hw_debug |= RADEON_CRT2_DISP1_SEL; ++ } else { ++ if (radeon_is_r300(dev_priv)) { ++ disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; ++ disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2; ++ } else if (dev_priv->chip_family == CHIP_R200) { ++ fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | ++ RADEON_FP2_DVO_RATE_SEL_SDR); ++ fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; ++ } else ++ disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; ++ } ++ ++ RADEON_WRITE(RADEON_DAC_CNTL2, dac2_cntl); ++ ++ if (radeon_is_r300(dev_priv)) { ++ RADEON_WRITE_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); ++ RADEON_WRITE(RADEON_DISP_TV_OUT_CNTL, disp_output_cntl); ++ } else if (dev_priv->chip_family == CHIP_R200) ++ RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); ++ else ++ RADEON_WRITE(RADEON_DISP_HW_DEBUG, disp_hw_debug); ++ ++ if (dev_priv->is_atom_bios) ++ radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++ else ++ radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); ++ ++} ++ ++static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; ++ uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; ++ enum drm_connector_status found = connector_status_disconnected; ++ bool color = true; ++ ++ // FIXME tv ++ ++ /* save the regs we need */ ++ pixclks_cntl = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); ++ gpiopad_a = radeon_is_r300(dev_priv) ? RADEON_READ(RADEON_GPIOPAD_A) : 0; ++ disp_output_cntl = radeon_is_r300(dev_priv) ? RADEON_READ(RADEON_DISP_OUTPUT_CNTL) : 0; ++ disp_hw_debug = radeon_is_r300(dev_priv) ? 0 : RADEON_READ(RADEON_DISP_HW_DEBUG); ++ crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL); ++ tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL); ++ dac_ext_cntl = RADEON_READ(RADEON_DAC_EXT_CNTL); ++ dac_cntl2 = RADEON_READ(RADEON_DAC_CNTL2); ++ ++ tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb ++ | RADEON_PIX2CLK_DAC_ALWAYS_ONb); ++ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); ++ ++ if (radeon_is_r300(dev_priv)) ++ RADEON_WRITE_P(RADEON_GPIOPAD_A, 1, ~1); ++ ++ tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; ++ tmp |= RADEON_CRTC2_CRT2_ON | ++ (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); ++ ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, tmp); ++ ++ if (radeon_is_r300(dev_priv)) { ++ tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; ++ tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; ++ RADEON_WRITE(RADEON_DISP_OUTPUT_CNTL, tmp); ++ } else { ++ tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; ++ RADEON_WRITE(RADEON_DISP_HW_DEBUG, tmp); ++ } ++ ++ tmp = RADEON_TV_DAC_NBLANK | ++ RADEON_TV_DAC_NHOLD | ++ RADEON_TV_MONITOR_DETECT_EN | ++ RADEON_TV_DAC_STD_PS2; ++ ++ RADEON_WRITE(RADEON_TV_DAC_CNTL, tmp); ++ ++ tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN | ++ RADEON_DAC2_FORCE_DATA_EN; ++ ++ if (color) ++ tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB; ++ else ++ tmp |= RADEON_DAC_FORCE_DATA_SEL_G; ++ ++ if (radeon_is_r300(dev_priv)) ++ tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); ++ else ++ tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); ++ ++ RADEON_WRITE(RADEON_DAC_EXT_CNTL, tmp); ++ ++ tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; ++ RADEON_WRITE(RADEON_DAC_CNTL2, tmp); ++ ++ udelay(10000); ++ ++ if (radeon_is_r300(dev_priv)) { ++ if (RADEON_READ(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) ++ found = connector_status_connected; ++ } else { ++ if (RADEON_READ(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) ++ found = connector_status_connected; ++ } ++ ++ /* restore regs we used */ ++ RADEON_WRITE(RADEON_DAC_CNTL2, dac_cntl2); ++ RADEON_WRITE(RADEON_DAC_EXT_CNTL, dac_ext_cntl); ++ RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl); ++ RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); ++ ++ if (radeon_is_r300(dev_priv)) { ++ RADEON_WRITE(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); ++ RADEON_WRITE_P(RADEON_GPIOPAD_A, gpiopad_a, ~1 ); ++ } else { ++ RADEON_WRITE(RADEON_DISP_HW_DEBUG, disp_hw_debug); ++ } ++ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, pixclks_cntl); ++ ++ //return found; ++ return connector_status_disconnected; ++ ++} ++ ++static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = { ++ .dpms = radeon_legacy_tv_dac_dpms, ++ .mode_fixup = radeon_legacy_tv_dac_mode_fixup, ++ .prepare = radeon_legacy_tv_dac_prepare, ++ .mode_set = radeon_legacy_tv_dac_mode_set, ++ .commit = radeon_legacy_tv_dac_commit, ++ .detect = radeon_legacy_tv_dac_detect, ++}; ++ ++ ++static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = { ++ .destroy = radeon_enc_destroy, ++}; ++ ++void ++radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_encoder *encoder; ++ struct radeon_encoder *radeon_encoder; ++ ++ /* see if we already added it */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ radeon_encoder = to_radeon_encoder(encoder); ++ if (radeon_encoder->encoder_id == encoder_id) { ++ radeon_encoder->devices |= supported_device; ++ return; ++ } ++ ++ } ++ ++ /* add a new one */ ++ radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); ++ if (!radeon_encoder) ++ return; ++ ++ encoder = &radeon_encoder->base; ++ encoder->possible_crtcs = 0x3; ++ encoder->possible_clones = 0; ++ ++ radeon_encoder->enc_priv = NULL; ++ ++ radeon_encoder->encoder_id = encoder_id; ++ radeon_encoder->devices = supported_device; ++ ++ switch (radeon_encoder->encoder_id) { ++ case ENCODER_OBJECT_ID_INTERNAL_LVDS: ++ drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); ++ drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs); ++ if (dev_priv->is_atom_bios) ++ radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); ++ else ++ radeon_encoder->enc_priv = radeon_combios_get_lvds_info(radeon_encoder); ++ radeon_encoder->rmx_type = RMX_FULL; ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_TMDS1: ++ drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS); ++ drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs); ++ if (dev_priv->is_atom_bios) ++ radeon_encoder->enc_priv = radeon_atombios_get_tmds_info(radeon_encoder); ++ else ++ radeon_encoder->enc_priv = radeon_combios_get_tmds_info(radeon_encoder); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC1: ++ drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC); ++ drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs); ++ if (!dev_priv->is_atom_bios) ++ radeon_encoder->enc_priv = radeon_combios_get_primary_dac_info(radeon_encoder); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DAC2: ++ drm_encoder_init(dev, encoder, &radeon_legacy_tv_dac_enc_funcs, DRM_MODE_ENCODER_TVDAC); ++ drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs); ++ if (!dev_priv->is_atom_bios) ++ radeon_encoder->enc_priv = radeon_combios_get_tv_dac_info(radeon_encoder); ++ break; ++ case ENCODER_OBJECT_ID_INTERNAL_DVO1: ++ drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs,DRM_MODE_ENCODER_TMDS); ++ drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs); ++ if (!dev_priv->is_atom_bios) ++ radeon_combios_get_ext_tmds_info(radeon_encoder); ++ break; ++ } ++} ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_mem.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_mem.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_mem.c 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_mem.c 2009-04-26 02:56:56.009726691 +0200 +@@ -294,7 +294,7 @@ + return -EFAULT; + + if (*heap) { +- DRM_ERROR("heap already initialized?"); ++ DRM_DEBUG("heap already initialized?\n"); + return -EFAULT; + } + +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_mode.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_mode.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_mode.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_mode.h 2009-04-26 03:02:02.303725699 +0200 +@@ -0,0 +1,399 @@ ++/* ++ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and ++ * VA Linux Systems Inc., Fremont, California. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Original Authors: ++ * Kevin E. Martin, Rickard E. Faith, Alan Hourihane ++ * ++ * Kernel port Author: Dave Airlie ++ */ ++ ++#ifndef RADEON_MODE_H ++#define RADEON_MODE_H ++ ++#include ++#include ++#include ++ ++#define to_radeon_crtc(x) container_of(x, struct radeon_crtc, base) ++#define to_radeon_connector(x) container_of(x, struct radeon_connector, base) ++#define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base) ++#define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base) ++ ++enum radeon_connector_type { ++ CONNECTOR_NONE, ++ CONNECTOR_VGA, ++ CONNECTOR_DVI_I, ++ CONNECTOR_DVI_D, ++ CONNECTOR_DVI_A, ++ CONNECTOR_STV, ++ CONNECTOR_CTV, ++ CONNECTOR_LVDS, ++ CONNECTOR_DIGITAL, ++ CONNECTOR_SCART, ++ CONNECTOR_HDMI_TYPE_A, ++ CONNECTOR_HDMI_TYPE_B, ++ CONNECTOR_0XC, ++ CONNECTOR_0XD, ++ CONNECTOR_DIN, ++ CONNECTOR_DISPLAY_PORT, ++ CONNECTOR_UNSUPPORTED ++}; ++ ++enum radeon_dac_type { ++ DAC_NONE = 0, ++ DAC_PRIMARY = 1, ++ DAC_TVDAC = 2, ++ DAC_EXT = 3 ++}; ++ ++enum radeon_tmds_type { ++ TMDS_NONE = 0, ++ TMDS_INT = 1, ++ TMDS_EXT = 2, ++ TMDS_LVTMA = 3, ++ TMDS_DDIA = 4, ++ TMDS_UNIPHY = 5 ++}; ++ ++enum radeon_dvi_type { ++ DVI_AUTO, ++ DVI_DIGITAL, ++ DVI_ANALOG ++}; ++ ++enum radeon_rmx_type { ++ RMX_OFF, ++ RMX_FULL, ++ RMX_CENTER, ++ RMX_ASPECT ++}; ++ ++enum radeon_tv_std { ++ TV_STD_NTSC, ++ TV_STD_PAL, ++ TV_STD_PAL_M, ++ TV_STD_PAL_60, ++ TV_STD_NTSC_J, ++ TV_STD_SCART_PAL, ++ TV_STD_SECAM, ++ TV_STD_PAL_CN, ++}; ++ ++struct radeon_i2c_bus_rec { ++ bool valid; ++ uint32_t mask_clk_reg; ++ uint32_t mask_data_reg; ++ uint32_t a_clk_reg; ++ uint32_t a_data_reg; ++ uint32_t put_clk_reg; ++ uint32_t put_data_reg; ++ uint32_t get_clk_reg; ++ uint32_t get_data_reg; ++ uint32_t mask_clk_mask; ++ uint32_t mask_data_mask; ++ uint32_t put_clk_mask; ++ uint32_t put_data_mask; ++ uint32_t get_clk_mask; ++ uint32_t get_data_mask; ++ uint32_t a_clk_mask; ++ uint32_t a_data_mask; ++}; ++ ++struct radeon_tmds_pll { ++ uint32_t freq; ++ uint32_t value; ++}; ++ ++#define RADEON_MAX_BIOS_CONNECTOR 16 ++ ++#define RADEON_PLL_USE_BIOS_DIVS (1 << 0) ++#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1) ++#define RADEON_PLL_USE_REF_DIV (1 << 2) ++#define RADEON_PLL_LEGACY (1 << 3) ++#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4) ++#define RADEON_PLL_PREFER_HIGH_REF_DIV (1 << 5) ++#define RADEON_PLL_PREFER_LOW_FB_DIV (1 << 6) ++#define RADEON_PLL_PREFER_HIGH_FB_DIV (1 << 7) ++#define RADEON_PLL_PREFER_LOW_POST_DIV (1 << 8) ++#define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9) ++ ++struct radeon_pll { ++ uint16_t reference_freq; ++ uint16_t reference_div; ++ uint32_t pll_in_min; ++ uint32_t pll_in_max; ++ uint32_t pll_out_min; ++ uint32_t pll_out_max; ++ uint16_t xclk; ++ ++ uint32_t min_ref_div; ++ uint32_t max_ref_div; ++ uint32_t min_post_div; ++ uint32_t max_post_div; ++ uint32_t min_feedback_div; ++ uint32_t max_feedback_div; ++ uint32_t best_vco; ++}; ++ ++struct radeon_i2c_chan { ++ struct drm_device *dev; ++ struct i2c_adapter adapter; ++ struct i2c_algo_bit_data algo; ++ struct radeon_i2c_bus_rec rec; ++}; ++ ++struct radeon_mode_info { ++ struct atom_context *atom_context; ++ struct radeon_pll p1pll; ++ struct radeon_pll p2pll; ++ struct radeon_pll spll; ++ struct radeon_pll mpll; ++ uint32_t mclk; ++ uint32_t sclk; ++}; ++ ++struct radeon_crtc { ++ struct drm_crtc base; ++ int crtc_id; ++ u16 lut_r[256], lut_g[256], lut_b[256]; ++ bool enabled; ++ bool can_tile; ++ uint32_t crtc_offset; ++ struct radeon_framebuffer *fbdev_fb; ++ struct drm_mode_set mode_set; ++ struct drm_gem_object *cursor_bo; ++ uint64_t cursor_addr; ++}; ++ ++#define RADEON_USE_RMX 1 ++ ++struct radeon_native_mode { ++ /* preferred mode */ ++ uint32_t panel_xres, panel_yres; ++ uint32_t hoverplus, hsync_width; ++ uint32_t hblank; ++ uint32_t voverplus, vsync_width; ++ uint32_t vblank; ++ uint32_t dotclock; ++ uint32_t flags; ++}; ++ ++struct radeon_encoder_primary_dac { ++ /* legacy primary dac */ ++ uint32_t ps2_pdac_adj; ++}; ++ ++struct radeon_encoder_lvds { ++ /* legacy lvds */ ++ uint16_t panel_vcc_delay; ++ uint16_t panel_pwr_delay; ++ uint16_t panel_digon_delay; ++ uint16_t panel_blon_delay; ++ uint32_t panel_ref_divider; ++ uint32_t panel_post_divider; ++ uint32_t panel_fb_divider; ++ bool use_bios_dividers; ++ uint32_t lvds_gen_cntl; ++ /* panel mode */ ++ struct radeon_native_mode native_mode; ++}; ++ ++struct radeon_encoder_tv_dac { ++ /* legacy tv dac */ ++ uint32_t ps2_tvdac_adj; ++ uint32_t ntsc_tvdac_adj; ++ uint32_t pal_tvdac_adj; ++ ++ enum radeon_tv_std tv_std; ++}; ++ ++struct radeon_encoder_int_tmds { ++ /* legacy int tmds */ ++ struct radeon_tmds_pll tmds_pll[4]; ++}; ++ ++struct radeon_encoder_atom_dig { ++ /* atom dig */ ++ bool coherent_mode; ++ int dig_block; ++ /* atom lvds */ ++ uint32_t lvds_misc; ++ uint16_t panel_pwr_delay; ++ /* panel mode */ ++ struct radeon_native_mode native_mode; ++}; ++ ++struct radeon_encoder { ++ struct drm_encoder base; ++ uint32_t encoder_id; ++ uint32_t devices; ++ uint32_t flags; ++ uint32_t pixel_clock; ++ enum radeon_rmx_type rmx_type; ++ struct radeon_native_mode native_mode; ++ void *enc_priv; ++}; ++ ++struct radeon_connector_atom_dig { ++ uint32_t igp_lane_info; ++ bool linkb; ++}; ++ ++struct radeon_connector { ++ struct drm_connector base; ++ uint32_t connector_id; ++ uint32_t devices; ++ struct radeon_i2c_chan *ddc_bus; ++ int use_digital; ++ void *con_priv; ++}; ++ ++struct radeon_framebuffer { ++ struct drm_framebuffer base; ++ struct drm_bo_kmap_obj kmap_obj; ++ struct drm_gem_object *obj; ++}; ++ ++extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, ++ struct radeon_i2c_bus_rec *rec, ++ const char *name); ++extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); ++extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); ++extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); ++extern struct drm_connector *radeon_connector_add(struct drm_device *dev, int bios_index); ++ ++extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); ++ ++extern void radeon_compute_pll(struct radeon_pll *pll, ++ uint64_t freq, ++ uint32_t *dot_clock_p, ++ uint32_t *fb_div_p, ++ uint32_t *ref_div_p, ++ uint32_t *post_div_p, ++ int flags); ++ ++struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); ++struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv); ++struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv); ++struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index); ++struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); ++extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); ++extern int atombios_get_encoder_mode(struct drm_encoder *encoder); ++ ++extern void radeon_crtc_load_lut(struct drm_crtc *crtc); ++extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb); ++extern int atombios_crtc_mode_set(struct drm_crtc *crtc, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode, ++ int x, int y, ++ struct drm_framebuffer *old_fb); ++extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode); ++ ++extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb); ++extern void radeon_legacy_atom_set_surface(struct drm_crtc *crtc); ++ ++extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, ++ struct drm_file *file_priv, ++ uint32_t handle, ++ uint32_t width, ++ uint32_t height); ++extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, ++ int x, int y); ++ ++extern bool radeon_atom_get_clock_info(struct drm_device *dev); ++extern bool radeon_combios_get_clock_info(struct drm_device *dev); ++extern struct radeon_encoder_atom_dig * ++radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); ++extern struct radeon_encoder_int_tmds * ++radeon_atombios_get_tmds_info(struct radeon_encoder *encoder); ++extern struct radeon_encoder_lvds * ++radeon_combios_get_lvds_info(struct radeon_encoder *encoder); ++extern struct radeon_encoder_int_tmds * ++radeon_combios_get_tmds_info(struct radeon_encoder *encoder); ++extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder); ++extern struct radeon_encoder_tv_dac * ++radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); ++extern struct radeon_encoder_primary_dac * ++radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder); ++extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock); ++extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev); ++extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock); ++extern void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev); ++extern void ++radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc); ++extern void ++radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on); ++extern void ++radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc); ++extern void ++radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on); ++extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, ++ u16 blue, int regno); ++struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev, ++ struct drm_mode_fb_cmd *mode_cmd, ++ struct drm_gem_object *obj); ++ ++int radeonfb_probe(struct drm_device *dev); ++ ++int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); ++bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev); ++void radeon_atombios_init_crtc(struct drm_device *dev, ++ struct radeon_crtc *radeon_crtc); ++void radeon_legacy_init_crtc(struct drm_device *dev, ++ struct radeon_crtc *radeon_crtc); ++void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state); ++ ++void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable); ++void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable); ++void radeon_combios_dyn_clk_setup(struct drm_device *dev, int enable); ++void radeon_get_clock_info(struct drm_device *dev); ++ ++extern bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev); ++extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev); ++ ++void radeon_rmx_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode); ++void radeon_enc_destroy(struct drm_encoder *encoder); ++void radeon_emit_copy_blit(struct drm_device * dev, ++ uint32_t src_offset, ++ uint32_t dst_offset, ++ uint32_t pages); ++void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); ++void radeon_combios_asic_init(struct drm_device *dev); ++extern int radeon_static_clocks_init(struct drm_device *dev); ++ ++void radeon_init_disp_bw_legacy(struct drm_device *dev, ++ struct drm_display_mode *mode1, ++ uint32_t pixel_bytes1, ++ struct drm_display_mode *mode2, ++ uint32_t pixel_bytes2); ++void radeon_init_disp_bw_avivo(struct drm_device *dev, ++ struct drm_display_mode *mode1, ++ uint32_t pixel_bytes1, ++ struct drm_display_mode *mode2, ++ uint32_t pixel_bytes2); ++void radeon_init_disp_bandwidth(struct drm_device *dev); ++#endif +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_pm.c linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_pm.c +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_pm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_pm.c 2009-04-26 03:02:06.889726767 +0200 +@@ -0,0 +1,263 @@ ++/* ++ * Copyright 2007-8 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Dave Airlie ++ * Alex Deucher ++ */ ++#include "drmP.h" ++#include "radeon_drm.h" ++#include "radeon_drv.h" ++ ++#include "atom.h" ++ ++#include "drm_crtc_helper.h" ++ ++int radeon_suspend(struct drm_device *dev, pm_message_t state) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_framebuffer *fb; ++ int i; ++ ++ if (!dev || !dev_priv) { ++ return -ENODEV; ++ } ++ ++ if (state.event == PM_EVENT_PRETHAW) ++ return 0; ++ ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) { ++ /* Disable *all* interrupts */ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) ++ RADEON_WRITE(R500_DxMODE_INT_MASK, 0); ++ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); ++ return 0; ++ } ++ ++ /* unpin the front buffers */ ++ list_for_each_entry(fb, &dev->mode_config.fb_kernel_list, filp_head) { ++ struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); ++ ++ if (!radeon_fb) ++ continue; ++ ++ if (!radeon_fb->obj); ++ continue; ++ ++ radeon_gem_object_unpin(radeon_fb->obj); ++ } ++ ++ if (!(dev_priv->flags & RADEON_IS_IGP)) ++ drm_bo_evict_mm(dev, DRM_BO_MEM_VRAM, 0); ++ ++ dev_priv->pmregs.crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL); ++ for (i = 0; i < 8; i++) ++ dev_priv->pmregs.bios_scratch[i] = RADEON_READ(RADEON_BIOS_0_SCRATCH + (i * 4)); ++ ++ radeon_modeset_cp_suspend(dev); ++ ++ /* Disable *all* interrupts */ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) ++ RADEON_WRITE(R500_DxMODE_INT_MASK, 0); ++ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); ++ ++ { ++ u32 irq_temp; ++ radeon_acknowledge_irqs(dev_priv, &irq_temp); ++ } ++ ++ if (dev_priv->flags & RADEON_IS_PCIE) { ++ memcpy_fromio(dev_priv->mm.pcie_table_backup, dev_priv->mm.pcie_table.kmap.virtual, dev_priv->gart_info.table_size); ++ } ++ ++ pci_save_state(dev->pdev); ++ ++ if (state.event == PM_EVENT_SUSPEND) { ++ /* Shut down the device */ ++ pci_disable_device(dev->pdev); ++ pci_set_power_state(dev->pdev, PCI_D3hot); ++ } ++ return 0; ++} ++ ++int radeon_resume(struct drm_device *dev) ++{ ++ struct drm_radeon_private *dev_priv = dev->dev_private; ++ struct drm_framebuffer *fb; ++ int i; ++ ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) { ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) ++ RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); ++ RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); ++ return 0; ++ } ++ ++ pci_set_power_state(dev->pdev, PCI_D0); ++ pci_restore_state(dev->pdev); ++ if (pci_enable_device(dev->pdev)) ++ return -1; ++ ++ ++ DRM_ERROR("\n"); ++ /* on atom cards re init the whole card ++ and set the modes again */ ++ ++ if (dev_priv->is_atom_bios) { ++ struct atom_context *ctx = dev_priv->mode_info.atom_context; ++ atom_asic_init(ctx); ++ } else { ++ radeon_combios_asic_init(dev); ++ } ++ ++ ++ for (i = 0; i < 8; i++) ++ RADEON_WRITE(RADEON_BIOS_0_SCRATCH + (i * 4), dev_priv->pmregs.bios_scratch[i]); ++ ++ /* VGA render mayhaps */ ++ if (dev_priv->chip_family >= CHIP_RS600) { ++ uint32_t tmp; ++ ++ RADEON_WRITE(AVIVO_D1VGA_CONTROL, 0); ++ RADEON_WRITE(AVIVO_D2VGA_CONTROL, 0); ++ tmp = RADEON_READ(0x300); ++ tmp &= ~(3 << 16); ++ RADEON_WRITE(0x300, tmp); ++ RADEON_WRITE(0x308, (1 << 8)); ++ RADEON_WRITE(0x310, dev_priv->fb_location); ++ RADEON_WRITE(0x594, 0); ++ } ++ ++ RADEON_WRITE(RADEON_CRTC_EXT_CNTL, dev_priv->pmregs.crtc_ext_cntl); ++ ++ radeon_static_clocks_init(dev); ++ ++ radeon_init_memory_map(dev); ++ ++ pci_set_master(dev->pdev); ++ /* Turn on bus mastering -todo fix properly */ ++ radeon_enable_bm(dev_priv); ++ ++ if (dev_priv->flags & RADEON_IS_PCIE) { ++ memcpy_toio(dev_priv->mm.pcie_table.kmap.virtual, dev_priv->mm.pcie_table_backup, dev_priv->gart_info.table_size); ++ } ++ ++ if (dev_priv->mm.ring.kmap.virtual) ++ memset(dev_priv->mm.ring.kmap.virtual, 0, RADEON_DEFAULT_RING_SIZE); ++ ++ if (dev_priv->mm.ring_read.kmap.virtual) ++ memset(dev_priv->mm.ring_read.kmap.virtual, 0, PAGE_SIZE); ++ ++ radeon_modeset_cp_resume(dev); ++ ++ /* reset swi reg */ ++ RADEON_WRITE(RADEON_LAST_SWI_REG, dev_priv->counter); ++ ++ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) ++ RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); ++ RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); ++ ++ /* reset the context for userspace */ ++ if (dev->primary->master) { ++ struct drm_radeon_master_private *master_priv = dev->primary->master->driver_priv; ++ if (master_priv->sarea_priv) ++ master_priv->sarea_priv->ctx_owner = 0; ++ } ++ ++ /* pin the front buffers */ ++ list_for_each_entry(fb, &dev->mode_config.fb_kernel_list, filp_head) { ++ ++ struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); ++ ++ if (!radeon_fb) ++ continue; ++ ++ if (!radeon_fb->obj) ++ continue; ++ ++ radeon_gem_object_pin(radeon_fb->obj, ++ PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM); ++ } ++ /* blat the mode back in */ ++ drm_helper_resume_force_mode(dev); ++ ++ return 0; ++} ++ ++bool radeon_set_pcie_lanes(struct drm_device *dev, int lanes) ++{ ++ drm_radeon_private_t *dev_priv = dev->dev_private; ++ uint32_t link_width_cntl, mask; ++ ++ /* FIXME wait for idle */ ++ ++ ++ switch (lanes) { ++ case 0: ++ mask = RADEON_PCIE_LC_LINK_WIDTH_X0; ++ break; ++ case 1: ++ mask = RADEON_PCIE_LC_LINK_WIDTH_X1; ++ break; ++ case 2: ++ mask = RADEON_PCIE_LC_LINK_WIDTH_X2; ++ break; ++ case 4: ++ mask = RADEON_PCIE_LC_LINK_WIDTH_X4; ++ break; ++ case 8: ++ mask = RADEON_PCIE_LC_LINK_WIDTH_X8; ++ break; ++ case 12: ++ mask = RADEON_PCIE_LC_LINK_WIDTH_X12; ++ break; ++ case 16: ++ default: ++ mask = RADEON_PCIE_LC_LINK_WIDTH_X16; ++ break; ++ } ++ ++ link_width_cntl = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_LC_LINK_WIDTH_CNTL); ++ ++ if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == ++ (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) ++ return true; ++ ++ link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | ++ RADEON_PCIE_LC_RECONFIG_NOW | ++ RADEON_PCIE_LC_RECONFIG_LATER | ++ RADEON_PCIE_LC_SHORT_RECONFIG_EN); ++ link_width_cntl |= mask; ++ RADEON_WRITE_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); ++ RADEON_WRITE_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl | RADEON_PCIE_LC_RECONFIG_NOW); ++ ++ /* wait for lane set to complete */ ++ link_width_cntl = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_LC_LINK_WIDTH_CNTL); ++ while (link_width_cntl == 0xffffffff) ++ link_width_cntl = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_LC_LINK_WIDTH_CNTL); ++ ++ if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == ++ (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) ++ return true; ++ else ++ return false; ++} ++ +diff -Naur linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_reg.h linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_reg.h +--- linux-2.6.29.1/drivers/gpu/drm/radeon/radeon_reg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/drivers/gpu/drm/radeon/radeon_reg.h 2009-04-26 03:02:10.931975729 +0200 +@@ -0,0 +1,5361 @@ ++/* ++ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and ++ * VA Linux Systems Inc., Fremont, California. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation on the rights to use, copy, modify, merge, ++ * publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, ++ * subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR ++ * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++/* ++ * Authors: ++ * Kevin E. Martin ++ * Rickard E. Faith ++ * Alan Hourihane ++ * ++ * References: ++ * ++ * !!!! FIXME !!!! ++ * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical ++ * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April ++ * 1999. ++ * ++ * !!!! FIXME !!!! ++ * RAGE 128 Software Development Manual (Technical Reference Manual P/N ++ * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. ++ * ++ */ ++ ++/* !!!! FIXME !!!! NOTE: THIS FILE HAS BEEN CONVERTED FROM r128_reg.h ++ * AND CONTAINS REGISTERS AND REGISTER DEFINITIONS THAT ARE NOT CORRECT ++ * ON THE RADEON. A FULL AUDIT OF THIS CODE IS NEEDED! */ ++ ++#ifndef _RADEON_REG_H_ ++#define _RADEON_REG_H_ ++ ++#define ATI_DATATYPE_VQ 0 ++#define ATI_DATATYPE_CI4 1 ++#define ATI_DATATYPE_CI8 2 ++#define ATI_DATATYPE_ARGB1555 3 ++#define ATI_DATATYPE_RGB565 4 ++#define ATI_DATATYPE_RGB888 5 ++#define ATI_DATATYPE_ARGB8888 6 ++#define ATI_DATATYPE_RGB332 7 ++#define ATI_DATATYPE_Y8 8 ++#define ATI_DATATYPE_RGB8 9 ++#define ATI_DATATYPE_CI16 10 ++#define ATI_DATATYPE_VYUY_422 11 ++#define ATI_DATATYPE_YVYU_422 12 ++#define ATI_DATATYPE_AYUV_444 14 ++#define ATI_DATATYPE_ARGB4444 15 ++ ++ /* Registers for 2D/Video/Overlay */ ++#define RADEON_ADAPTER_ID 0x0f2c /* PCI */ ++#define RADEON_AGP_BASE 0x0170 ++#define RADEON_AGP_CNTL 0x0174 ++# define RADEON_AGP_APER_SIZE_256MB (0x00 << 0) ++# define RADEON_AGP_APER_SIZE_128MB (0x20 << 0) ++# define RADEON_AGP_APER_SIZE_64MB (0x30 << 0) ++# define RADEON_AGP_APER_SIZE_32MB (0x38 << 0) ++# define RADEON_AGP_APER_SIZE_16MB (0x3c << 0) ++# define RADEON_AGP_APER_SIZE_8MB (0x3e << 0) ++# define RADEON_AGP_APER_SIZE_4MB (0x3f << 0) ++# define RADEON_AGP_APER_SIZE_MASK (0x3f << 0) ++#define RADEON_STATUS_PCI_CONFIG 0x06 ++# define RADEON_CAP_LIST 0x100000 ++#define RADEON_CAPABILITIES_PTR_PCI_CONFIG 0x34 /* offset in PCI config*/ ++# define RADEON_CAP_PTR_MASK 0xfc /* mask off reserved bits of CAP_PTR */ ++# define RADEON_CAP_ID_NULL 0x00 /* End of capability list */ ++# define RADEON_CAP_ID_AGP 0x02 /* AGP capability ID */ ++# define RADEON_CAP_ID_EXP 0x10 /* PCI Express */ ++#define RADEON_AGP_COMMAND 0x0f60 /* PCI */ ++#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config*/ ++# define RADEON_AGP_ENABLE (1<<8) ++#define RADEON_AGP_PLL_CNTL 0x000b /* PLL */ ++#define RADEON_AGP_STATUS 0x0f5c /* PCI */ ++# define RADEON_AGP_1X_MODE 0x01 ++# define RADEON_AGP_2X_MODE 0x02 ++# define RADEON_AGP_4X_MODE 0x04 ++# define RADEON_AGP_FW_MODE 0x10 ++# define RADEON_AGP_MODE_MASK 0x17 ++# define RADEON_AGPv3_MODE 0x08 ++# define RADEON_AGPv3_4X_MODE 0x01 ++# define RADEON_AGPv3_8X_MODE 0x02 ++#define RADEON_ATTRDR 0x03c1 /* VGA */ ++#define RADEON_ATTRDW 0x03c0 /* VGA */ ++#define RADEON_ATTRX 0x03c0 /* VGA */ ++#define RADEON_AUX_SC_CNTL 0x1660 ++# define RADEON_AUX1_SC_EN (1 << 0) ++# define RADEON_AUX1_SC_MODE_OR (0 << 1) ++# define RADEON_AUX1_SC_MODE_NAND (1 << 1) ++# define RADEON_AUX2_SC_EN (1 << 2) ++# define RADEON_AUX2_SC_MODE_OR (0 << 3) ++# define RADEON_AUX2_SC_MODE_NAND (1 << 3) ++# define RADEON_AUX3_SC_EN (1 << 4) ++# define RADEON_AUX3_SC_MODE_OR (0 << 5) ++# define RADEON_AUX3_SC_MODE_NAND (1 << 5) ++#define RADEON_AUX1_SC_BOTTOM 0x1670 ++#define RADEON_AUX1_SC_LEFT 0x1664 ++#define RADEON_AUX1_SC_RIGHT 0x1668 ++#define RADEON_AUX1_SC_TOP 0x166c ++#define RADEON_AUX2_SC_BOTTOM 0x1680 ++#define RADEON_AUX2_SC_LEFT 0x1674 ++#define RADEON_AUX2_SC_RIGHT 0x1678 ++#define RADEON_AUX2_SC_TOP 0x167c ++#define RADEON_AUX3_SC_BOTTOM 0x1690 ++#define RADEON_AUX3_SC_LEFT 0x1684 ++#define RADEON_AUX3_SC_RIGHT 0x1688 ++#define RADEON_AUX3_SC_TOP 0x168c ++#define RADEON_AUX_WINDOW_HORZ_CNTL 0x02d8 ++#define RADEON_AUX_WINDOW_VERT_CNTL 0x02dc ++ ++#define RADEON_BASE_CODE 0x0f0b ++#define RADEON_BIOS_0_SCRATCH 0x0010 ++# define RADEON_FP_PANEL_SCALABLE (1 << 16) ++# define RADEON_FP_PANEL_SCALE_EN (1 << 17) ++# define RADEON_FP_CHIP_SCALE_EN (1 << 18) ++# define RADEON_DRIVER_BRIGHTNESS_EN (1 << 26) ++# define RADEON_DISPLAY_ROT_MASK (3 << 28) ++# define RADEON_DISPLAY_ROT_00 (0 << 28) ++# define RADEON_DISPLAY_ROT_90 (1 << 28) ++# define RADEON_DISPLAY_ROT_180 (2 << 28) ++# define RADEON_DISPLAY_ROT_270 (3 << 28) ++#define RADEON_BIOS_1_SCRATCH 0x0014 ++#define RADEON_BIOS_2_SCRATCH 0x0018 ++#define RADEON_BIOS_3_SCRATCH 0x001c ++#define RADEON_BIOS_4_SCRATCH 0x0020 ++# define RADEON_CRT1_ATTACHED_MASK (3 << 0) ++# define RADEON_CRT1_ATTACHED_MONO (1 << 0) ++# define RADEON_CRT1_ATTACHED_COLOR (2 << 0) ++# define RADEON_LCD1_ATTACHED (1 << 2) ++# define RADEON_DFP1_ATTACHED (1 << 3) ++# define RADEON_TV1_ATTACHED_MASK (3 << 4) ++# define RADEON_TV1_ATTACHED_COMP (1 << 4) ++# define RADEON_TV1_ATTACHED_SVIDEO (2 << 4) ++# define RADEON_CRT2_ATTACHED_MASK (3 << 8) ++# define RADEON_CRT2_ATTACHED_MONO (1 << 8) ++# define RADEON_CRT2_ATTACHED_COLOR (2 << 8) ++# define RADEON_DFP2_ATTACHED (1 << 11) ++#define RADEON_BIOS_5_SCRATCH 0x0024 ++# define RADEON_LCD1_ON (1 << 0) ++# define RADEON_CRT1_ON (1 << 1) ++# define RADEON_TV1_ON (1 << 2) ++# define RADEON_DFP1_ON (1 << 3) ++# define RADEON_CRT2_ON (1 << 5) ++# define RADEON_CV1_ON (1 << 6) ++# define RADEON_DFP2_ON (1 << 7) ++# define RADEON_LCD1_CRTC_MASK (1 << 8) ++# define RADEON_LCD1_CRTC_SHIFT 8 ++# define RADEON_CRT1_CRTC_MASK (1 << 9) ++# define RADEON_CRT1_CRTC_SHIFT 9 ++# define RADEON_TV1_CRTC_MASK (1 << 10) ++# define RADEON_TV1_CRTC_SHIFT 10 ++# define RADEON_DFP1_CRTC_MASK (1 << 11) ++# define RADEON_DFP1_CRTC_SHIFT 11 ++# define RADEON_CRT2_CRTC_MASK (1 << 12) ++# define RADEON_CRT2_CRTC_SHIFT 12 ++# define RADEON_CV1_CRTC_MASK (1 << 13) ++# define RADEON_CV1_CRTC_SHIFT 13 ++# define RADEON_DFP2_CRTC_MASK (1 << 14) ++# define RADEON_DFP2_CRTC_SHIFT 14 ++# define RADEON_ACC_REQ_LCD1 (1 << 16) ++# define RADEON_ACC_REQ_CRT1 (1 << 17) ++# define RADEON_ACC_REQ_TV1 (1 << 18) ++# define RADEON_ACC_REQ_DFP1 (1 << 19) ++# define RADEON_ACC_REQ_CRT2 (1 << 21) ++# define RADEON_ACC_REQ_TV2 (1 << 22) ++# define RADEON_ACC_REQ_DFP2 (1 << 23) ++#define RADEON_BIOS_6_SCRATCH 0x0028 ++# define RADEON_ACC_MODE_CHANGE (1 << 2) ++# define RADEON_EXT_DESKTOP_MODE (1 << 3) ++# define RADEON_LCD_DPMS_ON (1 << 20) ++# define RADEON_CRT_DPMS_ON (1 << 21) ++# define RADEON_TV_DPMS_ON (1 << 22) ++# define RADEON_DFP_DPMS_ON (1 << 23) ++# define RADEON_DPMS_MASK (3 << 24) ++# define RADEON_DPMS_ON (0 << 24) ++# define RADEON_DPMS_STANDBY (1 << 24) ++# define RADEON_DPMS_SUSPEND (2 << 24) ++# define RADEON_DPMS_OFF (3 << 24) ++# define RADEON_SCREEN_BLANKING (1 << 26) ++# define RADEON_DRIVER_CRITICAL (1 << 27) ++# define RADEON_DISPLAY_SWITCHING_DIS (1 << 30) ++#define RADEON_BIOS_7_SCRATCH 0x002c ++# define RADEON_SYS_HOTKEY (1 << 10) ++# define RADEON_DRV_LOADED (1 << 12) ++#define RADEON_BIOS_ROM 0x0f30 /* PCI */ ++#define RADEON_BIST 0x0f0f /* PCI */ ++#define RADEON_BRUSH_DATA0 0x1480 ++#define RADEON_BRUSH_DATA1 0x1484 ++#define RADEON_BRUSH_DATA10 0x14a8 ++#define RADEON_BRUSH_DATA11 0x14ac ++#define RADEON_BRUSH_DATA12 0x14b0 ++#define RADEON_BRUSH_DATA13 0x14b4 ++#define RADEON_BRUSH_DATA14 0x14b8 ++#define RADEON_BRUSH_DATA15 0x14bc ++#define RADEON_BRUSH_DATA16 0x14c0 ++#define RADEON_BRUSH_DATA17 0x14c4 ++#define RADEON_BRUSH_DATA18 0x14c8 ++#define RADEON_BRUSH_DATA19 0x14cc ++#define RADEON_BRUSH_DATA2 0x1488 ++#define RADEON_BRUSH_DATA20 0x14d0 ++#define RADEON_BRUSH_DATA21 0x14d4 ++#define RADEON_BRUSH_DATA22 0x14d8 ++#define RADEON_BRUSH_DATA23 0x14dc ++#define RADEON_BRUSH_DATA24 0x14e0 ++#define RADEON_BRUSH_DATA25 0x14e4 ++#define RADEON_BRUSH_DATA26 0x14e8 ++#define RADEON_BRUSH_DATA27 0x14ec ++#define RADEON_BRUSH_DATA28 0x14f0 ++#define RADEON_BRUSH_DATA29 0x14f4 ++#define RADEON_BRUSH_DATA3 0x148c ++#define RADEON_BRUSH_DATA30 0x14f8 ++#define RADEON_BRUSH_DATA31 0x14fc ++#define RADEON_BRUSH_DATA32 0x1500 ++#define RADEON_BRUSH_DATA33 0x1504 ++#define RADEON_BRUSH_DATA34 0x1508 ++#define RADEON_BRUSH_DATA35 0x150c ++#define RADEON_BRUSH_DATA36 0x1510 ++#define RADEON_BRUSH_DATA37 0x1514 ++#define RADEON_BRUSH_DATA38 0x1518 ++#define RADEON_BRUSH_DATA39 0x151c ++#define RADEON_BRUSH_DATA4 0x1490 ++#define RADEON_BRUSH_DATA40 0x1520 ++#define RADEON_BRUSH_DATA41 0x1524 ++#define RADEON_BRUSH_DATA42 0x1528 ++#define RADEON_BRUSH_DATA43 0x152c ++#define RADEON_BRUSH_DATA44 0x1530 ++#define RADEON_BRUSH_DATA45 0x1534 ++#define RADEON_BRUSH_DATA46 0x1538 ++#define RADEON_BRUSH_DATA47 0x153c ++#define RADEON_BRUSH_DATA48 0x1540 ++#define RADEON_BRUSH_DATA49 0x1544 ++#define RADEON_BRUSH_DATA5 0x1494 ++#define RADEON_BRUSH_DATA50 0x1548 ++#define RADEON_BRUSH_DATA51 0x154c ++#define RADEON_BRUSH_DATA52 0x1550 ++#define RADEON_BRUSH_DATA53 0x1554 ++#define RADEON_BRUSH_DATA54 0x1558 ++#define RADEON_BRUSH_DATA55 0x155c ++#define RADEON_BRUSH_DATA56 0x1560 ++#define RADEON_BRUSH_DATA57 0x1564 ++#define RADEON_BRUSH_DATA58 0x1568 ++#define RADEON_BRUSH_DATA59 0x156c ++#define RADEON_BRUSH_DATA6 0x1498 ++#define RADEON_BRUSH_DATA60 0x1570 ++#define RADEON_BRUSH_DATA61 0x1574 ++#define RADEON_BRUSH_DATA62 0x1578 ++#define RADEON_BRUSH_DATA63 0x157c ++#define RADEON_BRUSH_DATA7 0x149c ++#define RADEON_BRUSH_DATA8 0x14a0 ++#define RADEON_BRUSH_DATA9 0x14a4 ++#define RADEON_BRUSH_SCALE 0x1470 ++#define RADEON_BRUSH_Y_X 0x1474 ++#define RADEON_BUS_CNTL 0x0030 ++# define RADEON_BUS_MASTER_DIS (1 << 6) ++# define RADEON_BUS_BIOS_DIS_ROM (1 << 12) ++# define RADEON_BUS_RD_DISCARD_EN (1 << 24) ++# define RADEON_BUS_RD_ABORT_EN (1 << 25) ++# define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) ++# define RADEON_BUS_WRT_BURST (1 << 29) ++# define RADEON_BUS_READ_BURST (1 << 30) ++#define RADEON_BUS_CNTL1 0x0034 ++# define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) ++ ++//#define RADEON_PCIE_INDEX 0x0030 ++//#define RADEON_PCIE_DATA 0x0034 ++#define RADEON_PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE */ ++# define RADEON_PCIE_LC_LINK_WIDTH_SHIFT 0 ++# define RADEON_PCIE_LC_LINK_WIDTH_MASK 0x7 ++# define RADEON_PCIE_LC_LINK_WIDTH_X0 0 ++# define RADEON_PCIE_LC_LINK_WIDTH_X1 1 ++# define RADEON_PCIE_LC_LINK_WIDTH_X2 2 ++# define RADEON_PCIE_LC_LINK_WIDTH_X4 3 ++# define RADEON_PCIE_LC_LINK_WIDTH_X8 4 ++# define RADEON_PCIE_LC_LINK_WIDTH_X12 5 ++# define RADEON_PCIE_LC_LINK_WIDTH_X16 6 ++# define RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT 4 ++# define RADEON_PCIE_LC_LINK_WIDTH_RD_MASK 0x70 ++# define RADEON_PCIE_LC_RECONFIG_NOW (1 << 8) ++# define RADEON_PCIE_LC_RECONFIG_LATER (1 << 9) ++# define RADEON_PCIE_LC_SHORT_RECONFIG_EN (1 << 10) ++ ++#define RADEON_CACHE_CNTL 0x1724 ++#define RADEON_CACHE_LINE 0x0f0c /* PCI */ ++#define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */ ++#define RADEON_CAPABILITIES_PTR 0x0f34 /* PCI */ ++#define RADEON_CLK_PIN_CNTL 0x0001 /* PLL */ ++# define RADEON_SCLK_DYN_START_CNTL (1 << 15) ++#define RADEON_CLOCK_CNTL_DATA 0x000c ++#define RADEON_CLOCK_CNTL_INDEX 0x0008 ++# define RADEON_PLL_WR_EN (1 << 7) ++# define RADEON_PLL_DIV_SEL (3 << 8) ++# define RADEON_PLL2_DIV_SEL_MASK ~(3 << 8) ++#define RADEON_CLK_PWRMGT_CNTL 0x0014 ++# define RADEON_ENGIN_DYNCLK_MODE (1 << 12) ++# define RADEON_ACTIVE_HILO_LAT_MASK (3 << 13) ++# define RADEON_ACTIVE_HILO_LAT_SHIFT 13 ++# define RADEON_DISP_DYN_STOP_LAT_MASK (1 << 12) ++# define RADEON_MC_BUSY (1 << 16) ++# define RADEON_DLL_READY (1 << 19) ++# define RADEON_CG_NO1_DEBUG_0 (1 << 24) ++# define RADEON_CG_NO1_DEBUG_MASK (0x1f << 24) ++# define RADEON_DYN_STOP_MODE_MASK (7 << 21) ++# define RADEON_TVPLL_PWRMGT_OFF (1 << 30) ++# define RADEON_TVCLK_TURNOFF (1 << 31) ++#define RADEON_PLL_PWRMGT_CNTL 0x0015 ++# define RADEON_TCL_BYPASS_DISABLE (1 << 20) ++#define RADEON_CLR_CMP_CLR_3D 0x1a24 ++#define RADEON_CLR_CMP_CLR_DST 0x15c8 ++#define RADEON_CLR_CMP_CLR_SRC 0x15c4 ++#define RADEON_CLR_CMP_CNTL 0x15c0 ++# define RADEON_SRC_CMP_EQ_COLOR (4 << 0) ++# define RADEON_SRC_CMP_NEQ_COLOR (5 << 0) ++# define RADEON_CLR_CMP_SRC_SOURCE (1 << 24) ++#define RADEON_CLR_CMP_MASK 0x15cc ++# define RADEON_CLR_CMP_MSK 0xffffffff ++#define RADEON_CLR_CMP_MASK_3D 0x1A28 ++#define RADEON_COMMAND 0x0f04 /* PCI */ ++#define RADEON_COMPOSITE_SHADOW_ID 0x1a0c ++#define RADEON_CONFIG_APER_0_BASE 0x0100 ++#define RADEON_CONFIG_APER_1_BASE 0x0104 ++#define RADEON_CONFIG_APER_SIZE 0x0108 ++#define RADEON_CONFIG_BONDS 0x00e8 ++#define RADEON_CONFIG_CNTL 0x00e0 ++# define RADEON_CFG_ATI_REV_A11 (0 << 16) ++# define RADEON_CFG_ATI_REV_A12 (1 << 16) ++# define RADEON_CFG_ATI_REV_A13 (2 << 16) ++# define RADEON_CFG_ATI_REV_ID_MASK (0xf << 16) ++#define RADEON_CONFIG_MEMSIZE 0x00f8 ++#define RADEON_CONFIG_MEMSIZE_EMBEDDED 0x0114 ++#define RADEON_CONFIG_REG_1_BASE 0x010c ++#define RADEON_CONFIG_REG_APER_SIZE 0x0110 ++#define RADEON_CONFIG_XSTRAP 0x00e4 ++#define RADEON_CONSTANT_COLOR_C 0x1d34 ++# define RADEON_CONSTANT_COLOR_MASK 0x00ffffff ++# define RADEON_CONSTANT_COLOR_ONE 0x00ffffff ++# define RADEON_CONSTANT_COLOR_ZERO 0x00000000 ++#define RADEON_CRC_CMDFIFO_ADDR 0x0740 ++#define RADEON_CRC_CMDFIFO_DOUT 0x0744 ++#define RADEON_GRPH_BUFFER_CNTL 0x02f0 ++# define RADEON_GRPH_START_REQ_MASK (0x7f) ++# define RADEON_GRPH_START_REQ_SHIFT 0 ++# define RADEON_GRPH_STOP_REQ_MASK (0x7f<<8) ++# define RADEON_GRPH_STOP_REQ_SHIFT 8 ++# define RADEON_GRPH_CRITICAL_POINT_MASK (0x7f<<16) ++# define RADEON_GRPH_CRITICAL_POINT_SHIFT 16 ++# define RADEON_GRPH_CRITICAL_CNTL (1<<28) ++# define RADEON_GRPH_BUFFER_SIZE (1<<29) ++# define RADEON_GRPH_CRITICAL_AT_SOF (1<<30) ++# define RADEON_GRPH_STOP_CNTL (1<<31) ++#define RADEON_GRPH2_BUFFER_CNTL 0x03f0 ++# define RADEON_GRPH2_START_REQ_MASK (0x7f) ++# define RADEON_GRPH2_START_REQ_SHIFT 0 ++# define RADEON_GRPH2_STOP_REQ_MASK (0x7f<<8) ++# define RADEON_GRPH2_STOP_REQ_SHIFT 8 ++# define RADEON_GRPH2_CRITICAL_POINT_MASK (0x7f<<16) ++# define RADEON_GRPH2_CRITICAL_POINT_SHIFT 16 ++# define RADEON_GRPH2_CRITICAL_CNTL (1<<28) ++# define RADEON_GRPH2_BUFFER_SIZE (1<<29) ++# define RADEON_GRPH2_CRITICAL_AT_SOF (1<<30) ++# define RADEON_GRPH2_STOP_CNTL (1<<31) ++#define RADEON_CRTC_CRNT_FRAME 0x0214 ++#define RADEON_CRTC_EXT_CNTL 0x0054 ++# define RADEON_CRTC_VGA_XOVERSCAN (1 << 0) ++# define RADEON_VGA_ATI_LINEAR (1 << 3) ++# define RADEON_XCRT_CNT_EN (1 << 6) ++# define RADEON_CRTC_HSYNC_DIS (1 << 8) ++# define RADEON_CRTC_VSYNC_DIS (1 << 9) ++# define RADEON_CRTC_DISPLAY_DIS (1 << 10) ++# define RADEON_CRTC_SYNC_TRISTAT (1 << 11) ++# define RADEON_CRTC_CRT_ON (1 << 15) ++#define RADEON_CRTC_EXT_CNTL_DPMS_BYTE 0x0055 ++# define RADEON_CRTC_HSYNC_DIS_BYTE (1 << 0) ++# define RADEON_CRTC_VSYNC_DIS_BYTE (1 << 1) ++# define RADEON_CRTC_DISPLAY_DIS_BYTE (1 << 2) ++#define RADEON_CRTC_GEN_CNTL 0x0050 ++# define RADEON_CRTC_DBL_SCAN_EN (1 << 0) ++# define RADEON_CRTC_INTERLACE_EN (1 << 1) ++# define RADEON_CRTC_CSYNC_EN (1 << 4) ++# define RADEON_CRTC_ICON_EN (1 << 15) ++# define RADEON_CRTC_CUR_EN (1 << 16) ++# define RADEON_CRTC_CUR_MODE_MASK (7 << 20) ++# define RADEON_CRTC_CUR_MODE_SHIFT 20 ++# define RADEON_CRTC_CUR_MODE_MONO 0 ++# define RADEON_CRTC_CUR_MODE_24BPP 2 ++# define RADEON_CRTC_EXT_DISP_EN (1 << 24) ++# define RADEON_CRTC_EN (1 << 25) ++# define RADEON_CRTC_DISP_REQ_EN_B (1 << 26) ++#define RADEON_CRTC2_GEN_CNTL 0x03f8 ++# define RADEON_CRTC2_DBL_SCAN_EN (1 << 0) ++# define RADEON_CRTC2_INTERLACE_EN (1 << 1) ++# define RADEON_CRTC2_SYNC_TRISTAT (1 << 4) ++# define RADEON_CRTC2_HSYNC_TRISTAT (1 << 5) ++# define RADEON_CRTC2_VSYNC_TRISTAT (1 << 6) ++# define RADEON_CRTC2_CRT2_ON (1 << 7) ++# define RADEON_CRTC2_PIX_WIDTH_SHIFT 8 ++# define RADEON_CRTC2_PIX_WIDTH_MASK (0xf << 8) ++# define RADEON_CRTC2_ICON_EN (1 << 15) ++# define RADEON_CRTC2_CUR_EN (1 << 16) ++# define RADEON_CRTC2_CUR_MODE_MASK (7 << 20) ++# define RADEON_CRTC2_DISP_DIS (1 << 23) ++# define RADEON_CRTC2_EN (1 << 25) ++# define RADEON_CRTC2_DISP_REQ_EN_B (1 << 26) ++# define RADEON_CRTC2_CSYNC_EN (1 << 27) ++# define RADEON_CRTC2_HSYNC_DIS (1 << 28) ++# define RADEON_CRTC2_VSYNC_DIS (1 << 29) ++#define RADEON_CRTC_MORE_CNTL 0x27c ++# define RADEON_CRTC_AUTO_HORZ_CENTER_EN (1<<2) ++# define RADEON_CRTC_AUTO_VERT_CENTER_EN (1<<3) ++# define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4) ++# define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5) ++#define RADEON_CRTC_GUI_TRIG_VLINE 0x0218 ++#define RADEON_CRTC_H_SYNC_STRT_WID 0x0204 ++# define RADEON_CRTC_H_SYNC_STRT_PIX (0x07 << 0) ++# define RADEON_CRTC_H_SYNC_STRT_CHAR (0x3ff << 3) ++# define RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT 3 ++# define RADEON_CRTC_H_SYNC_WID (0x3f << 16) ++# define RADEON_CRTC_H_SYNC_WID_SHIFT 16 ++# define RADEON_CRTC_H_SYNC_POL (1 << 23) ++#define RADEON_CRTC2_H_SYNC_STRT_WID 0x0304 ++# define RADEON_CRTC2_H_SYNC_STRT_PIX (0x07 << 0) ++# define RADEON_CRTC2_H_SYNC_STRT_CHAR (0x3ff << 3) ++# define RADEON_CRTC2_H_SYNC_STRT_CHAR_SHIFT 3 ++# define RADEON_CRTC2_H_SYNC_WID (0x3f << 16) ++# define RADEON_CRTC2_H_SYNC_WID_SHIFT 16 ++# define RADEON_CRTC2_H_SYNC_POL (1 << 23) ++#define RADEON_CRTC_H_TOTAL_DISP 0x0200 ++# define RADEON_CRTC_H_TOTAL (0x03ff << 0) ++# define RADEON_CRTC_H_TOTAL_SHIFT 0 ++# define RADEON_CRTC_H_DISP (0x01ff << 16) ++# define RADEON_CRTC_H_DISP_SHIFT 16 ++#define RADEON_CRTC2_H_TOTAL_DISP 0x0300 ++# define RADEON_CRTC2_H_TOTAL (0x03ff << 0) ++# define RADEON_CRTC2_H_TOTAL_SHIFT 0 ++# define RADEON_CRTC2_H_DISP (0x01ff << 16) ++# define RADEON_CRTC2_H_DISP_SHIFT 16 ++ ++#define RADEON_CRTC_OFFSET_RIGHT 0x0220 ++#define RADEON_CRTC_OFFSET 0x0224 ++# define RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET (1<<30) ++# define RADEON_CRTC_OFFSET__OFFSET_LOCK (1<<31) ++ ++#define RADEON_CRTC2_OFFSET 0x0324 ++# define RADEON_CRTC2_OFFSET__GUI_TRIG_OFFSET (1<<30) ++# define RADEON_CRTC2_OFFSET__OFFSET_LOCK (1<<31) ++#define RADEON_CRTC_OFFSET_CNTL 0x0228 ++# define RADEON_CRTC_TILE_LINE_SHIFT 0 ++# define RADEON_CRTC_TILE_LINE_RIGHT_SHIFT 4 ++# define R300_CRTC_X_Y_MODE_EN_RIGHT (1 << 6) ++# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_MASK (3 << 7) ++# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_AUTO (0 << 7) ++# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_SINGLE (1 << 7) ++# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_DOUBLE (2 << 7) ++# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_DIS (3 << 7) ++# define R300_CRTC_X_Y_MODE_EN (1 << 9) ++# define R300_CRTC_MICRO_TILE_BUFFER_MASK (3 << 10) ++# define R300_CRTC_MICRO_TILE_BUFFER_AUTO (0 << 10) ++# define R300_CRTC_MICRO_TILE_BUFFER_SINGLE (1 << 10) ++# define R300_CRTC_MICRO_TILE_BUFFER_DOUBLE (2 << 10) ++# define R300_CRTC_MICRO_TILE_BUFFER_DIS (3 << 10) ++# define R300_CRTC_MICRO_TILE_EN_RIGHT (1 << 12) ++# define R300_CRTC_MICRO_TILE_EN (1 << 13) ++# define R300_CRTC_MACRO_TILE_EN_RIGHT (1 << 14) ++# define R300_CRTC_MACRO_TILE_EN (1 << 15) ++# define RADEON_CRTC_TILE_EN_RIGHT (1 << 14) ++# define RADEON_CRTC_TILE_EN (1 << 15) ++# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) ++# define RADEON_CRTC_STEREO_OFFSET_EN (1 << 17) ++ ++#define R300_CRTC_TILE_X0_Y0 0x0350 ++#define R300_CRTC2_TILE_X0_Y0 0x0358 ++ ++#define RADEON_CRTC2_OFFSET_CNTL 0x0328 ++# define RADEON_CRTC2_OFFSET_FLIP_CNTL (1 << 16) ++# define RADEON_CRTC2_TILE_EN (1 << 15) ++#define RADEON_CRTC_PITCH 0x022c ++# define RADEON_CRTC_PITCH__SHIFT 0 ++# define RADEON_CRTC_PITCH__RIGHT_SHIFT 16 ++ ++#define RADEON_CRTC2_PITCH 0x032c ++#define RADEON_CRTC_STATUS 0x005c ++# define RADEON_CRTC_VBLANK_SAVE (1 << 1) ++# define RADEON_CRTC_VBLANK_SAVE_CLEAR (1 << 1) ++#define RADEON_CRTC2_STATUS 0x03fc ++# define RADEON_CRTC2_VBLANK_SAVE (1 << 1) ++# define RADEON_CRTC2_VBLANK_SAVE_CLEAR (1 << 1) ++#define RADEON_CRTC_V_SYNC_STRT_WID 0x020c ++# define RADEON_CRTC_V_SYNC_STRT (0x7ff << 0) ++# define RADEON_CRTC_V_SYNC_STRT_SHIFT 0 ++# define RADEON_CRTC_V_SYNC_WID (0x1f << 16) ++# define RADEON_CRTC_V_SYNC_WID_SHIFT 16 ++# define RADEON_CRTC_V_SYNC_POL (1 << 23) ++#define RADEON_CRTC2_V_SYNC_STRT_WID 0x030c ++# define RADEON_CRTC2_V_SYNC_STRT (0x7ff << 0) ++# define RADEON_CRTC2_V_SYNC_STRT_SHIFT 0 ++# define RADEON_CRTC2_V_SYNC_WID (0x1f << 16) ++# define RADEON_CRTC2_V_SYNC_WID_SHIFT 16 ++# define RADEON_CRTC2_V_SYNC_POL (1 << 23) ++#define RADEON_CRTC_V_TOTAL_DISP 0x0208 ++# define RADEON_CRTC_V_TOTAL (0x07ff << 0) ++# define RADEON_CRTC_V_TOTAL_SHIFT 0 ++# define RADEON_CRTC_V_DISP (0x07ff << 16) ++# define RADEON_CRTC_V_DISP_SHIFT 16 ++#define RADEON_CRTC2_V_TOTAL_DISP 0x0308 ++# define RADEON_CRTC2_V_TOTAL (0x07ff << 0) ++# define RADEON_CRTC2_V_TOTAL_SHIFT 0 ++# define RADEON_CRTC2_V_DISP (0x07ff << 16) ++# define RADEON_CRTC2_V_DISP_SHIFT 16 ++#define RADEON_CRTC_VLINE_CRNT_VLINE 0x0210 ++# define RADEON_CRTC_CRNT_VLINE_MASK (0x7ff << 16) ++#define RADEON_CRTC2_CRNT_FRAME 0x0314 ++#define RADEON_CRTC2_GUI_TRIG_VLINE 0x0318 ++#define RADEON_CRTC2_STATUS 0x03fc ++#define RADEON_CRTC2_VLINE_CRNT_VLINE 0x0310 ++#define RADEON_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ ++#define RADEON_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ ++#define RADEON_CUR_CLR0 0x026c ++#define RADEON_CUR_CLR1 0x0270 ++#define RADEON_CUR_HORZ_VERT_OFF 0x0268 ++#define RADEON_CUR_HORZ_VERT_POSN 0x0264 ++#define RADEON_CUR_OFFSET 0x0260 ++# define RADEON_CUR_LOCK (1 << 31) ++#define RADEON_CUR2_CLR0 0x036c ++#define RADEON_CUR2_CLR1 0x0370 ++#define RADEON_CUR2_HORZ_VERT_OFF 0x0368 ++#define RADEON_CUR2_HORZ_VERT_POSN 0x0364 ++#define RADEON_CUR2_OFFSET 0x0360 ++# define RADEON_CUR2_LOCK (1 << 31) ++ ++#define RADEON_DAC_CNTL 0x0058 ++# define RADEON_DAC_RANGE_CNTL (3 << 0) ++# define RADEON_DAC_RANGE_CNTL_PS2 (2 << 0) ++# define RADEON_DAC_RANGE_CNTL_MASK 0x03 ++# define RADEON_DAC_BLANKING (1 << 2) ++# define RADEON_DAC_CMP_EN (1 << 3) ++# define RADEON_DAC_CMP_OUTPUT (1 << 7) ++# define RADEON_DAC_8BIT_EN (1 << 8) ++# define RADEON_DAC_TVO_EN (1 << 10) ++# define RADEON_DAC_VGA_ADR_EN (1 << 13) ++# define RADEON_DAC_PDWN (1 << 15) ++# define RADEON_DAC_MASK_ALL (0xff << 24) ++#define RADEON_DAC_CNTL2 0x007c ++# define RADEON_DAC2_TV_CLK_SEL (0 << 1) ++# define RADEON_DAC2_DAC_CLK_SEL (1 << 0) ++# define RADEON_DAC2_DAC2_CLK_SEL (1 << 1) ++# define RADEON_DAC2_PALETTE_ACC_CTL (1 << 5) ++# define RADEON_DAC2_CMP_EN (1 << 7) ++# define RADEON_DAC2_CMP_OUT_R (1 << 8) ++# define RADEON_DAC2_CMP_OUT_G (1 << 9) ++# define RADEON_DAC2_CMP_OUT_B (1 << 10) ++# define RADEON_DAC2_CMP_OUTPUT (1 << 11) ++#define RADEON_DAC_EXT_CNTL 0x0280 ++# define RADEON_DAC2_FORCE_BLANK_OFF_EN (1 << 0) ++# define RADEON_DAC2_FORCE_DATA_EN (1 << 1) ++# define RADEON_DAC_FORCE_BLANK_OFF_EN (1 << 4) ++# define RADEON_DAC_FORCE_DATA_EN (1 << 5) ++# define RADEON_DAC_FORCE_DATA_SEL_MASK (3 << 6) ++# define RADEON_DAC_FORCE_DATA_SEL_R (0 << 6) ++# define RADEON_DAC_FORCE_DATA_SEL_G (1 << 6) ++# define RADEON_DAC_FORCE_DATA_SEL_B (2 << 6) ++# define RADEON_DAC_FORCE_DATA_SEL_RGB (3 << 6) ++# define RADEON_DAC_FORCE_DATA_MASK 0x0003ff00 ++# define RADEON_DAC_FORCE_DATA_SHIFT 8 ++#define RADEON_DAC_MACRO_CNTL 0x0d04 ++# define RADEON_DAC_PDWN_R (1 << 16) ++# define RADEON_DAC_PDWN_G (1 << 17) ++# define RADEON_DAC_PDWN_B (1 << 18) ++#define RADEON_DISP_PWR_MAN 0x0d08 ++# define RADEON_DISP_PWR_MAN_D3_CRTC_EN (1 << 0) ++# define RADEON_DISP_PWR_MAN_D3_CRTC2_EN (1 << 4) ++# define RADEON_DISP_PWR_MAN_DPMS_ON (0 << 8) ++# define RADEON_DISP_PWR_MAN_DPMS_STANDBY (1 << 8) ++# define RADEON_DISP_PWR_MAN_DPMS_SUSPEND (2 << 8) ++# define RADEON_DISP_PWR_MAN_DPMS_OFF (3 << 8) ++# define RADEON_DISP_D3_RST (1 << 16) ++# define RADEON_DISP_D3_REG_RST (1 << 17) ++# define RADEON_DISP_D3_GRPH_RST (1 << 18) ++# define RADEON_DISP_D3_SUBPIC_RST (1 << 19) ++# define RADEON_DISP_D3_OV0_RST (1 << 20) ++# define RADEON_DISP_D1D2_GRPH_RST (1 << 21) ++# define RADEON_DISP_D1D2_SUBPIC_RST (1 << 22) ++# define RADEON_DISP_D1D2_OV0_RST (1 << 23) ++# define RADEON_DIG_TMDS_ENABLE_RST (1 << 24) ++# define RADEON_TV_ENABLE_RST (1 << 25) ++# define RADEON_AUTO_PWRUP_EN (1 << 26) ++#define RADEON_TV_DAC_CNTL 0x088c ++# define RADEON_TV_DAC_NBLANK (1 << 0) ++# define RADEON_TV_DAC_NHOLD (1 << 1) ++# define RADEON_TV_DAC_PEDESTAL (1 << 2) ++# define RADEON_TV_MONITOR_DETECT_EN (1 << 4) ++# define RADEON_TV_DAC_CMPOUT (1 << 5) ++# define RADEON_TV_DAC_STD_MASK (3 << 8) ++# define RADEON_TV_DAC_STD_PAL (0 << 8) ++# define RADEON_TV_DAC_STD_NTSC (1 << 8) ++# define RADEON_TV_DAC_STD_PS2 (2 << 8) ++# define RADEON_TV_DAC_STD_RS343 (3 << 8) ++# define RADEON_TV_DAC_BGSLEEP (1 << 6) ++# define RADEON_TV_DAC_BGADJ_MASK (0xf << 16) ++# define RADEON_TV_DAC_BGADJ_SHIFT 16 ++# define RADEON_TV_DAC_DACADJ_MASK (0xf << 20) ++# define RADEON_TV_DAC_DACADJ_SHIFT 20 ++# define RADEON_TV_DAC_RDACPD (1 << 24) ++# define RADEON_TV_DAC_GDACPD (1 << 25) ++# define RADEON_TV_DAC_BDACPD (1 << 26) ++# define RADEON_TV_DAC_RDACDET (1 << 29) ++# define RADEON_TV_DAC_GDACDET (1 << 30) ++# define RADEON_TV_DAC_BDACDET (1 << 31) ++# define R420_TV_DAC_DACADJ_MASK (0x1f << 20) ++# define R420_TV_DAC_RDACPD (1 << 25) ++# define R420_TV_DAC_GDACPD (1 << 26) ++# define R420_TV_DAC_BDACPD (1 << 27) ++# define R420_TV_DAC_TVENABLE (1 << 28) ++#define RADEON_DISP_HW_DEBUG 0x0d14 ++# define RADEON_CRT2_DISP1_SEL (1 << 5) ++#define RADEON_DISP_OUTPUT_CNTL 0x0d64 ++# define RADEON_DISP_DAC_SOURCE_MASK 0x03 ++# define RADEON_DISP_DAC2_SOURCE_MASK 0x0c ++# define RADEON_DISP_DAC_SOURCE_CRTC2 0x01 ++# define RADEON_DISP_DAC_SOURCE_RMX 0x02 ++# define RADEON_DISP_DAC_SOURCE_LTU 0x03 ++# define RADEON_DISP_DAC2_SOURCE_CRTC2 0x04 ++# define RADEON_DISP_TVDAC_SOURCE_MASK (0x03 << 2) ++# define RADEON_DISP_TVDAC_SOURCE_CRTC 0x0 ++# define RADEON_DISP_TVDAC_SOURCE_CRTC2 (0x01 << 2) ++# define RADEON_DISP_TVDAC_SOURCE_RMX (0x02 << 2) ++# define RADEON_DISP_TVDAC_SOURCE_LTU (0x03 << 2) ++# define RADEON_DISP_TRANS_MATRIX_MASK (0x03 << 4) ++# define RADEON_DISP_TRANS_MATRIX_ALPHA_MSB (0x00 << 4) ++# define RADEON_DISP_TRANS_MATRIX_GRAPHICS (0x01 << 4) ++# define RADEON_DISP_TRANS_MATRIX_VIDEO (0x02 << 4) ++# define RADEON_DISP_TV_SOURCE_CRTC (1 << 16) /* crtc1 or crtc2 */ ++# define RADEON_DISP_TV_SOURCE_LTU (0 << 16) /* linear transform unit */ ++#define RADEON_DISP_TV_OUT_CNTL 0x0d6c ++# define RADEON_DISP_TV_PATH_SRC_CRTC2 (1 << 16) ++# define RADEON_DISP_TV_PATH_SRC_CRTC1 (0 << 16) ++#define RADEON_DAC_CRC_SIG 0x02cc ++#define RADEON_DAC_DATA 0x03c9 /* VGA */ ++#define RADEON_DAC_MASK 0x03c6 /* VGA */ ++#define RADEON_DAC_R_INDEX 0x03c7 /* VGA */ ++#define RADEON_DAC_W_INDEX 0x03c8 /* VGA */ ++#define RADEON_DDA_CONFIG 0x02e0 ++#define RADEON_DDA_ON_OFF 0x02e4 ++#define RADEON_DEFAULT_OFFSET 0x16e0 ++#define RADEON_DEFAULT_PITCH 0x16e4 ++#define RADEON_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 ++# define RADEON_DEFAULT_SC_RIGHT_MAX (0x1fff << 0) ++# define RADEON_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) ++#define RADEON_DESTINATION_3D_CLR_CMP_VAL 0x1820 ++#define RADEON_DESTINATION_3D_CLR_CMP_MSK 0x1824 ++#define RADEON_DEVICE_ID 0x0f02 /* PCI */ ++#define RADEON_DISP_MISC_CNTL 0x0d00 ++# define RADEON_SOFT_RESET_GRPH_PP (1 << 0) ++#define RADEON_DISP_MERGE_CNTL 0x0d60 ++# define RADEON_DISP_ALPHA_MODE_MASK 0x03 ++# define RADEON_DISP_ALPHA_MODE_KEY 0 ++# define RADEON_DISP_ALPHA_MODE_PER_PIXEL 1 ++# define RADEON_DISP_ALPHA_MODE_GLOBAL 2 ++# define RADEON_DISP_RGB_OFFSET_EN (1 << 8) ++# define RADEON_DISP_GRPH_ALPHA_MASK (0xff << 16) ++# define RADEON_DISP_OV0_ALPHA_MASK (0xff << 24) ++# define RADEON_DISP_LIN_TRANS_BYPASS (0x01 << 9) ++#define RADEON_DISP2_MERGE_CNTL 0x0d68 ++# define RADEON_DISP2_RGB_OFFSET_EN (1 << 8) ++#define RADEON_DISP_LIN_TRANS_GRPH_A 0x0d80 ++#define RADEON_DISP_LIN_TRANS_GRPH_B 0x0d84 ++#define RADEON_DISP_LIN_TRANS_GRPH_C 0x0d88 ++#define RADEON_DISP_LIN_TRANS_GRPH_D 0x0d8c ++#define RADEON_DISP_LIN_TRANS_GRPH_E 0x0d90 ++#define RADEON_DISP_LIN_TRANS_GRPH_F 0x0d98 ++#define RADEON_DP_BRUSH_BKGD_CLR 0x1478 ++#define RADEON_DP_BRUSH_FRGD_CLR 0x147c ++#define RADEON_DP_CNTL 0x16c0 ++# define RADEON_DST_X_LEFT_TO_RIGHT (1 << 0) ++# define RADEON_DST_Y_TOP_TO_BOTTOM (1 << 1) ++# define RADEON_DP_DST_TILE_LINEAR (0 << 3) ++# define RADEON_DP_DST_TILE_MACRO (1 << 3) ++# define RADEON_DP_DST_TILE_MICRO (2 << 3) ++# define RADEON_DP_DST_TILE_BOTH (3 << 3) ++#define RADEON_DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0 ++# define RADEON_DST_Y_MAJOR (1 << 2) ++# define RADEON_DST_Y_DIR_TOP_TO_BOTTOM (1 << 15) ++# define RADEON_DST_X_DIR_LEFT_TO_RIGHT (1 << 31) ++#define RADEON_DP_DATATYPE 0x16c4 ++# define RADEON_HOST_BIG_ENDIAN_EN (1 << 29) ++#define RADEON_DP_GUI_MASTER_CNTL 0x146c ++# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) ++# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) ++# define RADEON_GMC_SRC_CLIPPING (1 << 2) ++# define RADEON_GMC_DST_CLIPPING (1 << 3) ++# define RADEON_GMC_BRUSH_DATATYPE_MASK (0x0f << 4) ++# define RADEON_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4) ++# define RADEON_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4) ++# define RADEON_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4) ++# define RADEON_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) ++# define RADEON_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) ++# define RADEON_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) ++# define RADEON_GMC_BRUSH_32x32_MONO_FG_BG (8 << 4) ++# define RADEON_GMC_BRUSH_32x32_MONO_FG_LA (9 << 4) ++# define RADEON_GMC_BRUSH_8x8_COLOR (10 << 4) ++# define RADEON_GMC_BRUSH_1X8_COLOR (12 << 4) ++# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) ++# define RADEON_GMC_BRUSH_NONE (15 << 4) ++# define RADEON_GMC_DST_8BPP_CI (2 << 8) ++# define RADEON_GMC_DST_15BPP (3 << 8) ++# define RADEON_GMC_DST_16BPP (4 << 8) ++# define RADEON_GMC_DST_24BPP (5 << 8) ++# define RADEON_GMC_DST_32BPP (6 << 8) ++# define RADEON_GMC_DST_8BPP_RGB (7 << 8) ++# define RADEON_GMC_DST_Y8 (8 << 8) ++# define RADEON_GMC_DST_RGB8 (9 << 8) ++# define RADEON_GMC_DST_VYUY (11 << 8) ++# define RADEON_GMC_DST_YVYU (12 << 8) ++# define RADEON_GMC_DST_AYUV444 (14 << 8) ++# define RADEON_GMC_DST_ARGB4444 (15 << 8) ++# define RADEON_GMC_DST_DATATYPE_MASK (0x0f << 8) ++# define RADEON_GMC_DST_DATATYPE_SHIFT 8 ++# define RADEON_GMC_SRC_DATATYPE_MASK (3 << 12) ++# define RADEON_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12) ++# define RADEON_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12) ++# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) ++# define RADEON_GMC_BYTE_PIX_ORDER (1 << 14) ++# define RADEON_GMC_BYTE_MSB_TO_LSB (0 << 14) ++# define RADEON_GMC_BYTE_LSB_TO_MSB (1 << 14) ++# define RADEON_GMC_CONVERSION_TEMP (1 << 15) ++# define RADEON_GMC_CONVERSION_TEMP_6500 (0 << 15) ++# define RADEON_GMC_CONVERSION_TEMP_9300 (1 << 15) ++# define RADEON_GMC_ROP3_MASK (0xff << 16) ++# define RADEON_DP_SRC_SOURCE_MASK (7 << 24) ++# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) ++# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) ++# define RADEON_GMC_3D_FCN_EN (1 << 27) ++# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) ++# define RADEON_GMC_AUX_CLIP_DIS (1 << 29) ++# define RADEON_GMC_WR_MSK_DIS (1 << 30) ++# define RADEON_GMC_LD_BRUSH_Y_X (1 << 31) ++# define RADEON_ROP3_ZERO 0x00000000 ++# define RADEON_ROP3_DSa 0x00880000 ++# define RADEON_ROP3_SDna 0x00440000 ++# define RADEON_ROP3_S 0x00cc0000 ++# define RADEON_ROP3_DSna 0x00220000 ++# define RADEON_ROP3_D 0x00aa0000 ++# define RADEON_ROP3_DSx 0x00660000 ++# define RADEON_ROP3_DSo 0x00ee0000 ++# define RADEON_ROP3_DSon 0x00110000 ++# define RADEON_ROP3_DSxn 0x00990000 ++# define RADEON_ROP3_Dn 0x00550000 ++# define RADEON_ROP3_SDno 0x00dd0000 ++# define RADEON_ROP3_Sn 0x00330000 ++# define RADEON_ROP3_DSno 0x00bb0000 ++# define RADEON_ROP3_DSan 0x00770000 ++# define RADEON_ROP3_ONE 0x00ff0000 ++# define RADEON_ROP3_DPa 0x00a00000 ++# define RADEON_ROP3_PDna 0x00500000 ++# define RADEON_ROP3_P 0x00f00000 ++# define RADEON_ROP3_DPna 0x000a0000 ++# define RADEON_ROP3_D 0x00aa0000 ++# define RADEON_ROP3_DPx 0x005a0000 ++# define RADEON_ROP3_DPo 0x00fa0000 ++# define RADEON_ROP3_DPon 0x00050000 ++# define RADEON_ROP3_PDxn 0x00a50000 ++# define RADEON_ROP3_PDno 0x00f50000 ++# define RADEON_ROP3_Pn 0x000f0000 ++# define RADEON_ROP3_DPno 0x00af0000 ++# define RADEON_ROP3_DPan 0x005f0000 ++#define RADEON_DP_GUI_MASTER_CNTL_C 0x1c84 ++#define RADEON_DP_MIX 0x16c8 ++#define RADEON_DP_SRC_BKGD_CLR 0x15dc ++#define RADEON_DP_SRC_FRGD_CLR 0x15d8 ++#define RADEON_DP_WRITE_MASK 0x16cc ++#define RADEON_DST_BRES_DEC 0x1630 ++#define RADEON_DST_BRES_ERR 0x1628 ++#define RADEON_DST_BRES_INC 0x162c ++#define RADEON_DST_BRES_LNTH 0x1634 ++#define RADEON_DST_BRES_LNTH_SUB 0x1638 ++#define RADEON_DST_HEIGHT 0x1410 ++#define RADEON_DST_HEIGHT_WIDTH 0x143c ++#define RADEON_DST_HEIGHT_WIDTH_8 0x158c ++#define RADEON_DST_HEIGHT_WIDTH_BW 0x15b4 ++#define RADEON_DST_HEIGHT_Y 0x15a0 ++#define RADEON_DST_LINE_START 0x1600 ++#define RADEON_DST_LINE_END 0x1604 ++#define RADEON_DST_LINE_PATCOUNT 0x1608 ++# define RADEON_BRES_CNTL_SHIFT 8 ++#define RADEON_DST_OFFSET 0x1404 ++#define RADEON_DST_PITCH 0x1408 ++#define RADEON_DST_PITCH_OFFSET 0x142c ++#define RADEON_DST_PITCH_OFFSET_C 0x1c80 ++# define RADEON_PITCH_SHIFT 21 ++# define RADEON_DST_TILE_LINEAR (0 << 30) ++# define RADEON_DST_TILE_MACRO (1 << 30) ++# define RADEON_DST_TILE_MICRO (2 << 30) ++# define RADEON_DST_TILE_BOTH (3 << 30) ++#define RADEON_DST_WIDTH 0x140c ++#define RADEON_DST_WIDTH_HEIGHT 0x1598 ++#define RADEON_DST_WIDTH_X 0x1588 ++#define RADEON_DST_WIDTH_X_INCY 0x159c ++#define RADEON_DST_X 0x141c ++#define RADEON_DST_X_SUB 0x15a4 ++#define RADEON_DST_X_Y 0x1594 ++#define RADEON_DST_Y 0x1420 ++#define RADEON_DST_Y_SUB 0x15a8 ++#define RADEON_DST_Y_X 0x1438 ++ ++#define RADEON_FCP_CNTL 0x0910 ++# define RADEON_FCP0_SRC_PCICLK 0 ++# define RADEON_FCP0_SRC_PCLK 1 ++# define RADEON_FCP0_SRC_PCLKb 2 ++# define RADEON_FCP0_SRC_HREF 3 ++# define RADEON_FCP0_SRC_GND 4 ++# define RADEON_FCP0_SRC_HREFb 5 ++#define RADEON_FLUSH_1 0x1704 ++#define RADEON_FLUSH_2 0x1708 ++#define RADEON_FLUSH_3 0x170c ++#define RADEON_FLUSH_4 0x1710 ++#define RADEON_FLUSH_5 0x1714 ++#define RADEON_FLUSH_6 0x1718 ++#define RADEON_FLUSH_7 0x171c ++#define RADEON_FOG_3D_TABLE_START 0x1810 ++#define RADEON_FOG_3D_TABLE_END 0x1814 ++#define RADEON_FOG_3D_TABLE_DENSITY 0x181c ++#define RADEON_FOG_TABLE_INDEX 0x1a14 ++#define RADEON_FOG_TABLE_DATA 0x1a18 ++#define RADEON_FP_CRTC_H_TOTAL_DISP 0x0250 ++#define RADEON_FP_CRTC_V_TOTAL_DISP 0x0254 ++# define RADEON_FP_CRTC_H_TOTAL_MASK 0x000003ff ++# define RADEON_FP_CRTC_H_DISP_MASK 0x01ff0000 ++# define RADEON_FP_CRTC_V_TOTAL_MASK 0x00000fff ++# define RADEON_FP_CRTC_V_DISP_MASK 0x0fff0000 ++# define RADEON_FP_H_SYNC_STRT_CHAR_MASK 0x00001ff8 ++# define RADEON_FP_H_SYNC_WID_MASK 0x003f0000 ++# define RADEON_FP_V_SYNC_STRT_MASK 0x00000fff ++# define RADEON_FP_V_SYNC_WID_MASK 0x001f0000 ++# define RADEON_FP_CRTC_H_TOTAL_SHIFT 0x00000000 ++# define RADEON_FP_CRTC_H_DISP_SHIFT 0x00000010 ++# define RADEON_FP_CRTC_V_TOTAL_SHIFT 0x00000000 ++# define RADEON_FP_CRTC_V_DISP_SHIFT 0x00000010 ++# define RADEON_FP_H_SYNC_STRT_CHAR_SHIFT 0x00000003 ++# define RADEON_FP_H_SYNC_WID_SHIFT 0x00000010 ++# define RADEON_FP_V_SYNC_STRT_SHIFT 0x00000000 ++# define RADEON_FP_V_SYNC_WID_SHIFT 0x00000010 ++#define RADEON_FP_GEN_CNTL 0x0284 ++# define RADEON_FP_FPON (1 << 0) ++# define RADEON_FP_BLANK_EN (1 << 1) ++# define RADEON_FP_TMDS_EN (1 << 2) ++# define RADEON_FP_PANEL_FORMAT (1 << 3) ++# define RADEON_FP_EN_TMDS (1 << 7) ++# define RADEON_FP_DETECT_SENSE (1 << 8) ++# define R200_FP_SOURCE_SEL_MASK (3 << 10) ++# define R200_FP_SOURCE_SEL_CRTC1 (0 << 10) ++# define R200_FP_SOURCE_SEL_CRTC2 (1 << 10) ++# define R200_FP_SOURCE_SEL_RMX (2 << 10) ++# define R200_FP_SOURCE_SEL_TRANS (3 << 10) ++# define RADEON_FP_SEL_CRTC1 (0 << 13) ++# define RADEON_FP_SEL_CRTC2 (1 << 13) ++# define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15) ++# define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) ++# define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17) ++# define RADEON_FP_CRTC_USE_SHADOW_VEND (1 << 18) ++# define RADEON_FP_RMX_HVSYNC_CONTROL_EN (1 << 20) ++# define RADEON_FP_DFP_SYNC_SEL (1 << 21) ++# define RADEON_FP_CRTC_LOCK_8DOT (1 << 22) ++# define RADEON_FP_CRT_SYNC_SEL (1 << 23) ++# define RADEON_FP_USE_SHADOW_EN (1 << 24) ++# define RADEON_FP_CRT_SYNC_ALT (1 << 26) ++#define RADEON_FP2_GEN_CNTL 0x0288 ++# define RADEON_FP2_BLANK_EN (1 << 1) ++# define RADEON_FP2_ON (1 << 2) ++# define RADEON_FP2_PANEL_FORMAT (1 << 3) ++# define RADEON_FP2_DETECT_SENSE (1 << 8) ++# define R200_FP2_SOURCE_SEL_MASK (3 << 10) ++# define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) ++# define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) ++# define R200_FP2_SOURCE_SEL_RMX (2 << 10) ++# define R200_FP2_SOURCE_SEL_TRANS_UNIT (3 << 10) ++# define RADEON_FP2_SRC_SEL_MASK (3 << 13) ++# define RADEON_FP2_SRC_SEL_CRTC2 (1 << 13) ++# define RADEON_FP2_FP_POL (1 << 16) ++# define RADEON_FP2_LP_POL (1 << 17) ++# define RADEON_FP2_SCK_POL (1 << 18) ++# define RADEON_FP2_LCD_CNTL_MASK (7 << 19) ++# define RADEON_FP2_PAD_FLOP_EN (1 << 22) ++# define RADEON_FP2_CRC_EN (1 << 23) ++# define RADEON_FP2_CRC_READ_EN (1 << 24) ++# define RADEON_FP2_DVO_EN (1 << 25) ++# define RADEON_FP2_DVO_RATE_SEL_SDR (1 << 26) ++# define R200_FP2_DVO_RATE_SEL_SDR (1 << 27) ++# define R300_FP2_DVO_CLOCK_MODE_SINGLE (1 << 28) ++# define R300_FP2_DVO_DUAL_CHANNEL_EN (1 << 29) ++#define RADEON_FP_H_SYNC_STRT_WID 0x02c4 ++#define RADEON_FP_H2_SYNC_STRT_WID 0x03c4 ++#define RADEON_FP_HORZ_STRETCH 0x028c ++#define RADEON_FP_HORZ2_STRETCH 0x038c ++# define RADEON_HORZ_STRETCH_RATIO_MASK 0xffff ++# define RADEON_HORZ_STRETCH_RATIO_MAX 4096 ++# define RADEON_HORZ_PANEL_SIZE (0x1ff << 16) ++# define RADEON_HORZ_PANEL_SHIFT 16 ++# define RADEON_HORZ_STRETCH_PIXREP (0 << 25) ++# define RADEON_HORZ_STRETCH_BLEND (1 << 26) ++# define RADEON_HORZ_STRETCH_ENABLE (1 << 25) ++# define RADEON_HORZ_AUTO_RATIO (1 << 27) ++# define RADEON_HORZ_FP_LOOP_STRETCH (0x7 << 28) ++# define RADEON_HORZ_AUTO_RATIO_INC (1 << 31) ++#define RADEON_FP_HORZ_VERT_ACTIVE 0x0278 ++#define RADEON_FP_V_SYNC_STRT_WID 0x02c8 ++#define RADEON_FP_VERT_STRETCH 0x0290 ++#define RADEON_FP_V2_SYNC_STRT_WID 0x03c8 ++#define RADEON_FP_VERT2_STRETCH 0x0390 ++# define RADEON_VERT_PANEL_SIZE (0xfff << 12) ++# define RADEON_VERT_PANEL_SHIFT 12 ++# define RADEON_VERT_STRETCH_RATIO_MASK 0xfff ++# define RADEON_VERT_STRETCH_RATIO_SHIFT 0 ++# define RADEON_VERT_STRETCH_RATIO_MAX 4096 ++# define RADEON_VERT_STRETCH_ENABLE (1 << 25) ++# define RADEON_VERT_STRETCH_LINEREP (0 << 26) ++# define RADEON_VERT_STRETCH_BLEND (1 << 26) ++# define RADEON_VERT_AUTO_RATIO_EN (1 << 27) ++# define RADEON_VERT_AUTO_RATIO_INC (1 << 31) ++# define RADEON_VERT_STRETCH_RESERVED 0x71000000 ++#define RS400_FP_2ND_GEN_CNTL 0x0384 ++# define RS400_FP_2ND_ON (1 << 0) ++# define RS400_FP_2ND_BLANK_EN (1 << 1) ++# define RS400_TMDS_2ND_EN (1 << 2) ++# define RS400_PANEL_FORMAT_2ND (1 << 3) ++# define RS400_FP_2ND_EN_TMDS (1 << 7) ++# define RS400_FP_2ND_DETECT_SENSE (1 << 8) ++# define RS400_FP_2ND_SOURCE_SEL_MASK (3 << 10) ++# define RS400_FP_2ND_SOURCE_SEL_CRTC1 (0 << 10) ++# define RS400_FP_2ND_SOURCE_SEL_CRTC2 (1 << 10) ++# define RS400_FP_2ND_SOURCE_SEL_RMX (2 << 10) ++# define RS400_FP_2ND_DETECT_EN (1 << 12) ++# define RS400_HPD_2ND_SEL (1 << 13) ++#define RS400_FP2_2_GEN_CNTL 0x0388 ++# define RS400_FP2_2_BLANK_EN (1 << 1) ++# define RS400_FP2_2_ON (1 << 2) ++# define RS400_FP2_2_PANEL_FORMAT (1 << 3) ++# define RS400_FP2_2_DETECT_SENSE (1 << 8) ++# define RS400_FP2_2_SOURCE_SEL_MASK (3 << 10) ++# define RS400_FP2_2_SOURCE_SEL_CRTC1 (0 << 10) ++# define RS400_FP2_2_SOURCE_SEL_CRTC2 (1 << 10) ++# define RS400_FP2_2_SOURCE_SEL_RMX (2 << 10) ++# define RS400_FP2_2_DVO2_EN (1 << 25) ++#define RS400_TMDS2_CNTL 0x0394 ++#define RS400_TMDS2_TRANSMITTER_CNTL 0x03a4 ++# define RS400_TMDS2_PLLEN (1 << 0) ++# define RS400_TMDS2_PLLRST (1 << 1) ++ ++#define RADEON_GEN_INT_CNTL 0x0040 ++#define RADEON_GEN_INT_STATUS 0x0044 ++# define RADEON_VSYNC_INT_AK (1 << 2) ++# define RADEON_VSYNC_INT (1 << 2) ++# define RADEON_VSYNC2_INT_AK (1 << 6) ++# define RADEON_VSYNC2_INT (1 << 6) ++#define RADEON_GENENB 0x03c3 /* VGA */ ++#define RADEON_GENFC_RD 0x03ca /* VGA */ ++#define RADEON_GENFC_WT 0x03da /* VGA, 0x03ba */ ++#define RADEON_GENMO_RD 0x03cc /* VGA */ ++#define RADEON_GENMO_WT 0x03c2 /* VGA */ ++#define RADEON_GENS0 0x03c2 /* VGA */ ++#define RADEON_GENS1 0x03da /* VGA, 0x03ba */ ++#define RADEON_GPIO_MONID 0x0068 /* DDC interface via I2C */ ++#define RADEON_GPIO_MONIDB 0x006c ++#define RADEON_GPIO_CRT2_DDC 0x006c ++#define RADEON_GPIO_DVI_DDC 0x0064 ++#define RADEON_GPIO_VGA_DDC 0x0060 ++# define RADEON_GPIO_A_0 (1 << 0) ++# define RADEON_GPIO_A_1 (1 << 1) ++# define RADEON_GPIO_Y_0 (1 << 8) ++# define RADEON_GPIO_Y_1 (1 << 9) ++# define RADEON_GPIO_Y_SHIFT_0 8 ++# define RADEON_GPIO_Y_SHIFT_1 9 ++# define RADEON_GPIO_EN_0 (1 << 16) ++# define RADEON_GPIO_EN_1 (1 << 17) ++# define RADEON_GPIO_MASK_0 (1 << 24) /*??*/ ++# define RADEON_GPIO_MASK_1 (1 << 25) /*??*/ ++#define RADEON_GRPH8_DATA 0x03cf /* VGA */ ++#define RADEON_GRPH8_IDX 0x03ce /* VGA */ ++#define RADEON_GUI_SCRATCH_REG0 0x15e0 ++#define RADEON_GUI_SCRATCH_REG1 0x15e4 ++#define RADEON_GUI_SCRATCH_REG2 0x15e8 ++#define RADEON_GUI_SCRATCH_REG3 0x15ec ++#define RADEON_GUI_SCRATCH_REG4 0x15f0 ++#define RADEON_GUI_SCRATCH_REG5 0x15f4 ++ ++#define RADEON_HEADER 0x0f0e /* PCI */ ++#define RADEON_HOST_DATA0 0x17c0 ++#define RADEON_HOST_DATA1 0x17c4 ++#define RADEON_HOST_DATA2 0x17c8 ++#define RADEON_HOST_DATA3 0x17cc ++#define RADEON_HOST_DATA4 0x17d0 ++#define RADEON_HOST_DATA5 0x17d4 ++#define RADEON_HOST_DATA6 0x17d8 ++#define RADEON_HOST_DATA7 0x17dc ++#define RADEON_HOST_DATA_LAST 0x17e0 ++#define RADEON_HOST_PATH_CNTL 0x0130 ++# define RADEON_HDP_SOFT_RESET (1 << 26) ++# define RADEON_HDP_APER_CNTL (1 << 23) ++#define RADEON_HTOTAL_CNTL 0x0009 /* PLL */ ++# define RADEON_HTOT_CNTL_VGA_EN (1 << 28) ++#define RADEON_HTOTAL2_CNTL 0x002e /* PLL */ ++ ++ /* Multimedia I2C bus */ ++#define RADEON_I2C_CNTL_0 0x0090 ++#define RADEON_I2C_DONE (1<<0) ++#define RADEON_I2C_NACK (1<<1) ++#define RADEON_I2C_HALT (1<<2) ++#define RADEON_I2C_SOFT_RST (1<<5) ++#define RADEON_I2C_DRIVE_EN (1<<6) ++#define RADEON_I2C_DRIVE_SEL (1<<7) ++#define RADEON_I2C_START (1<<8) ++#define RADEON_I2C_STOP (1<<9) ++#define RADEON_I2C_RECEIVE (1<<10) ++#define RADEON_I2C_ABORT (1<<11) ++#define RADEON_I2C_GO (1<<12) ++#define RADEON_I2C_CNTL_1 0x0094 ++#define RADEON_I2C_SEL (1<<16) ++#define RADEON_I2C_EN (1<<17) ++#define RADEON_I2C_DATA 0x0098 ++ ++#define RADEON_DVI_I2C_CNTL_0 0x02e0 ++#define RADEON_DVI_I2C_CNTL_1 0x02e4 /* ? */ ++#define RADEON_DVI_I2C_DATA 0x02e8 ++ ++#define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */ ++#define RADEON_INTERRUPT_PIN 0x0f3d /* PCI */ ++#define RADEON_IO_BASE 0x0f14 /* PCI */ ++ ++#define RADEON_LATENCY 0x0f0d /* PCI */ ++#define RADEON_LEAD_BRES_DEC 0x1608 ++#define RADEON_LEAD_BRES_LNTH 0x161c ++#define RADEON_LEAD_BRES_LNTH_SUB 0x1624 ++#define RADEON_LVDS_GEN_CNTL 0x02d0 ++# define RADEON_LVDS_ON (1 << 0) ++# define RADEON_LVDS_DISPLAY_DIS (1 << 1) ++# define RADEON_LVDS_PANEL_TYPE (1 << 2) ++# define RADEON_LVDS_PANEL_FORMAT (1 << 3) ++# define RADEON_LVDS_NO_FM (0 << 4) ++# define RADEON_LVDS_2_GREY (1 << 4) ++# define RADEON_LVDS_4_GREY (2 << 4) ++# define RADEON_LVDS_RST_FM (1 << 6) ++# define RADEON_LVDS_EN (1 << 7) ++# define RADEON_LVDS_BL_MOD_LEVEL_SHIFT 8 ++# define RADEON_LVDS_BL_MOD_LEVEL_MASK (0xff << 8) ++# define RADEON_LVDS_BL_MOD_EN (1 << 16) ++# define RADEON_LVDS_BL_CLK_SEL (1 << 17) ++# define RADEON_LVDS_DIGON (1 << 18) ++# define RADEON_LVDS_BLON (1 << 19) ++# define RADEON_LVDS_FP_POL_LOW (1 << 20) ++# define RADEON_LVDS_LP_POL_LOW (1 << 21) ++# define RADEON_LVDS_DTM_POL_LOW (1 << 22) ++# define RADEON_LVDS_SEL_CRTC2 (1 << 23) ++# define RADEON_LVDS_FPDI_EN (1 << 27) ++# define RADEON_LVDS_HSYNC_DELAY_SHIFT 28 ++#define RADEON_LVDS_PLL_CNTL 0x02d4 ++# define RADEON_HSYNC_DELAY_SHIFT 28 ++# define RADEON_HSYNC_DELAY_MASK (0xf << 28) ++# define RADEON_LVDS_PLL_EN (1 << 16) ++# define RADEON_LVDS_PLL_RESET (1 << 17) ++# define R300_LVDS_SRC_SEL_MASK (3 << 18) ++# define R300_LVDS_SRC_SEL_CRTC1 (0 << 18) ++# define R300_LVDS_SRC_SEL_CRTC2 (1 << 18) ++# define R300_LVDS_SRC_SEL_RMX (2 << 18) ++#define RADEON_LVDS_SS_GEN_CNTL 0x02ec ++# define RADEON_LVDS_PWRSEQ_DELAY1_SHIFT 16 ++# define RADEON_LVDS_PWRSEQ_DELAY2_SHIFT 20 ++ ++#define RADEON_MAX_LATENCY 0x0f3f /* PCI */ ++#define RADEON_MC_AGP_LOCATION 0x014c ++#define RADEON_MC_FB_LOCATION 0x0148 ++#define RADEON_DISPLAY_BASE_ADDR 0x23c ++#define RADEON_DISPLAY2_BASE_ADDR 0x33c ++#define RADEON_OV0_BASE_ADDR 0x43c ++#define RADEON_NB_TOM 0x15c ++#define R300_MC_INIT_MISC_LAT_TIMER 0x180 ++# define R300_MC_DISP0R_INIT_LAT_SHIFT 8 ++# define R300_MC_DISP0R_INIT_LAT_MASK 0xf ++# define R300_MC_DISP1R_INIT_LAT_SHIFT 12 ++# define R300_MC_DISP1R_INIT_LAT_MASK 0xf ++#define RADEON_MCLK_CNTL 0x0012 /* PLL */ ++# define RADEON_FORCEON_MCLKA (1 << 16) ++# define RADEON_FORCEON_MCLKB (1 << 17) ++# define RADEON_FORCEON_YCLKA (1 << 18) ++# define RADEON_FORCEON_YCLKB (1 << 19) ++# define RADEON_FORCEON_MC (1 << 20) ++# define RADEON_FORCEON_AIC (1 << 21) ++# define R300_DISABLE_MC_MCLKA (1 << 21) ++# define R300_DISABLE_MC_MCLKB (1 << 21) ++#define RADEON_MCLK_MISC 0x001f /* PLL */ ++# define RADEON_MC_MCLK_MAX_DYN_STOP_LAT (1 << 12) ++# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) ++# define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) ++# define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) ++#define RADEON_LCD_GPIO_MASK 0x01a0 ++#define RADEON_GPIOPAD_EN 0x01a0 ++#define RADEON_LCD_GPIO_Y_REG 0x01a4 ++#define RADEON_MDGPIO_A_REG 0x01ac ++#define RADEON_MDGPIO_EN_REG 0x01b0 ++#define RADEON_MDGPIO_MASK 0x0198 ++#define RADEON_GPIOPAD_MASK 0x0198 ++#define RADEON_GPIOPAD_A 0x019c ++#define RADEON_MDGPIO_Y_REG 0x01b4 ++#define RADEON_MEM_ADDR_CONFIG 0x0148 ++#define RADEON_MEM_BASE 0x0f10 /* PCI */ ++#define RADEON_MEM_CNTL 0x0140 ++# define RADEON_MEM_NUM_CHANNELS_MASK 0x01 ++# define RADEON_MEM_USE_B_CH_ONLY (1 << 1) ++# define RV100_HALF_MODE (1 << 3) ++# define R300_MEM_NUM_CHANNELS_MASK 0x03 ++# define R300_MEM_USE_CD_CH_ONLY (1 << 2) ++#define RADEON_MEM_TIMING_CNTL 0x0144 /* EXT_MEM_CNTL */ ++#define RADEON_MEM_INIT_LAT_TIMER 0x0154 ++#define RADEON_MEM_INTF_CNTL 0x014c ++#define RADEON_MEM_SDRAM_MODE_REG 0x0158 ++# define RADEON_SDRAM_MODE_MASK 0xffff0000 ++# define RADEON_B3MEM_RESET_MASK 0x6fffffff ++# define RADEON_MEM_CFG_TYPE_DDR (1 << 30) ++#define RADEON_MEM_STR_CNTL 0x0150 ++# define RADEON_MEM_PWRUP_COMPL_A (1 << 0) ++# define RADEON_MEM_PWRUP_COMPL_B (1 << 1) ++# define R300_MEM_PWRUP_COMPL_C (1 << 2) ++# define R300_MEM_PWRUP_COMPL_D (1 << 3) ++# define RADEON_MEM_PWRUP_COMPLETE 0x03 ++# define R300_MEM_PWRUP_COMPLETE 0x0f ++#define RADEON_MC_STATUS 0x0150 ++# define RADEON_MC_IDLE (1 << 2) ++# define R300_MC_IDLE (1 << 4) ++#define RADEON_MEM_VGA_RP_SEL 0x003c ++#define RADEON_MEM_VGA_WP_SEL 0x0038 ++#define RADEON_MIN_GRANT 0x0f3e /* PCI */ ++#define RADEON_MM_DATA 0x0004 ++#define RADEON_MM_INDEX 0x0000 ++#define RADEON_MPLL_CNTL 0x000e /* PLL */ ++#define RADEON_MPP_TB_CONFIG 0x01c0 /* ? */ ++#define RADEON_MPP_GP_CONFIG 0x01c8 /* ? */ ++#define RADEON_SEPROM_CNTL1 0x01c0 ++# define RADEON_SCK_PRESCALE_SHIFT 24 ++# define RADEON_SCK_PRESCALE_MASK (0xff << 24) ++#define R300_MC_IND_INDEX 0x01f8 ++# define R300_MC_IND_ADDR_MASK 0x3f ++# define R300_MC_IND_WR_EN (1 << 8) ++#define R300_MC_IND_DATA 0x01fc ++#define R300_MC_READ_CNTL_AB 0x017c ++# define R300_MEM_RBS_POSITION_A_MASK 0x03 ++#define R300_MC_READ_CNTL_CD_mcind 0x24 ++# define R300_MEM_RBS_POSITION_C_MASK 0x03 ++ ++#define RADEON_N_VIF_COUNT 0x0248 ++ ++#define RADEON_OV0_AUTO_FLIP_CNTL 0x0470 ++# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_NUM 0x00000007 ++# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_REPEAT_FIELD 0x00000008 ++# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 0x00000010 ++# define RADEON_OV0_AUTO_FLIP_CNTL_IGNORE_REPEAT_FIELD 0x00000020 ++# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE 0x00000040 ++# define RADEON_OV0_AUTO_FLIP_CNTL_VID_PORT_SELECT 0x00000300 ++# define RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN 0x00010000 ++# define RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN 0x00040000 ++# define RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN 0x00080000 ++# define RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE 0x00800000 ++ ++#define RADEON_OV0_COLOUR_CNTL 0x04E0 ++#define RADEON_OV0_DEINTERLACE_PATTERN 0x0474 ++#define RADEON_OV0_EXCLUSIVE_HORZ 0x0408 ++# define RADEON_EXCL_HORZ_START_MASK 0x000000ff ++# define RADEON_EXCL_HORZ_END_MASK 0x0000ff00 ++# define RADEON_EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 ++# define RADEON_EXCL_HORZ_EXCLUSIVE_EN 0x80000000 ++#define RADEON_OV0_EXCLUSIVE_VERT 0x040C ++# define RADEON_EXCL_VERT_START_MASK 0x000003ff ++# define RADEON_EXCL_VERT_END_MASK 0x03ff0000 ++#define RADEON_OV0_FILTER_CNTL 0x04A0 ++# define RADEON_FILTER_PROGRAMMABLE_COEF 0x0 ++# define RADEON_FILTER_HC_COEF_HORZ_Y 0x1 ++# define RADEON_FILTER_HC_COEF_HORZ_UV 0x2 ++# define RADEON_FILTER_HC_COEF_VERT_Y 0x4 ++# define RADEON_FILTER_HC_COEF_VERT_UV 0x8 ++# define RADEON_FILTER_HARDCODED_COEF 0xf ++# define RADEON_FILTER_COEF_MASK 0xf ++ ++#define RADEON_OV0_FOUR_TAP_COEF_0 0x04B0 ++#define RADEON_OV0_FOUR_TAP_COEF_1 0x04B4 ++#define RADEON_OV0_FOUR_TAP_COEF_2 0x04B8 ++#define RADEON_OV0_FOUR_TAP_COEF_3 0x04BC ++#define RADEON_OV0_FOUR_TAP_COEF_4 0x04C0 ++#define RADEON_OV0_FLAG_CNTL 0x04DC ++#define RADEON_OV0_GAMMA_000_00F 0x0d40 ++#define RADEON_OV0_GAMMA_010_01F 0x0d44 ++#define RADEON_OV0_GAMMA_020_03F 0x0d48 ++#define RADEON_OV0_GAMMA_040_07F 0x0d4c ++#define RADEON_OV0_GAMMA_080_0BF 0x0e00 ++#define RADEON_OV0_GAMMA_0C0_0FF 0x0e04 ++#define RADEON_OV0_GAMMA_100_13F 0x0e08 ++#define RADEON_OV0_GAMMA_140_17F 0x0e0c ++#define RADEON_OV0_GAMMA_180_1BF 0x0e10 ++#define RADEON_OV0_GAMMA_1C0_1FF 0x0e14 ++#define RADEON_OV0_GAMMA_200_23F 0x0e18 ++#define RADEON_OV0_GAMMA_240_27F 0x0e1c ++#define RADEON_OV0_GAMMA_280_2BF 0x0e20 ++#define RADEON_OV0_GAMMA_2C0_2FF 0x0e24 ++#define RADEON_OV0_GAMMA_300_33F 0x0e28 ++#define RADEON_OV0_GAMMA_340_37F 0x0e2c ++#define RADEON_OV0_GAMMA_380_3BF 0x0d50 ++#define RADEON_OV0_GAMMA_3C0_3FF 0x0d54 ++#define RADEON_OV0_GRAPHICS_KEY_CLR_LOW 0x04EC ++#define RADEON_OV0_GRAPHICS_KEY_CLR_HIGH 0x04F0 ++#define RADEON_OV0_H_INC 0x0480 ++#define RADEON_OV0_KEY_CNTL 0x04F4 ++# define RADEON_VIDEO_KEY_FN_MASK 0x00000003L ++# define RADEON_VIDEO_KEY_FN_FALSE 0x00000000L ++# define RADEON_VIDEO_KEY_FN_TRUE 0x00000001L ++# define RADEON_VIDEO_KEY_FN_EQ 0x00000002L ++# define RADEON_VIDEO_KEY_FN_NE 0x00000003L ++# define RADEON_GRAPHIC_KEY_FN_MASK 0x00000030L ++# define RADEON_GRAPHIC_KEY_FN_FALSE 0x00000000L ++# define RADEON_GRAPHIC_KEY_FN_TRUE 0x00000010L ++# define RADEON_GRAPHIC_KEY_FN_EQ 0x00000020L ++# define RADEON_GRAPHIC_KEY_FN_NE 0x00000030L ++# define RADEON_CMP_MIX_MASK 0x00000100L ++# define RADEON_CMP_MIX_OR 0x00000000L ++# define RADEON_CMP_MIX_AND 0x00000100L ++#define RADEON_OV0_LIN_TRANS_A 0x0d20 ++#define RADEON_OV0_LIN_TRANS_B 0x0d24 ++#define RADEON_OV0_LIN_TRANS_C 0x0d28 ++#define RADEON_OV0_LIN_TRANS_D 0x0d2c ++#define RADEON_OV0_LIN_TRANS_E 0x0d30 ++#define RADEON_OV0_LIN_TRANS_F 0x0d34 ++#define RADEON_OV0_P1_BLANK_LINES_AT_TOP 0x0430 ++# define RADEON_P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL ++# define RADEON_P1_ACTIVE_LINES_M1 0x0fff0000L ++#define RADEON_OV0_P1_H_ACCUM_INIT 0x0488 ++#define RADEON_OV0_P1_V_ACCUM_INIT 0x0428 ++# define RADEON_OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L ++# define RADEON_OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L ++#define RADEON_OV0_P1_X_START_END 0x0494 ++#define RADEON_OV0_P2_X_START_END 0x0498 ++#define RADEON_OV0_P23_BLANK_LINES_AT_TOP 0x0434 ++# define RADEON_P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ffL ++# define RADEON_P23_ACTIVE_LINES_M1 0x07ff0000L ++#define RADEON_OV0_P23_H_ACCUM_INIT 0x048C ++#define RADEON_OV0_P23_V_ACCUM_INIT 0x042C ++#define RADEON_OV0_P3_X_START_END 0x049C ++#define RADEON_OV0_REG_LOAD_CNTL 0x0410 ++# define RADEON_REG_LD_CTL_LOCK 0x00000001L ++# define RADEON_REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L ++# define RADEON_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L ++# define RADEON_REG_LD_CTL_LOCK_READBACK 0x00000008L ++# define RADEON_REG_LD_CTL_FLIP_READBACK 0x00000010L ++#define RADEON_OV0_SCALE_CNTL 0x0420 ++# define RADEON_SCALER_HORZ_PICK_NEAREST 0x00000004L ++# define RADEON_SCALER_VERT_PICK_NEAREST 0x00000008L ++# define RADEON_SCALER_SIGNED_UV 0x00000010L ++# define RADEON_SCALER_GAMMA_SEL_MASK 0x00000060L ++# define RADEON_SCALER_GAMMA_SEL_BRIGHT 0x00000000L ++# define RADEON_SCALER_GAMMA_SEL_G22 0x00000020L ++# define RADEON_SCALER_GAMMA_SEL_G18 0x00000040L ++# define RADEON_SCALER_GAMMA_SEL_G14 0x00000060L ++# define RADEON_SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L ++# define RADEON_SCALER_SURFAC_FORMAT 0x00000f00L ++# define RADEON_SCALER_SOURCE_15BPP 0x00000300L ++# define RADEON_SCALER_SOURCE_16BPP 0x00000400L ++# define RADEON_SCALER_SOURCE_32BPP 0x00000600L ++# define RADEON_SCALER_SOURCE_YUV9 0x00000900L ++# define RADEON_SCALER_SOURCE_YUV12 0x00000A00L ++# define RADEON_SCALER_SOURCE_VYUY422 0x00000B00L ++# define RADEON_SCALER_SOURCE_YVYU422 0x00000C00L ++# define RADEON_SCALER_ADAPTIVE_DEINT 0x00001000L ++# define RADEON_SCALER_TEMPORAL_DEINT 0x00002000L ++# define RADEON_SCALER_CRTC_SEL 0x00004000L ++# define RADEON_SCALER_SMART_SWITCH 0x00008000L ++# define RADEON_SCALER_BURST_PER_PLANE 0x007F0000L ++# define RADEON_SCALER_DOUBLE_BUFFER 0x01000000L ++# define RADEON_SCALER_DIS_LIMIT 0x08000000L ++# define RADEON_SCALER_LIN_TRANS_BYPASS 0x10000000L ++# define RADEON_SCALER_INT_EMU 0x20000000L ++# define RADEON_SCALER_ENABLE 0x40000000L ++# define RADEON_SCALER_SOFT_RESET 0x80000000L ++#define RADEON_OV0_STEP_BY 0x0484 ++#define RADEON_OV0_TEST 0x04F8 ++#define RADEON_OV0_V_INC 0x0424 ++#define RADEON_OV0_VID_BUF_PITCH0_VALUE 0x0460 ++#define RADEON_OV0_VID_BUF_PITCH1_VALUE 0x0464 ++#define RADEON_OV0_VID_BUF0_BASE_ADRS 0x0440 ++# define RADEON_VIF_BUF0_PITCH_SEL 0x00000001L ++# define RADEON_VIF_BUF0_TILE_ADRS 0x00000002L ++# define RADEON_VIF_BUF0_BASE_ADRS_MASK 0x03fffff0L ++# define RADEON_VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000L ++#define RADEON_OV0_VID_BUF1_BASE_ADRS 0x0444 ++# define RADEON_VIF_BUF1_PITCH_SEL 0x00000001L ++# define RADEON_VIF_BUF1_TILE_ADRS 0x00000002L ++# define RADEON_VIF_BUF1_BASE_ADRS_MASK 0x03fffff0L ++# define RADEON_VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000L ++#define RADEON_OV0_VID_BUF2_BASE_ADRS 0x0448 ++# define RADEON_VIF_BUF2_PITCH_SEL 0x00000001L ++# define RADEON_VIF_BUF2_TILE_ADRS 0x00000002L ++# define RADEON_VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L ++# define RADEON_VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L ++#define RADEON_OV0_VID_BUF3_BASE_ADRS 0x044C ++#define RADEON_OV0_VID_BUF4_BASE_ADRS 0x0450 ++#define RADEON_OV0_VID_BUF5_BASE_ADRS 0x0454 ++#define RADEON_OV0_VIDEO_KEY_CLR_HIGH 0x04E8 ++#define RADEON_OV0_VIDEO_KEY_CLR_LOW 0x04E4 ++#define RADEON_OV0_Y_X_START 0x0400 ++#define RADEON_OV0_Y_X_END 0x0404 ++#define RADEON_OV1_Y_X_START 0x0600 ++#define RADEON_OV1_Y_X_END 0x0604 ++#define RADEON_OVR_CLR 0x0230 ++#define RADEON_OVR_WID_LEFT_RIGHT 0x0234 ++#define RADEON_OVR_WID_TOP_BOTTOM 0x0238 ++ ++/* first capture unit */ ++ ++#define RADEON_CAP0_BUF0_OFFSET 0x0920 ++#define RADEON_CAP0_BUF1_OFFSET 0x0924 ++#define RADEON_CAP0_BUF0_EVEN_OFFSET 0x0928 ++#define RADEON_CAP0_BUF1_EVEN_OFFSET 0x092C ++ ++#define RADEON_CAP0_BUF_PITCH 0x0930 ++#define RADEON_CAP0_V_WINDOW 0x0934 ++#define RADEON_CAP0_H_WINDOW 0x0938 ++#define RADEON_CAP0_VBI0_OFFSET 0x093C ++#define RADEON_CAP0_VBI1_OFFSET 0x0940 ++#define RADEON_CAP0_VBI_V_WINDOW 0x0944 ++#define RADEON_CAP0_VBI_H_WINDOW 0x0948 ++#define RADEON_CAP0_PORT_MODE_CNTL 0x094C ++#define RADEON_CAP0_TRIG_CNTL 0x0950 ++#define RADEON_CAP0_DEBUG 0x0954 ++#define RADEON_CAP0_CONFIG 0x0958 ++# define RADEON_CAP0_CONFIG_CONTINUOS 0x00000001 ++# define RADEON_CAP0_CONFIG_START_FIELD_EVEN 0x00000002 ++# define RADEON_CAP0_CONFIG_START_BUF_GET 0x00000004 ++# define RADEON_CAP0_CONFIG_START_BUF_SET 0x00000008 ++# define RADEON_CAP0_CONFIG_BUF_TYPE_ALT 0x00000010 ++# define RADEON_CAP0_CONFIG_BUF_TYPE_FRAME 0x00000020 ++# define RADEON_CAP0_CONFIG_ONESHOT_MODE_FRAME 0x00000040 ++# define RADEON_CAP0_CONFIG_BUF_MODE_DOUBLE 0x00000080 ++# define RADEON_CAP0_CONFIG_BUF_MODE_TRIPLE 0x00000100 ++# define RADEON_CAP0_CONFIG_MIRROR_EN 0x00000200 ++# define RADEON_CAP0_CONFIG_ONESHOT_MIRROR_EN 0x00000400 ++# define RADEON_CAP0_CONFIG_VIDEO_SIGNED_UV 0x00000800 ++# define RADEON_CAP0_CONFIG_ANC_DECODE_EN 0x00001000 ++# define RADEON_CAP0_CONFIG_VBI_EN 0x00002000 ++# define RADEON_CAP0_CONFIG_SOFT_PULL_DOWN_EN 0x00004000 ++# define RADEON_CAP0_CONFIG_VIP_EXTEND_FLAG_EN 0x00008000 ++# define RADEON_CAP0_CONFIG_FAKE_FIELD_EN 0x00010000 ++# define RADEON_CAP0_CONFIG_ODD_ONE_MORE_LINE 0x00020000 ++# define RADEON_CAP0_CONFIG_EVEN_ONE_MORE_LINE 0x00040000 ++# define RADEON_CAP0_CONFIG_HORZ_DIVIDE_2 0x00080000 ++# define RADEON_CAP0_CONFIG_HORZ_DIVIDE_4 0x00100000 ++# define RADEON_CAP0_CONFIG_VERT_DIVIDE_2 0x00200000 ++# define RADEON_CAP0_CONFIG_VERT_DIVIDE_4 0x00400000 ++# define RADEON_CAP0_CONFIG_FORMAT_BROOKTREE 0x00000000 ++# define RADEON_CAP0_CONFIG_FORMAT_CCIR656 0x00800000 ++# define RADEON_CAP0_CONFIG_FORMAT_ZV 0x01000000 ++# define RADEON_CAP0_CONFIG_FORMAT_VIP 0x01800000 ++# define RADEON_CAP0_CONFIG_FORMAT_TRANSPORT 0x02000000 ++# define RADEON_CAP0_CONFIG_HORZ_DECIMATOR 0x04000000 ++# define RADEON_CAP0_CONFIG_VIDEO_IN_YVYU422 0x00000000 ++# define RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422 0x20000000 ++# define RADEON_CAP0_CONFIG_VBI_DIVIDE_2 0x40000000 ++# define RADEON_CAP0_CONFIG_VBI_DIVIDE_4 0x80000000 ++#define RADEON_CAP0_ANC_ODD_OFFSET 0x095C ++#define RADEON_CAP0_ANC_EVEN_OFFSET 0x0960 ++#define RADEON_CAP0_ANC_H_WINDOW 0x0964 ++#define RADEON_CAP0_VIDEO_SYNC_TEST 0x0968 ++#define RADEON_CAP0_ONESHOT_BUF_OFFSET 0x096C ++#define RADEON_CAP0_BUF_STATUS 0x0970 ++/* #define RADEON_CAP0_DWNSC_XRATIO 0x0978 */ ++/* #define RADEON_CAP0_XSHARPNESS 0x097C */ ++#define RADEON_CAP0_VBI2_OFFSET 0x0980 ++#define RADEON_CAP0_VBI3_OFFSET 0x0984 ++#define RADEON_CAP0_ANC2_OFFSET 0x0988 ++#define RADEON_CAP0_ANC3_OFFSET 0x098C ++#define RADEON_VID_BUFFER_CONTROL 0x0900 ++ ++/* second capture unit */ ++ ++#define RADEON_CAP1_BUF0_OFFSET 0x0990 ++#define RADEON_CAP1_BUF1_OFFSET 0x0994 ++#define RADEON_CAP1_BUF0_EVEN_OFFSET 0x0998 ++#define RADEON_CAP1_BUF1_EVEN_OFFSET 0x099C ++ ++#define RADEON_CAP1_BUF_PITCH 0x09A0 ++#define RADEON_CAP1_V_WINDOW 0x09A4 ++#define RADEON_CAP1_H_WINDOW 0x09A8 ++#define RADEON_CAP1_VBI_ODD_OFFSET 0x09AC ++#define RADEON_CAP1_VBI_EVEN_OFFSET 0x09B0 ++#define RADEON_CAP1_VBI_V_WINDOW 0x09B4 ++#define RADEON_CAP1_VBI_H_WINDOW 0x09B8 ++#define RADEON_CAP1_PORT_MODE_CNTL 0x09BC ++#define RADEON_CAP1_TRIG_CNTL 0x09C0 ++#define RADEON_CAP1_DEBUG 0x09C4 ++#define RADEON_CAP1_CONFIG 0x09C8 ++#define RADEON_CAP1_ANC_ODD_OFFSET 0x09CC ++#define RADEON_CAP1_ANC_EVEN_OFFSET 0x09D0 ++#define RADEON_CAP1_ANC_H_WINDOW 0x09D4 ++#define RADEON_CAP1_VIDEO_SYNC_TEST 0x09D8 ++#define RADEON_CAP1_ONESHOT_BUF_OFFSET 0x09DC ++#define RADEON_CAP1_BUF_STATUS 0x09E0 ++#define RADEON_CAP1_DWNSC_XRATIO 0x09E8 ++#define RADEON_CAP1_XSHARPNESS 0x09EC ++ ++/* misc multimedia registers */ ++ ++#define RADEON_IDCT_RUNS 0x1F80 ++#define RADEON_IDCT_LEVELS 0x1F84 ++#define RADEON_IDCT_CONTROL 0x1FBC ++#define RADEON_IDCT_AUTH_CONTROL 0x1F88 ++#define RADEON_IDCT_AUTH 0x1F8C ++ ++#define RADEON_P2PLL_CNTL 0x002a /* P2PLL */ ++# define RADEON_P2PLL_RESET (1 << 0) ++# define RADEON_P2PLL_SLEEP (1 << 1) ++# define RADEON_P2PLL_PVG_MASK (7 << 11) ++# define RADEON_P2PLL_PVG_SHIFT 11 ++# define RADEON_P2PLL_ATOMIC_UPDATE_EN (1 << 16) ++# define RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN (1 << 17) ++# define RADEON_P2PLL_ATOMIC_UPDATE_VSYNC (1 << 18) ++#define RADEON_P2PLL_DIV_0 0x002c ++# define RADEON_P2PLL_FB0_DIV_MASK 0x07ff ++# define RADEON_P2PLL_POST0_DIV_MASK 0x00070000 ++#define RADEON_P2PLL_REF_DIV 0x002B /* PLL */ ++# define RADEON_P2PLL_REF_DIV_MASK 0x03ff ++# define RADEON_P2PLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ ++# define RADEON_P2PLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ ++# define R300_PPLL_REF_DIV_ACC_MASK (0x3ff << 18) ++# define R300_PPLL_REF_DIV_ACC_SHIFT 18 ++#define RADEON_PALETTE_DATA 0x00b4 ++#define RADEON_PALETTE_30_DATA 0x00b8 ++#define RADEON_PALETTE_INDEX 0x00b0 ++#define RADEON_PCI_GART_PAGE 0x017c ++#define RADEON_PIXCLKS_CNTL 0x002d ++# define RADEON_PIX2CLK_SRC_SEL_MASK 0x03 ++# define RADEON_PIX2CLK_SRC_SEL_CPUCLK 0x00 ++# define RADEON_PIX2CLK_SRC_SEL_PSCANCLK 0x01 ++# define RADEON_PIX2CLK_SRC_SEL_BYTECLK 0x02 ++# define RADEON_PIX2CLK_SRC_SEL_P2PLLCLK 0x03 ++# define RADEON_PIX2CLK_ALWAYS_ONb (1<<6) ++# define RADEON_PIX2CLK_DAC_ALWAYS_ONb (1<<7) ++# define RADEON_PIXCLK_TV_SRC_SEL (1 << 8) ++# define RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb (1 << 9) ++# define R300_DVOCLK_ALWAYS_ONb (1 << 10) ++# define RADEON_PIXCLK_BLEND_ALWAYS_ONb (1 << 11) ++# define RADEON_PIXCLK_GV_ALWAYS_ONb (1 << 12) ++# define RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb (1 << 13) ++# define R300_PIXCLK_DVO_ALWAYS_ONb (1 << 13) ++# define RADEON_PIXCLK_LVDS_ALWAYS_ONb (1 << 14) ++# define RADEON_PIXCLK_TMDS_ALWAYS_ONb (1 << 15) ++# define R300_PIXCLK_TRANS_ALWAYS_ONb (1 << 16) ++# define R300_PIXCLK_TVO_ALWAYS_ONb (1 << 17) ++# define R300_P2G2CLK_ALWAYS_ONb (1 << 18) ++# define R300_P2G2CLK_DAC_ALWAYS_ONb (1 << 19) ++# define R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF (1 << 23) ++#define RADEON_PLANE_3D_MASK_C 0x1d44 ++#define RADEON_PLL_TEST_CNTL 0x0013 /* PLL */ ++# define RADEON_PLL_MASK_READ_B (1 << 9) ++#define RADEON_PMI_CAP_ID 0x0f5c /* PCI */ ++#define RADEON_PMI_DATA 0x0f63 /* PCI */ ++#define RADEON_PMI_NXT_CAP_PTR 0x0f5d /* PCI */ ++#define RADEON_PMI_PMC_REG 0x0f5e /* PCI */ ++#define RADEON_PMI_PMCSR_REG 0x0f60 /* PCI */ ++#define RADEON_PMI_REGISTER 0x0f5c /* PCI */ ++#define RADEON_PPLL_CNTL 0x0002 /* PLL */ ++# define RADEON_PPLL_RESET (1 << 0) ++# define RADEON_PPLL_SLEEP (1 << 1) ++# define RADEON_PPLL_PVG_MASK (7 << 11) ++# define RADEON_PPLL_PVG_SHIFT 11 ++# define RADEON_PPLL_ATOMIC_UPDATE_EN (1 << 16) ++# define RADEON_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) ++# define RADEON_PPLL_ATOMIC_UPDATE_VSYNC (1 << 18) ++#define RADEON_PPLL_DIV_0 0x0004 /* PLL */ ++#define RADEON_PPLL_DIV_1 0x0005 /* PLL */ ++#define RADEON_PPLL_DIV_2 0x0006 /* PLL */ ++#define RADEON_PPLL_DIV_3 0x0007 /* PLL */ ++# define RADEON_PPLL_FB3_DIV_MASK 0x07ff ++# define RADEON_PPLL_POST3_DIV_MASK 0x00070000 ++#define RADEON_PPLL_REF_DIV 0x0003 /* PLL */ ++# define RADEON_PPLL_REF_DIV_MASK 0x03ff ++# define RADEON_PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ ++# define RADEON_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ ++#define RADEON_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ ++ ++#define RADEON_RBBM_GUICNTL 0x172c ++# define RADEON_HOST_DATA_SWAP_NONE (0 << 0) ++# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) ++# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0) ++# define RADEON_HOST_DATA_SWAP_HDW (3 << 0) ++#define RADEON_RBBM_SOFT_RESET 0x00f0 ++# define RADEON_SOFT_RESET_CP (1 << 0) ++# define RADEON_SOFT_RESET_HI (1 << 1) ++# define RADEON_SOFT_RESET_SE (1 << 2) ++# define RADEON_SOFT_RESET_RE (1 << 3) ++# define RADEON_SOFT_RESET_PP (1 << 4) ++# define RADEON_SOFT_RESET_E2 (1 << 5) ++# define RADEON_SOFT_RESET_RB (1 << 6) ++# define RADEON_SOFT_RESET_HDP (1 << 7) ++#define RADEON_RBBM_STATUS 0x0e40 ++# define RADEON_RBBM_FIFOCNT_MASK 0x007f ++# define RADEON_RBBM_ACTIVE (1 << 31) ++#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c ++# define RADEON_RB2D_DC_FLUSH (3 << 0) ++# define RADEON_RB2D_DC_FREE (3 << 2) ++# define RADEON_RB2D_DC_FLUSH_ALL 0xf ++# define RADEON_RB2D_DC_BUSY (1 << 31) ++#define RADEON_RB2D_DSTCACHE_MODE 0x3428 ++#define RADEON_DSTCACHE_CTLSTAT 0x1714 ++ ++#define RADEON_RB3D_ZCACHE_MODE 0x3250 ++#define RADEON_RB3D_ZCACHE_CTLSTAT 0x3254 ++# define RADEON_RB3D_ZC_FLUSH_ALL 0x5 ++#define RADEON_RB3D_DSTCACHE_MODE 0x3258 ++# define RADEON_RB3D_DC_CACHE_ENABLE (0) ++# define RADEON_RB3D_DC_2D_CACHE_DISABLE (1) ++# define RADEON_RB3D_DC_3D_CACHE_DISABLE (2) ++# define RADEON_RB3D_DC_CACHE_DISABLE (3) ++# define RADEON_RB3D_DC_2D_CACHE_LINESIZE_128 (1 << 2) ++# define RADEON_RB3D_DC_3D_CACHE_LINESIZE_128 (2 << 2) ++# define RADEON_RB3D_DC_2D_CACHE_AUTOFLUSH (1 << 8) ++# define RADEON_RB3D_DC_3D_CACHE_AUTOFLUSH (2 << 8) ++# define R200_RB3D_DC_2D_CACHE_AUTOFREE (1 << 10) ++# define R200_RB3D_DC_3D_CACHE_AUTOFREE (2 << 10) ++# define RADEON_RB3D_DC_FORCE_RMW (1 << 16) ++# define RADEON_RB3D_DC_DISABLE_RI_FILL (1 << 24) ++# define RADEON_RB3D_DC_DISABLE_RI_READ (1 << 25) ++ ++#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325C ++# define RADEON_RB3D_DC_FLUSH (3 << 0) ++# define RADEON_RB3D_DC_FREE (3 << 2) ++# define RADEON_RB3D_DC_FLUSH_ALL 0xf ++# define RADEON_RB3D_DC_BUSY (1 << 31) ++ ++#define RADEON_REG_BASE 0x0f18 /* PCI */ ++#define RADEON_REGPROG_INF 0x0f09 /* PCI */ ++#define RADEON_REVISION_ID 0x0f08 /* PCI */ ++ ++#define RADEON_SC_BOTTOM 0x164c ++#define RADEON_SC_BOTTOM_RIGHT 0x16f0 ++#define RADEON_SC_BOTTOM_RIGHT_C 0x1c8c ++#define RADEON_SC_LEFT 0x1640 ++#define RADEON_SC_RIGHT 0x1644 ++#define RADEON_SC_TOP 0x1648 ++#define RADEON_SC_TOP_LEFT 0x16ec ++#define RADEON_SC_TOP_LEFT_C 0x1c88 ++# define RADEON_SC_SIGN_MASK_LO 0x8000 ++# define RADEON_SC_SIGN_MASK_HI 0x80000000 ++#define RADEON_M_SPLL_REF_FB_DIV 0x000a /* PLL */ ++# define RADEON_M_SPLL_REF_DIV_SHIFT 0 ++# define RADEON_M_SPLL_REF_DIV_MASK 0xff ++# define RADEON_MPLL_FB_DIV_SHIFT 8 ++# define RADEON_MPLL_FB_DIV_MASK 0xff ++# define RADEON_SPLL_FB_DIV_SHIFT 16 ++# define RADEON_SPLL_FB_DIV_MASK 0xff ++#define RADEON_SCLK_CNTL 0x000d /* PLL */ ++# define RADEON_SCLK_SRC_SEL_MASK 0x0007 ++# define RADEON_DYN_STOP_LAT_MASK 0x00007ff8 ++# define RADEON_CP_MAX_DYN_STOP_LAT 0x0008 ++# define RADEON_SCLK_FORCEON_MASK 0xffff8000 ++# define RADEON_SCLK_FORCE_DISP2 (1<<15) ++# define RADEON_SCLK_FORCE_CP (1<<16) ++# define RADEON_SCLK_FORCE_HDP (1<<17) ++# define RADEON_SCLK_FORCE_DISP1 (1<<18) ++# define RADEON_SCLK_FORCE_TOP (1<<19) ++# define RADEON_SCLK_FORCE_E2 (1<<20) ++# define RADEON_SCLK_FORCE_SE (1<<21) ++# define RADEON_SCLK_FORCE_IDCT (1<<22) ++# define RADEON_SCLK_FORCE_VIP (1<<23) ++# define RADEON_SCLK_FORCE_RE (1<<24) ++# define RADEON_SCLK_FORCE_PB (1<<25) ++# define RADEON_SCLK_FORCE_TAM (1<<26) ++# define RADEON_SCLK_FORCE_TDM (1<<27) ++# define RADEON_SCLK_FORCE_RB (1<<28) ++# define RADEON_SCLK_FORCE_TV_SCLK (1<<29) ++# define RADEON_SCLK_FORCE_SUBPIC (1<<30) ++# define RADEON_SCLK_FORCE_OV0 (1<<31) ++# define R300_SCLK_FORCE_VAP (1<<21) ++# define R300_SCLK_FORCE_SR (1<<25) ++# define R300_SCLK_FORCE_PX (1<<26) ++# define R300_SCLK_FORCE_TX (1<<27) ++# define R300_SCLK_FORCE_US (1<<28) ++# define R300_SCLK_FORCE_SU (1<<30) ++#define R300_SCLK_CNTL2 0x1e /* PLL */ ++# define R300_SCLK_TCL_MAX_DYN_STOP_LAT (1<<10) ++# define R300_SCLK_GA_MAX_DYN_STOP_LAT (1<<11) ++# define R300_SCLK_CBA_MAX_DYN_STOP_LAT (1<<12) ++# define R300_SCLK_FORCE_TCL (1<<13) ++# define R300_SCLK_FORCE_CBA (1<<14) ++# define R300_SCLK_FORCE_GA (1<<15) ++#define RADEON_SCLK_MORE_CNTL 0x0035 /* PLL */ ++# define RADEON_SCLK_MORE_MAX_DYN_STOP_LAT 0x0007 ++# define RADEON_SCLK_MORE_FORCEON 0x0700 ++#define RADEON_SDRAM_MODE_REG 0x0158 ++#define RADEON_SEQ8_DATA 0x03c5 /* VGA */ ++#define RADEON_SEQ8_IDX 0x03c4 /* VGA */ ++#define RADEON_SNAPSHOT_F_COUNT 0x0244 ++#define RADEON_SNAPSHOT_VH_COUNTS 0x0240 ++#define RADEON_SNAPSHOT_VIF_COUNT 0x024c ++#define RADEON_SRC_OFFSET 0x15ac ++#define RADEON_SRC_PITCH 0x15b0 ++#define RADEON_SRC_PITCH_OFFSET 0x1428 ++#define RADEON_SRC_SC_BOTTOM 0x165c ++#define RADEON_SRC_SC_BOTTOM_RIGHT 0x16f4 ++#define RADEON_SRC_SC_RIGHT 0x1654 ++#define RADEON_SRC_X 0x1414 ++#define RADEON_SRC_X_Y 0x1590 ++#define RADEON_SRC_Y 0x1418 ++#define RADEON_SRC_Y_X 0x1434 ++#define RADEON_STATUS 0x0f06 /* PCI */ ++#define RADEON_SUBPIC_CNTL 0x0540 /* ? */ ++#define RADEON_SUB_CLASS 0x0f0a /* PCI */ ++#define RADEON_SURFACE_CNTL 0x0b00 ++# define RADEON_SURF_TRANSLATION_DIS (1 << 8) ++# define RADEON_NONSURF_AP0_SWP_16BPP (1 << 20) ++# define RADEON_NONSURF_AP0_SWP_32BPP (1 << 21) ++# define RADEON_NONSURF_AP1_SWP_16BPP (1 << 22) ++# define RADEON_NONSURF_AP1_SWP_32BPP (1 << 23) ++#define RADEON_SURFACE0_INFO 0x0b0c ++# define RADEON_SURF_TILE_COLOR_MACRO (0 << 16) ++# define RADEON_SURF_TILE_COLOR_BOTH (1 << 16) ++# define RADEON_SURF_TILE_DEPTH_32BPP (2 << 16) ++# define RADEON_SURF_TILE_DEPTH_16BPP (3 << 16) ++# define R200_SURF_TILE_NONE (0 << 16) ++# define R200_SURF_TILE_COLOR_MACRO (1 << 16) ++# define R200_SURF_TILE_COLOR_MICRO (2 << 16) ++# define R200_SURF_TILE_COLOR_BOTH (3 << 16) ++# define R200_SURF_TILE_DEPTH_32BPP (4 << 16) ++# define R200_SURF_TILE_DEPTH_16BPP (5 << 16) ++# define R300_SURF_TILE_NONE (0 << 16) ++# define R300_SURF_TILE_COLOR_MACRO (1 << 16) ++# define R300_SURF_TILE_DEPTH_32BPP (2 << 16) ++# define RADEON_SURF_AP0_SWP_16BPP (1 << 20) ++# define RADEON_SURF_AP0_SWP_32BPP (1 << 21) ++# define RADEON_SURF_AP1_SWP_16BPP (1 << 22) ++# define RADEON_SURF_AP1_SWP_32BPP (1 << 23) ++#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 ++#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 ++#define RADEON_SURFACE1_INFO 0x0b1c ++#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 ++#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 ++#define RADEON_SURFACE2_INFO 0x0b2c ++#define RADEON_SURFACE2_LOWER_BOUND 0x0b24 ++#define RADEON_SURFACE2_UPPER_BOUND 0x0b28 ++#define RADEON_SURFACE3_INFO 0x0b3c ++#define RADEON_SURFACE3_LOWER_BOUND 0x0b34 ++#define RADEON_SURFACE3_UPPER_BOUND 0x0b38 ++#define RADEON_SURFACE4_INFO 0x0b4c ++#define RADEON_SURFACE4_LOWER_BOUND 0x0b44 ++#define RADEON_SURFACE4_UPPER_BOUND 0x0b48 ++#define RADEON_SURFACE5_INFO 0x0b5c ++#define RADEON_SURFACE5_LOWER_BOUND 0x0b54 ++#define RADEON_SURFACE5_UPPER_BOUND 0x0b58 ++#define RADEON_SURFACE6_INFO 0x0b6c ++#define RADEON_SURFACE6_LOWER_BOUND 0x0b64 ++#define RADEON_SURFACE6_UPPER_BOUND 0x0b68 ++#define RADEON_SURFACE7_INFO 0x0b7c ++#define RADEON_SURFACE7_LOWER_BOUND 0x0b74 ++#define RADEON_SURFACE7_UPPER_BOUND 0x0b78 ++#define RADEON_SW_SEMAPHORE 0x013c ++ ++#define RADEON_TEST_DEBUG_CNTL 0x0120 ++#define RADEON_TEST_DEBUG_CNTL__TEST_DEBUG_OUT_EN 0x00000001 ++ ++#define RADEON_TEST_DEBUG_MUX 0x0124 ++#define RADEON_TEST_DEBUG_OUT 0x012c ++#define RADEON_TMDS_PLL_CNTL 0x02a8 ++#define RADEON_TMDS_TRANSMITTER_CNTL 0x02a4 ++# define RADEON_TMDS_TRANSMITTER_PLLEN 1 ++# define RADEON_TMDS_TRANSMITTER_PLLRST 2 ++#define RADEON_TRAIL_BRES_DEC 0x1614 ++#define RADEON_TRAIL_BRES_ERR 0x160c ++#define RADEON_TRAIL_BRES_INC 0x1610 ++#define RADEON_TRAIL_X 0x1618 ++#define RADEON_TRAIL_X_SUB 0x1620 ++ ++#define RADEON_VCLK_ECP_CNTL 0x0008 /* PLL */ ++# define RADEON_VCLK_SRC_SEL_MASK 0x03 ++# define RADEON_VCLK_SRC_SEL_CPUCLK 0x00 ++# define RADEON_VCLK_SRC_SEL_PSCANCLK 0x01 ++# define RADEON_VCLK_SRC_SEL_BYTECLK 0x02 ++# define RADEON_VCLK_SRC_SEL_PPLLCLK 0x03 ++# define RADEON_PIXCLK_ALWAYS_ONb (1<<6) ++# define RADEON_PIXCLK_DAC_ALWAYS_ONb (1<<7) ++# define R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF (1<<23) ++ ++#define RADEON_VENDOR_ID 0x0f00 /* PCI */ ++#define RADEON_VGA_DDA_CONFIG 0x02e8 ++#define RADEON_VGA_DDA_ON_OFF 0x02ec ++#define RADEON_VID_BUFFER_CONTROL 0x0900 ++#define RADEON_VIDEOMUX_CNTL 0x0190 ++ ++ /* VIP bus */ ++#define RADEON_VIPH_CH0_DATA 0x0c00 ++#define RADEON_VIPH_CH1_DATA 0x0c04 ++#define RADEON_VIPH_CH2_DATA 0x0c08 ++#define RADEON_VIPH_CH3_DATA 0x0c0c ++#define RADEON_VIPH_CH0_ADDR 0x0c10 ++#define RADEON_VIPH_CH1_ADDR 0x0c14 ++#define RADEON_VIPH_CH2_ADDR 0x0c18 ++#define RADEON_VIPH_CH3_ADDR 0x0c1c ++#define RADEON_VIPH_CH0_SBCNT 0x0c20 ++#define RADEON_VIPH_CH1_SBCNT 0x0c24 ++#define RADEON_VIPH_CH2_SBCNT 0x0c28 ++#define RADEON_VIPH_CH3_SBCNT 0x0c2c ++#define RADEON_VIPH_CH0_ABCNT 0x0c30 ++#define RADEON_VIPH_CH1_ABCNT 0x0c34 ++#define RADEON_VIPH_CH2_ABCNT 0x0c38 ++#define RADEON_VIPH_CH3_ABCNT 0x0c3c ++#define RADEON_VIPH_CONTROL 0x0c40 ++# define RADEON_VIP_BUSY 0 ++# define RADEON_VIP_IDLE 1 ++# define RADEON_VIP_RESET 2 ++# define RADEON_VIPH_EN (1 << 21) ++#define RADEON_VIPH_DV_LAT 0x0c44 ++#define RADEON_VIPH_BM_CHUNK 0x0c48 ++#define RADEON_VIPH_DV_INT 0x0c4c ++#define RADEON_VIPH_TIMEOUT_STAT 0x0c50 ++#define RADEON_VIPH_TIMEOUT_STAT__VIPH_REG_STAT 0x00000010 ++#define RADEON_VIPH_TIMEOUT_STAT__VIPH_REG_AK 0x00000010 ++#define RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS 0x01000000 ++ ++#define RADEON_VIPH_REG_DATA 0x0084 ++#define RADEON_VIPH_REG_ADDR 0x0080 ++ ++ ++#define RADEON_WAIT_UNTIL 0x1720 ++# define RADEON_WAIT_CRTC_PFLIP (1 << 0) ++# define RADEON_WAIT_RE_CRTC_VLINE (1 << 1) ++# define RADEON_WAIT_FE_CRTC_VLINE (1 << 2) ++# define RADEON_WAIT_CRTC_VLINE (1 << 3) ++# define RADEON_WAIT_DMA_VID_IDLE (1 << 8) ++# define RADEON_WAIT_DMA_GUI_IDLE (1 << 9) ++# define RADEON_WAIT_CMDFIFO (1 << 10) /* wait for CMDFIFO_ENTRIES */ ++# define RADEON_WAIT_OV0_FLIP (1 << 11) ++# define RADEON_WAIT_AGP_FLUSH (1 << 13) ++# define RADEON_WAIT_2D_IDLE (1 << 14) ++# define RADEON_WAIT_3D_IDLE (1 << 15) ++# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) ++# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) ++# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) ++# define RADEON_CMDFIFO_ENTRIES_SHIFT 10 ++# define RADEON_CMDFIFO_ENTRIES_MASK 0x7f ++# define RADEON_WAIT_VAP_IDLE (1 << 28) ++# define RADEON_WAIT_BOTH_CRTC_PFLIP (1 << 30) ++# define RADEON_ENG_DISPLAY_SELECT_CRTC0 (0 << 31) ++# define RADEON_ENG_DISPLAY_SELECT_CRTC1 (1 << 31) ++ ++#define RADEON_X_MPLL_REF_FB_DIV 0x000a /* PLL */ ++#define RADEON_XCLK_CNTL 0x000d /* PLL */ ++#define RADEON_XDLL_CNTL 0x000c /* PLL */ ++#define RADEON_XPLL_CNTL 0x000b /* PLL */ ++ ++ ++ ++ /* Registers for 3D/TCL */ ++#define RADEON_PP_BORDER_COLOR_0 0x1d40 ++#define RADEON_PP_BORDER_COLOR_1 0x1d44 ++#define RADEON_PP_BORDER_COLOR_2 0x1d48 ++#define RADEON_PP_CNTL 0x1c38 ++# define RADEON_STIPPLE_ENABLE (1 << 0) ++# define RADEON_SCISSOR_ENABLE (1 << 1) ++# define RADEON_PATTERN_ENABLE (1 << 2) ++# define RADEON_SHADOW_ENABLE (1 << 3) ++# define RADEON_TEX_ENABLE_MASK (0xf << 4) ++# define RADEON_TEX_0_ENABLE (1 << 4) ++# define RADEON_TEX_1_ENABLE (1 << 5) ++# define RADEON_TEX_2_ENABLE (1 << 6) ++# define RADEON_TEX_3_ENABLE (1 << 7) ++# define RADEON_TEX_BLEND_ENABLE_MASK (0xf << 12) ++# define RADEON_TEX_BLEND_0_ENABLE (1 << 12) ++# define RADEON_TEX_BLEND_1_ENABLE (1 << 13) ++# define RADEON_TEX_BLEND_2_ENABLE (1 << 14) ++# define RADEON_TEX_BLEND_3_ENABLE (1 << 15) ++# define RADEON_PLANAR_YUV_ENABLE (1 << 20) ++# define RADEON_SPECULAR_ENABLE (1 << 21) ++# define RADEON_FOG_ENABLE (1 << 22) ++# define RADEON_ALPHA_TEST_ENABLE (1 << 23) ++# define RADEON_ANTI_ALIAS_NONE (0 << 24) ++# define RADEON_ANTI_ALIAS_LINE (1 << 24) ++# define RADEON_ANTI_ALIAS_POLY (2 << 24) ++# define RADEON_ANTI_ALIAS_LINE_POLY (3 << 24) ++# define RADEON_BUMP_MAP_ENABLE (1 << 26) ++# define RADEON_BUMPED_MAP_T0 (0 << 27) ++# define RADEON_BUMPED_MAP_T1 (1 << 27) ++# define RADEON_BUMPED_MAP_T2 (2 << 27) ++# define RADEON_TEX_3D_ENABLE_0 (1 << 29) ++# define RADEON_TEX_3D_ENABLE_1 (1 << 30) ++# define RADEON_MC_ENABLE (1 << 31) ++#define RADEON_PP_FOG_COLOR 0x1c18 ++# define RADEON_FOG_COLOR_MASK 0x00ffffff ++# define RADEON_FOG_VERTEX (0 << 24) ++# define RADEON_FOG_TABLE (1 << 24) ++# define RADEON_FOG_USE_DEPTH (0 << 25) ++# define RADEON_FOG_USE_DIFFUSE_ALPHA (2 << 25) ++# define RADEON_FOG_USE_SPEC_ALPHA (3 << 25) ++#define RADEON_PP_LUM_MATRIX 0x1d00 ++#define RADEON_PP_MISC 0x1c14 ++# define RADEON_REF_ALPHA_MASK 0x000000ff ++# define RADEON_ALPHA_TEST_FAIL (0 << 8) ++# define RADEON_ALPHA_TEST_LESS (1 << 8) ++# define RADEON_ALPHA_TEST_LEQUAL (2 << 8) ++# define RADEON_ALPHA_TEST_EQUAL (3 << 8) ++# define RADEON_ALPHA_TEST_GEQUAL (4 << 8) ++# define RADEON_ALPHA_TEST_GREATER (5 << 8) ++# define RADEON_ALPHA_TEST_NEQUAL (6 << 8) ++# define RADEON_ALPHA_TEST_PASS (7 << 8) ++# define RADEON_ALPHA_TEST_OP_MASK (7 << 8) ++# define RADEON_CHROMA_FUNC_FAIL (0 << 16) ++# define RADEON_CHROMA_FUNC_PASS (1 << 16) ++# define RADEON_CHROMA_FUNC_NEQUAL (2 << 16) ++# define RADEON_CHROMA_FUNC_EQUAL (3 << 16) ++# define RADEON_CHROMA_KEY_NEAREST (0 << 18) ++# define RADEON_CHROMA_KEY_ZERO (1 << 18) ++# define RADEON_SHADOW_ID_AUTO_INC (1 << 20) ++# define RADEON_SHADOW_FUNC_EQUAL (0 << 21) ++# define RADEON_SHADOW_FUNC_NEQUAL (1 << 21) ++# define RADEON_SHADOW_PASS_1 (0 << 22) ++# define RADEON_SHADOW_PASS_2 (1 << 22) ++# define RADEON_RIGHT_HAND_CUBE_D3D (0 << 24) ++# define RADEON_RIGHT_HAND_CUBE_OGL (1 << 24) ++#define RADEON_PP_ROT_MATRIX_0 0x1d58 ++#define RADEON_PP_ROT_MATRIX_1 0x1d5c ++#define RADEON_PP_TXFILTER_0 0x1c54 ++#define RADEON_PP_TXFILTER_1 0x1c6c ++#define RADEON_PP_TXFILTER_2 0x1c84 ++# define RADEON_MAG_FILTER_NEAREST (0 << 0) ++# define RADEON_MAG_FILTER_LINEAR (1 << 0) ++# define RADEON_MAG_FILTER_MASK (1 << 0) ++# define RADEON_MIN_FILTER_NEAREST (0 << 1) ++# define RADEON_MIN_FILTER_LINEAR (1 << 1) ++# define RADEON_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) ++# define RADEON_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) ++# define RADEON_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) ++# define RADEON_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) ++# define RADEON_MIN_FILTER_ANISO_NEAREST (8 << 1) ++# define RADEON_MIN_FILTER_ANISO_LINEAR (9 << 1) ++# define RADEON_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) ++# define RADEON_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) ++# define RADEON_MIN_FILTER_MASK (15 << 1) ++# define RADEON_MAX_ANISO_1_TO_1 (0 << 5) ++# define RADEON_MAX_ANISO_2_TO_1 (1 << 5) ++# define RADEON_MAX_ANISO_4_TO_1 (2 << 5) ++# define RADEON_MAX_ANISO_8_TO_1 (3 << 5) ++# define RADEON_MAX_ANISO_16_TO_1 (4 << 5) ++# define RADEON_MAX_ANISO_MASK (7 << 5) ++# define RADEON_LOD_BIAS_MASK (0xff << 8) ++# define RADEON_LOD_BIAS_SHIFT 8 ++# define RADEON_MAX_MIP_LEVEL_MASK (0x0f << 16) ++# define RADEON_MAX_MIP_LEVEL_SHIFT 16 ++# define RADEON_YUV_TO_RGB (1 << 20) ++# define RADEON_YUV_TEMPERATURE_COOL (0 << 21) ++# define RADEON_YUV_TEMPERATURE_HOT (1 << 21) ++# define RADEON_YUV_TEMPERATURE_MASK (1 << 21) ++# define RADEON_WRAPEN_S (1 << 22) ++# define RADEON_CLAMP_S_WRAP (0 << 23) ++# define RADEON_CLAMP_S_MIRROR (1 << 23) ++# define RADEON_CLAMP_S_CLAMP_LAST (2 << 23) ++# define RADEON_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) ++# define RADEON_CLAMP_S_CLAMP_BORDER (4 << 23) ++# define RADEON_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) ++# define RADEON_CLAMP_S_CLAMP_GL (6 << 23) ++# define RADEON_CLAMP_S_MIRROR_CLAMP_GL (7 << 23) ++# define RADEON_CLAMP_S_MASK (7 << 23) ++# define RADEON_WRAPEN_T (1 << 26) ++# define RADEON_CLAMP_T_WRAP (0 << 27) ++# define RADEON_CLAMP_T_MIRROR (1 << 27) ++# define RADEON_CLAMP_T_CLAMP_LAST (2 << 27) ++# define RADEON_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) ++# define RADEON_CLAMP_T_CLAMP_BORDER (4 << 27) ++# define RADEON_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) ++# define RADEON_CLAMP_T_CLAMP_GL (6 << 27) ++# define RADEON_CLAMP_T_MIRROR_CLAMP_GL (7 << 27) ++# define RADEON_CLAMP_T_MASK (7 << 27) ++# define RADEON_BORDER_MODE_OGL (0 << 31) ++# define RADEON_BORDER_MODE_D3D (1 << 31) ++#define RADEON_PP_TXFORMAT_0 0x1c58 ++#define RADEON_PP_TXFORMAT_1 0x1c70 ++#define RADEON_PP_TXFORMAT_2 0x1c88 ++# define RADEON_TXFORMAT_I8 (0 << 0) ++# define RADEON_TXFORMAT_AI88 (1 << 0) ++# define RADEON_TXFORMAT_RGB332 (2 << 0) ++# define RADEON_TXFORMAT_ARGB1555 (3 << 0) ++# define RADEON_TXFORMAT_RGB565 (4 << 0) ++# define RADEON_TXFORMAT_ARGB4444 (5 << 0) ++# define RADEON_TXFORMAT_ARGB8888 (6 << 0) ++# define RADEON_TXFORMAT_RGBA8888 (7 << 0) ++# define RADEON_TXFORMAT_Y8 (8 << 0) ++# define RADEON_TXFORMAT_VYUY422 (10 << 0) ++# define RADEON_TXFORMAT_YVYU422 (11 << 0) ++# define RADEON_TXFORMAT_DXT1 (12 << 0) ++# define RADEON_TXFORMAT_DXT23 (14 << 0) ++# define RADEON_TXFORMAT_DXT45 (15 << 0) ++# define RADEON_TXFORMAT_FORMAT_MASK (31 << 0) ++# define RADEON_TXFORMAT_FORMAT_SHIFT 0 ++# define RADEON_TXFORMAT_APPLE_YUV_MODE (1 << 5) ++# define RADEON_TXFORMAT_ALPHA_IN_MAP (1 << 6) ++# define RADEON_TXFORMAT_NON_POWER2 (1 << 7) ++# define RADEON_TXFORMAT_WIDTH_MASK (15 << 8) ++# define RADEON_TXFORMAT_WIDTH_SHIFT 8 ++# define RADEON_TXFORMAT_HEIGHT_MASK (15 << 12) ++# define RADEON_TXFORMAT_HEIGHT_SHIFT 12 ++# define RADEON_TXFORMAT_F5_WIDTH_MASK (15 << 16) ++# define RADEON_TXFORMAT_F5_WIDTH_SHIFT 16 ++# define RADEON_TXFORMAT_F5_HEIGHT_MASK (15 << 20) ++# define RADEON_TXFORMAT_F5_HEIGHT_SHIFT 20 ++# define RADEON_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) ++# define RADEON_TXFORMAT_ST_ROUTE_MASK (3 << 24) ++# define RADEON_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) ++# define RADEON_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) ++# define RADEON_TXFORMAT_ENDIAN_NO_SWAP (0 << 26) ++# define RADEON_TXFORMAT_ENDIAN_16BPP_SWAP (1 << 26) ++# define RADEON_TXFORMAT_ENDIAN_32BPP_SWAP (2 << 26) ++# define RADEON_TXFORMAT_ENDIAN_HALFDW_SWAP (3 << 26) ++# define RADEON_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) ++# define RADEON_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) ++# define RADEON_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) ++# define RADEON_TXFORMAT_PERSPECTIVE_ENABLE (1 << 31) ++#define RADEON_PP_CUBIC_FACES_0 0x1d24 ++#define RADEON_PP_CUBIC_FACES_1 0x1d28 ++#define RADEON_PP_CUBIC_FACES_2 0x1d2c ++# define RADEON_FACE_WIDTH_1_SHIFT 0 ++# define RADEON_FACE_HEIGHT_1_SHIFT 4 ++# define RADEON_FACE_WIDTH_1_MASK (0xf << 0) ++# define RADEON_FACE_HEIGHT_1_MASK (0xf << 4) ++# define RADEON_FACE_WIDTH_2_SHIFT 8 ++# define RADEON_FACE_HEIGHT_2_SHIFT 12 ++# define RADEON_FACE_WIDTH_2_MASK (0xf << 8) ++# define RADEON_FACE_HEIGHT_2_MASK (0xf << 12) ++# define RADEON_FACE_WIDTH_3_SHIFT 16 ++# define RADEON_FACE_HEIGHT_3_SHIFT 20 ++# define RADEON_FACE_WIDTH_3_MASK (0xf << 16) ++# define RADEON_FACE_HEIGHT_3_MASK (0xf << 20) ++# define RADEON_FACE_WIDTH_4_SHIFT 24 ++# define RADEON_FACE_HEIGHT_4_SHIFT 28 ++# define RADEON_FACE_WIDTH_4_MASK (0xf << 24) ++# define RADEON_FACE_HEIGHT_4_MASK (0xf << 28) ++ ++#define RADEON_PP_TXOFFSET_0 0x1c5c ++#define RADEON_PP_TXOFFSET_1 0x1c74 ++#define RADEON_PP_TXOFFSET_2 0x1c8c ++# define RADEON_TXO_ENDIAN_NO_SWAP (0 << 0) ++# define RADEON_TXO_ENDIAN_BYTE_SWAP (1 << 0) ++# define RADEON_TXO_ENDIAN_WORD_SWAP (2 << 0) ++# define RADEON_TXO_ENDIAN_HALFDW_SWAP (3 << 0) ++# define RADEON_TXO_MACRO_LINEAR (0 << 2) ++# define RADEON_TXO_MACRO_TILE (1 << 2) ++# define RADEON_TXO_MICRO_LINEAR (0 << 3) ++# define RADEON_TXO_MICRO_TILE_X2 (1 << 3) ++# define RADEON_TXO_MICRO_TILE_OPT (2 << 3) ++# define RADEON_TXO_OFFSET_MASK 0xffffffe0 ++# define RADEON_TXO_OFFSET_SHIFT 5 ++ ++#define RADEON_PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */ ++#define RADEON_PP_CUBIC_OFFSET_T0_1 0x1dd4 ++#define RADEON_PP_CUBIC_OFFSET_T0_2 0x1dd8 ++#define RADEON_PP_CUBIC_OFFSET_T0_3 0x1ddc ++#define RADEON_PP_CUBIC_OFFSET_T0_4 0x1de0 ++#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00 ++#define RADEON_PP_CUBIC_OFFSET_T1_1 0x1e04 ++#define RADEON_PP_CUBIC_OFFSET_T1_2 0x1e08 ++#define RADEON_PP_CUBIC_OFFSET_T1_3 0x1e0c ++#define RADEON_PP_CUBIC_OFFSET_T1_4 0x1e10 ++#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14 ++#define RADEON_PP_CUBIC_OFFSET_T2_1 0x1e18 ++#define RADEON_PP_CUBIC_OFFSET_T2_2 0x1e1c ++#define RADEON_PP_CUBIC_OFFSET_T2_3 0x1e20 ++#define RADEON_PP_CUBIC_OFFSET_T2_4 0x1e24 ++ ++#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */ ++#define RADEON_PP_TEX_SIZE_1 0x1d0c ++#define RADEON_PP_TEX_SIZE_2 0x1d14 ++# define RADEON_TEX_USIZE_MASK (0x7ff << 0) ++# define RADEON_TEX_USIZE_SHIFT 0 ++# define RADEON_TEX_VSIZE_MASK (0x7ff << 16) ++# define RADEON_TEX_VSIZE_SHIFT 16 ++# define RADEON_SIGNED_RGB_MASK (1 << 30) ++# define RADEON_SIGNED_RGB_SHIFT 30 ++# define RADEON_SIGNED_ALPHA_MASK (1 << 31) ++# define RADEON_SIGNED_ALPHA_SHIFT 31 ++#define RADEON_PP_TEX_PITCH_0 0x1d08 /* NPOT */ ++#define RADEON_PP_TEX_PITCH_1 0x1d10 /* NPOT */ ++#define RADEON_PP_TEX_PITCH_2 0x1d18 /* NPOT */ ++/* note: bits 13-5: 32 byte aligned stride of texture map */ ++ ++#define RADEON_PP_TXCBLEND_0 0x1c60 ++#define RADEON_PP_TXCBLEND_1 0x1c78 ++#define RADEON_PP_TXCBLEND_2 0x1c90 ++# define RADEON_COLOR_ARG_A_SHIFT 0 ++# define RADEON_COLOR_ARG_A_MASK (0x1f << 0) ++# define RADEON_COLOR_ARG_A_ZERO (0 << 0) ++# define RADEON_COLOR_ARG_A_CURRENT_COLOR (2 << 0) ++# define RADEON_COLOR_ARG_A_CURRENT_ALPHA (3 << 0) ++# define RADEON_COLOR_ARG_A_DIFFUSE_COLOR (4 << 0) ++# define RADEON_COLOR_ARG_A_DIFFUSE_ALPHA (5 << 0) ++# define RADEON_COLOR_ARG_A_SPECULAR_COLOR (6 << 0) ++# define RADEON_COLOR_ARG_A_SPECULAR_ALPHA (7 << 0) ++# define RADEON_COLOR_ARG_A_TFACTOR_COLOR (8 << 0) ++# define RADEON_COLOR_ARG_A_TFACTOR_ALPHA (9 << 0) ++# define RADEON_COLOR_ARG_A_T0_COLOR (10 << 0) ++# define RADEON_COLOR_ARG_A_T0_ALPHA (11 << 0) ++# define RADEON_COLOR_ARG_A_T1_COLOR (12 << 0) ++# define RADEON_COLOR_ARG_A_T1_ALPHA (13 << 0) ++# define RADEON_COLOR_ARG_A_T2_COLOR (14 << 0) ++# define RADEON_COLOR_ARG_A_T2_ALPHA (15 << 0) ++# define RADEON_COLOR_ARG_A_T3_COLOR (16 << 0) ++# define RADEON_COLOR_ARG_A_T3_ALPHA (17 << 0) ++# define RADEON_COLOR_ARG_B_SHIFT 5 ++# define RADEON_COLOR_ARG_B_MASK (0x1f << 5) ++# define RADEON_COLOR_ARG_B_ZERO (0 << 5) ++# define RADEON_COLOR_ARG_B_CURRENT_COLOR (2 << 5) ++# define RADEON_COLOR_ARG_B_CURRENT_ALPHA (3 << 5) ++# define RADEON_COLOR_ARG_B_DIFFUSE_COLOR (4 << 5) ++# define RADEON_COLOR_ARG_B_DIFFUSE_ALPHA (5 << 5) ++# define RADEON_COLOR_ARG_B_SPECULAR_COLOR (6 << 5) ++# define RADEON_COLOR_ARG_B_SPECULAR_ALPHA (7 << 5) ++# define RADEON_COLOR_ARG_B_TFACTOR_COLOR (8 << 5) ++# define RADEON_COLOR_ARG_B_TFACTOR_ALPHA (9 << 5) ++# define RADEON_COLOR_ARG_B_T0_COLOR (10 << 5) ++# define RADEON_COLOR_ARG_B_T0_ALPHA (11 << 5) ++# define RADEON_COLOR_ARG_B_T1_COLOR (12 << 5) ++# define RADEON_COLOR_ARG_B_T1_ALPHA (13 << 5) ++# define RADEON_COLOR_ARG_B_T2_COLOR (14 << 5) ++# define RADEON_COLOR_ARG_B_T2_ALPHA (15 << 5) ++# define RADEON_COLOR_ARG_B_T3_COLOR (16 << 5) ++# define RADEON_COLOR_ARG_B_T3_ALPHA (17 << 5) ++# define RADEON_COLOR_ARG_C_SHIFT 10 ++# define RADEON_COLOR_ARG_C_MASK (0x1f << 10) ++# define RADEON_COLOR_ARG_C_ZERO (0 << 10) ++# define RADEON_COLOR_ARG_C_CURRENT_COLOR (2 << 10) ++# define RADEON_COLOR_ARG_C_CURRENT_ALPHA (3 << 10) ++# define RADEON_COLOR_ARG_C_DIFFUSE_COLOR (4 << 10) ++# define RADEON_COLOR_ARG_C_DIFFUSE_ALPHA (5 << 10) ++# define RADEON_COLOR_ARG_C_SPECULAR_COLOR (6 << 10) ++# define RADEON_COLOR_ARG_C_SPECULAR_ALPHA (7 << 10) ++# define RADEON_COLOR_ARG_C_TFACTOR_COLOR (8 << 10) ++# define RADEON_COLOR_ARG_C_TFACTOR_ALPHA (9 << 10) ++# define RADEON_COLOR_ARG_C_T0_COLOR (10 << 10) ++# define RADEON_COLOR_ARG_C_T0_ALPHA (11 << 10) ++# define RADEON_COLOR_ARG_C_T1_COLOR (12 << 10) ++# define RADEON_COLOR_ARG_C_T1_ALPHA (13 << 10) ++# define RADEON_COLOR_ARG_C_T2_COLOR (14 << 10) ++# define RADEON_COLOR_ARG_C_T2_ALPHA (15 << 10) ++# define RADEON_COLOR_ARG_C_T3_COLOR (16 << 10) ++# define RADEON_COLOR_ARG_C_T3_ALPHA (17 << 10) ++# define RADEON_COMP_ARG_A (1 << 15) ++# define RADEON_COMP_ARG_A_SHIFT 15 ++# define RADEON_COMP_ARG_B (1 << 16) ++# define RADEON_COMP_ARG_B_SHIFT 16 ++# define RADEON_COMP_ARG_C (1 << 17) ++# define RADEON_COMP_ARG_C_SHIFT 17 ++# define RADEON_BLEND_CTL_MASK (7 << 18) ++# define RADEON_BLEND_CTL_ADD (0 << 18) ++# define RADEON_BLEND_CTL_SUBTRACT (1 << 18) ++# define RADEON_BLEND_CTL_ADDSIGNED (2 << 18) ++# define RADEON_BLEND_CTL_BLEND (3 << 18) ++# define RADEON_BLEND_CTL_DOT3 (4 << 18) ++# define RADEON_SCALE_SHIFT 21 ++# define RADEON_SCALE_MASK (3 << 21) ++# define RADEON_SCALE_1X (0 << 21) ++# define RADEON_SCALE_2X (1 << 21) ++# define RADEON_SCALE_4X (2 << 21) ++# define RADEON_CLAMP_TX (1 << 23) ++# define RADEON_T0_EQ_TCUR (1 << 24) ++# define RADEON_T1_EQ_TCUR (1 << 25) ++# define RADEON_T2_EQ_TCUR (1 << 26) ++# define RADEON_T3_EQ_TCUR (1 << 27) ++# define RADEON_COLOR_ARG_MASK 0x1f ++# define RADEON_COMP_ARG_SHIFT 15 ++#define RADEON_PP_TXABLEND_0 0x1c64 ++#define RADEON_PP_TXABLEND_1 0x1c7c ++#define RADEON_PP_TXABLEND_2 0x1c94 ++# define RADEON_ALPHA_ARG_A_SHIFT 0 ++# define RADEON_ALPHA_ARG_A_MASK (0xf << 0) ++# define RADEON_ALPHA_ARG_A_ZERO (0 << 0) ++# define RADEON_ALPHA_ARG_A_CURRENT_ALPHA (1 << 0) ++# define RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA (2 << 0) ++# define RADEON_ALPHA_ARG_A_SPECULAR_ALPHA (3 << 0) ++# define RADEON_ALPHA_ARG_A_TFACTOR_ALPHA (4 << 0) ++# define RADEON_ALPHA_ARG_A_T0_ALPHA (5 << 0) ++# define RADEON_ALPHA_ARG_A_T1_ALPHA (6 << 0) ++# define RADEON_ALPHA_ARG_A_T2_ALPHA (7 << 0) ++# define RADEON_ALPHA_ARG_A_T3_ALPHA (8 << 0) ++# define RADEON_ALPHA_ARG_B_SHIFT 4 ++# define RADEON_ALPHA_ARG_B_MASK (0xf << 4) ++# define RADEON_ALPHA_ARG_B_ZERO (0 << 4) ++# define RADEON_ALPHA_ARG_B_CURRENT_ALPHA (1 << 4) ++# define RADEON_ALPHA_ARG_B_DIFFUSE_ALPHA (2 << 4) ++# define RADEON_ALPHA_ARG_B_SPECULAR_ALPHA (3 << 4) ++# define RADEON_ALPHA_ARG_B_TFACTOR_ALPHA (4 << 4) ++# define RADEON_ALPHA_ARG_B_T0_ALPHA (5 << 4) ++# define RADEON_ALPHA_ARG_B_T1_ALPHA (6 << 4) ++# define RADEON_ALPHA_ARG_B_T2_ALPHA (7 << 4) ++# define RADEON_ALPHA_ARG_B_T3_ALPHA (8 << 4) ++# define RADEON_ALPHA_ARG_C_SHIFT 8 ++# define RADEON_ALPHA_ARG_C_MASK (0xf << 8) ++# define RADEON_ALPHA_ARG_C_ZERO (0 << 8) ++# define RADEON_ALPHA_ARG_C_CURRENT_ALPHA (1 << 8) ++# define RADEON_ALPHA_ARG_C_DIFFUSE_ALPHA (2 << 8) ++# define RADEON_ALPHA_ARG_C_SPECULAR_ALPHA (3 << 8) ++# define RADEON_ALPHA_ARG_C_TFACTOR_ALPHA (4 << 8) ++# define RADEON_ALPHA_ARG_C_T0_ALPHA (5 << 8) ++# define RADEON_ALPHA_ARG_C_T1_ALPHA (6 << 8) ++# define RADEON_ALPHA_ARG_C_T2_ALPHA (7 << 8) ++# define RADEON_ALPHA_ARG_C_T3_ALPHA (8 << 8) ++# define RADEON_DOT_ALPHA_DONT_REPLICATE (1 << 9) ++# define RADEON_ALPHA_ARG_MASK 0xf ++ ++#define RADEON_PP_TFACTOR_0 0x1c68 ++#define RADEON_PP_TFACTOR_1 0x1c80 ++#define RADEON_PP_TFACTOR_2 0x1c98 ++ ++#define RADEON_RB3D_BLENDCNTL 0x1c20 ++# define RADEON_COMB_FCN_MASK (3 << 12) ++# define RADEON_COMB_FCN_ADD_CLAMP (0 << 12) ++# define RADEON_COMB_FCN_ADD_NOCLAMP (1 << 12) ++# define RADEON_COMB_FCN_SUB_CLAMP (2 << 12) ++# define RADEON_COMB_FCN_SUB_NOCLAMP (3 << 12) ++# define RADEON_SRC_BLEND_GL_ZERO (32 << 16) ++# define RADEON_SRC_BLEND_GL_ONE (33 << 16) ++# define RADEON_SRC_BLEND_GL_SRC_COLOR (34 << 16) ++# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) ++# define RADEON_SRC_BLEND_GL_DST_COLOR (36 << 16) ++# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) ++# define RADEON_SRC_BLEND_GL_SRC_ALPHA (38 << 16) ++# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) ++# define RADEON_SRC_BLEND_GL_DST_ALPHA (40 << 16) ++# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) ++# define RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) ++# define RADEON_SRC_BLEND_MASK (63 << 16) ++# define RADEON_DST_BLEND_GL_ZERO (32 << 24) ++# define RADEON_DST_BLEND_GL_ONE (33 << 24) ++# define RADEON_DST_BLEND_GL_SRC_COLOR (34 << 24) ++# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) ++# define RADEON_DST_BLEND_GL_DST_COLOR (36 << 24) ++# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) ++# define RADEON_DST_BLEND_GL_SRC_ALPHA (38 << 24) ++# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) ++# define RADEON_DST_BLEND_GL_DST_ALPHA (40 << 24) ++# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) ++# define RADEON_DST_BLEND_MASK (63 << 24) ++#define RADEON_RB3D_CNTL 0x1c3c ++# define RADEON_ALPHA_BLEND_ENABLE (1 << 0) ++# define RADEON_PLANE_MASK_ENABLE (1 << 1) ++# define RADEON_DITHER_ENABLE (1 << 2) ++# define RADEON_ROUND_ENABLE (1 << 3) ++# define RADEON_SCALE_DITHER_ENABLE (1 << 4) ++# define RADEON_DITHER_INIT (1 << 5) ++# define RADEON_ROP_ENABLE (1 << 6) ++# define RADEON_STENCIL_ENABLE (1 << 7) ++# define RADEON_Z_ENABLE (1 << 8) ++# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9) ++# define RADEON_RB3D_COLOR_FORMAT_SHIFT 10 ++ ++# define RADEON_COLOR_FORMAT_ARGB1555 3 ++# define RADEON_COLOR_FORMAT_RGB565 4 ++# define RADEON_COLOR_FORMAT_ARGB8888 6 ++# define RADEON_COLOR_FORMAT_RGB332 7 ++# define RADEON_COLOR_FORMAT_Y8 8 ++# define RADEON_COLOR_FORMAT_RGB8 9 ++# define RADEON_COLOR_FORMAT_YUV422_VYUY 11 ++# define RADEON_COLOR_FORMAT_YUV422_YVYU 12 ++# define RADEON_COLOR_FORMAT_aYUV444 14 ++# define RADEON_COLOR_FORMAT_ARGB4444 15 ++ ++# define RADEON_CLRCMP_FLIP_ENABLE (1 << 14) ++#define RADEON_RB3D_COLOROFFSET 0x1c40 ++# define RADEON_COLOROFFSET_MASK 0xfffffff0 ++#define RADEON_RB3D_COLORPITCH 0x1c48 ++# define RADEON_COLORPITCH_MASK 0x000001ff8 ++# define RADEON_COLOR_TILE_ENABLE (1 << 16) ++# define RADEON_COLOR_MICROTILE_ENABLE (1 << 17) ++# define RADEON_COLOR_ENDIAN_NO_SWAP (0 << 18) ++# define RADEON_COLOR_ENDIAN_WORD_SWAP (1 << 18) ++# define RADEON_COLOR_ENDIAN_DWORD_SWAP (2 << 18) ++#define RADEON_RB3D_DEPTHOFFSET 0x1c24 ++#define RADEON_RB3D_DEPTHPITCH 0x1c28 ++# define RADEON_DEPTHPITCH_MASK 0x00001ff8 ++# define RADEON_DEPTH_ENDIAN_NO_SWAP (0 << 18) ++# define RADEON_DEPTH_ENDIAN_WORD_SWAP (1 << 18) ++# define RADEON_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) ++#define RADEON_RB3D_PLANEMASK 0x1d84 ++#define RADEON_RB3D_ROPCNTL 0x1d80 ++# define RADEON_ROP_MASK (15 << 8) ++# define RADEON_ROP_CLEAR (0 << 8) ++# define RADEON_ROP_NOR (1 << 8) ++# define RADEON_ROP_AND_INVERTED (2 << 8) ++# define RADEON_ROP_COPY_INVERTED (3 << 8) ++# define RADEON_ROP_AND_REVERSE (4 << 8) ++# define RADEON_ROP_INVERT (5 << 8) ++# define RADEON_ROP_XOR (6 << 8) ++# define RADEON_ROP_NAND (7 << 8) ++# define RADEON_ROP_AND (8 << 8) ++# define RADEON_ROP_EQUIV (9 << 8) ++# define RADEON_ROP_NOOP (10 << 8) ++# define RADEON_ROP_OR_INVERTED (11 << 8) ++# define RADEON_ROP_COPY (12 << 8) ++# define RADEON_ROP_OR_REVERSE (13 << 8) ++# define RADEON_ROP_OR (14 << 8) ++# define RADEON_ROP_SET (15 << 8) ++#define RADEON_RB3D_STENCILREFMASK 0x1d7c ++# define RADEON_STENCIL_REF_SHIFT 0 ++# define RADEON_STENCIL_REF_MASK (0xff << 0) ++# define RADEON_STENCIL_MASK_SHIFT 16 ++# define RADEON_STENCIL_VALUE_MASK (0xff << 16) ++# define RADEON_STENCIL_WRITEMASK_SHIFT 24 ++# define RADEON_STENCIL_WRITE_MASK (0xff << 24) ++#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c ++# define RADEON_DEPTH_FORMAT_MASK (0xf << 0) ++# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) ++# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) ++# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) ++# define RADEON_DEPTH_FORMAT_32BIT_INT_Z (4 << 0) ++# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) ++# define RADEON_DEPTH_FORMAT_16BIT_FLOAT_W (7 << 0) ++# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) ++# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) ++# define RADEON_Z_TEST_NEVER (0 << 4) ++# define RADEON_Z_TEST_LESS (1 << 4) ++# define RADEON_Z_TEST_LEQUAL (2 << 4) ++# define RADEON_Z_TEST_EQUAL (3 << 4) ++# define RADEON_Z_TEST_GEQUAL (4 << 4) ++# define RADEON_Z_TEST_GREATER (5 << 4) ++# define RADEON_Z_TEST_NEQUAL (6 << 4) ++# define RADEON_Z_TEST_ALWAYS (7 << 4) ++# define RADEON_Z_TEST_MASK (7 << 4) ++# define RADEON_STENCIL_TEST_NEVER (0 << 12) ++# define RADEON_STENCIL_TEST_LESS (1 << 12) ++# define RADEON_STENCIL_TEST_LEQUAL (2 << 12) ++# define RADEON_STENCIL_TEST_EQUAL (3 << 12) ++# define RADEON_STENCIL_TEST_GEQUAL (4 << 12) ++# define RADEON_STENCIL_TEST_GREATER (5 << 12) ++# define RADEON_STENCIL_TEST_NEQUAL (6 << 12) ++# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) ++# define RADEON_STENCIL_TEST_MASK (0x7 << 12) ++# define RADEON_STENCIL_FAIL_KEEP (0 << 16) ++# define RADEON_STENCIL_FAIL_ZERO (1 << 16) ++# define RADEON_STENCIL_FAIL_REPLACE (2 << 16) ++# define RADEON_STENCIL_FAIL_INC (3 << 16) ++# define RADEON_STENCIL_FAIL_DEC (4 << 16) ++# define RADEON_STENCIL_FAIL_INVERT (5 << 16) ++# define RADEON_STENCIL_FAIL_MASK (0x7 << 16) ++# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) ++# define RADEON_STENCIL_ZPASS_ZERO (1 << 20) ++# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) ++# define RADEON_STENCIL_ZPASS_INC (3 << 20) ++# define RADEON_STENCIL_ZPASS_DEC (4 << 20) ++# define RADEON_STENCIL_ZPASS_INVERT (5 << 20) ++# define RADEON_STENCIL_ZPASS_MASK (0x7 << 20) ++# define RADEON_STENCIL_ZFAIL_KEEP (0 << 24) ++# define RADEON_STENCIL_ZFAIL_ZERO (1 << 24) ++# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) ++# define RADEON_STENCIL_ZFAIL_INC (3 << 24) ++# define RADEON_STENCIL_ZFAIL_DEC (4 << 24) ++# define RADEON_STENCIL_ZFAIL_INVERT (5 << 24) ++# define RADEON_STENCIL_ZFAIL_MASK (0x7 << 24) ++# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) ++# define RADEON_FORCE_Z_DIRTY (1 << 29) ++# define RADEON_Z_WRITE_ENABLE (1 << 30) ++#define RADEON_RE_LINE_PATTERN 0x1cd0 ++# define RADEON_LINE_PATTERN_MASK 0x0000ffff ++# define RADEON_LINE_REPEAT_COUNT_SHIFT 16 ++# define RADEON_LINE_PATTERN_START_SHIFT 24 ++# define RADEON_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) ++# define RADEON_LINE_PATTERN_BIG_BIT_ORDER (1 << 28) ++# define RADEON_LINE_PATTERN_AUTO_RESET (1 << 29) ++#define RADEON_RE_LINE_STATE 0x1cd4 ++# define RADEON_LINE_CURRENT_PTR_SHIFT 0 ++# define RADEON_LINE_CURRENT_COUNT_SHIFT 8 ++#define RADEON_RE_MISC 0x26c4 ++# define RADEON_STIPPLE_COORD_MASK 0x1f ++# define RADEON_STIPPLE_X_OFFSET_SHIFT 0 ++# define RADEON_STIPPLE_X_OFFSET_MASK (0x1f << 0) ++# define RADEON_STIPPLE_Y_OFFSET_SHIFT 8 ++# define RADEON_STIPPLE_Y_OFFSET_MASK (0x1f << 8) ++# define RADEON_STIPPLE_LITTLE_BIT_ORDER (0 << 16) ++# define RADEON_STIPPLE_BIG_BIT_ORDER (1 << 16) ++#define RADEON_RE_SOLID_COLOR 0x1c1c ++#define RADEON_RE_TOP_LEFT 0x26c0 ++# define RADEON_RE_LEFT_SHIFT 0 ++# define RADEON_RE_TOP_SHIFT 16 ++#define RADEON_RE_WIDTH_HEIGHT 0x1c44 ++# define RADEON_RE_WIDTH_SHIFT 0 ++# define RADEON_RE_HEIGHT_SHIFT 16 ++ ++#define RADEON_SE_CNTL 0x1c4c ++# define RADEON_FFACE_CULL_CW (0 << 0) ++# define RADEON_FFACE_CULL_CCW (1 << 0) ++# define RADEON_FFACE_CULL_DIR_MASK (1 << 0) ++# define RADEON_BFACE_CULL (0 << 1) ++# define RADEON_BFACE_SOLID (3 << 1) ++# define RADEON_FFACE_CULL (0 << 3) ++# define RADEON_FFACE_SOLID (3 << 3) ++# define RADEON_FFACE_CULL_MASK (3 << 3) ++# define RADEON_BADVTX_CULL_DISABLE (1 << 5) ++# define RADEON_FLAT_SHADE_VTX_0 (0 << 6) ++# define RADEON_FLAT_SHADE_VTX_1 (1 << 6) ++# define RADEON_FLAT_SHADE_VTX_2 (2 << 6) ++# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) ++# define RADEON_DIFFUSE_SHADE_SOLID (0 << 8) ++# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) ++# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) ++# define RADEON_DIFFUSE_SHADE_MASK (3 << 8) ++# define RADEON_ALPHA_SHADE_SOLID (0 << 10) ++# define RADEON_ALPHA_SHADE_FLAT (1 << 10) ++# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) ++# define RADEON_ALPHA_SHADE_MASK (3 << 10) ++# define RADEON_SPECULAR_SHADE_SOLID (0 << 12) ++# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) ++# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) ++# define RADEON_SPECULAR_SHADE_MASK (3 << 12) ++# define RADEON_FOG_SHADE_SOLID (0 << 14) ++# define RADEON_FOG_SHADE_FLAT (1 << 14) ++# define RADEON_FOG_SHADE_GOURAUD (2 << 14) ++# define RADEON_FOG_SHADE_MASK (3 << 14) ++# define RADEON_ZBIAS_ENABLE_POINT (1 << 16) ++# define RADEON_ZBIAS_ENABLE_LINE (1 << 17) ++# define RADEON_ZBIAS_ENABLE_TRI (1 << 18) ++# define RADEON_WIDELINE_ENABLE (1 << 20) ++# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) ++# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) ++# define RADEON_VTX_PIX_CENTER_D3D (0 << 27) ++# define RADEON_VTX_PIX_CENTER_OGL (1 << 27) ++# define RADEON_ROUND_MODE_TRUNC (0 << 28) ++# define RADEON_ROUND_MODE_ROUND (1 << 28) ++# define RADEON_ROUND_MODE_ROUND_EVEN (2 << 28) ++# define RADEON_ROUND_MODE_ROUND_ODD (3 << 28) ++# define RADEON_ROUND_PREC_16TH_PIX (0 << 30) ++# define RADEON_ROUND_PREC_8TH_PIX (1 << 30) ++# define RADEON_ROUND_PREC_4TH_PIX (2 << 30) ++# define RADEON_ROUND_PREC_HALF_PIX (3 << 30) ++#define R200_RE_CNTL 0x1c50 ++# define R200_STIPPLE_ENABLE 0x1 ++# define R200_SCISSOR_ENABLE 0x2 ++# define R200_PATTERN_ENABLE 0x4 ++# define R200_PERSPECTIVE_ENABLE 0x8 ++# define R200_POINT_SMOOTH 0x20 ++# define R200_VTX_STQ0_D3D 0x00010000 ++# define R200_VTX_STQ1_D3D 0x00040000 ++# define R200_VTX_STQ2_D3D 0x00100000 ++# define R200_VTX_STQ3_D3D 0x00400000 ++# define R200_VTX_STQ4_D3D 0x01000000 ++# define R200_VTX_STQ5_D3D 0x04000000 ++#define RADEON_SE_CNTL_STATUS 0x2140 ++# define RADEON_VC_NO_SWAP (0 << 0) ++# define RADEON_VC_16BIT_SWAP (1 << 0) ++# define RADEON_VC_32BIT_SWAP (2 << 0) ++# define RADEON_VC_HALF_DWORD_SWAP (3 << 0) ++# define RADEON_TCL_BYPASS (1 << 8) ++#define RADEON_SE_COORD_FMT 0x1c50 ++# define RADEON_VTX_XY_PRE_MULT_1_OVER_W0 (1 << 0) ++# define RADEON_VTX_Z_PRE_MULT_1_OVER_W0 (1 << 1) ++# define RADEON_VTX_ST0_NONPARAMETRIC (1 << 8) ++# define RADEON_VTX_ST1_NONPARAMETRIC (1 << 9) ++# define RADEON_VTX_ST2_NONPARAMETRIC (1 << 10) ++# define RADEON_VTX_ST3_NONPARAMETRIC (1 << 11) ++# define RADEON_VTX_W0_NORMALIZE (1 << 12) ++# define RADEON_VTX_W0_IS_NOT_1_OVER_W0 (1 << 16) ++# define RADEON_VTX_ST0_PRE_MULT_1_OVER_W0 (1 << 17) ++# define RADEON_VTX_ST1_PRE_MULT_1_OVER_W0 (1 << 19) ++# define RADEON_VTX_ST2_PRE_MULT_1_OVER_W0 (1 << 21) ++# define RADEON_VTX_ST3_PRE_MULT_1_OVER_W0 (1 << 23) ++# define RADEON_TEX1_W_ROUTING_USE_W0 (0 << 26) ++# define RADEON_TEX1_W_ROUTING_USE_Q1 (1 << 26) ++#define RADEON_SE_LINE_WIDTH 0x1db8 ++#define RADEON_SE_TCL_LIGHT_MODEL_CTL 0x226c ++# define RADEON_LIGHTING_ENABLE (1 << 0) ++# define RADEON_LIGHT_IN_MODELSPACE (1 << 1) ++# define RADEON_LOCAL_VIEWER (1 << 2) ++# define RADEON_NORMALIZE_NORMALS (1 << 3) ++# define RADEON_RESCALE_NORMALS (1 << 4) ++# define RADEON_SPECULAR_LIGHTS (1 << 5) ++# define RADEON_DIFFUSE_SPECULAR_COMBINE (1 << 6) ++# define RADEON_LIGHT_ALPHA (1 << 7) ++# define RADEON_LOCAL_LIGHT_VEC_GL (1 << 8) ++# define RADEON_LIGHT_NO_NORMAL_AMBIENT_ONLY (1 << 9) ++# define RADEON_LM_SOURCE_STATE_PREMULT 0 ++# define RADEON_LM_SOURCE_STATE_MULT 1 ++# define RADEON_LM_SOURCE_VERTEX_DIFFUSE 2 ++# define RADEON_LM_SOURCE_VERTEX_SPECULAR 3 ++# define RADEON_EMISSIVE_SOURCE_SHIFT 16 ++# define RADEON_AMBIENT_SOURCE_SHIFT 18 ++# define RADEON_DIFFUSE_SOURCE_SHIFT 20 ++# define RADEON_SPECULAR_SOURCE_SHIFT 22 ++#define RADEON_SE_TCL_MATERIAL_AMBIENT_RED 0x2220 ++#define RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN 0x2224 ++#define RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE 0x2228 ++#define RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA 0x222c ++#define RADEON_SE_TCL_MATERIAL_DIFFUSE_RED 0x2230 ++#define RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN 0x2234 ++#define RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE 0x2238 ++#define RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA 0x223c ++#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 ++#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN 0x2214 ++#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE 0x2218 ++#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA 0x221c ++#define RADEON_SE_TCL_MATERIAL_SPECULAR_RED 0x2240 ++#define RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN 0x2244 ++#define RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE 0x2248 ++#define RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA 0x224c ++#define RADEON_SE_TCL_MATRIX_SELECT_0 0x225c ++# define RADEON_MODELVIEW_0_SHIFT 0 ++# define RADEON_MODELVIEW_1_SHIFT 4 ++# define RADEON_MODELVIEW_2_SHIFT 8 ++# define RADEON_MODELVIEW_3_SHIFT 12 ++# define RADEON_IT_MODELVIEW_0_SHIFT 16 ++# define RADEON_IT_MODELVIEW_1_SHIFT 20 ++# define RADEON_IT_MODELVIEW_2_SHIFT 24 ++# define RADEON_IT_MODELVIEW_3_SHIFT 28 ++#define RADEON_SE_TCL_MATRIX_SELECT_1 0x2260 ++# define RADEON_MODELPROJECT_0_SHIFT 0 ++# define RADEON_MODELPROJECT_1_SHIFT 4 ++# define RADEON_MODELPROJECT_2_SHIFT 8 ++# define RADEON_MODELPROJECT_3_SHIFT 12 ++# define RADEON_TEXMAT_0_SHIFT 16 ++# define RADEON_TEXMAT_1_SHIFT 20 ++# define RADEON_TEXMAT_2_SHIFT 24 ++# define RADEON_TEXMAT_3_SHIFT 28 ++ ++ ++#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 ++# define RADEON_TCL_VTX_W0 (1 << 0) ++# define RADEON_TCL_VTX_FP_DIFFUSE (1 << 1) ++# define RADEON_TCL_VTX_FP_ALPHA (1 << 2) ++# define RADEON_TCL_VTX_PK_DIFFUSE (1 << 3) ++# define RADEON_TCL_VTX_FP_SPEC (1 << 4) ++# define RADEON_TCL_VTX_FP_FOG (1 << 5) ++# define RADEON_TCL_VTX_PK_SPEC (1 << 6) ++# define RADEON_TCL_VTX_ST0 (1 << 7) ++# define RADEON_TCL_VTX_ST1 (1 << 8) ++# define RADEON_TCL_VTX_Q1 (1 << 9) ++# define RADEON_TCL_VTX_ST2 (1 << 10) ++# define RADEON_TCL_VTX_Q2 (1 << 11) ++# define RADEON_TCL_VTX_ST3 (1 << 12) ++# define RADEON_TCL_VTX_Q3 (1 << 13) ++# define RADEON_TCL_VTX_Q0 (1 << 14) ++# define RADEON_TCL_VTX_WEIGHT_COUNT_SHIFT 15 ++# define RADEON_TCL_VTX_NORM0 (1 << 18) ++# define RADEON_TCL_VTX_XY1 (1 << 27) ++# define RADEON_TCL_VTX_Z1 (1 << 28) ++# define RADEON_TCL_VTX_W1 (1 << 29) ++# define RADEON_TCL_VTX_NORM1 (1 << 30) ++# define RADEON_TCL_VTX_Z0 (1 << 31) ++ ++#define RADEON_SE_TCL_OUTPUT_VTX_SEL 0x2258 ++# define RADEON_TCL_COMPUTE_XYZW (1 << 0) ++# define RADEON_TCL_COMPUTE_DIFFUSE (1 << 1) ++# define RADEON_TCL_COMPUTE_SPECULAR (1 << 2) ++# define RADEON_TCL_FORCE_NAN_IF_COLOR_NAN (1 << 3) ++# define RADEON_TCL_FORCE_INORDER_PROC (1 << 4) ++# define RADEON_TCL_TEX_INPUT_TEX_0 0 ++# define RADEON_TCL_TEX_INPUT_TEX_1 1 ++# define RADEON_TCL_TEX_INPUT_TEX_2 2 ++# define RADEON_TCL_TEX_INPUT_TEX_3 3 ++# define RADEON_TCL_TEX_COMPUTED_TEX_0 8 ++# define RADEON_TCL_TEX_COMPUTED_TEX_1 9 ++# define RADEON_TCL_TEX_COMPUTED_TEX_2 10 ++# define RADEON_TCL_TEX_COMPUTED_TEX_3 11 ++# define RADEON_TCL_TEX_0_OUTPUT_SHIFT 16 ++# define RADEON_TCL_TEX_1_OUTPUT_SHIFT 20 ++# define RADEON_TCL_TEX_2_OUTPUT_SHIFT 24 ++# define RADEON_TCL_TEX_3_OUTPUT_SHIFT 28 ++ ++#define RADEON_SE_TCL_PER_LIGHT_CTL_0 0x2270 ++# define RADEON_LIGHT_0_ENABLE (1 << 0) ++# define RADEON_LIGHT_0_ENABLE_AMBIENT (1 << 1) ++# define RADEON_LIGHT_0_ENABLE_SPECULAR (1 << 2) ++# define RADEON_LIGHT_0_IS_LOCAL (1 << 3) ++# define RADEON_LIGHT_0_IS_SPOT (1 << 4) ++# define RADEON_LIGHT_0_DUAL_CONE (1 << 5) ++# define RADEON_LIGHT_0_ENABLE_RANGE_ATTEN (1 << 6) ++# define RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN (1 << 7) ++# define RADEON_LIGHT_0_SHIFT 0 ++# define RADEON_LIGHT_1_ENABLE (1 << 16) ++# define RADEON_LIGHT_1_ENABLE_AMBIENT (1 << 17) ++# define RADEON_LIGHT_1_ENABLE_SPECULAR (1 << 18) ++# define RADEON_LIGHT_1_IS_LOCAL (1 << 19) ++# define RADEON_LIGHT_1_IS_SPOT (1 << 20) ++# define RADEON_LIGHT_1_DUAL_CONE (1 << 21) ++# define RADEON_LIGHT_1_ENABLE_RANGE_ATTEN (1 << 22) ++# define RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN (1 << 23) ++# define RADEON_LIGHT_1_SHIFT 16 ++#define RADEON_SE_TCL_PER_LIGHT_CTL_1 0x2274 ++# define RADEON_LIGHT_2_SHIFT 0 ++# define RADEON_LIGHT_3_SHIFT 16 ++#define RADEON_SE_TCL_PER_LIGHT_CTL_2 0x2278 ++# define RADEON_LIGHT_4_SHIFT 0 ++# define RADEON_LIGHT_5_SHIFT 16 ++#define RADEON_SE_TCL_PER_LIGHT_CTL_3 0x227c ++# define RADEON_LIGHT_6_SHIFT 0 ++# define RADEON_LIGHT_7_SHIFT 16 ++ ++#define RADEON_SE_TCL_SHININESS 0x2250 ++ ++#define RADEON_SE_TCL_TEXTURE_PROC_CTL 0x2268 ++# define RADEON_TEXGEN_TEXMAT_0_ENABLE (1 << 0) ++# define RADEON_TEXGEN_TEXMAT_1_ENABLE (1 << 1) ++# define RADEON_TEXGEN_TEXMAT_2_ENABLE (1 << 2) ++# define RADEON_TEXGEN_TEXMAT_3_ENABLE (1 << 3) ++# define RADEON_TEXMAT_0_ENABLE (1 << 4) ++# define RADEON_TEXMAT_1_ENABLE (1 << 5) ++# define RADEON_TEXMAT_2_ENABLE (1 << 6) ++# define RADEON_TEXMAT_3_ENABLE (1 << 7) ++# define RADEON_TEXGEN_INPUT_MASK 0xf ++# define RADEON_TEXGEN_INPUT_TEXCOORD_0 0 ++# define RADEON_TEXGEN_INPUT_TEXCOORD_1 1 ++# define RADEON_TEXGEN_INPUT_TEXCOORD_2 2 ++# define RADEON_TEXGEN_INPUT_TEXCOORD_3 3 ++# define RADEON_TEXGEN_INPUT_OBJ 4 ++# define RADEON_TEXGEN_INPUT_EYE 5 ++# define RADEON_TEXGEN_INPUT_EYE_NORMAL 6 ++# define RADEON_TEXGEN_INPUT_EYE_REFLECT 7 ++# define RADEON_TEXGEN_INPUT_EYE_NORMALIZED 8 ++# define RADEON_TEXGEN_0_INPUT_SHIFT 16 ++# define RADEON_TEXGEN_1_INPUT_SHIFT 20 ++# define RADEON_TEXGEN_2_INPUT_SHIFT 24 ++# define RADEON_TEXGEN_3_INPUT_SHIFT 28 ++ ++#define RADEON_SE_TCL_UCP_VERT_BLEND_CTL 0x2264 ++# define RADEON_UCP_IN_CLIP_SPACE (1 << 0) ++# define RADEON_UCP_IN_MODEL_SPACE (1 << 1) ++# define RADEON_UCP_ENABLE_0 (1 << 2) ++# define RADEON_UCP_ENABLE_1 (1 << 3) ++# define RADEON_UCP_ENABLE_2 (1 << 4) ++# define RADEON_UCP_ENABLE_3 (1 << 5) ++# define RADEON_UCP_ENABLE_4 (1 << 6) ++# define RADEON_UCP_ENABLE_5 (1 << 7) ++# define RADEON_TCL_FOG_MASK (3 << 8) ++# define RADEON_TCL_FOG_DISABLE (0 << 8) ++# define RADEON_TCL_FOG_EXP (1 << 8) ++# define RADEON_TCL_FOG_EXP2 (2 << 8) ++# define RADEON_TCL_FOG_LINEAR (3 << 8) ++# define RADEON_RNG_BASED_FOG (1 << 10) ++# define RADEON_LIGHT_TWOSIDE (1 << 11) ++# define RADEON_BLEND_OP_COUNT_MASK (7 << 12) ++# define RADEON_BLEND_OP_COUNT_SHIFT 12 ++# define RADEON_POSITION_BLEND_OP_ENABLE (1 << 16) ++# define RADEON_NORMAL_BLEND_OP_ENABLE (1 << 17) ++# define RADEON_VERTEX_BLEND_SRC_0_PRIMARY (1 << 18) ++# define RADEON_VERTEX_BLEND_SRC_0_SECONDARY (1 << 18) ++# define RADEON_VERTEX_BLEND_SRC_1_PRIMARY (1 << 19) ++# define RADEON_VERTEX_BLEND_SRC_1_SECONDARY (1 << 19) ++# define RADEON_VERTEX_BLEND_SRC_2_PRIMARY (1 << 20) ++# define RADEON_VERTEX_BLEND_SRC_2_SECONDARY (1 << 20) ++# define RADEON_VERTEX_BLEND_SRC_3_PRIMARY (1 << 21) ++# define RADEON_VERTEX_BLEND_SRC_3_SECONDARY (1 << 21) ++# define RADEON_VERTEX_BLEND_WGT_MINUS_ONE (1 << 22) ++# define RADEON_CULL_FRONT_IS_CW (0 << 28) ++# define RADEON_CULL_FRONT_IS_CCW (1 << 28) ++# define RADEON_CULL_FRONT (1 << 29) ++# define RADEON_CULL_BACK (1 << 30) ++# define RADEON_FORCE_W_TO_ONE (1 << 31) ++ ++#define RADEON_SE_VPORT_XSCALE 0x1d98 ++#define RADEON_SE_VPORT_XOFFSET 0x1d9c ++#define RADEON_SE_VPORT_YSCALE 0x1da0 ++#define RADEON_SE_VPORT_YOFFSET 0x1da4 ++#define RADEON_SE_VPORT_ZSCALE 0x1da8 ++#define RADEON_SE_VPORT_ZOFFSET 0x1dac ++#define RADEON_SE_ZBIAS_FACTOR 0x1db0 ++#define RADEON_SE_ZBIAS_CONSTANT 0x1db4 ++ ++#define RADEON_SE_VTX_FMT 0x2080 ++# define RADEON_SE_VTX_FMT_XY 0x00000000 ++# define RADEON_SE_VTX_FMT_W0 0x00000001 ++# define RADEON_SE_VTX_FMT_FPCOLOR 0x00000002 ++# define RADEON_SE_VTX_FMT_FPALPHA 0x00000004 ++# define RADEON_SE_VTX_FMT_PKCOLOR 0x00000008 ++# define RADEON_SE_VTX_FMT_FPSPEC 0x00000010 ++# define RADEON_SE_VTX_FMT_FPFOG 0x00000020 ++# define RADEON_SE_VTX_FMT_PKSPEC 0x00000040 ++# define RADEON_SE_VTX_FMT_ST0 0x00000080 ++# define RADEON_SE_VTX_FMT_ST1 0x00000100 ++# define RADEON_SE_VTX_FMT_Q1 0x00000200 ++# define RADEON_SE_VTX_FMT_ST2 0x00000400 ++# define RADEON_SE_VTX_FMT_Q2 0x00000800 ++# define RADEON_SE_VTX_FMT_ST3 0x00001000 ++# define RADEON_SE_VTX_FMT_Q3 0x00002000 ++# define RADEON_SE_VTX_FMT_Q0 0x00004000 ++# define RADEON_SE_VTX_FMT_BLND_WEIGHT_CNT_MASK 0x00038000 ++# define RADEON_SE_VTX_FMT_N0 0x00040000 ++# define RADEON_SE_VTX_FMT_XY1 0x08000000 ++# define RADEON_SE_VTX_FMT_Z1 0x10000000 ++# define RADEON_SE_VTX_FMT_W1 0x20000000 ++# define RADEON_SE_VTX_FMT_N1 0x40000000 ++# define RADEON_SE_VTX_FMT_Z 0x80000000 ++ ++#define RADEON_SE_VF_CNTL 0x2084 ++# define RADEON_VF_PRIM_TYPE_POINT_LIST 1 ++# define RADEON_VF_PRIM_TYPE_LINE_LIST 2 ++# define RADEON_VF_PRIM_TYPE_LINE_STRIP 3 ++# define RADEON_VF_PRIM_TYPE_TRIANGLE_LIST 4 ++# define RADEON_VF_PRIM_TYPE_TRIANGLE_FAN 5 ++# define RADEON_VF_PRIM_TYPE_TRIANGLE_STRIP 6 ++# define RADEON_VF_PRIM_TYPE_TRIANGLE_FLAG 7 ++# define RADEON_VF_PRIM_TYPE_RECTANGLE_LIST 8 ++# define RADEON_VF_PRIM_TYPE_POINT_LIST_3 9 ++# define RADEON_VF_PRIM_TYPE_LINE_LIST_3 10 ++# define RADEON_VF_PRIM_TYPE_SPIRIT_LIST 11 ++# define RADEON_VF_PRIM_TYPE_LINE_LOOP 12 ++# define RADEON_VF_PRIM_TYPE_QUAD_LIST 13 ++# define RADEON_VF_PRIM_TYPE_QUAD_STRIP 14 ++# define RADEON_VF_PRIM_TYPE_POLYGON 15 ++# define RADEON_VF_PRIM_WALK_STATE (0<<4) ++# define RADEON_VF_PRIM_WALK_INDEX (1<<4) ++# define RADEON_VF_PRIM_WALK_LIST (2<<4) ++# define RADEON_VF_PRIM_WALK_DATA (3<<4) ++# define RADEON_VF_COLOR_ORDER_RGBA (1<<6) ++# define RADEON_VF_RADEON_MODE (1<<8) ++# define RADEON_VF_TCL_OUTPUT_CTL_ENA (1<<9) ++# define RADEON_VF_PROG_STREAM_ENA (1<<10) ++# define RADEON_VF_INDEX_SIZE_SHIFT 11 ++# define RADEON_VF_NUM_VERTICES_SHIFT 16 ++ ++#define RADEON_SE_PORT_DATA0 0x2000 ++ ++#define R200_SE_VAP_CNTL 0x2080 ++# define R200_VAP_TCL_ENABLE 0x00000001 ++# define R200_VAP_SINGLE_BUF_STATE_ENABLE 0x00000010 ++# define R200_VAP_FORCE_W_TO_ONE 0x00010000 ++# define R200_VAP_D3D_TEX_DEFAULT 0x00020000 ++# define R200_VAP_VF_MAX_VTX_NUM__SHIFT 18 ++# define R200_VAP_VF_MAX_VTX_NUM (9 << 18) ++# define R200_VAP_DX_CLIP_SPACE_DEF 0x00400000 ++#define R200_VF_MAX_VTX_INDX 0x210c ++#define R200_VF_MIN_VTX_INDX 0x2110 ++#define R200_SE_VTE_CNTL 0x20b0 ++# define R200_VPORT_X_SCALE_ENA 0x00000001 ++# define R200_VPORT_X_OFFSET_ENA 0x00000002 ++# define R200_VPORT_Y_SCALE_ENA 0x00000004 ++# define R200_VPORT_Y_OFFSET_ENA 0x00000008 ++# define R200_VPORT_Z_SCALE_ENA 0x00000010 ++# define R200_VPORT_Z_OFFSET_ENA 0x00000020 ++# define R200_VTX_XY_FMT 0x00000100 ++# define R200_VTX_Z_FMT 0x00000200 ++# define R200_VTX_W0_FMT 0x00000400 ++# define R200_VTX_W0_NORMALIZE 0x00000800 ++# define R200_VTX_ST_DENORMALIZED 0x00001000 ++#define R200_SE_VAP_CNTL_STATUS 0x2140 ++# define R200_VC_NO_SWAP (0 << 0) ++# define R200_VC_16BIT_SWAP (1 << 0) ++# define R200_VC_32BIT_SWAP (2 << 0) ++#define R200_PP_TXFILTER_0 0x2c00 ++#define R200_PP_TXFILTER_1 0x2c20 ++#define R200_PP_TXFILTER_2 0x2c40 ++#define R200_PP_TXFILTER_3 0x2c60 ++#define R200_PP_TXFILTER_4 0x2c80 ++#define R200_PP_TXFILTER_5 0x2ca0 ++# define R200_MAG_FILTER_NEAREST (0 << 0) ++# define R200_MAG_FILTER_LINEAR (1 << 0) ++# define R200_MAG_FILTER_MASK (1 << 0) ++# define R200_MIN_FILTER_NEAREST (0 << 1) ++# define R200_MIN_FILTER_LINEAR (1 << 1) ++# define R200_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) ++# define R200_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) ++# define R200_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) ++# define R200_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) ++# define R200_MIN_FILTER_ANISO_NEAREST (8 << 1) ++# define R200_MIN_FILTER_ANISO_LINEAR (9 << 1) ++# define R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) ++# define R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) ++# define R200_MIN_FILTER_MASK (15 << 1) ++# define R200_MAX_ANISO_1_TO_1 (0 << 5) ++# define R200_MAX_ANISO_2_TO_1 (1 << 5) ++# define R200_MAX_ANISO_4_TO_1 (2 << 5) ++# define R200_MAX_ANISO_8_TO_1 (3 << 5) ++# define R200_MAX_ANISO_16_TO_1 (4 << 5) ++# define R200_MAX_ANISO_MASK (7 << 5) ++# define R200_MAX_MIP_LEVEL_MASK (0x0f << 16) ++# define R200_MAX_MIP_LEVEL_SHIFT 16 ++# define R200_YUV_TO_RGB (1 << 20) ++# define R200_YUV_TEMPERATURE_COOL (0 << 21) ++# define R200_YUV_TEMPERATURE_HOT (1 << 21) ++# define R200_YUV_TEMPERATURE_MASK (1 << 21) ++# define R200_WRAPEN_S (1 << 22) ++# define R200_CLAMP_S_WRAP (0 << 23) ++# define R200_CLAMP_S_MIRROR (1 << 23) ++# define R200_CLAMP_S_CLAMP_LAST (2 << 23) ++# define R200_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) ++# define R200_CLAMP_S_CLAMP_BORDER (4 << 23) ++# define R200_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) ++# define R200_CLAMP_S_CLAMP_GL (6 << 23) ++# define R200_CLAMP_S_MIRROR_CLAMP_GL (7 << 23) ++# define R200_CLAMP_S_MASK (7 << 23) ++# define R200_WRAPEN_T (1 << 26) ++# define R200_CLAMP_T_WRAP (0 << 27) ++# define R200_CLAMP_T_MIRROR (1 << 27) ++# define R200_CLAMP_T_CLAMP_LAST (2 << 27) ++# define R200_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) ++# define R200_CLAMP_T_CLAMP_BORDER (4 << 27) ++# define R200_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) ++# define R200_CLAMP_T_CLAMP_GL (6 << 27) ++# define R200_CLAMP_T_MIRROR_CLAMP_GL (7 << 27) ++# define R200_CLAMP_T_MASK (7 << 27) ++# define R200_KILL_LT_ZERO (1 << 30) ++# define R200_BORDER_MODE_OGL (0 << 31) ++# define R200_BORDER_MODE_D3D (1 << 31) ++#define R200_PP_TXFORMAT_0 0x2c04 ++#define R200_PP_TXFORMAT_1 0x2c24 ++#define R200_PP_TXFORMAT_2 0x2c44 ++#define R200_PP_TXFORMAT_3 0x2c64 ++#define R200_PP_TXFORMAT_4 0x2c84 ++#define R200_PP_TXFORMAT_5 0x2ca4 ++# define R200_TXFORMAT_I8 (0 << 0) ++# define R200_TXFORMAT_AI88 (1 << 0) ++# define R200_TXFORMAT_RGB332 (2 << 0) ++# define R200_TXFORMAT_ARGB1555 (3 << 0) ++# define R200_TXFORMAT_RGB565 (4 << 0) ++# define R200_TXFORMAT_ARGB4444 (5 << 0) ++# define R200_TXFORMAT_ARGB8888 (6 << 0) ++# define R200_TXFORMAT_RGBA8888 (7 << 0) ++# define R200_TXFORMAT_Y8 (8 << 0) ++# define R200_TXFORMAT_AVYU4444 (9 << 0) ++# define R200_TXFORMAT_VYUY422 (10 << 0) ++# define R200_TXFORMAT_YVYU422 (11 << 0) ++# define R200_TXFORMAT_DXT1 (12 << 0) ++# define R200_TXFORMAT_DXT23 (14 << 0) ++# define R200_TXFORMAT_DXT45 (15 << 0) ++# define R200_TXFORMAT_ABGR8888 (22 << 0) ++# define R200_TXFORMAT_FORMAT_MASK (31 << 0) ++# define R200_TXFORMAT_FORMAT_SHIFT 0 ++# define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6) ++# define R200_TXFORMAT_NON_POWER2 (1 << 7) ++# define R200_TXFORMAT_WIDTH_MASK (15 << 8) ++# define R200_TXFORMAT_WIDTH_SHIFT 8 ++# define R200_TXFORMAT_HEIGHT_MASK (15 << 12) ++# define R200_TXFORMAT_HEIGHT_SHIFT 12 ++# define R200_TXFORMAT_F5_WIDTH_MASK (15 << 16) /* cube face 5 */ ++# define R200_TXFORMAT_F5_WIDTH_SHIFT 16 ++# define R200_TXFORMAT_F5_HEIGHT_MASK (15 << 20) ++# define R200_TXFORMAT_F5_HEIGHT_SHIFT 20 ++# define R200_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) ++# define R200_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) ++# define R200_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) ++# define R200_TXFORMAT_ST_ROUTE_STQ3 (3 << 24) ++# define R200_TXFORMAT_ST_ROUTE_STQ4 (4 << 24) ++# define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24) ++# define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24) ++# define R200_TXFORMAT_ST_ROUTE_SHIFT 24 ++# define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) ++# define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) ++# define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) ++#define R200_PP_TXFORMAT_X_0 0x2c08 ++#define R200_PP_TXFORMAT_X_1 0x2c28 ++#define R200_PP_TXFORMAT_X_2 0x2c48 ++#define R200_PP_TXFORMAT_X_3 0x2c68 ++#define R200_PP_TXFORMAT_X_4 0x2c88 ++#define R200_PP_TXFORMAT_X_5 0x2ca8 ++ ++#define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ ++#define R200_PP_TXSIZE_1 0x2c2c /* NPOT only */ ++#define R200_PP_TXSIZE_2 0x2c4c /* NPOT only */ ++#define R200_PP_TXSIZE_3 0x2c6c /* NPOT only */ ++#define R200_PP_TXSIZE_4 0x2c8c /* NPOT only */ ++#define R200_PP_TXSIZE_5 0x2cac /* NPOT only */ ++ ++#define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */ ++#define R200_PP_TXPITCH_1 0x2c30 /* NPOT only */ ++#define R200_PP_TXPITCH_2 0x2c50 /* NPOT only */ ++#define R200_PP_TXPITCH_3 0x2c70 /* NPOT only */ ++#define R200_PP_TXPITCH_4 0x2c90 /* NPOT only */ ++#define R200_PP_TXPITCH_5 0x2cb0 /* NPOT only */ ++ ++#define R200_PP_TXOFFSET_0 0x2d00 ++# define R200_TXO_ENDIAN_NO_SWAP (0 << 0) ++# define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) ++# define R200_TXO_ENDIAN_WORD_SWAP (2 << 0) ++# define R200_TXO_ENDIAN_HALFDW_SWAP (3 << 0) ++# define R200_TXO_MACRO_LINEAR (0 << 2) ++# define R200_TXO_MACRO_TILE (1 << 2) ++# define R200_TXO_MICRO_LINEAR (0 << 3) ++# define R200_TXO_MICRO_TILE (1 << 3) ++# define R200_TXO_OFFSET_MASK 0xffffffe0 ++# define R200_TXO_OFFSET_SHIFT 5 ++#define R200_PP_TXOFFSET_1 0x2d18 ++#define R200_PP_TXOFFSET_2 0x2d30 ++#define R200_PP_TXOFFSET_3 0x2d48 ++#define R200_PP_TXOFFSET_4 0x2d60 ++#define R200_PP_TXOFFSET_5 0x2d78 ++ ++#define R200_PP_TFACTOR_0 0x2ee0 ++#define R200_PP_TFACTOR_1 0x2ee4 ++#define R200_PP_TFACTOR_2 0x2ee8 ++#define R200_PP_TFACTOR_3 0x2eec ++#define R200_PP_TFACTOR_4 0x2ef0 ++#define R200_PP_TFACTOR_5 0x2ef4 ++ ++#define R200_PP_TXCBLEND_0 0x2f00 ++# define R200_TXC_ARG_A_ZERO (0) ++# define R200_TXC_ARG_A_CURRENT_COLOR (2) ++# define R200_TXC_ARG_A_CURRENT_ALPHA (3) ++# define R200_TXC_ARG_A_DIFFUSE_COLOR (4) ++# define R200_TXC_ARG_A_DIFFUSE_ALPHA (5) ++# define R200_TXC_ARG_A_SPECULAR_COLOR (6) ++# define R200_TXC_ARG_A_SPECULAR_ALPHA (7) ++# define R200_TXC_ARG_A_TFACTOR_COLOR (8) ++# define R200_TXC_ARG_A_TFACTOR_ALPHA (9) ++# define R200_TXC_ARG_A_R0_COLOR (10) ++# define R200_TXC_ARG_A_R0_ALPHA (11) ++# define R200_TXC_ARG_A_R1_COLOR (12) ++# define R200_TXC_ARG_A_R1_ALPHA (13) ++# define R200_TXC_ARG_A_R2_COLOR (14) ++# define R200_TXC_ARG_A_R2_ALPHA (15) ++# define R200_TXC_ARG_A_R3_COLOR (16) ++# define R200_TXC_ARG_A_R3_ALPHA (17) ++# define R200_TXC_ARG_A_R4_COLOR (18) ++# define R200_TXC_ARG_A_R4_ALPHA (19) ++# define R200_TXC_ARG_A_R5_COLOR (20) ++# define R200_TXC_ARG_A_R5_ALPHA (21) ++# define R200_TXC_ARG_A_TFACTOR1_COLOR (26) ++# define R200_TXC_ARG_A_TFACTOR1_ALPHA (27) ++# define R200_TXC_ARG_A_MASK (31 << 0) ++# define R200_TXC_ARG_A_SHIFT 0 ++# define R200_TXC_ARG_B_ZERO (0 << 5) ++# define R200_TXC_ARG_B_CURRENT_COLOR (2 << 5) ++# define R200_TXC_ARG_B_CURRENT_ALPHA (3 << 5) ++# define R200_TXC_ARG_B_DIFFUSE_COLOR (4 << 5) ++# define R200_TXC_ARG_B_DIFFUSE_ALPHA (5 << 5) ++# define R200_TXC_ARG_B_SPECULAR_COLOR (6 << 5) ++# define R200_TXC_ARG_B_SPECULAR_ALPHA (7 << 5) ++# define R200_TXC_ARG_B_TFACTOR_COLOR (8 << 5) ++# define R200_TXC_ARG_B_TFACTOR_ALPHA (9 << 5) ++# define R200_TXC_ARG_B_R0_COLOR (10 << 5) ++# define R200_TXC_ARG_B_R0_ALPHA (11 << 5) ++# define R200_TXC_ARG_B_R1_COLOR (12 << 5) ++# define R200_TXC_ARG_B_R1_ALPHA (13 << 5) ++# define R200_TXC_ARG_B_R2_COLOR (14 << 5) ++# define R200_TXC_ARG_B_R2_ALPHA (15 << 5) ++# define R200_TXC_ARG_B_R3_COLOR (16 << 5) ++# define R200_TXC_ARG_B_R3_ALPHA (17 << 5) ++# define R200_TXC_ARG_B_R4_COLOR (18 << 5) ++# define R200_TXC_ARG_B_R4_ALPHA (19 << 5) ++# define R200_TXC_ARG_B_R5_COLOR (20 << 5) ++# define R200_TXC_ARG_B_R5_ALPHA (21 << 5) ++# define R200_TXC_ARG_B_TFACTOR1_COLOR (26 << 5) ++# define R200_TXC_ARG_B_TFACTOR1_ALPHA (27 << 5) ++# define R200_TXC_ARG_B_MASK (31 << 5) ++# define R200_TXC_ARG_B_SHIFT 5 ++# define R200_TXC_ARG_C_ZERO (0 << 10) ++# define R200_TXC_ARG_C_CURRENT_COLOR (2 << 10) ++# define R200_TXC_ARG_C_CURRENT_ALPHA (3 << 10) ++# define R200_TXC_ARG_C_DIFFUSE_COLOR (4 << 10) ++# define R200_TXC_ARG_C_DIFFUSE_ALPHA (5 << 10) ++# define R200_TXC_ARG_C_SPECULAR_COLOR (6 << 10) ++# define R200_TXC_ARG_C_SPECULAR_ALPHA (7 << 10) ++# define R200_TXC_ARG_C_TFACTOR_COLOR (8 << 10) ++# define R200_TXC_ARG_C_TFACTOR_ALPHA (9 << 10) ++# define R200_TXC_ARG_C_R0_COLOR (10 << 10) ++# define R200_TXC_ARG_C_R0_ALPHA (11 << 10) ++# define R200_TXC_ARG_C_R1_COLOR (12 << 10) ++# define R200_TXC_ARG_C_R1_ALPHA (13 << 10) ++# define R200_TXC_ARG_C_R2_COLOR (14 << 10) ++# define R200_TXC_ARG_C_R2_ALPHA (15 << 10) ++# define R200_TXC_ARG_C_R3_COLOR (16 << 10) ++# define R200_TXC_ARG_C_R3_ALPHA (17 << 10) ++# define R200_TXC_ARG_C_R4_COLOR (18 << 10) ++# define R200_TXC_ARG_C_R4_ALPHA (19 << 10) ++# define R200_TXC_ARG_C_R5_COLOR (20 << 10) ++# define R200_TXC_ARG_C_R5_ALPHA (21 << 10) ++# define R200_TXC_ARG_C_TFACTOR1_COLOR (26 << 10) ++# define R200_TXC_ARG_C_TFACTOR1_ALPHA (27 << 10) ++# define R200_TXC_ARG_C_MASK (31 << 10) ++# define R200_TXC_ARG_C_SHIFT 10 ++# define R200_TXC_COMP_ARG_A (1 << 16) ++# define R200_TXC_COMP_ARG_A_SHIFT (16) ++# define R200_TXC_BIAS_ARG_A (1 << 17) ++# define R200_TXC_SCALE_ARG_A (1 << 18) ++# define R200_TXC_NEG_ARG_A (1 << 19) ++# define R200_TXC_COMP_ARG_B (1 << 20) ++# define R200_TXC_COMP_ARG_B_SHIFT (20) ++# define R200_TXC_BIAS_ARG_B (1 << 21) ++# define R200_TXC_SCALE_ARG_B (1 << 22) ++# define R200_TXC_NEG_ARG_B (1 << 23) ++# define R200_TXC_COMP_ARG_C (1 << 24) ++# define R200_TXC_COMP_ARG_C_SHIFT (24) ++# define R200_TXC_BIAS_ARG_C (1 << 25) ++# define R200_TXC_SCALE_ARG_C (1 << 26) ++# define R200_TXC_NEG_ARG_C (1 << 27) ++# define R200_TXC_OP_MADD (0 << 28) ++# define R200_TXC_OP_CND0 (2 << 28) ++# define R200_TXC_OP_LERP (3 << 28) ++# define R200_TXC_OP_DOT3 (4 << 28) ++# define R200_TXC_OP_DOT4 (5 << 28) ++# define R200_TXC_OP_CONDITIONAL (6 << 28) ++# define R200_TXC_OP_DOT2_ADD (7 << 28) ++# define R200_TXC_OP_MASK (7 << 28) ++#define R200_PP_TXCBLEND2_0 0x2f04 ++# define R200_TXC_TFACTOR_SEL_SHIFT 0 ++# define R200_TXC_TFACTOR_SEL_MASK 0x7 ++# define R200_TXC_TFACTOR1_SEL_SHIFT 4 ++# define R200_TXC_TFACTOR1_SEL_MASK (0x7 << 4) ++# define R200_TXC_SCALE_SHIFT 8 ++# define R200_TXC_SCALE_MASK (7 << 8) ++# define R200_TXC_SCALE_1X (0 << 8) ++# define R200_TXC_SCALE_2X (1 << 8) ++# define R200_TXC_SCALE_4X (2 << 8) ++# define R200_TXC_SCALE_8X (3 << 8) ++# define R200_TXC_SCALE_INV2 (5 << 8) ++# define R200_TXC_SCALE_INV4 (6 << 8) ++# define R200_TXC_SCALE_INV8 (7 << 8) ++# define R200_TXC_CLAMP_SHIFT 12 ++# define R200_TXC_CLAMP_MASK (3 << 12) ++# define R200_TXC_CLAMP_WRAP (0 << 12) ++# define R200_TXC_CLAMP_0_1 (1 << 12) ++# define R200_TXC_CLAMP_8_8 (2 << 12) ++# define R200_TXC_OUTPUT_REG_MASK (7 << 16) ++# define R200_TXC_OUTPUT_REG_NONE (0 << 16) ++# define R200_TXC_OUTPUT_REG_R0 (1 << 16) ++# define R200_TXC_OUTPUT_REG_R1 (2 << 16) ++# define R200_TXC_OUTPUT_REG_R2 (3 << 16) ++# define R200_TXC_OUTPUT_REG_R3 (4 << 16) ++# define R200_TXC_OUTPUT_REG_R4 (5 << 16) ++# define R200_TXC_OUTPUT_REG_R5 (6 << 16) ++# define R200_TXC_OUTPUT_MASK_MASK (7 << 20) ++# define R200_TXC_OUTPUT_MASK_RGB (0 << 20) ++# define R200_TXC_OUTPUT_MASK_RG (1 << 20) ++# define R200_TXC_OUTPUT_MASK_RB (2 << 20) ++# define R200_TXC_OUTPUT_MASK_R (3 << 20) ++# define R200_TXC_OUTPUT_MASK_GB (4 << 20) ++# define R200_TXC_OUTPUT_MASK_G (5 << 20) ++# define R200_TXC_OUTPUT_MASK_B (6 << 20) ++# define R200_TXC_OUTPUT_MASK_NONE (7 << 20) ++# define R200_TXC_REPL_NORMAL 0 ++# define R200_TXC_REPL_RED 1 ++# define R200_TXC_REPL_GREEN 2 ++# define R200_TXC_REPL_BLUE 3 ++# define R200_TXC_REPL_ARG_A_SHIFT 26 ++# define R200_TXC_REPL_ARG_A_MASK (3 << 26) ++# define R200_TXC_REPL_ARG_B_SHIFT 28 ++# define R200_TXC_REPL_ARG_B_MASK (3 << 28) ++# define R200_TXC_REPL_ARG_C_SHIFT 30 ++# define R200_TXC_REPL_ARG_C_MASK (3 << 30) ++#define R200_PP_TXABLEND_0 0x2f08 ++# define R200_TXA_ARG_A_ZERO (0) ++# define R200_TXA_ARG_A_CURRENT_ALPHA (2) /* guess */ ++# define R200_TXA_ARG_A_CURRENT_BLUE (3) /* guess */ ++# define R200_TXA_ARG_A_DIFFUSE_ALPHA (4) ++# define R200_TXA_ARG_A_DIFFUSE_BLUE (5) ++# define R200_TXA_ARG_A_SPECULAR_ALPHA (6) ++# define R200_TXA_ARG_A_SPECULAR_BLUE (7) ++# define R200_TXA_ARG_A_TFACTOR_ALPHA (8) ++# define R200_TXA_ARG_A_TFACTOR_BLUE (9) ++# define R200_TXA_ARG_A_R0_ALPHA (10) ++# define R200_TXA_ARG_A_R0_BLUE (11) ++# define R200_TXA_ARG_A_R1_ALPHA (12) ++# define R200_TXA_ARG_A_R1_BLUE (13) ++# define R200_TXA_ARG_A_R2_ALPHA (14) ++# define R200_TXA_ARG_A_R2_BLUE (15) ++# define R200_TXA_ARG_A_R3_ALPHA (16) ++# define R200_TXA_ARG_A_R3_BLUE (17) ++# define R200_TXA_ARG_A_R4_ALPHA (18) ++# define R200_TXA_ARG_A_R4_BLUE (19) ++# define R200_TXA_ARG_A_R5_ALPHA (20) ++# define R200_TXA_ARG_A_R5_BLUE (21) ++# define R200_TXA_ARG_A_TFACTOR1_ALPHA (26) ++# define R200_TXA_ARG_A_TFACTOR1_BLUE (27) ++# define R200_TXA_ARG_A_MASK (31 << 0) ++# define R200_TXA_ARG_A_SHIFT 0 ++# define R200_TXA_ARG_B_ZERO (0 << 5) ++# define R200_TXA_ARG_B_CURRENT_ALPHA (2 << 5) /* guess */ ++# define R200_TXA_ARG_B_CURRENT_BLUE (3 << 5) /* guess */ ++# define R200_TXA_ARG_B_DIFFUSE_ALPHA (4 << 5) ++# define R200_TXA_ARG_B_DIFFUSE_BLUE (5 << 5) ++# define R200_TXA_ARG_B_SPECULAR_ALPHA (6 << 5) ++# define R200_TXA_ARG_B_SPECULAR_BLUE (7 << 5) ++# define R200_TXA_ARG_B_TFACTOR_ALPHA (8 << 5) ++# define R200_TXA_ARG_B_TFACTOR_BLUE (9 << 5) ++# define R200_TXA_ARG_B_R0_ALPHA (10 << 5) ++# define R200_TXA_ARG_B_R0_BLUE (11 << 5) ++# define R200_TXA_ARG_B_R1_ALPHA (12 << 5) ++# define R200_TXA_ARG_B_R1_BLUE (13 << 5) ++# define R200_TXA_ARG_B_R2_ALPHA (14 << 5) ++# define R200_TXA_ARG_B_R2_BLUE (15 << 5) ++# define R200_TXA_ARG_B_R3_ALPHA (16 << 5) ++# define R200_TXA_ARG_B_R3_BLUE (17 << 5) ++# define R200_TXA_ARG_B_R4_ALPHA (18 << 5) ++# define R200_TXA_ARG_B_R4_BLUE (19 << 5) ++# define R200_TXA_ARG_B_R5_ALPHA (20 << 5) ++# define R200_TXA_ARG_B_R5_BLUE (21 << 5) ++# define R200_TXA_ARG_B_TFACTOR1_ALPHA (26 << 5) ++# define R200_TXA_ARG_B_TFACTOR1_BLUE (27 << 5) ++# define R200_TXA_ARG_B_MASK (31 << 5) ++# define R200_TXA_ARG_B_SHIFT 5 ++# define R200_TXA_ARG_C_ZERO (0 << 10) ++# define R200_TXA_ARG_C_CURRENT_ALPHA (2 << 10) /* guess */ ++# define R200_TXA_ARG_C_CURRENT_BLUE (3 << 10) /* guess */ ++# define R200_TXA_ARG_C_DIFFUSE_ALPHA (4 << 10) ++# define R200_TXA_ARG_C_DIFFUSE_BLUE (5 << 10) ++# define R200_TXA_ARG_C_SPECULAR_ALPHA (6 << 10) ++# define R200_TXA_ARG_C_SPECULAR_BLUE (7 << 10) ++# define R200_TXA_ARG_C_TFACTOR_ALPHA (8 << 10) ++# define R200_TXA_ARG_C_TFACTOR_BLUE (9 << 10) ++# define R200_TXA_ARG_C_R0_ALPHA (10 << 10) ++# define R200_TXA_ARG_C_R0_BLUE (11 << 10) ++# define R200_TXA_ARG_C_R1_ALPHA (12 << 10) ++# define R200_TXA_ARG_C_R1_BLUE (13 << 10) ++# define R200_TXA_ARG_C_R2_ALPHA (14 << 10) ++# define R200_TXA_ARG_C_R2_BLUE (15 << 10) ++# define R200_TXA_ARG_C_R3_ALPHA (16 << 10) ++# define R200_TXA_ARG_C_R3_BLUE (17 << 10) ++# define R200_TXA_ARG_C_R4_ALPHA (18 << 10) ++# define R200_TXA_ARG_C_R4_BLUE (19 << 10) ++# define R200_TXA_ARG_C_R5_ALPHA (20 << 10) ++# define R200_TXA_ARG_C_R5_BLUE (21 << 10) ++# define R200_TXA_ARG_C_TFACTOR1_ALPHA (26 << 10) ++# define R200_TXA_ARG_C_TFACTOR1_BLUE (27 << 10) ++# define R200_TXA_ARG_C_MASK (31 << 10) ++# define R200_TXA_ARG_C_SHIFT 10 ++# define R200_TXA_COMP_ARG_A (1 << 16) ++# define R200_TXA_COMP_ARG_A_SHIFT (16) ++# define R200_TXA_BIAS_ARG_A (1 << 17) ++# define R200_TXA_SCALE_ARG_A (1 << 18) ++# define R200_TXA_NEG_ARG_A (1 << 19) ++# define R200_TXA_COMP_ARG_B (1 << 20) ++# define R200_TXA_COMP_ARG_B_SHIFT (20) ++# define R200_TXA_BIAS_ARG_B (1 << 21) ++# define R200_TXA_SCALE_ARG_B (1 << 22) ++# define R200_TXA_NEG_ARG_B (1 << 23) ++# define R200_TXA_COMP_ARG_C (1 << 24) ++# define R200_TXA_COMP_ARG_C_SHIFT (24) ++# define R200_TXA_BIAS_ARG_C (1 << 25) ++# define R200_TXA_SCALE_ARG_C (1 << 26) ++# define R200_TXA_NEG_ARG_C (1 << 27) ++# define R200_TXA_OP_MADD (0 << 28) ++# define R200_TXA_OP_CND0 (2 << 28) ++# define R200_TXA_OP_LERP (3 << 28) ++# define R200_TXA_OP_CONDITIONAL (6 << 28) ++# define R200_TXA_OP_MASK (7 << 28) ++#define R200_PP_TXABLEND2_0 0x2f0c ++# define R200_TXA_TFACTOR_SEL_SHIFT 0 ++# define R200_TXA_TFACTOR_SEL_MASK 0x7 ++# define R200_TXA_TFACTOR1_SEL_SHIFT 4 ++# define R200_TXA_TFACTOR1_SEL_MASK (0x7 << 4) ++# define R200_TXA_SCALE_SHIFT 8 ++# define R200_TXA_SCALE_MASK (7 << 8) ++# define R200_TXA_SCALE_1X (0 << 8) ++# define R200_TXA_SCALE_2X (1 << 8) ++# define R200_TXA_SCALE_4X (2 << 8) ++# define R200_TXA_SCALE_8X (3 << 8) ++# define R200_TXA_SCALE_INV2 (5 << 8) ++# define R200_TXA_SCALE_INV4 (6 << 8) ++# define R200_TXA_SCALE_INV8 (7 << 8) ++# define R200_TXA_CLAMP_SHIFT 12 ++# define R200_TXA_CLAMP_MASK (3 << 12) ++# define R200_TXA_CLAMP_WRAP (0 << 12) ++# define R200_TXA_CLAMP_0_1 (1 << 12) ++# define R200_TXA_CLAMP_8_8 (2 << 12) ++# define R200_TXA_OUTPUT_REG_MASK (7 << 16) ++# define R200_TXA_OUTPUT_REG_NONE (0 << 16) ++# define R200_TXA_OUTPUT_REG_R0 (1 << 16) ++# define R200_TXA_OUTPUT_REG_R1 (2 << 16) ++# define R200_TXA_OUTPUT_REG_R2 (3 << 16) ++# define R200_TXA_OUTPUT_REG_R3 (4 << 16) ++# define R200_TXA_OUTPUT_REG_R4 (5 << 16) ++# define R200_TXA_OUTPUT_REG_R5 (6 << 16) ++# define R200_TXA_DOT_ALPHA (1 << 20) ++# define R200_TXA_REPL_NORMAL 0 ++# define R200_TXA_REPL_RED 1 ++# define R200_TXA_REPL_GREEN 2 ++# define R200_TXA_REPL_ARG_A_SHIFT 26 ++# define R200_TXA_REPL_ARG_A_MASK (3 << 26) ++# define R200_TXA_REPL_ARG_B_SHIFT 28 ++# define R200_TXA_REPL_ARG_B_MASK (3 << 28) ++# define R200_TXA_REPL_ARG_C_SHIFT 30 ++# define R200_TXA_REPL_ARG_C_MASK (3 << 30) ++ ++#define R200_SE_VTX_FMT_0 0x2088 ++# define R200_VTX_XY 0 /* always have xy */ ++# define R200_VTX_Z0 (1<<0) ++# define R200_VTX_W0 (1<<1) ++# define R200_VTX_WEIGHT_COUNT_SHIFT (2) ++# define R200_VTX_PV_MATRIX_SEL (1<<5) ++# define R200_VTX_N0 (1<<6) ++# define R200_VTX_POINT_SIZE (1<<7) ++# define R200_VTX_DISCRETE_FOG (1<<8) ++# define R200_VTX_SHININESS_0 (1<<9) ++# define R200_VTX_SHININESS_1 (1<<10) ++# define R200_VTX_COLOR_NOT_PRESENT 0 ++# define R200_VTX_PK_RGBA 1 ++# define R200_VTX_FP_RGB 2 ++# define R200_VTX_FP_RGBA 3 ++# define R200_VTX_COLOR_MASK 3 ++# define R200_VTX_COLOR_0_SHIFT 11 ++# define R200_VTX_COLOR_1_SHIFT 13 ++# define R200_VTX_COLOR_2_SHIFT 15 ++# define R200_VTX_COLOR_3_SHIFT 17 ++# define R200_VTX_COLOR_4_SHIFT 19 ++# define R200_VTX_COLOR_5_SHIFT 21 ++# define R200_VTX_COLOR_6_SHIFT 23 ++# define R200_VTX_COLOR_7_SHIFT 25 ++# define R200_VTX_XY1 (1<<28) ++# define R200_VTX_Z1 (1<<29) ++# define R200_VTX_W1 (1<<30) ++# define R200_VTX_N1 (1<<31) ++#define R200_SE_VTX_FMT_1 0x208c ++# define R200_VTX_TEX0_COMP_CNT_SHIFT 0 ++# define R200_VTX_TEX1_COMP_CNT_SHIFT 3 ++# define R200_VTX_TEX2_COMP_CNT_SHIFT 6 ++# define R200_VTX_TEX3_COMP_CNT_SHIFT 9 ++# define R200_VTX_TEX4_COMP_CNT_SHIFT 12 ++# define R200_VTX_TEX5_COMP_CNT_SHIFT 15 ++ ++#define R200_SE_TCL_OUTPUT_VTX_FMT_0 0x2090 ++#define R200_SE_TCL_OUTPUT_VTX_FMT_1 0x2094 ++#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 ++# define R200_OUTPUT_XYZW (1<<0) ++# define R200_OUTPUT_COLOR_0 (1<<8) ++# define R200_OUTPUT_COLOR_1 (1<<9) ++# define R200_OUTPUT_TEX_0 (1<<16) ++# define R200_OUTPUT_TEX_1 (1<<17) ++# define R200_OUTPUT_TEX_2 (1<<18) ++# define R200_OUTPUT_TEX_3 (1<<19) ++# define R200_OUTPUT_TEX_4 (1<<20) ++# define R200_OUTPUT_TEX_5 (1<<21) ++# define R200_OUTPUT_TEX_MASK (0x3f<<16) ++# define R200_OUTPUT_DISCRETE_FOG (1<<24) ++# define R200_OUTPUT_PT_SIZE (1<<25) ++# define R200_FORCE_INORDER_PROC (1<<31) ++#define R200_PP_CNTL_X 0x2cc4 ++#define R200_PP_TXMULTI_CTL_0 0x2c1c ++#define R200_SE_VTX_STATE_CNTL 0x2180 ++# define R200_UPDATE_USER_COLOR_0_ENA_MASK (1<<16) ++ ++ /* Registers for CP and Microcode Engine */ ++#define RADEON_CP_ME_RAM_ADDR 0x07d4 ++#define RADEON_CP_ME_RAM_RADDR 0x07d8 ++#define RADEON_CP_ME_RAM_DATAH 0x07dc ++#define RADEON_CP_ME_RAM_DATAL 0x07e0 ++ ++#define RADEON_CP_RB_BASE 0x0700 ++#define RADEON_CP_RB_CNTL 0x0704 ++#define RADEON_CP_RB_RPTR_ADDR 0x070c ++#define RADEON_CP_RB_RPTR 0x0710 ++#define RADEON_CP_RB_WPTR 0x0714 ++ ++#define RADEON_CP_IB_BASE 0x0738 ++#define RADEON_CP_IB_BUFSZ 0x073c ++ ++#define RADEON_CP_CSQ_CNTL 0x0740 ++# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) ++# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) ++# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) ++# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) ++# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) ++# define RADEON_CSQ_PRIBM_INDBM (4 << 28) ++# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) ++ ++#define R300_CP_RESYNC_ADDR 0x778 ++#define R300_CP_RESYNC_DATA 0x77c ++ ++#define RADEON_CP_CSQ_STAT 0x07f8 ++# define RADEON_CSQ_RPTR_PRIMARY_MASK (0xff << 0) ++# define RADEON_CSQ_WPTR_PRIMARY_MASK (0xff << 8) ++# define RADEON_CSQ_RPTR_INDIRECT_MASK (0xff << 16) ++# define RADEON_CSQ_WPTR_INDIRECT_MASK (0xff << 24) ++#define RADEON_CP_CSQ_ADDR 0x07f0 ++#define RADEON_CP_CSQ_DATA 0x07f4 ++#define RADEON_CP_CSQ_APER_PRIMARY 0x1000 ++#define RADEON_CP_CSQ_APER_INDIRECT 0x1300 ++ ++#define RADEON_CP_RB_WPTR_DELAY 0x0718 ++# define RADEON_PRE_WRITE_TIMER_SHIFT 0 ++# define RADEON_PRE_WRITE_LIMIT_SHIFT 23 ++ ++#define RADEON_AIC_CNTL 0x01d0 ++# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) ++#define RADEON_AIC_LO_ADDR 0x01dc ++ ++ ++ ++ /* Constants */ ++//#define RADEON_LAST_FRAME_REG RADEON_GUI_SCRATCH_REG0 ++//efine RADEON_LAST_CLEAR_REG RADEON_GUI_SCRATCH_REG2 ++ ++ ++ ++ /* CP packet types */ ++#define RADEON_CP_PACKET0 0x00000000 ++#define RADEON_CP_PACKET1 0x40000000 ++#define RADEON_CP_PACKET2 0x80000000 ++#define RADEON_CP_PACKET3 0xC0000000 ++# define RADEON_CP_PACKET_MASK 0xC0000000 ++# define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 ++# define RADEON_CP_PACKET_MAX_DWORDS (1 << 12) ++# define RADEON_CP_PACKET0_REG_MASK 0x000007ff ++# define R300_CP_PACKET0_REG_MASK 0x00001fff ++# define RADEON_CP_PACKET1_REG0_MASK 0x000007ff ++# define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 ++ ++#define RADEON_CP_PACKET0_ONE_REG_WR 0x00008000 ++ ++#define RADEON_CP_PACKET3_NOP 0xC0001000 ++#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 ++#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 ++#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 ++#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 ++#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 ++#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 ++#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 ++#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 ++#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 ++#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 ++#define R200_CP_PACKET3_3D_DRAW_IMMD_2 0xc0003500 ++#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 ++#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 ++#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 ++#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 ++#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 ++#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 ++#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 ++#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 ++#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 ++#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 ++ ++ ++#define RADEON_CP_VC_FRMT_XY 0x00000000 ++#define RADEON_CP_VC_FRMT_W0 0x00000001 ++#define RADEON_CP_VC_FRMT_FPCOLOR 0x00000002 ++#define RADEON_CP_VC_FRMT_FPALPHA 0x00000004 ++#define RADEON_CP_VC_FRMT_PKCOLOR 0x00000008 ++#define RADEON_CP_VC_FRMT_FPSPEC 0x00000010 ++#define RADEON_CP_VC_FRMT_FPFOG 0x00000020 ++#define RADEON_CP_VC_FRMT_PKSPEC 0x00000040 ++#define RADEON_CP_VC_FRMT_ST0 0x00000080 ++#define RADEON_CP_VC_FRMT_ST1 0x00000100 ++#define RADEON_CP_VC_FRMT_Q1 0x00000200 ++#define RADEON_CP_VC_FRMT_ST2 0x00000400 ++#define RADEON_CP_VC_FRMT_Q2 0x00000800 ++#define RADEON_CP_VC_FRMT_ST3 0x00001000 ++#define RADEON_CP_VC_FRMT_Q3 0x00002000 ++#define RADEON_CP_VC_FRMT_Q0 0x00004000 ++#define RADEON_CP_VC_FRMT_BLND_WEIGHT_CNT_MASK 0x00038000 ++#define RADEON_CP_VC_FRMT_N0 0x00040000 ++#define RADEON_CP_VC_FRMT_XY1 0x08000000 ++#define RADEON_CP_VC_FRMT_Z1 0x10000000 ++#define RADEON_CP_VC_FRMT_W1 0x20000000 ++#define RADEON_CP_VC_FRMT_N1 0x40000000 ++#define RADEON_CP_VC_FRMT_Z 0x80000000 ++ ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP 0x00000003 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE_2 0x00000007 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST 0x00000008 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST 0x00000009 ++#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST 0x0000000a ++#define RADEON_CP_VC_CNTL_PRIM_WALK_IND 0x00000010 ++#define RADEON_CP_VC_CNTL_PRIM_WALK_LIST 0x00000020 ++#define RADEON_CP_VC_CNTL_PRIM_WALK_RING 0x00000030 ++#define RADEON_CP_VC_CNTL_COLOR_ORDER_BGRA 0x00000000 ++#define RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA 0x00000040 ++#define RADEON_CP_VC_CNTL_MAOS_ENABLE 0x00000080 ++#define RADEON_CP_VC_CNTL_VTX_FMT_NON_RADEON_MODE 0x00000000 ++#define RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE 0x00000100 ++#define RADEON_CP_VC_CNTL_TCL_DISABLE 0x00000000 ++#define RADEON_CP_VC_CNTL_TCL_ENABLE 0x00000200 ++#define RADEON_CP_VC_CNTL_NUM_SHIFT 16 ++ ++#define RADEON_VS_MATRIX_0_ADDR 0 ++#define RADEON_VS_MATRIX_1_ADDR 4 ++#define RADEON_VS_MATRIX_2_ADDR 8 ++#define RADEON_VS_MATRIX_3_ADDR 12 ++#define RADEON_VS_MATRIX_4_ADDR 16 ++#define RADEON_VS_MATRIX_5_ADDR 20 ++#define RADEON_VS_MATRIX_6_ADDR 24 ++#define RADEON_VS_MATRIX_7_ADDR 28 ++#define RADEON_VS_MATRIX_8_ADDR 32 ++#define RADEON_VS_MATRIX_9_ADDR 36 ++#define RADEON_VS_MATRIX_10_ADDR 40 ++#define RADEON_VS_MATRIX_11_ADDR 44 ++#define RADEON_VS_MATRIX_12_ADDR 48 ++#define RADEON_VS_MATRIX_13_ADDR 52 ++#define RADEON_VS_MATRIX_14_ADDR 56 ++#define RADEON_VS_MATRIX_15_ADDR 60 ++#define RADEON_VS_LIGHT_AMBIENT_ADDR 64 ++#define RADEON_VS_LIGHT_DIFFUSE_ADDR 72 ++#define RADEON_VS_LIGHT_SPECULAR_ADDR 80 ++#define RADEON_VS_LIGHT_DIRPOS_ADDR 88 ++#define RADEON_VS_LIGHT_HWVSPOT_ADDR 96 ++#define RADEON_VS_LIGHT_ATTENUATION_ADDR 104 ++#define RADEON_VS_MATRIX_EYE2CLIP_ADDR 112 ++#define RADEON_VS_UCP_ADDR 116 ++#define RADEON_VS_GLOBAL_AMBIENT_ADDR 122 ++#define RADEON_VS_FOG_PARAM_ADDR 123 ++#define RADEON_VS_EYE_VECTOR_ADDR 124 ++ ++#define RADEON_SS_LIGHT_DCD_ADDR 0 ++#define RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR 8 ++#define RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR 16 ++#define RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR 24 ++#define RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR 32 ++#define RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR 48 ++#define RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR 49 ++#define RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR 50 ++#define RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 51 ++#define RADEON_SS_SHININESS 60 ++ ++#define RADEON_TV_MASTER_CNTL 0x0800 ++# define RADEON_TV_ASYNC_RST (1 << 0) ++# define RADEON_CRT_ASYNC_RST (1 << 1) ++# define RADEON_RESTART_PHASE_FIX (1 << 3) ++# define RADEON_TV_FIFO_ASYNC_RST (1 << 4) ++# define RADEON_VIN_ASYNC_RST (1 << 5) ++# define RADEON_AUD_ASYNC_RST (1 << 6) ++# define RADEON_DVS_ASYNC_RST (1 << 7) ++# define RADEON_CRT_FIFO_CE_EN (1 << 9) ++# define RADEON_TV_FIFO_CE_EN (1 << 10) ++# define RADEON_RE_SYNC_NOW_SEL_MASK (3 << 14) ++# define RADEON_TVCLK_ALWAYS_ONb (1 << 30) ++# define RADEON_TV_ON (1 << 31) ++#define RADEON_TV_PRE_DAC_MUX_CNTL 0x0888 ++# define RADEON_Y_RED_EN (1 << 0) ++# define RADEON_C_GRN_EN (1 << 1) ++# define RADEON_CMP_BLU_EN (1 << 2) ++# define RADEON_DAC_DITHER_EN (1 << 3) ++# define RADEON_RED_MX_FORCE_DAC_DATA (6 << 4) ++# define RADEON_GRN_MX_FORCE_DAC_DATA (6 << 8) ++# define RADEON_BLU_MX_FORCE_DAC_DATA (6 << 12) ++# define RADEON_TV_FORCE_DAC_DATA_SHIFT 16 ++#define RADEON_TV_RGB_CNTL 0x0804 ++# define RADEON_SWITCH_TO_BLUE (1 << 4) ++# define RADEON_RGB_DITHER_EN (1 << 5) ++# define RADEON_RGB_SRC_SEL_MASK (3 << 8) ++# define RADEON_RGB_SRC_SEL_CRTC1 (0 << 8) ++# define RADEON_RGB_SRC_SEL_RMX (1 << 8) ++# define RADEON_RGB_SRC_SEL_CRTC2 (2 << 8) ++# define RADEON_RGB_CONVERT_BY_PASS (1 << 10) ++# define RADEON_UVRAM_READ_MARGIN_SHIFT 16 ++# define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT 20 ++# define RADEON_TVOUT_SCALE_EN (1 << 26) ++#define RADEON_TV_SYNC_CNTL 0x0808 ++# define RADEON_SYNC_OE (1 << 0) ++# define RADEON_SYNC_OUT (1 << 1) ++# define RADEON_SYNC_IN (1 << 2) ++# define RADEON_SYNC_PUB (1 << 3) ++# define RADEON_SYNC_PD (1 << 4) ++# define RADEON_TV_SYNC_IO_DRIVE (1 << 5) ++#define RADEON_TV_HTOTAL 0x080c ++#define RADEON_TV_HDISP 0x0810 ++#define RADEON_TV_HSTART 0x0818 ++#define RADEON_TV_HCOUNT 0x081C ++#define RADEON_TV_VTOTAL 0x0820 ++#define RADEON_TV_VDISP 0x0824 ++#define RADEON_TV_VCOUNT 0x0828 ++#define RADEON_TV_FTOTAL 0x082c ++#define RADEON_TV_FCOUNT 0x0830 ++#define RADEON_TV_FRESTART 0x0834 ++#define RADEON_TV_HRESTART 0x0838 ++#define RADEON_TV_VRESTART 0x083c ++#define RADEON_TV_HOST_READ_DATA 0x0840 ++#define RADEON_TV_HOST_WRITE_DATA 0x0844 ++#define RADEON_TV_HOST_RD_WT_CNTL 0x0848 ++# define RADEON_HOST_FIFO_RD (1 << 12) ++# define RADEON_HOST_FIFO_RD_ACK (1 << 13) ++# define RADEON_HOST_FIFO_WT (1 << 14) ++# define RADEON_HOST_FIFO_WT_ACK (1 << 15) ++#define RADEON_TV_VSCALER_CNTL1 0x084c ++# define RADEON_UV_INC_MASK 0xffff ++# define RADEON_UV_INC_SHIFT 0 ++# define RADEON_Y_W_EN (1 << 24) ++# define RADEON_RESTART_FIELD (1 << 29) /* restart on field 0 */ ++# define RADEON_Y_DEL_W_SIG_SHIFT 26 ++#define RADEON_TV_TIMING_CNTL 0x0850 ++# define RADEON_H_INC_MASK 0xfff ++# define RADEON_H_INC_SHIFT 0 ++# define RADEON_REQ_Y_FIRST (1 << 19) ++# define RADEON_FORCE_BURST_ALWAYS (1 << 21) ++# define RADEON_UV_POST_SCALE_BYPASS (1 << 23) ++# define RADEON_UV_OUTPUT_POST_SCALE_SHIFT 24 ++#define RADEON_TV_VSCALER_CNTL2 0x0854 ++# define RADEON_DITHER_MODE (1 << 0) ++# define RADEON_Y_OUTPUT_DITHER_EN (1 << 1) ++# define RADEON_UV_OUTPUT_DITHER_EN (1 << 2) ++# define RADEON_UV_TO_BUF_DITHER_EN (1 << 3) ++#define RADEON_TV_Y_FALL_CNTL 0x0858 ++# define RADEON_Y_FALL_PING_PONG (1 << 16) ++# define RADEON_Y_COEF_EN (1 << 17) ++#define RADEON_TV_Y_RISE_CNTL 0x085c ++# define RADEON_Y_RISE_PING_PONG (1 << 16) ++#define RADEON_TV_Y_SAW_TOOTH_CNTL 0x0860 ++#define RADEON_TV_UPSAMP_AND_GAIN_CNTL 0x0864 ++# define RADEON_YUPSAMP_EN (1 << 0) ++# define RADEON_UVUPSAMP_EN (1 << 2) ++#define RADEON_TV_GAIN_LIMIT_SETTINGS 0x0868 ++# define RADEON_Y_GAIN_LIMIT_SHIFT 0 ++# define RADEON_UV_GAIN_LIMIT_SHIFT 16 ++#define RADEON_TV_LINEAR_GAIN_SETTINGS 0x086c ++# define RADEON_Y_GAIN_SHIFT 0 ++# define RADEON_UV_GAIN_SHIFT 16 ++#define RADEON_TV_MODULATOR_CNTL1 0x0870 ++# define RADEON_YFLT_EN (1 << 2) ++# define RADEON_UVFLT_EN (1 << 3) ++# define RADEON_ALT_PHASE_EN (1 << 6) ++# define RADEON_SYNC_TIP_LEVEL (1 << 7) ++# define RADEON_BLANK_LEVEL_SHIFT 8 ++# define RADEON_SET_UP_LEVEL_SHIFT 16 ++# define RADEON_SLEW_RATE_LIMIT (1 << 23) ++# define RADEON_CY_FILT_BLEND_SHIFT 28 ++#define RADEON_TV_MODULATOR_CNTL2 0x0874 ++# define RADEON_TV_U_BURST_LEVEL_MASK 0x1ff ++# define RADEON_TV_V_BURST_LEVEL_MASK 0x1ff ++# define RADEON_TV_V_BURST_LEVEL_SHIFT 16 ++#define RADEON_TV_CRC_CNTL 0x0890 ++#define RADEON_TV_UV_ADR 0x08ac ++# define RADEON_MAX_UV_ADR_MASK 0x000000ff ++# define RADEON_MAX_UV_ADR_SHIFT 0 ++# define RADEON_TABLE1_BOT_ADR_MASK 0x0000ff00 ++# define RADEON_TABLE1_BOT_ADR_SHIFT 8 ++# define RADEON_TABLE3_TOP_ADR_MASK 0x00ff0000 ++# define RADEON_TABLE3_TOP_ADR_SHIFT 16 ++# define RADEON_HCODE_TABLE_SEL_MASK 0x06000000 ++# define RADEON_HCODE_TABLE_SEL_SHIFT 25 ++# define RADEON_VCODE_TABLE_SEL_MASK 0x18000000 ++# define RADEON_VCODE_TABLE_SEL_SHIFT 27 ++# define RADEON_TV_MAX_FIFO_ADDR 0x1a7 ++# define RADEON_TV_MAX_FIFO_ADDR_INTERNAL 0x1ff ++#define RADEON_TV_PLL_FINE_CNTL 0x0020 /* PLL */ ++#define RADEON_TV_PLL_CNTL 0x0021 /* PLL */ ++# define RADEON_TV_M0LO_MASK 0xff ++# define RADEON_TV_M0HI_MASK 0x7 ++# define RADEON_TV_M0HI_SHIFT 18 ++# define RADEON_TV_N0LO_MASK 0x1ff ++# define RADEON_TV_N0LO_SHIFT 8 ++# define RADEON_TV_N0HI_MASK 0x3 ++# define RADEON_TV_N0HI_SHIFT 21 ++# define RADEON_TV_P_MASK 0xf ++# define RADEON_TV_P_SHIFT 24 ++# define RADEON_TV_SLIP_EN (1 << 23) ++# define RADEON_TV_DTO_EN (1 << 28) ++#define RADEON_TV_PLL_CNTL1 0x0022 /* PLL */ ++# define RADEON_TVPLL_RESET (1 << 1) ++# define RADEON_TVPLL_SLEEP (1 << 3) ++# define RADEON_TVPLL_REFCLK_SEL (1 << 4) ++# define RADEON_TVPCP_SHIFT 8 ++# define RADEON_TVPCP_MASK (7 << 8) ++# define RADEON_TVPVG_SHIFT 11 ++# define RADEON_TVPVG_MASK (7 << 11) ++# define RADEON_TVPDC_SHIFT 14 ++# define RADEON_TVPDC_MASK (3 << 14) ++# define RADEON_TVPLL_TEST_DIS (1 << 31) ++# define RADEON_TVCLK_SRC_SEL_TVPLL (1 << 30) ++ ++#define RS400_DISP2_REQ_CNTL1 0xe30 ++# define RS400_DISP2_START_REQ_LEVEL_SHIFT 0 ++# define RS400_DISP2_START_REQ_LEVEL_MASK 0x3ff ++# define RS400_DISP2_STOP_REQ_LEVEL_SHIFT 12 ++# define RS400_DISP2_STOP_REQ_LEVEL_MASK 0x3ff ++# define RS400_DISP2_ALLOW_FID_LEVEL_SHIFT 22 ++# define RS400_DISP2_ALLOW_FID_LEVEL_MASK 0x3ff ++#define RS400_DISP2_REQ_CNTL2 0xe34 ++# define RS400_DISP2_CRITICAL_POINT_START_SHIFT 12 ++# define RS400_DISP2_CRITICAL_POINT_START_MASK 0x3ff ++# define RS400_DISP2_CRITICAL_POINT_STOP_SHIFT 22 ++# define RS400_DISP2_CRITICAL_POINT_STOP_MASK 0x3ff ++#define RS400_DMIF_MEM_CNTL1 0xe38 ++# define RS400_DISP2_START_ADR_SHIFT 0 ++# define RS400_DISP2_START_ADR_MASK 0x3ff ++# define RS400_DISP1_CRITICAL_POINT_START_SHIFT 12 ++# define RS400_DISP1_CRITICAL_POINT_START_MASK 0x3ff ++# define RS400_DISP1_CRITICAL_POINT_STOP_SHIFT 22 ++# define RS400_DISP1_CRITICAL_POINT_STOP_MASK 0x3ff ++#define RS400_DISP1_REQ_CNTL1 0xe3c ++# define RS400_DISP1_START_REQ_LEVEL_SHIFT 0 ++# define RS400_DISP1_START_REQ_LEVEL_MASK 0x3ff ++# define RS400_DISP1_STOP_REQ_LEVEL_SHIFT 12 ++# define RS400_DISP1_STOP_REQ_LEVEL_MASK 0x3ff ++# define RS400_DISP1_ALLOW_FID_LEVEL_SHIFT 22 ++# define RS400_DISP1_ALLOW_FID_LEVEL_MASK 0x3ff ++ ++#define RS690_MC_INDEX 0x78 ++# define RS690_MC_INDEX_MASK 0x1ff ++# define RS690_MC_INDEX_WR_EN (1 << 9) ++# define RS690_MC_INDEX_WR_ACK 0x7f ++#define RS690_MC_DATA 0x7c ++ ++#define RS690_MC_FB_LOCATION 0x100 ++#define RS690_MC_AGP_LOCATION 0x101 ++#define RS690_MC_AGP_BASE 0x102 ++#define RS690_MC_AGP_BASE_2 0x103 ++#define RS690_MC_INIT_MISC_LAT_TIMER 0x104 ++#define RS690_MC_STATUS 0x90 ++#define RS690_MC_STATUS_IDLE (1 << 0) ++ ++#define AVIVO_MC_INDEX 0x0070 ++#define R520_MC_STATUS 0x00 ++#define R520_MC_STATUS_IDLE (1<<1) ++#define RV515_MC_STATUS 0x08 ++#define RV515_MC_STATUS_IDLE (1<<4) ++#define RV515_MC_INIT_MISC_LAT_TIMER 0x09 ++#define AVIVO_MC_DATA 0x0074 ++ ++#define RV515_MC_FB_LOCATION 0x1 ++#define RV515_MC_AGP_LOCATION 0x2 ++#define RV515_MC_AGP_BASE 0x3 ++#define RV515_MC_AGP_BASE_2 0x4 ++#define RV515_MC_CNTL 0x5 ++# define RV515_MEM_NUM_CHANNELS_MASK 0x3 ++#define R520_MC_FB_LOCATION 0x4 ++#define R520_MC_AGP_LOCATION 0x5 ++#define R520_MC_AGP_BASE 0x6 ++#define R520_MC_AGP_BASE_2 0x7 ++#define R520_MC_CNTL0 0x8 ++# define R520_MEM_NUM_CHANNELS_MASK (0x3 << 24) ++# define R520_MEM_NUM_CHANNELS_SHIFT 24 ++# define R520_MC_CHANNEL_SIZE (1 << 23) ++ ++#define R600_RAMCFG 0x2408 ++# define R600_CHANSIZE (1 << 7) ++# define R600_CHANSIZE_OVERRIDE (1 << 10) ++ ++#define R600_SRBM_STATUS 0x0e50 ++ ++#define AVIVO_HDP_FB_LOCATION 0x134 ++ ++#define AVIVO_VGA_RENDER_CONTROL 0x0300 ++# define AVIVO_VGA_VSTATUS_CNTL_MASK (3 << 16) ++#define AVIVO_D1VGA_CONTROL 0x0330 ++# define AVIVO_DVGA_CONTROL_MODE_ENABLE (1<<0) ++# define AVIVO_DVGA_CONTROL_TIMING_SELECT (1<<8) ++# define AVIVO_DVGA_CONTROL_SYNC_POLARITY_SELECT (1<<9) ++# define AVIVO_DVGA_CONTROL_OVERSCAN_TIMING_SELECT (1<<10) ++# define AVIVO_DVGA_CONTROL_OVERSCAN_COLOR_EN (1<<16) ++# define AVIVO_DVGA_CONTROL_ROTATE (1<<24) ++#define AVIVO_D2VGA_CONTROL 0x0338 ++ ++#define AVIVO_EXT1_PPLL_REF_DIV_SRC 0x400 ++#define AVIVO_EXT1_PPLL_REF_DIV 0x404 ++#define AVIVO_EXT1_PPLL_UPDATE_LOCK 0x408 ++#define AVIVO_EXT1_PPLL_UPDATE_CNTL 0x40c ++ ++#define AVIVO_EXT2_PPLL_REF_DIV_SRC 0x410 ++#define AVIVO_EXT2_PPLL_REF_DIV 0x414 ++#define AVIVO_EXT2_PPLL_UPDATE_LOCK 0x418 ++#define AVIVO_EXT2_PPLL_UPDATE_CNTL 0x41c ++ ++#define AVIVO_EXT1_PPLL_FB_DIV 0x430 ++#define AVIVO_EXT2_PPLL_FB_DIV 0x434 ++ ++#define AVIVO_EXT1_PPLL_POST_DIV_SRC 0x438 ++#define AVIVO_EXT1_PPLL_POST_DIV 0x43c ++ ++#define AVIVO_EXT2_PPLL_POST_DIV_SRC 0x440 ++#define AVIVO_EXT2_PPLL_POST_DIV 0x444 ++ ++#define AVIVO_EXT1_PPLL_CNTL 0x448 ++#define AVIVO_EXT2_PPLL_CNTL 0x44c ++ ++#define AVIVO_P1PLL_CNTL 0x450 ++#define AVIVO_P2PLL_CNTL 0x454 ++#define AVIVO_P1PLL_INT_SS_CNTL 0x458 ++#define AVIVO_P2PLL_INT_SS_CNTL 0x45c ++#define AVIVO_P1PLL_TMDSA_CNTL 0x460 ++#define AVIVO_P2PLL_LVTMA_CNTL 0x464 ++ ++#define AVIVO_PCLK_CRTC1_CNTL 0x480 ++#define AVIVO_PCLK_CRTC2_CNTL 0x484 ++ ++#define AVIVO_D1CRTC_H_TOTAL 0x6000 ++#define AVIVO_D1CRTC_H_BLANK_START_END 0x6004 ++#define AVIVO_D1CRTC_H_SYNC_A 0x6008 ++#define AVIVO_D1CRTC_H_SYNC_A_CNTL 0x600c ++#define AVIVO_D1CRTC_H_SYNC_B 0x6010 ++#define AVIVO_D1CRTC_H_SYNC_B_CNTL 0x6014 ++ ++#define AVIVO_D1CRTC_V_TOTAL 0x6020 ++#define AVIVO_D1CRTC_V_BLANK_START_END 0x6024 ++#define AVIVO_D1CRTC_V_SYNC_A 0x6028 ++#define AVIVO_D1CRTC_V_SYNC_A_CNTL 0x602c ++#define AVIVO_D1CRTC_V_SYNC_B 0x6030 ++#define AVIVO_D1CRTC_V_SYNC_B_CNTL 0x6034 ++ ++#define AVIVO_D1CRTC_CONTROL 0x6080 ++# define AVIVO_CRTC_EN (1 << 0) ++#define AVIVO_D1CRTC_BLANK_CONTROL 0x6084 ++#define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 ++#define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c ++#define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 ++ ++/* master controls */ ++#define AVIVO_DC_CRTC_MASTER_EN 0x60f8 ++#define AVIVO_DC_CRTC_TV_CONTROL 0x60fc ++ ++#define AVIVO_D1GRPH_ENABLE 0x6100 ++#define AVIVO_D1GRPH_CONTROL 0x6104 ++# define AVIVO_D1GRPH_CONTROL_DEPTH_8BPP (0 << 0) ++# define AVIVO_D1GRPH_CONTROL_DEPTH_16BPP (1 << 0) ++# define AVIVO_D1GRPH_CONTROL_DEPTH_32BPP (2 << 0) ++# define AVIVO_D1GRPH_CONTROL_DEPTH_64BPP (3 << 0) ++ ++# define AVIVO_D1GRPH_CONTROL_8BPP_INDEXED (0 << 8) ++ ++# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555 (0 << 8) ++# define AVIVO_D1GRPH_CONTROL_16BPP_RGB565 (1 << 8) ++# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444 (2 << 8) ++# define AVIVO_D1GRPH_CONTROL_16BPP_AI88 (3 << 8) ++# define AVIVO_D1GRPH_CONTROL_16BPP_MONO16 (4 << 8) ++ ++# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888 (0 << 8) ++# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010 (1 << 8) ++# define AVIVO_D1GRPH_CONTROL_32BPP_DIGITAL (2 << 8) ++# define AVIVO_D1GRPH_CONTROL_32BPP_8B_ARGB2101010 (3 << 8) ++ ++ ++# define AVIVO_D1GRPH_CONTROL_64BPP_ARGB16161616 (0 << 8) ++ ++# define AVIVO_D1GRPH_SWAP_RB (1 << 16) ++# define AVIVO_D1GRPH_TILED (1 << 20) ++# define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) ++ ++#define AVIVO_D1GRPH_LUT_SEL 0x6108 ++#define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 ++#define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 ++#define AVIVO_D1GRPH_PITCH 0x6120 ++#define AVIVO_D1GRPH_SURFACE_OFFSET_X 0x6124 ++#define AVIVO_D1GRPH_SURFACE_OFFSET_Y 0x6128 ++#define AVIVO_D1GRPH_X_START 0x612c ++#define AVIVO_D1GRPH_Y_START 0x6130 ++#define AVIVO_D1GRPH_X_END 0x6134 ++#define AVIVO_D1GRPH_Y_END 0x6138 ++#define AVIVO_D1GRPH_UPDATE 0x6144 ++# define AVIVO_D1GRPH_UPDATE_LOCK (1 << 16) ++#define AVIVO_D1GRPH_FLIP_CONTROL 0x6148 ++ ++#define AVIVO_D1CUR_CONTROL 0x6400 ++# define AVIVO_D1CURSOR_EN (1 << 0) ++# define AVIVO_D1CURSOR_MODE_SHIFT 8 ++# define AVIVO_D1CURSOR_MODE_MASK (3 << 8) ++# define AVIVO_D1CURSOR_MODE_24BPP 2 ++#define AVIVO_D1CUR_SURFACE_ADDRESS 0x6408 ++#define AVIVO_D1CUR_SIZE 0x6410 ++#define AVIVO_D1CUR_POSITION 0x6414 ++#define AVIVO_D1CUR_HOT_SPOT 0x6418 ++#define AVIVO_D1CUR_UPDATE 0x6424 ++# define AVIVO_D1CURSOR_UPDATE_LOCK (1 << 16) ++ ++#define AVIVO_DC_LUT_RW_SELECT 0x6480 ++#define AVIVO_DC_LUT_RW_MODE 0x6484 ++#define AVIVO_DC_LUT_RW_INDEX 0x6488 ++#define AVIVO_DC_LUT_SEQ_COLOR 0x648c ++#define AVIVO_DC_LUT_PWL_DATA 0x6490 ++#define AVIVO_DC_LUT_30_COLOR 0x6494 ++#define AVIVO_DC_LUT_READ_PIPE_SELECT 0x6498 ++#define AVIVO_DC_LUT_WRITE_EN_MASK 0x649c ++#define AVIVO_DC_LUT_AUTOFILL 0x64a0 ++ ++#define AVIVO_DC_LUTA_CONTROL 0x64c0 ++#define AVIVO_DC_LUTA_BLACK_OFFSET_BLUE 0x64c4 ++#define AVIVO_DC_LUTA_BLACK_OFFSET_GREEN 0x64c8 ++#define AVIVO_DC_LUTA_BLACK_OFFSET_RED 0x64cc ++#define AVIVO_DC_LUTA_WHITE_OFFSET_BLUE 0x64d0 ++#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN 0x64d4 ++#define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8 ++ ++#define AVIVO_DC_LB_MEMORY_SPLIT 0x6520 ++# define AVIVO_DC_LB_MEMORY_SPLIT_MASK 0x3 ++# define AVIVO_DC_LB_MEMORY_SPLIT_SHIFT 0 ++# define AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0 ++# define AVIVO_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1 ++# define AVIVO_DC_LB_MEMORY_SPLIT_D1_ONLY 2 ++# define AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3 ++# define AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE (1 << 2) ++# define AVIVO_DC_LB_DISP1_END_ADR_SHIFT 4 ++# define AVIVO_DC_LB_DISP1_END_ADR_MASK 0x7ff ++ ++#define AVIVO_D1MODE_DATA_FORMAT 0x6528 ++# define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) ++#define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C ++#define AVIVO_D1MODE_VLINE_START_END 0x6538 ++#define AVIVO_D1MODE_VIEWPORT_START 0x6580 ++#define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 ++#define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588 ++#define AVIVO_D1MODE_EXT_OVERSCAN_TOP_BOTTOM 0x658c ++ ++#define AVIVO_D1SCL_SCALER_ENABLE 0x6590 ++#define AVIVO_D1SCL_SCALER_TAP_CONTROL 0x6594 ++#define AVIVO_D1SCL_UPDATE 0x65cc ++# define AVIVO_D1SCL_UPDATE_LOCK (1 << 16) ++ ++/* second crtc */ ++#define AVIVO_D2CRTC_H_TOTAL 0x6800 ++#define AVIVO_D2CRTC_H_BLANK_START_END 0x6804 ++#define AVIVO_D2CRTC_H_SYNC_A 0x6808 ++#define AVIVO_D2CRTC_H_SYNC_A_CNTL 0x680c ++#define AVIVO_D2CRTC_H_SYNC_B 0x6810 ++#define AVIVO_D2CRTC_H_SYNC_B_CNTL 0x6814 ++ ++#define AVIVO_D2CRTC_V_TOTAL 0x6820 ++#define AVIVO_D2CRTC_V_BLANK_START_END 0x6824 ++#define AVIVO_D2CRTC_V_SYNC_A 0x6828 ++#define AVIVO_D2CRTC_V_SYNC_A_CNTL 0x682c ++#define AVIVO_D2CRTC_V_SYNC_B 0x6830 ++#define AVIVO_D2CRTC_V_SYNC_B_CNTL 0x6834 ++ ++#define AVIVO_D2CRTC_CONTROL 0x6880 ++#define AVIVO_D2CRTC_BLANK_CONTROL 0x6884 ++#define AVIVO_D2CRTC_INTERLACE_CONTROL 0x6888 ++#define AVIVO_D2CRTC_INTERLACE_STATUS 0x688c ++#define AVIVO_D2CRTC_STEREO_CONTROL 0x68c4 ++ ++#define AVIVO_D2GRPH_ENABLE 0x6900 ++#define AVIVO_D2GRPH_CONTROL 0x6904 ++#define AVIVO_D2GRPH_LUT_SEL 0x6908 ++#define AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS 0x6910 ++#define AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS 0x6918 ++#define AVIVO_D2GRPH_PITCH 0x6920 ++#define AVIVO_D2GRPH_SURFACE_OFFSET_X 0x6924 ++#define AVIVO_D2GRPH_SURFACE_OFFSET_Y 0x6928 ++#define AVIVO_D2GRPH_X_START 0x692c ++#define AVIVO_D2GRPH_Y_START 0x6930 ++#define AVIVO_D2GRPH_X_END 0x6934 ++#define AVIVO_D2GRPH_Y_END 0x6938 ++#define AVIVO_D2GRPH_UPDATE 0x6944 ++#define AVIVO_D2GRPH_FLIP_CONTROL 0x6948 ++ ++#define AVIVO_D2CUR_CONTROL 0x6c00 ++#define AVIVO_D2CUR_SURFACE_ADDRESS 0x6c08 ++#define AVIVO_D2CUR_SIZE 0x6c10 ++#define AVIVO_D2CUR_POSITION 0x6c14 ++ ++#define AVIVO_D2MODE_VLINE_START_END 0x6d38 ++#define AVIVO_D2MODE_VIEWPORT_START 0x6d80 ++#define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 ++#define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6d88 ++#define AVIVO_D2MODE_EXT_OVERSCAN_TOP_BOTTOM 0x6d8c ++ ++#define AVIVO_D2SCL_SCALER_ENABLE 0x6d90 ++#define AVIVO_D2SCL_SCALER_TAP_CONTROL 0x6d94 ++ ++#define AVIVO_DDIA_BIT_DEPTH_CONTROL 0x7214 ++ ++#define AVIVO_DACA_ENABLE 0x7800 ++# define AVIVO_DAC_ENABLE (1 << 0) ++#define AVIVO_DACA_SOURCE_SELECT 0x7804 ++# define AVIVO_DAC_SOURCE_CRTC1 (0 << 0) ++# define AVIVO_DAC_SOURCE_CRTC2 (1 << 0) ++# define AVIVO_DAC_SOURCE_TV (2 << 0) ++ ++#define AVIVO_DACA_FORCE_OUTPUT_CNTL 0x783c ++# define AVIVO_DACA_FORCE_OUTPUT_CNTL_FORCE_DATA_EN (1 << 0) ++# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_SHIFT (8) ++# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_BLUE (1 << 0) ++# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_GREEN (1 << 1) ++# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_RED (1 << 2) ++# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_ON_BLANKB_ONLY (1 << 24) ++#define AVIVO_DACA_POWERDOWN 0x7850 ++# define AVIVO_DACA_POWERDOWN_POWERDOWN (1 << 0) ++# define AVIVO_DACA_POWERDOWN_BLUE (1 << 8) ++# define AVIVO_DACA_POWERDOWN_GREEN (1 << 16) ++# define AVIVO_DACA_POWERDOWN_RED (1 << 24) ++ ++#define AVIVO_DACB_ENABLE 0x7a00 ++#define AVIVO_DACB_SOURCE_SELECT 0x7a04 ++#define AVIVO_DACB_FORCE_OUTPUT_CNTL 0x7a3c ++# define AVIVO_DACB_FORCE_OUTPUT_CNTL_FORCE_DATA_EN (1 << 0) ++# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_SHIFT (8) ++# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_BLUE (1 << 0) ++# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_GREEN (1 << 1) ++# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_RED (1 << 2) ++# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_ON_BLANKB_ONLY (1 << 24) ++#define AVIVO_DACB_POWERDOWN 0x7a50 ++# define AVIVO_DACB_POWERDOWN_POWERDOWN (1 << 0) ++# define AVIVO_DACB_POWERDOWN_BLUE (1 << 8) ++# define AVIVO_DACB_POWERDOWN_GREEN (1 << 16) ++# define AVIVO_DACB_POWERDOWN_RED ++ ++#define AVIVO_TMDSA_CNTL 0x7880 ++# define AVIVO_TMDSA_CNTL_ENABLE (1 << 0) ++# define AVIVO_TMDSA_CNTL_HPD_MASK (1 << 4) ++# define AVIVO_TMDSA_CNTL_HPD_SELECT (1 << 8) ++# define AVIVO_TMDSA_CNTL_SYNC_PHASE (1 << 12) ++# define AVIVO_TMDSA_CNTL_PIXEL_ENCODING (1 << 16) ++# define AVIVO_TMDSA_CNTL_DUAL_LINK_ENABLE (1 << 24) ++# define AVIVO_TMDSA_CNTL_SWAP (1 << 28) ++#define AVIVO_TMDSA_SOURCE_SELECT 0x7884 ++/* 78a8 appears to be some kind of (reasonably tolerant) clock? ++ * 78d0 definitely hits the transmitter, definitely clock. */ ++/* MYSTERY1 This appears to control dithering? */ ++#define AVIVO_TMDSA_BIT_DEPTH_CONTROL 0x7894 ++# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_EN (1 << 0) ++# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_DEPTH (1 << 4) ++# define AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN (1 << 8) ++# define AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH (1 << 12) ++# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_EN (1 << 16) ++# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_DEPTH (1 << 20) ++# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_LEVEL (1 << 24) ++# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_RESET (1 << 26) ++#define AVIVO_TMDSA_DCBALANCER_CONTROL 0x78d0 ++# define AVIVO_TMDSA_DCBALANCER_CONTROL_EN (1 << 0) ++# define AVIVO_TMDSA_DCBALANCER_CONTROL_TEST_EN (1 << 8) ++# define AVIVO_TMDSA_DCBALANCER_CONTROL_TEST_IN_SHIFT (16) ++# define AVIVO_TMDSA_DCBALANCER_CONTROL_FORCE (1 << 24) ++#define AVIVO_TMDSA_DATA_SYNCHRONIZATION 0x78d8 ++# define AVIVO_TMDSA_DATA_SYNCHRONIZATION_DSYNSEL (1 << 0) ++# define AVIVO_TMDSA_DATA_SYNCHRONIZATION_PFREQCHG (1 << 8) ++#define AVIVO_TMDSA_CLOCK_ENABLE 0x7900 ++#define AVIVO_TMDSA_TRANSMITTER_ENABLE 0x7904 ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_TX0_ENABLE (1 << 0) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKC0EN (1 << 1) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD00EN (1 << 2) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD01EN (1 << 3) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD02EN (1 << 4) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_TX1_ENABLE (1 << 8) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD10EN (1 << 10) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD11EN (1 << 11) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD12EN (1 << 12) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_TX_ENABLE_HPD_MASK (1 << 16) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKCEN_HPD_MASK (1 << 17) ++# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKDEN_HPD_MASK (1 << 18) ++ ++#define AVIVO_TMDSA_TRANSMITTER_CONTROL 0x7910 ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_ENABLE (1 << 0) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_RESET (1 << 1) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_HPD_MASK_SHIFT (2) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_IDSCKSEL (1 << 4) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_BGSLEEP (1 << 5) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_PWRUP_SEQ_EN (1 << 6) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_TMCLK (1 << 8) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_TMCLK_FROM_PADS (1 << 13) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_TDCLK (1 << 14) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_TDCLK_FROM_PADS (1 << 15) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_CLK_PATTERN_SHIFT (16) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_BYPASS_PLL (1 << 28) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_USE_CLK_DATA (1 << 29) ++# define AVIVO_TMDSA_TRANSMITTER_CONTROL_INPUT_TEST_CLK_SEL (1 << 31) ++ ++#define AVIVO_LVTMA_CNTL 0x7a80 ++# define AVIVO_LVTMA_CNTL_ENABLE (1 << 0) ++# define AVIVO_LVTMA_CNTL_HPD_MASK (1 << 4) ++# define AVIVO_LVTMA_CNTL_HPD_SELECT (1 << 8) ++# define AVIVO_LVTMA_CNTL_SYNC_PHASE (1 << 12) ++# define AVIVO_LVTMA_CNTL_PIXEL_ENCODING (1 << 16) ++# define AVIVO_LVTMA_CNTL_DUAL_LINK_ENABLE (1 << 24) ++# define AVIVO_LVTMA_CNTL_SWAP (1 << 28) ++#define AVIVO_LVTMA_SOURCE_SELECT 0x7a84 ++#define AVIVO_LVTMA_COLOR_FORMAT 0x7a88 ++#define AVIVO_LVTMA_BIT_DEPTH_CONTROL 0x7a94 ++# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN (1 << 0) ++# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_DEPTH (1 << 4) ++# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN (1 << 8) ++# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH (1 << 12) ++# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_EN (1 << 16) ++# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_DEPTH (1 << 20) ++# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_LEVEL (1 << 24) ++# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_RESET (1 << 26) ++ ++ ++ ++#define AVIVO_LVTMA_DCBALANCER_CONTROL 0x7ad0 ++# define AVIVO_LVTMA_DCBALANCER_CONTROL_EN (1 << 0) ++# define AVIVO_LVTMA_DCBALANCER_CONTROL_TEST_EN (1 << 8) ++# define AVIVO_LVTMA_DCBALANCER_CONTROL_TEST_IN_SHIFT (16) ++# define AVIVO_LVTMA_DCBALANCER_CONTROL_FORCE (1 << 24) ++ ++#define AVIVO_LVTMA_DATA_SYNCHRONIZATION 0x78d8 ++# define AVIVO_LVTMA_DATA_SYNCHRONIZATION_DSYNSEL (1 << 0) ++# define AVIVO_LVTMA_DATA_SYNCHRONIZATION_PFREQCHG (1 << 8) ++#define R500_LVTMA_CLOCK_ENABLE 0x7b00 ++#define R600_LVTMA_CLOCK_ENABLE 0x7b04 ++ ++#define R500_LVTMA_TRANSMITTER_ENABLE 0x7b04 ++#define R600_LVTMA_TRANSMITTER_ENABLE 0x7b08 ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKC0EN (1 << 1) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD00EN (1 << 2) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD01EN (1 << 3) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD02EN (1 << 4) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD03EN (1 << 5) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKC1EN (1 << 9) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD10EN (1 << 10) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD11EN (1 << 11) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD12EN (1 << 12) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKCEN_HPD_MASK (1 << 17) ++# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKDEN_HPD_MASK (1 << 18) ++ ++#define R500_LVTMA_TRANSMITTER_CONTROL 0x7b10 ++#define R600_LVTMA_TRANSMITTER_CONTROL 0x7b14 ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_ENABLE (1 << 0) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_RESET (1 << 1) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_HPD_MASK_SHIFT (2) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_IDSCKSEL (1 << 4) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_BGSLEEP (1 << 5) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_PWRUP_SEQ_EN (1 << 6) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_TMCLK (1 << 8) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_TMCLK_FROM_PADS (1 << 13) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_TDCLK (1 << 14) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_TDCLK_FROM_PADS (1 << 15) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_CLK_PATTERN_SHIFT (16) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_BYPASS_PLL (1 << 28) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_USE_CLK_DATA (1 << 29) ++# define AVIVO_LVTMA_TRANSMITTER_CONTROL_INPUT_TEST_CLK_SEL (1 << 31) ++ ++#define R500_LVTMA_PWRSEQ_CNTL 0x7af0 ++#define R600_LVTMA_PWRSEQ_CNTL 0x7af4 ++# define AVIVO_LVTMA_PWRSEQ_EN (1 << 0) ++# define AVIVO_LVTMA_PWRSEQ_PLL_ENABLE_MASK (1 << 2) ++# define AVIVO_LVTMA_PWRSEQ_PLL_RESET_MASK (1 << 3) ++# define AVIVO_LVTMA_PWRSEQ_TARGET_STATE (1 << 4) ++# define AVIVO_LVTMA_SYNCEN (1 << 8) ++# define AVIVO_LVTMA_SYNCEN_OVRD (1 << 9) ++# define AVIVO_LVTMA_SYNCEN_POL (1 << 10) ++# define AVIVO_LVTMA_DIGON (1 << 16) ++# define AVIVO_LVTMA_DIGON_OVRD (1 << 17) ++# define AVIVO_LVTMA_DIGON_POL (1 << 18) ++# define AVIVO_LVTMA_BLON (1 << 24) ++# define AVIVO_LVTMA_BLON_OVRD (1 << 25) ++# define AVIVO_LVTMA_BLON_POL (1 << 26) ++ ++#define R500_LVTMA_PWRSEQ_STATE 0x7af4 ++#define R600_LVTMA_PWRSEQ_STATE 0x7af8 ++# define AVIVO_LVTMA_PWRSEQ_STATE_TARGET_STATE_R (1 << 0) ++# define AVIVO_LVTMA_PWRSEQ_STATE_DIGON (1 << 1) ++# define AVIVO_LVTMA_PWRSEQ_STATE_SYNCEN (1 << 2) ++# define AVIVO_LVTMA_PWRSEQ_STATE_BLON (1 << 3) ++# define AVIVO_LVTMA_PWRSEQ_STATE_DONE (1 << 4) ++# define AVIVO_LVTMA_PWRSEQ_STATE_STATUS_SHIFT (8) ++ ++#define AVIVO_LVDS_BACKLIGHT_CNTL 0x7af8 ++# define AVIVO_LVDS_BACKLIGHT_CNTL_EN (1 << 0) ++# define AVIVO_LVDS_BACKLIGHT_LEVEL_MASK 0x0000ff00 ++# define AVIVO_LVDS_BACKLIGHT_LEVEL_SHIFT 8 ++ ++#define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988 ++ ++#define AVIVO_GPIO_0 0x7e30 ++#define AVIVO_GPIO_1 0x7e40 ++#define AVIVO_GPIO_2 0x7e50 ++#define AVIVO_GPIO_3 0x7e60 ++ ++#define AVIVO_DC_GPIO_HPD_Y 0x7e9c ++ ++#define AVIVO_I2C_STATUS 0x7d30 ++# define AVIVO_I2C_STATUS_DONE (1 << 0) ++# define AVIVO_I2C_STATUS_NACK (1 << 1) ++# define AVIVO_I2C_STATUS_HALT (1 << 2) ++# define AVIVO_I2C_STATUS_GO (1 << 3) ++# define AVIVO_I2C_STATUS_MASK 0x7 ++/* If radeon_mm_i2c is to be believed, this is HALT, NACK, and maybe ++ * DONE? */ ++# define AVIVO_I2C_STATUS_CMD_RESET 0x7 ++# define AVIVO_I2C_STATUS_CMD_WAIT (1 << 3) ++#define AVIVO_I2C_STOP 0x7d34 ++#define AVIVO_I2C_START_CNTL 0x7d38 ++# define AVIVO_I2C_START (1 << 8) ++# define AVIVO_I2C_CONNECTOR0 (0 << 16) ++# define AVIVO_I2C_CONNECTOR1 (1 << 16) ++#define R520_I2C_START (1<<0) ++#define R520_I2C_STOP (1<<1) ++#define R520_I2C_RX (1<<2) ++#define R520_I2C_EN (1<<8) ++#define R520_I2C_DDC1 (0<<16) ++#define R520_I2C_DDC2 (1<<16) ++#define R520_I2C_DDC3 (2<<16) ++#define R520_I2C_DDC_MASK (3<<16) ++#define AVIVO_I2C_CONTROL2 0x7d3c ++# define AVIVO_I2C_7D3C_SIZE_SHIFT 8 ++# define AVIVO_I2C_7D3C_SIZE_MASK (0xf << 8) ++#define AVIVO_I2C_CONTROL3 0x7d40 ++/* Reading is done 4 bytes at a time: read the bottom 8 bits from ++ * 7d44, four times in a row. ++ * Writing is a little more complex. First write DATA with ++ * 0xnnnnnnzz, then 0xnnnnnnyy, where nnnnnn is some non-deterministic ++ * magic number, zz is, I think, the slave address, and yy is the byte ++ * you want to write. */ ++#define AVIVO_I2C_DATA 0x7d44 ++#define R520_I2C_ADDR_COUNT_MASK (0x7) ++#define R520_I2C_DATA_COUNT_SHIFT (8) ++#define R520_I2C_DATA_COUNT_MASK (0xF00) ++#define AVIVO_I2C_CNTL 0x7d50 ++# define AVIVO_I2C_EN (1 << 0) ++# define AVIVO_I2C_RESET (1 << 8) ++ ++#define R600_GENERAL_PWRMGT 0x618 ++# define R600_OPEN_DRAIN_PADS (1 << 11) ++ ++#define R600_LOWER_GPIO_ENABLE 0x710 ++#define R600_CTXSW_VID_LOWER_GPIO_CNTL 0x718 ++#define R600_HIGH_VID_LOWER_GPIO_CNTL 0x71c ++#define R600_MEDIUM_VID_LOWER_GPIO_CNTL 0x720 ++#define R600_LOW_VID_LOWER_GPIO_CNTL 0x724 ++ ++#define R600_MC_VM_FB_LOCATION 0x2180 ++#define R600_MC_VM_AGP_TOP 0x2184 ++#define R600_MC_VM_AGP_BOT 0x2188 ++#define R600_MC_VM_AGP_BASE 0x218c ++#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 ++#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 ++#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 ++ ++#define R700_MC_VM_FB_LOCATION 0x2024 ++ ++#define R600_HDP_NONSURFACE_BASE 0x2c04 ++ ++#define R600_BUS_CNTL 0x5420 ++#define R600_CONFIG_CNTL 0x5424 ++#define R600_CONFIG_MEMSIZE 0x5428 ++#define R600_CONFIG_F0_BASE 0x542C ++#define R600_CONFIG_APER_SIZE 0x5430 ++ ++#define R600_ROM_CNTL 0x1600 ++# define R600_SCK_OVERWRITE (1 << 1) ++# define R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT 28 ++# define R600_SCK_PRESCALE_CRYSTAL_CLK_MASK (0xf << 28) ++ ++#define R600_BIOS_0_SCRATCH 0x1724 ++#define R600_BIOS_1_SCRATCH 0x1728 ++#define R600_BIOS_2_SCRATCH 0x172c ++#define R600_BIOS_3_SCRATCH 0x1730 ++#define R600_BIOS_4_SCRATCH 0x1734 ++#define R600_BIOS_5_SCRATCH 0x1738 ++#define R600_BIOS_6_SCRATCH 0x173c ++#define R600_BIOS_7_SCRATCH 0x1740 ++ ++#define R300_GB_TILE_CONFIG 0x4018 ++# define R300_ENABLE_TILING (1 << 0) ++# define R300_PIPE_COUNT_RV350 (0 << 1) ++# define R300_PIPE_COUNT_R300 (3 << 1) ++# define R300_PIPE_COUNT_R420_3P (6 << 1) ++# define R300_PIPE_COUNT_R420 (7 << 1) ++# define R300_TILE_SIZE_8 (0 << 4) ++# define R300_TILE_SIZE_16 (1 << 4) ++# define R300_TILE_SIZE_32 (2 << 4) ++# define R300_SUBPIXEL_1_12 (0 << 16) ++# define R300_SUBPIXEL_1_16 (1 << 16) ++#define R300_GB_SELECT 0x401c ++#define R300_GB_ENABLE 0x4008 ++#define R300_GB_AA_CONFIG 0x4020 ++#define R400_GB_PIPE_SELECT 0x402c ++#define R300_GB_MSPOS0 0x4010 ++# define R300_MS_X0_SHIFT 0 ++# define R300_MS_Y0_SHIFT 4 ++# define R300_MS_X1_SHIFT 8 ++# define R300_MS_Y1_SHIFT 12 ++# define R300_MS_X2_SHIFT 16 ++# define R300_MS_Y2_SHIFT 20 ++# define R300_MSBD0_Y_SHIFT 24 ++# define R300_MSBD0_X_SHIFT 28 ++#define R300_GB_MSPOS1 0x4014 ++# define R300_MS_X3_SHIFT 0 ++# define R300_MS_Y3_SHIFT 4 ++# define R300_MS_X4_SHIFT 8 ++# define R300_MS_Y4_SHIFT 12 ++# define R300_MS_X5_SHIFT 16 ++# define R300_MS_Y5_SHIFT 20 ++# define R300_MSBD1_SHIFT 24 ++ ++#define R300_GA_ENHANCE 0x4274 ++# define R300_GA_DEADLOCK_CNTL (1 << 0) ++# define R300_GA_FASTSYNC_CNTL (1 << 1) ++ ++#define R300_GA_POLY_MODE 0x4288 ++# define R300_FRONT_PTYPE_POINT (0 << 4) ++# define R300_FRONT_PTYPE_LINE (1 << 4) ++# define R300_FRONT_PTYPE_TRIANGE (2 << 4) ++# define R300_BACK_PTYPE_POINT (0 << 7) ++# define R300_BACK_PTYPE_LINE (1 << 7) ++# define R300_BACK_PTYPE_TRIANGE (2 << 7) ++#define R300_GA_ROUND_MODE 0x428c ++# define R300_GEOMETRY_ROUND_TRUNC (0 << 0) ++# define R300_GEOMETRY_ROUND_NEAREST (1 << 0) ++# define R300_COLOR_ROUND_TRUNC (0 << 2) ++# define R300_COLOR_ROUND_NEAREST (1 << 2) ++#define R300_GA_COLOR_CONTROL 0x4278 ++# define R300_RGB0_SHADING_SOLID (0 << 0) ++# define R300_RGB0_SHADING_FLAT (1 << 0) ++# define R300_RGB0_SHADING_GOURAUD (2 << 0) ++# define R300_ALPHA0_SHADING_SOLID (0 << 2) ++# define R300_ALPHA0_SHADING_FLAT (1 << 2) ++# define R300_ALPHA0_SHADING_GOURAUD (2 << 2) ++# define R300_RGB1_SHADING_SOLID (0 << 4) ++# define R300_RGB1_SHADING_FLAT (1 << 4) ++# define R300_RGB1_SHADING_GOURAUD (2 << 4) ++# define R300_ALPHA1_SHADING_SOLID (0 << 6) ++# define R300_ALPHA1_SHADING_FLAT (1 << 6) ++# define R300_ALPHA1_SHADING_GOURAUD (2 << 6) ++# define R300_RGB2_SHADING_SOLID (0 << 8) ++# define R300_RGB2_SHADING_FLAT (1 << 8) ++# define R300_RGB2_SHADING_GOURAUD (2 << 8) ++# define R300_ALPHA2_SHADING_SOLID (0 << 10) ++# define R300_ALPHA2_SHADING_FLAT (1 << 10) ++# define R300_ALPHA2_SHADING_GOURAUD (2 << 10) ++# define R300_RGB3_SHADING_SOLID (0 << 12) ++# define R300_RGB3_SHADING_FLAT (1 << 12) ++# define R300_RGB3_SHADING_GOURAUD (2 << 12) ++# define R300_ALPHA3_SHADING_SOLID (0 << 14) ++# define R300_ALPHA3_SHADING_FLAT (1 << 14) ++# define R300_ALPHA3_SHADING_GOURAUD (2 << 14) ++#define R300_GA_OFFSET 0x4290 ++ ++#define R500_SU_REG_DEST 0x42c8 ++ ++#define R300_VAP_CNTL_STATUS 0x2140 ++# define R300_PVS_BYPASS (1 << 8) ++#define R300_VAP_PVS_STATE_FLUSH_REG 0x2284 ++#define R300_VAP_CNTL 0x2080 ++# define R300_PVS_NUM_SLOTS_SHIFT 0 ++# define R300_PVS_NUM_CNTLRS_SHIFT 4 ++# define R300_PVS_NUM_FPUS_SHIFT 8 ++# define R300_VF_MAX_VTX_NUM_SHIFT 18 ++# define R300_GL_CLIP_SPACE_DEF (0 << 22) ++# define R300_DX_CLIP_SPACE_DEF (1 << 22) ++# define R500_TCL_STATE_OPTIMIZATION (1 << 23) ++#define R300_VAP_VTE_CNTL 0x20B0 ++# define R300_VPORT_X_SCALE_ENA (1 << 0) ++# define R300_VPORT_X_OFFSET_ENA (1 << 1) ++# define R300_VPORT_Y_SCALE_ENA (1 << 2) ++# define R300_VPORT_Y_OFFSET_ENA (1 << 3) ++# define R300_VPORT_Z_SCALE_ENA (1 << 4) ++# define R300_VPORT_Z_OFFSET_ENA (1 << 5) ++# define R300_VTX_XY_FMT (1 << 8) ++# define R300_VTX_Z_FMT (1 << 9) ++# define R300_VTX_W0_FMT (1 << 10) ++#define R300_VAP_VTX_STATE_CNTL 0x2180 ++#define R300_VAP_PSC_SGN_NORM_CNTL 0x21DC ++#define R300_VAP_PROG_STREAM_CNTL_0 0x2150 ++# define R300_DATA_TYPE_0_SHIFT 0 ++# define R300_DATA_TYPE_FLOAT_1 0 ++# define R300_DATA_TYPE_FLOAT_2 1 ++# define R300_DATA_TYPE_FLOAT_3 2 ++# define R300_DATA_TYPE_FLOAT_4 3 ++# define R300_DATA_TYPE_BYTE 4 ++# define R300_DATA_TYPE_D3DCOLOR 5 ++# define R300_DATA_TYPE_SHORT_2 6 ++# define R300_DATA_TYPE_SHORT_4 7 ++# define R300_DATA_TYPE_VECTOR_3_TTT 8 ++# define R300_DATA_TYPE_VECTOR_3_EET 9 ++# define R300_SKIP_DWORDS_0_SHIFT 4 ++# define R300_DST_VEC_LOC_0_SHIFT 8 ++# define R300_LAST_VEC_0 (1 << 13) ++# define R300_SIGNED_0 (1 << 14) ++# define R300_NORMALIZE_0 (1 << 15) ++# define R300_DATA_TYPE_1_SHIFT 16 ++# define R300_SKIP_DWORDS_1_SHIFT 20 ++# define R300_DST_VEC_LOC_1_SHIFT 24 ++# define R300_LAST_VEC_1 (1 << 29) ++# define R300_SIGNED_1 (1 << 30) ++# define R300_NORMALIZE_1 (1 << 31) ++#define R300_VAP_PROG_STREAM_CNTL_1 0x2154 ++# define R300_DATA_TYPE_2_SHIFT 0 ++# define R300_SKIP_DWORDS_2_SHIFT 4 ++# define R300_DST_VEC_LOC_2_SHIFT 8 ++# define R300_LAST_VEC_2 (1 << 13) ++# define R300_SIGNED_2 (1 << 14) ++# define R300_NORMALIZE_2 (1 << 15) ++# define R300_DATA_TYPE_3_SHIFT 16 ++# define R300_SKIP_DWORDS_3_SHIFT 20 ++# define R300_DST_VEC_LOC_3_SHIFT 24 ++# define R300_LAST_VEC_3 (1 << 29) ++# define R300_SIGNED_3 (1 << 30) ++# define R300_NORMALIZE_3 (1 << 31) ++#define R300_VAP_PROG_STREAM_CNTL_EXT_0 0x21e0 ++# define R300_SWIZZLE_SELECT_X_0_SHIFT 0 ++# define R300_SWIZZLE_SELECT_Y_0_SHIFT 3 ++# define R300_SWIZZLE_SELECT_Z_0_SHIFT 6 ++# define R300_SWIZZLE_SELECT_W_0_SHIFT 9 ++# define R300_SWIZZLE_SELECT_X 0 ++# define R300_SWIZZLE_SELECT_Y 1 ++# define R300_SWIZZLE_SELECT_Z 2 ++# define R300_SWIZZLE_SELECT_W 3 ++# define R300_SWIZZLE_SELECT_FP_ZERO 4 ++# define R300_SWIZZLE_SELECT_FP_ONE 5 ++# define R300_WRITE_ENA_0_SHIFT 12 ++# define R300_WRITE_ENA_X 1 ++# define R300_WRITE_ENA_Y 2 ++# define R300_WRITE_ENA_Z 4 ++# define R300_WRITE_ENA_W 8 ++# define R300_SWIZZLE_SELECT_X_1_SHIFT 16 ++# define R300_SWIZZLE_SELECT_Y_1_SHIFT 19 ++# define R300_SWIZZLE_SELECT_Z_1_SHIFT 22 ++# define R300_SWIZZLE_SELECT_W_1_SHIFT 25 ++# define R300_WRITE_ENA_1_SHIFT 28 ++#define R300_VAP_PROG_STREAM_CNTL_EXT_1 0x21e4 ++# define R300_SWIZZLE_SELECT_X_2_SHIFT 0 ++# define R300_SWIZZLE_SELECT_Y_2_SHIFT 3 ++# define R300_SWIZZLE_SELECT_Z_2_SHIFT 6 ++# define R300_SWIZZLE_SELECT_W_2_SHIFT 9 ++# define R300_WRITE_ENA_2_SHIFT 12 ++# define R300_SWIZZLE_SELECT_X_3_SHIFT 16 ++# define R300_SWIZZLE_SELECT_Y_3_SHIFT 19 ++# define R300_SWIZZLE_SELECT_Z_3_SHIFT 22 ++# define R300_SWIZZLE_SELECT_W_3_SHIFT 25 ++# define R300_WRITE_ENA_3_SHIFT 28 ++#define R300_VAP_PVS_CODE_CNTL_0 0x22D0 ++# define R300_PVS_FIRST_INST_SHIFT 0 ++# define R300_PVS_XYZW_VALID_INST_SHIFT 10 ++# define R300_PVS_LAST_INST_SHIFT 20 ++#define R300_VAP_PVS_CODE_CNTL_1 0x22D8 ++# define R300_PVS_LAST_VTX_SRC_INST_SHIFT 0 ++#define R300_VAP_PVS_VECTOR_INDX_REG 0x2200 ++#define R300_VAP_PVS_VECTOR_DATA_REG 0x2204 ++/* PVS instructions */ ++/* Opcode and dst instruction */ ++#define R300_PVS_DST_OPCODE(x) (x << 0) ++/* Vector ops */ ++# define R300_VECTOR_NO_OP 0 ++# define R300_VE_DOT_PRODUCT 1 ++# define R300_VE_MULTIPLY 2 ++# define R300_VE_ADD 3 ++# define R300_VE_MULTIPLY_ADD 4 ++# define R300_VE_DISTANCE_VECTOR 5 ++# define R300_VE_FRACTION 6 ++# define R300_VE_MAXIMUM 7 ++# define R300_VE_MINIMUM 8 ++# define R300_VE_SET_GREATER_THAN_EQUAL 9 ++# define R300_VE_SET_LESS_THAN 10 ++# define R300_VE_MULTIPLYX2_ADD 11 ++# define R300_VE_MULTIPLY_CLAMP 12 ++# define R300_VE_FLT2FIX_DX 13 ++# define R300_VE_FLT2FIX_DX_RND 14 ++/* R500 additions */ ++# define R500_VE_PRED_SET_EQ_PUSH 15 ++# define R500_VE_PRED_SET_GT_PUSH 16 ++# define R500_VE_PRED_SET_GTE_PUSH 17 ++# define R500_VE_PRED_SET_NEQ_PUSH 18 ++# define R500_VE_COND_WRITE_EQ 19 ++# define R500_VE_COND_WRITE_GT 20 ++# define R500_VE_COND_WRITE_GTE 21 ++# define R500_VE_COND_WRITE_NEQ 22 ++# define R500_VE_COND_MUX_EQ 23 ++# define R500_VE_COND_MUX_GT 24 ++# define R500_VE_COND_MUX_GTE 25 ++# define R500_VE_SET_GREATER_THAN 26 ++# define R500_VE_SET_EQUAL 27 ++# define R500_VE_SET_NOT_EQUAL 28 ++/* Math ops */ ++# define R300_MATH_NO_OP 0 ++# define R300_ME_EXP_BASE2_DX 1 ++# define R300_ME_LOG_BASE2_DX 2 ++# define R300_ME_EXP_BASEE_FF 3 ++# define R300_ME_LIGHT_COEFF_DX 4 ++# define R300_ME_POWER_FUNC_FF 5 ++# define R300_ME_RECIP_DX 6 ++# define R300_ME_RECIP_FF 7 ++# define R300_ME_RECIP_SQRT_DX 8 ++# define R300_ME_RECIP_SQRT_FF 9 ++# define R300_ME_MULTIPLY 10 ++# define R300_ME_EXP_BASE2_FULL_DX 11 ++# define R300_ME_LOG_BASE2_FULL_DX 12 ++# define R300_ME_POWER_FUNC_FF_CLAMP_B 13 ++# define R300_ME_POWER_FUNC_FF_CLAMP_B1 14 ++# define R300_ME_POWER_FUNC_FF_CLAMP_01 15 ++# define R300_ME_SIN 16 ++# define R300_ME_COS 17 ++/* R500 additions */ ++# define R500_ME_LOG_BASE2_IEEE 18 ++# define R500_ME_RECIP_IEEE 19 ++# define R500_ME_RECIP_SQRT_IEEE 20 ++# define R500_ME_PRED_SET_EQ 21 ++# define R500_ME_PRED_SET_GT 22 ++# define R500_ME_PRED_SET_GTE 23 ++# define R500_ME_PRED_SET_NEQ 24 ++# define R500_ME_PRED_SET_CLR 25 ++# define R500_ME_PRED_SET_INV 26 ++# define R500_ME_PRED_SET_POP 27 ++# define R500_ME_PRED_SET_RESTORE 28 ++/* macro */ ++# define R300_PVS_MACRO_OP_2CLK_MADD 0 ++# define R300_PVS_MACRO_OP_2CLK_M2X_ADD 1 ++#define R300_PVS_DST_MATH_INST (1 << 6) ++#define R300_PVS_DST_MACRO_INST (1 << 7) ++#define R300_PVS_DST_REG_TYPE(x) (x << 8) ++# define R300_PVS_DST_REG_TEMPORARY 0 ++# define R300_PVS_DST_REG_A0 1 ++# define R300_PVS_DST_REG_OUT 2 ++# define R500_PVS_DST_REG_OUT_REPL_X 3 ++# define R300_PVS_DST_REG_ALT_TEMPORARY 4 ++# define R300_PVS_DST_REG_INPUT 5 ++#define R300_PVS_DST_ADDR_MODE_1 (1 << 12) ++#define R300_PVS_DST_OFFSET(x) (x << 13) ++#define R300_PVS_DST_WE_X (1 << 20) ++#define R300_PVS_DST_WE_Y (1 << 21) ++#define R300_PVS_DST_WE_Z (1 << 22) ++#define R300_PVS_DST_WE_W (1 << 23) ++#define R300_PVS_DST_VE_SAT (1 << 24) ++#define R300_PVS_DST_ME_SAT (1 << 25) ++#define R300_PVS_DST_PRED_ENABLE (1 << 26) ++#define R300_PVS_DST_PRED_SENSE (1 << 27) ++#define R300_PVS_DST_DUAL_MATH_OP (1 << 28) ++#define R300_PVS_DST_ADDR_SEL(x) (x << 29) ++#define R300_PVS_DST_ADDR_MODE_0 (1 << 31) ++/* src operand instruction */ ++#define R300_PVS_SRC_REG_TYPE(x) (x << 0) ++# define R300_PVS_SRC_REG_TEMPORARY 0 ++# define R300_PVS_SRC_REG_INPUT 1 ++# define R300_PVS_SRC_REG_CONSTANT 2 ++# define R300_PVS_SRC_REG_ALT_TEMPORARY 3 ++#define R300_SPARE_0 (1 << 2) ++#define R300_PVS_SRC_ABS_XYZW (1 << 3) ++#define R300_PVS_SRC_ADDR_MODE_0 (1 << 4) ++#define R300_PVS_SRC_OFFSET(x) (x << 5) ++#define R300_PVS_SRC_SWIZZLE_X(x) (x << 13) ++#define R300_PVS_SRC_SWIZZLE_Y(x) (x << 16) ++#define R300_PVS_SRC_SWIZZLE_Z(x) (x << 19) ++#define R300_PVS_SRC_SWIZZLE_W(x) (x << 22) ++# define R300_PVS_SRC_SELECT_X 0 ++# define R300_PVS_SRC_SELECT_Y 1 ++# define R300_PVS_SRC_SELECT_Z 2 ++# define R300_PVS_SRC_SELECT_W 3 ++# define R300_PVS_SRC_SELECT_FORCE_0 4 ++# define R300_PVS_SRC_SELECT_FORCE_1 5 ++#define R300_PVS_SRC_NEG_X (1 << 25) ++#define R300_PVS_SRC_NEG_Y (1 << 26) ++#define R300_PVS_SRC_NEG_Z (1 << 27) ++#define R300_PVS_SRC_NEG_W (1 << 28) ++#define R300_PVS_SRC_ADDR_SEL(x) (x << 29) ++#define R300_PVS_SRC_ADDR_MODE_1 (1 << 31) ++ ++#define R300_VAP_PVS_FLOW_CNTL_OPC 0x22DC ++#define R300_VAP_OUT_VTX_FMT_0 0x2090 ++# define R300_VTX_POS_PRESENT (1 << 0) ++# define R300_VTX_COLOR_0_PRESENT (1 << 1) ++# define R300_VTX_COLOR_1_PRESENT (1 << 2) ++# define R300_VTX_COLOR_2_PRESENT (1 << 3) ++# define R300_VTX_COLOR_3_PRESENT (1 << 4) ++# define R300_VTX_PT_SIZE_PRESENT (1 << 16) ++#define R300_VAP_OUT_VTX_FMT_1 0x2094 ++# define R300_TEX_0_COMP_CNT_SHIFT 0 ++# define R300_TEX_1_COMP_CNT_SHIFT 3 ++# define R300_TEX_2_COMP_CNT_SHIFT 6 ++# define R300_TEX_3_COMP_CNT_SHIFT 9 ++# define R300_TEX_4_COMP_CNT_SHIFT 12 ++# define R300_TEX_5_COMP_CNT_SHIFT 15 ++# define R300_TEX_6_COMP_CNT_SHIFT 18 ++# define R300_TEX_7_COMP_CNT_SHIFT 21 ++#define R300_VAP_VTX_SIZE 0x20b4 ++#define R300_VAP_GB_VERT_CLIP_ADJ 0x2220 ++#define R300_VAP_GB_VERT_DISC_ADJ 0x2224 ++#define R300_VAP_GB_HORZ_CLIP_ADJ 0x2228 ++#define R300_VAP_GB_HORZ_DISC_ADJ 0x222c ++#define R300_VAP_CLIP_CNTL 0x221c ++# define R300_UCP_ENA_0 (1 << 0) ++# define R300_UCP_ENA_1 (1 << 1) ++# define R300_UCP_ENA_2 (1 << 2) ++# define R300_UCP_ENA_3 (1 << 3) ++# define R300_UCP_ENA_4 (1 << 4) ++# define R300_UCP_ENA_5 (1 << 5) ++# define R300_PS_UCP_MODE_SHIFT 14 ++# define R300_CLIP_DISABLE (1 << 16) ++# define R300_UCP_CULL_ONLY_ENA (1 << 17) ++# define R300_BOUNDARY_EDGE_FLAG_ENA (1 << 18) ++#define R300_VAP_PVS_STATE_FLUSH_REG 0x2284 ++ ++#define R500_VAP_INDEX_OFFSET 0x208c ++ ++#define R300_SU_TEX_WRAP 0x42a0 ++#define R300_SU_POLY_OFFSET_ENABLE 0x42b4 ++#define R300_SU_CULL_MODE 0x42b8 ++# define R300_CULL_FRONT (1 << 0) ++# define R300_CULL_BACK (1 << 1) ++# define R300_FACE_POS (0 << 2) ++# define R300_FACE_NEG (1 << 2) ++#define R300_SU_DEPTH_SCALE 0x42c0 ++#define R300_SU_DEPTH_OFFSET 0x42c4 ++ ++#define R300_RS_COUNT 0x4300 ++# define R300_RS_COUNT_IT_COUNT_SHIFT 0 ++# define R300_RS_COUNT_IC_COUNT_SHIFT 7 ++# define R300_RS_COUNT_HIRES_EN (1 << 18) ++ ++#define R300_RS_IP_0 0x4310 ++#define R300_RS_IP_1 0x4314 ++# define R300_RS_TEX_PTR(x) (x << 0) ++# define R300_RS_COL_PTR(x) (x << 6) ++# define R300_RS_COL_FMT(x) (x << 9) ++# define R300_RS_COL_FMT_RGBA 0 ++# define R300_RS_COL_FMT_RGB0 2 ++# define R300_RS_COL_FMT_RGB1 3 ++# define R300_RS_COL_FMT_000A 4 ++# define R300_RS_COL_FMT_0000 5 ++# define R300_RS_COL_FMT_0001 6 ++# define R300_RS_COL_FMT_111A 8 ++# define R300_RS_COL_FMT_1110 9 ++# define R300_RS_COL_FMT_1111 10 ++# define R300_RS_SEL_S(x) (x << 13) ++# define R300_RS_SEL_T(x) (x << 16) ++# define R300_RS_SEL_R(x) (x << 19) ++# define R300_RS_SEL_Q(x) (x << 22) ++# define R300_RS_SEL_C0 0 ++# define R300_RS_SEL_C1 1 ++# define R300_RS_SEL_C2 2 ++# define R300_RS_SEL_C3 3 ++# define R300_RS_SEL_K0 4 ++# define R300_RS_SEL_K1 5 ++#define R300_RS_INST_COUNT 0x4304 ++# define R300_INST_COUNT_RS(x) (x << 0) ++# define R300_RS_W_EN (1 << 4) ++# define R300_TX_OFFSET_RS(x) (x << 5) ++#define R300_RS_INST_0 0x4330 ++#define R300_RS_INST_1 0x4334 ++# define R300_INST_TEX_ID(x) (x << 0) ++# define R300_RS_INST_TEX_CN_WRITE (1 << 3) ++# define R300_INST_TEX_ADDR(x) (x << 6) ++ ++#define R300_TX_INVALTAGS 0x4100 ++#define R300_TX_FILTER0_0 0x4400 ++# define R300_TX_CLAMP_S(x) (x << 0) ++# define R300_TX_CLAMP_T(x) (x << 3) ++# define R300_TX_CLAMP_R(x) (x << 6) ++# define R300_TX_CLAMP_WRAP 0 ++# define R300_TX_CLAMP_MIRROR 1 ++# define R300_TX_CLAMP_CLAMP_LAST 2 ++# define R300_TX_CLAMP_MIRROR_CLAMP_LAST 3 ++# define R300_TX_CLAMP_CLAMP_BORDER 4 ++# define R300_TX_CLAMP_MIRROR_CLAMP_BORDER 5 ++# define R300_TX_CLAMP_CLAMP_GL 6 ++# define R300_TX_CLAMP_MIRROR_CLAMP_GL 7 ++# define R300_TX_MAG_FILTER_NEAREST (1 << 9) ++# define R300_TX_MIN_FILTER_NEAREST (1 << 11) ++# define R300_TX_MAG_FILTER_LINEAR (2 << 9) ++# define R300_TX_MIN_FILTER_LINEAR (2 << 11) ++# define R300_TX_ID_SHIFT 28 ++#define R300_TX_FILTER1_0 0x4440 ++#define R300_TX_FORMAT0_0 0x4480 ++# define R300_TXWIDTH_SHIFT 0 ++# define R300_TXHEIGHT_SHIFT 11 ++# define R300_NUM_LEVELS_SHIFT 26 ++# define R300_NUM_LEVELS_MASK 0x ++# define R300_TXPROJECTED (1 << 30) ++# define R300_TXPITCH_EN (1 << 31) ++#define R300_TX_FORMAT1_0 0x44c0 ++# define R300_TX_FORMAT_X8 0x0 ++# define R300_TX_FORMAT_X16 0x1 ++# define R300_TX_FORMAT_Y4X4 0x2 ++# define R300_TX_FORMAT_Y8X8 0x3 ++# define R300_TX_FORMAT_Y16X16 0x4 ++# define R300_TX_FORMAT_Z3Y3X2 0x5 ++# define R300_TX_FORMAT_Z5Y6X5 0x6 ++# define R300_TX_FORMAT_Z6Y5X5 0x7 ++# define R300_TX_FORMAT_Z11Y11X10 0x8 ++# define R300_TX_FORMAT_Z10Y11X11 0x9 ++# define R300_TX_FORMAT_W4Z4Y4X4 0xA ++# define R300_TX_FORMAT_W1Z5Y5X5 0xB ++# define R300_TX_FORMAT_W8Z8Y8X8 0xC ++# define R300_TX_FORMAT_W2Z10Y10X10 0xD ++# define R300_TX_FORMAT_W16Z16Y16X16 0xE ++# define R300_TX_FORMAT_DXT1 0xF ++# define R300_TX_FORMAT_DXT3 0x10 ++# define R300_TX_FORMAT_DXT5 0x11 ++# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */ ++# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */ ++# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ ++# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ ++# define R300_TX_FORMAT_VYUY422 0x14 /* no swizzle */ ++# define R300_TX_FORMAT_YVYU422 0x15 /* no swizzle */ ++# define R300_TX_FORMAT_X24_Y8 0x1e ++# define R300_TX_FORMAT_X32 0x1e ++ /* Floating point formats */ ++ /* Note - hardware supports both 16 and 32 bit floating point */ ++# define R300_TX_FORMAT_FL_I16 0x18 ++# define R300_TX_FORMAT_FL_I16A16 0x19 ++# define R300_TX_FORMAT_FL_R16G16B16A16 0x1A ++# define R300_TX_FORMAT_FL_I32 0x1B ++# define R300_TX_FORMAT_FL_I32A32 0x1C ++# define R300_TX_FORMAT_FL_R32G32B32A32 0x1D ++ /* alpha modes, convenience mostly */ ++ /* if you have alpha, pick constant appropriate to the ++ number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ ++# define R300_TX_FORMAT_ALPHA_1CH 0x000 ++# define R300_TX_FORMAT_ALPHA_2CH 0x200 ++# define R300_TX_FORMAT_ALPHA_4CH 0x600 ++# define R300_TX_FORMAT_ALPHA_NONE 0xA00 ++ /* Swizzling */ ++ /* constants */ ++# define R300_TX_FORMAT_X 0 ++# define R300_TX_FORMAT_Y 1 ++# define R300_TX_FORMAT_Z 2 ++# define R300_TX_FORMAT_W 3 ++# define R300_TX_FORMAT_ZERO 4 ++# define R300_TX_FORMAT_ONE 5 ++ /* 2.0*Z, everything above 1.0 is set to 0.0 */ ++# define R300_TX_FORMAT_CUT_Z 6 ++ /* 2.0*W, everything above 1.0 is set to 0.0 */ ++# define R300_TX_FORMAT_CUT_W 7 ++ ++# define R300_TX_FORMAT_B_SHIFT 18 ++# define R300_TX_FORMAT_G_SHIFT 15 ++# define R300_TX_FORMAT_R_SHIFT 12 ++# define R300_TX_FORMAT_A_SHIFT 9 ++ ++ /* Convenience macro to take care of layout and swizzling */ ++# define R300_EASY_TX_FORMAT(B, G, R, A, FMT) ( \ ++ ((R300_TX_FORMAT_##B)<microcode_version != UCODE_R200) { +- DRM_ERROR("Invalid 3d packet for r100-class chip\n"); ++ if ((dev_priv->chip_family < CHIP_R200) || ++ (dev_priv->chip_family > CHIP_RV280)) { ++ DRM_ERROR("Invalid 3d packet for non r200-class chip\n"); + return -EINVAL; + } + break; +@@ -359,8 +360,8 @@ + break; + + case RADEON_3D_RNDR_GEN_INDX_PRIM: +- if (dev_priv->microcode_version != UCODE_R100) { +- DRM_ERROR("Invalid 3d packet for r200-class chip\n"); ++ if (dev_priv->chip_family > CHIP_RS200) { ++ DRM_ERROR("Invalid 3d packet for non-r100-class chip\n"); + return -EINVAL; + } + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) { +@@ -370,8 +371,10 @@ + break; + + case RADEON_CP_INDX_BUFFER: +- if (dev_priv->microcode_version != UCODE_R200) { +- DRM_ERROR("Invalid 3d packet for r100-class chip\n"); ++ /* safe but r200 only */ ++ if ((dev_priv->chip_family < CHIP_R200) || ++ (dev_priv->chip_family > CHIP_RV280)) { ++ DRM_ERROR("Invalid 3d packet for non-r200-class chip\n"); + return -EINVAL; + } + if ((cmd[1] & 0x8000ffff) != 0x80000810) { +@@ -632,11 +635,7 @@ + * 1.3 cmdbuffers allow all previous state to be updated as well as + * the tcl scalar and vector areas. + */ +-static struct { +- int start; +- int len; +- const char *name; +-} packet[RADEON_MAX_STATE_PACKETS] = { ++struct _radeon_pkt_s radeon_packet[RADEON_MAX_STATE_PACKETS] = { + {RADEON_PP_MISC, 7, "RADEON_PP_MISC"}, + {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"}, + {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"}, +@@ -1018,7 +1017,7 @@ + int tileoffset, nrtilesx, nrtilesy, j; + /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */ + if ((dev_priv->flags & RADEON_HAS_HIERZ) +- && !(dev_priv->microcode_version == UCODE_R200)) { ++ && (dev_priv->chip_family < CHIP_R200)) { + /* FIXME : figure this out for r200 (when hierz is enabled). Or + maybe r200 actually doesn't need to put the low-res z value into + the tile cache like r100, but just needs to clear the hi-level z-buffer? +@@ -1047,7 +1046,8 @@ + ADVANCE_RING(); + tileoffset += depthpixperline >> 6; + } +- } else if (dev_priv->microcode_version == UCODE_R200) { ++ } else if ((dev_priv->chip_family >= CHIP_R200) && ++ (dev_priv->chip_family <= CHIP_RV280)) { + /* works for rv250. */ + /* find first macro tile (8x2 4x4 z-pixels on rv250) */ + tileoffset = +@@ -1102,7 +1102,8 @@ + + /* TODO don't always clear all hi-level z tiles */ + if ((dev_priv->flags & RADEON_HAS_HIERZ) +- && (dev_priv->microcode_version == UCODE_R200) ++ && ((dev_priv->chip_family >= CHIP_R200) && ++ (dev_priv->chip_family <= CHIP_RV280)) + && (flags & RADEON_USE_HIERZ)) + /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ + /* FIXME : the mask supposedly contains low-res z values. So can't set +@@ -1122,8 +1123,9 @@ + * rendering a quad into just those buffers. Thus, we have to + * make sure the 3D engine is configured correctly. + */ +- else if ((dev_priv->microcode_version == UCODE_R200) && +- (flags & (RADEON_DEPTH | RADEON_STENCIL))) { ++ else if ((dev_priv->chip_family >= CHIP_R200) && ++ (dev_priv->chip_family <= CHIP_RV280) && ++ (flags & (RADEON_DEPTH | RADEON_STENCIL))) { + + int tempPP_CNTL; + int tempRE_CNTL; +@@ -1884,10 +1886,11 @@ + OUT_RING((image->width << 16) | height); + RADEON_WAIT_UNTIL_2D_IDLE(); + ADVANCE_RING(); +- COMMIT_RING(); + + radeon_cp_discard_buffer(dev, file_priv->master, buf); + ++ COMMIT_RING(); ++ + /* Update the input parameters for next time */ + image->y += height; + image->height -= height; +@@ -2610,8 +2613,8 @@ + if (id >= RADEON_MAX_STATE_PACKETS) + return -EINVAL; + +- sz = packet[id].len; +- reg = packet[id].start; ++ sz = radeon_packet[id].len; ++ reg = radeon_packet[id].start; + + if (sz * sizeof(int) > cmdbuf->bufsz) { + DRM_ERROR("Packet size provided larger than data provided\n"); +@@ -2879,7 +2882,7 @@ + + orig_nbox = cmdbuf->nbox; + +- if (dev_priv->microcode_version == UCODE_R300) { ++ if (dev_priv->chip_family >= CHIP_R300) { + int temp; + temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); + +@@ -3081,6 +3084,9 @@ + case RADEON_PARAM_NUM_GB_PIPES: + value = dev_priv->num_gb_pipes; + break; ++ case RADEON_PARAM_DEVICE_ID: ++ value = dev->pci_device; /* just return the PCI device ID */ ++ break; + default: + DRM_DEBUG("Invalid parameter %d\n", param->param); + return -EINVAL; +@@ -3103,11 +3109,17 @@ + + switch (sp->param) { + case RADEON_SETPARAM_FB_LOCATION: ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; ++ + radeon_priv = file_priv->driver_priv; + radeon_priv->radeon_fb_delta = dev_priv->fb_location - + sp->value; + break; + case RADEON_SETPARAM_SWITCH_TILING: ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; ++ + if (sp->value == 0) { + DRM_DEBUG("color tiling disabled\n"); + dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO; +@@ -3123,13 +3135,21 @@ + } + break; + case RADEON_SETPARAM_PCIGART_LOCATION: ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; ++ + dev_priv->pcigart_offset = sp->value; + dev_priv->pcigart_offset_set = 1; + break; + case RADEON_SETPARAM_NEW_MEMMAP: ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; + dev_priv->new_memmap = sp->value; + break; + case RADEON_SETPARAM_PCIGART_TABLE_SIZE: ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return 0; ++ + dev_priv->gart_info.table_size = sp->value; + if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE) + dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; +@@ -3226,7 +3246,18 @@ + DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), +- DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH) ++ DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), ++ ++ DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH), ++ ++ DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_rendering, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH), + }; + + int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); +diff -Naur linux-2.6.29.1/include/drm/drm_crtc_helper.h linux-2.6.29.1.patch/include/drm/drm_crtc_helper.h +--- linux-2.6.29.1/include/drm/drm_crtc_helper.h 2009-04-26 02:52:17.321740370 +0200 ++++ linux-2.6.29.1.patch/include/drm/drm_crtc_helper.h 2009-04-26 02:57:54.703975076 +0200 +@@ -96,7 +96,7 @@ + extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, + struct drm_display_mode *mode, + int x, int y, +- struct drm_framebuffer *old_fb); ++ struct drm_framebuffer *old_fbm, int conn_changed); + extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); + + extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, +@@ -121,4 +121,6 @@ + } + + extern int drm_helper_resume_force_mode(struct drm_device *dev); ++extern void drm_helper_set_connector_dpms(struct drm_connector *connector, ++ int dpms_mode); + #endif +diff -Naur linux-2.6.29.1/include/drm/drm.h linux-2.6.29.1.patch/include/drm/drm.h +--- linux-2.6.29.1/include/drm/drm.h 2009-04-26 02:52:17.317746644 +0200 ++++ linux-2.6.29.1.patch/include/drm/drm.h 2009-04-26 02:57:26.282974984 +0200 +@@ -173,6 +173,7 @@ + _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ + _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ + _DRM_GEM = 6, /**< GEM object */ ++ _DRM_TTM = 7, /**< TTM type */ + }; + + /** +diff -Naur linux-2.6.29.1/include/drm/drm_objects.h linux-2.6.29.1.patch/include/drm/drm_objects.h +--- linux-2.6.29.1/include/drm/drm_objects.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1.patch/include/drm/drm_objects.h 2009-04-26 03:02:26.235975190 +0200 +@@ -0,0 +1,913 @@ ++/************************************************************************** ++ * ++ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ **************************************************************************/ ++/* ++ * Authors: Thomas Hellström ++ */ ++ ++#ifndef _DRM_OBJECTS_H ++#define _DRM_OBJECTS_H ++ ++struct drm_device; ++struct drm_bo_mem_reg; ++ ++#define DRM_FENCE_FLAG_EMIT 0x00000001 ++#define DRM_FENCE_FLAG_SHAREABLE 0x00000002 ++/** ++ * On hardware with no interrupt events for operation completion, ++ * indicates that the kernel should sleep while waiting for any blocking ++ * operation to complete rather than spinning. ++ * ++ * Has no effect otherwise. ++ */ ++#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004 ++#define DRM_FENCE_FLAG_NO_USER 0x00000010 ++ ++/* Reserved for driver use */ ++#define DRM_FENCE_MASK_DRIVER 0xFF000000 ++ ++#define DRM_FENCE_TYPE_EXE 0x00000001 ++ ++struct drm_fence_arg { ++ unsigned int handle; ++ unsigned int fence_class; ++ unsigned int type; ++ unsigned int flags; ++ unsigned int signaled; ++ unsigned int error; ++ unsigned int sequence; ++ unsigned int pad64; ++ uint64_t expand_pad[2]; /*Future expansion */ ++}; ++ ++/* Buffer permissions, referring to how the GPU uses the buffers. ++ * these translate to fence types used for the buffers. ++ * Typically a texture buffer is read, A destination buffer is write and ++ * a command (batch-) buffer is exe. Can be or-ed together. ++ */ ++ ++#define DRM_BO_FLAG_READ (1ULL << 0) ++#define DRM_BO_FLAG_WRITE (1ULL << 1) ++#define DRM_BO_FLAG_EXE (1ULL << 2) ++ ++/* ++ * All of the bits related to access mode ++ */ ++#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE) ++/* ++ * Status flags. Can be read to determine the actual state of a buffer. ++ * Can also be set in the buffer mask before validation. ++ */ ++ ++/* ++ * Mask: Never evict this buffer. Not even with force. This type of buffer is only ++ * available to root and must be manually removed before buffer manager shutdown ++ * or lock. ++ * Flags: Acknowledge ++ */ ++#define DRM_BO_FLAG_NO_EVICT (1ULL << 4) ++ ++/* ++ * Mask: Require that the buffer is placed in mappable memory when validated. ++ * If not set the buffer may or may not be in mappable memory when validated. ++ * Flags: If set, the buffer is in mappable memory. ++ */ ++#define DRM_BO_FLAG_MAPPABLE (1ULL << 5) ++ ++/* Mask: The buffer should be shareable with other processes. ++ * Flags: The buffer is shareable with other processes. ++ */ ++#define DRM_BO_FLAG_SHAREABLE (1ULL << 6) ++ ++/* Mask: If set, place the buffer in cache-coherent memory if available. ++ * If clear, never place the buffer in cache coherent memory if validated. ++ * Flags: The buffer is currently in cache-coherent memory. ++ */ ++#define DRM_BO_FLAG_CACHED (1ULL << 7) ++ ++/* Mask: Make sure that every time this buffer is validated, ++ * it ends up on the same location provided that the memory mask is the same. ++ * The buffer will also not be evicted when claiming space for ++ * other buffers. Basically a pinned buffer but it may be thrown out as ++ * part of buffer manager shutdown or locking. ++ * Flags: Acknowledge. ++ */ ++#define DRM_BO_FLAG_NO_MOVE (1ULL << 8) ++ ++/* ++ * Mask: if set the note the buffer contents are discardable ++ * Flags: if set the buffer contents are discardable on migration ++ */ ++#define DRM_BO_FLAG_DISCARDABLE (1ULL << 9) ++ ++/* Mask: Make sure the buffer is in cached memory when mapped. In conjunction ++ * with DRM_BO_FLAG_CACHED it also allows the buffer to be bound into the GART ++ * with unsnooped PTEs instead of snooped, by using chipset-specific cache ++ * flushing at bind time. A better name might be DRM_BO_FLAG_TT_UNSNOOPED, ++ * as the eviction to local memory (TTM unbind) on map is just a side effect ++ * to prevent aggressive cache prefetch from the GPU disturbing the cache ++ * management that the DRM is doing. ++ * ++ * Flags: Acknowledge. ++ * Buffers allocated with this flag should not be used for suballocators ++ * This type may have issues on CPUs with over-aggressive caching ++ * http://marc.info/?l=linux-kernel&m=102376926732464&w=2 ++ */ ++#define DRM_BO_FLAG_CACHED_MAPPED (1ULL << 19) ++ ++ ++/* Mask: Force DRM_BO_FLAG_CACHED flag strictly also if it is set. ++ * Flags: Acknowledge. ++ */ ++#define DRM_BO_FLAG_FORCE_CACHING (1ULL << 13) ++ ++/* ++ * Mask: Force DRM_BO_FLAG_MAPPABLE flag strictly also if it is clear. ++ * Flags: Acknowledge. ++ */ ++#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14) ++#define DRM_BO_FLAG_TILE (1ULL << 15) ++ ++/* ++ * Buffer has been mapped or touched since creation ++ * for VRAM we don't need to migrate, just fill with 0s for non-dirty ++ */ ++#define DRM_BO_FLAG_CLEAN (1ULL << 16) ++ ++/* ++ * Memory type flags that can be or'ed together in the mask, but only ++ * one appears in flags. ++ */ ++ ++/* System memory */ ++#define DRM_BO_FLAG_MEM_LOCAL (1ULL << 24) ++/* Translation table memory */ ++#define DRM_BO_FLAG_MEM_TT (1ULL << 25) ++/* Vram memory */ ++#define DRM_BO_FLAG_MEM_VRAM (1ULL << 26) ++/* Up to the driver to define. */ ++#define DRM_BO_FLAG_MEM_PRIV0 (1ULL << 27) ++#define DRM_BO_FLAG_MEM_PRIV1 (1ULL << 28) ++#define DRM_BO_FLAG_MEM_PRIV2 (1ULL << 29) ++#define DRM_BO_FLAG_MEM_PRIV3 (1ULL << 30) ++#define DRM_BO_FLAG_MEM_PRIV4 (1ULL << 31) ++/* We can add more of these now with a 64-bit flag type */ ++ ++/* ++ * This is a mask covering all of the memory type flags; easier to just ++ * use a single constant than a bunch of | values. It covers ++ * DRM_BO_FLAG_MEM_LOCAL through DRM_BO_FLAG_MEM_PRIV4 ++ */ ++#define DRM_BO_MASK_MEM 0x00000000FF000000ULL ++/* ++ * This adds all of the CPU-mapping options in with the memory ++ * type to label all bits which change how the page gets mapped ++ */ ++#define DRM_BO_MASK_MEMTYPE (DRM_BO_MASK_MEM | \ ++ DRM_BO_FLAG_CACHED_MAPPED | \ ++ DRM_BO_FLAG_CACHED | \ ++ DRM_BO_FLAG_MAPPABLE) ++ ++/* Driver-private flags */ ++#define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL ++ ++/* ++ * Don't block on validate and map. Instead, return EBUSY. ++ */ ++#define DRM_BO_HINT_DONT_BLOCK 0x00000002 ++/* ++ * Don't place this buffer on the unfenced list. This means ++ * that the buffer will not end up having a fence associated ++ * with it as a result of this operation ++ */ ++#define DRM_BO_HINT_DONT_FENCE 0x00000004 ++/** ++ * On hardware with no interrupt events for operation completion, ++ * indicates that the kernel should sleep while waiting for any blocking ++ * operation to complete rather than spinning. ++ * ++ * Has no effect otherwise. ++ */ ++#define DRM_BO_HINT_WAIT_LAZY 0x00000008 ++/* ++ * The client has compute relocations refering to this buffer using the ++ * offset in the presumed_offset field. If that offset ends up matching ++ * where this buffer lands, the kernel is free to skip executing those ++ * relocations ++ */ ++#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010 ++ ++#define DRM_BO_MEM_LOCAL 0 ++#define DRM_BO_MEM_TT 1 ++#define DRM_BO_MEM_VRAM 2 ++#define DRM_BO_MEM_PRIV0 3 ++#define DRM_BO_MEM_PRIV1 4 ++#define DRM_BO_MEM_PRIV2 5 ++#define DRM_BO_MEM_PRIV3 6 ++#define DRM_BO_MEM_PRIV4 7 ++ ++#define DRM_BO_MEM_TYPES 8 /* For now. */ ++ ++#define DRM_BO_LOCK_UNLOCK_BM (1 << 0) ++#define DRM_BO_LOCK_IGNORE_NO_EVICT (1 << 1) ++ ++ ++/*************************************************** ++ * Fence objects. (drm_fence.c) ++ */ ++ ++struct drm_fence_object { ++ struct drm_device *dev; ++ atomic_t usage; ++ ++ /* ++ * The below three fields are protected by the fence manager spinlock. ++ */ ++ ++ struct list_head ring; ++ int fence_class; ++ uint32_t native_types; ++ uint32_t type; ++ uint32_t signaled_types; ++ uint32_t sequence; ++ uint32_t waiting_types; ++ uint32_t error; ++}; ++ ++#define _DRM_FENCE_CLASSES 8 ++ ++struct drm_fence_class_manager { ++ struct list_head ring; ++ uint32_t pending_flush; ++ uint32_t waiting_types; ++ wait_queue_head_t fence_queue; ++ uint32_t highest_waiting_sequence; ++ uint32_t latest_queued_sequence; ++}; ++ ++struct drm_fence_manager { ++ int initialized; ++ rwlock_t lock; ++ struct drm_fence_class_manager fence_class[_DRM_FENCE_CLASSES]; ++ uint32_t num_classes; ++ atomic_t count; ++}; ++ ++struct drm_fence_driver { ++ unsigned long *waiting_jiffies; ++ uint32_t num_classes; ++ uint32_t wrap_diff; ++ uint32_t flush_diff; ++ uint32_t sequence_mask; ++ ++ /* ++ * Driver implemented functions: ++ * has_irq() : 1 if the hardware can update the indicated type_flags using an ++ * irq handler. 0 if polling is required. ++ * ++ * emit() : Emit a sequence number to the command stream. ++ * Return the sequence number. ++ * ++ * flush() : Make sure the flags indicated in fc->pending_flush will eventually ++ * signal for fc->highest_received_sequence and all preceding sequences. ++ * Acknowledge by clearing the flags fc->pending_flush. ++ * ++ * poll() : Call drm_fence_handler with any new information. ++ * ++ * needed_flush() : Given the current state of the fence->type flags and previusly ++ * executed or queued flushes, return the type_flags that need flushing. ++ * ++ * wait(): Wait for the "mask" flags to signal on a given fence, performing ++ * whatever's necessary to make this happen. ++ */ ++ ++ int (*has_irq) (struct drm_device *dev, uint32_t fence_class, ++ uint32_t flags); ++ int (*emit) (struct drm_device *dev, uint32_t fence_class, ++ uint32_t flags, uint32_t *breadcrumb, ++ uint32_t *native_type); ++ void (*flush) (struct drm_device *dev, uint32_t fence_class); ++ void (*poll) (struct drm_device *dev, uint32_t fence_class, ++ uint32_t types); ++ uint32_t (*needed_flush) (struct drm_fence_object *fence); ++ int (*wait) (struct drm_fence_object *fence, int lazy, ++ int interruptible, uint32_t mask); ++}; ++ ++extern int drm_fence_wait_polling(struct drm_fence_object *fence, int lazy, ++ int interruptible, uint32_t mask, ++ unsigned long end_jiffies); ++extern void drm_fence_handler(struct drm_device *dev, uint32_t fence_class, ++ uint32_t sequence, uint32_t type, ++ uint32_t error); ++extern void drm_fence_manager_init(struct drm_device *dev); ++extern void drm_fence_manager_takedown(struct drm_device *dev); ++extern void drm_fence_flush_old(struct drm_device *dev, uint32_t fence_class, ++ uint32_t sequence); ++extern int drm_fence_object_flush(struct drm_fence_object *fence, ++ uint32_t type); ++extern int drm_fence_object_signaled(struct drm_fence_object *fence, ++ uint32_t type); ++extern void drm_fence_usage_deref_locked(struct drm_fence_object **fence); ++extern void drm_fence_usage_deref_unlocked(struct drm_fence_object **fence); ++extern struct drm_fence_object *drm_fence_reference_locked(struct drm_fence_object *src); ++extern void drm_fence_reference_unlocked(struct drm_fence_object **dst, ++ struct drm_fence_object *src); ++extern int drm_fence_object_wait(struct drm_fence_object *fence, ++ int lazy, int ignore_signals, uint32_t mask); ++extern int drm_fence_object_create(struct drm_device *dev, uint32_t type, ++ uint32_t fence_flags, uint32_t fence_class, ++ struct drm_fence_object **c_fence); ++extern int drm_fence_object_emit(struct drm_fence_object *fence, ++ uint32_t fence_flags, uint32_t class, ++ uint32_t type); ++extern void drm_fence_fill_arg(struct drm_fence_object *fence, ++ struct drm_fence_arg *arg); ++ ++extern int drm_fence_add_user_object(struct drm_file *priv, ++ struct drm_fence_object *fence, ++ int shareable); ++ ++extern int drm_fence_create_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int drm_fence_destroy_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int drm_fence_reference_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int drm_fence_unreference_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int drm_fence_signaled_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int drm_fence_flush_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int drm_fence_wait_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int drm_fence_emit_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int drm_fence_buffers_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++/************************************************** ++ *TTMs ++ */ ++ ++/* ++ * The ttm backend GTT interface. (In our case AGP). ++ * Any similar type of device (PCIE?) ++ * needs only to implement these functions to be usable with the TTM interface. ++ * The AGP backend implementation lives in drm_agpsupport.c ++ * basically maps these calls to available functions in agpgart. ++ * Each drm device driver gets an ++ * additional function pointer that creates these types, ++ * so that the device can choose the correct aperture. ++ * (Multiple AGP apertures, etc.) ++ * Most device drivers will let this point to the standard AGP implementation. ++ */ ++ ++#define DRM_BE_FLAG_NEEDS_FREE 0x00000001 ++#define DRM_BE_FLAG_BOUND_CACHED 0x00000002 ++ ++struct drm_ttm_backend; ++struct drm_ttm_backend_func { ++ int (*needs_ub_cache_adjust) (struct drm_ttm_backend *backend); ++ int (*populate) (struct drm_ttm_backend *backend, ++ unsigned long num_pages, struct page **pages, ++ struct page *dummy_read_page); ++ void (*clear) (struct drm_ttm_backend *backend); ++ int (*bind) (struct drm_ttm_backend *backend, ++ struct drm_bo_mem_reg *bo_mem); ++ int (*unbind) (struct drm_ttm_backend *backend); ++ void (*destroy) (struct drm_ttm_backend *backend); ++}; ++ ++/** ++ * This structure associates a set of flags and methods with a drm_ttm ++ * object, and will also be subclassed by the particular backend. ++ * ++ * \sa #drm_agp_ttm_backend ++ */ ++struct drm_ttm_backend { ++ struct drm_device *dev; ++ uint32_t flags; ++ struct drm_ttm_backend_func *func; ++}; ++ ++struct drm_ttm { ++ struct page *dummy_read_page; ++ struct page **pages; ++ long first_himem_page; ++ long last_lomem_page; ++ uint32_t page_flags; ++ unsigned long num_pages; ++ atomic_t vma_count; ++ struct drm_device *dev; ++ int destroy; ++ uint32_t mapping_offset; ++ struct drm_ttm_backend *be; ++ unsigned long highest_lomem_entry; ++ unsigned long lowest_himem_entry; ++ enum { ++ ttm_bound, ++ ttm_evicted, ++ ttm_unbound, ++ ttm_unpopulated, ++ } state; ++ ++}; ++ ++extern struct drm_ttm *drm_ttm_create(struct drm_device *dev, unsigned long size, ++ uint32_t page_flags, ++ struct page *dummy_read_page); ++extern int drm_ttm_bind(struct drm_ttm *ttm, struct drm_bo_mem_reg *bo_mem); ++extern void drm_ttm_unbind(struct drm_ttm *ttm); ++extern void drm_ttm_evict(struct drm_ttm *ttm); ++extern void drm_ttm_fixup_caching(struct drm_ttm *ttm); ++extern struct page *drm_ttm_get_page(struct drm_ttm *ttm, int index); ++extern void drm_ttm_cache_flush(struct page *pages[], unsigned long num_pages); ++extern int drm_ttm_populate(struct drm_ttm *ttm, int cached); ++extern int drm_ttm_set_user(struct drm_ttm *ttm, ++ struct task_struct *tsk, ++ unsigned long start, ++ unsigned long num_pages); ++ ++/* ++ * Destroy a ttm. The user normally calls drmRmMap or a similar IOCTL to do ++ * this which calls this function iff there are no vmas referencing it anymore. ++ * Otherwise it is called when the last vma exits. ++ */ ++ ++extern int drm_ttm_destroy(struct drm_ttm *ttm); ++ ++#define DRM_FLAG_MASKED(_old, _new, _mask) {\ ++(_old) ^= (((_old) ^ (_new)) & (_mask)); \ ++} ++ ++#define DRM_TTM_MASK_FLAGS ((1 << PAGE_SHIFT) - 1) ++#define DRM_TTM_MASK_PFN (0xFFFFFFFFU - DRM_TTM_MASK_FLAGS) ++ ++/* ++ * Page flags. ++ */ ++ ++/* ++ * This ttm should not be cached by the CPU ++ */ ++#define DRM_TTM_PAGE_UNCACHED (1 << 0) ++/* ++ * This flat is not used at this time; I don't know what the ++ * intent was ++ */ ++#define DRM_TTM_PAGE_USED (1 << 1) ++/* ++ * This flat is not used at this time; I don't know what the ++ * intent was ++ */ ++#define DRM_TTM_PAGE_BOUND (1 << 2) ++/* ++ * This flat is not used at this time; I don't know what the ++ * intent was ++ */ ++#define DRM_TTM_PAGE_PRESENT (1 << 3) ++/* ++ * The array of page pointers was allocated with vmalloc ++ * instead of drm_calloc. ++ */ ++#define DRM_TTM_PAGEDIR_VMALLOC (1 << 4) ++/* ++ * This ttm is mapped from user space ++ */ ++#define DRM_TTM_PAGE_USER (1 << 5) ++/* ++ * This ttm will be written to by the GPU ++ */ ++#define DRM_TTM_PAGE_WRITE (1 << 6) ++/* ++ * This ttm was mapped to the GPU, and so the contents may have ++ * been modified ++ */ ++#define DRM_TTM_PAGE_USER_DIRTY (1 << 7) ++/* ++ * This flag is not used at this time; I don't know what the ++ * intent was. ++ */ ++#define DRM_TTM_PAGE_USER_DMA (1 << 8) ++/* ++ * The pages in this TTM were allocated cached ++ */ ++#define DRM_TTM_PAGE_ALLOC_CACHED (1 << 9) ++ ++/*************************************************** ++ * Buffer objects. (drm_bo.c, drm_bo_move.c) ++ */ ++ ++struct drm_bo_mem_reg { ++ struct drm_mm_node *mm_node; ++ unsigned long size; ++ unsigned long num_pages; ++ uint32_t page_alignment; ++ uint32_t mem_type; ++ /* ++ * Current buffer status flags, indicating ++ * where the buffer is located and which ++ * access modes are in effect ++ */ ++ uint64_t flags; ++ /** ++ * These are the flags proposed for ++ * a validate operation. If the ++ * validate succeeds, they'll get moved ++ * into the flags field ++ */ ++ uint64_t proposed_flags; ++ ++ uint32_t desired_tile_stride; ++ uint32_t hw_tile_stride; ++}; ++ ++enum drm_bo_type { ++ /* ++ * drm_bo_type_device are 'normal' drm allocations, ++ * pages are allocated from within the kernel automatically ++ * and the objects can be mmap'd from the drm device. Each ++ * drm_bo_type_device object has a unique name which can be ++ * used by other processes to share access to the underlying ++ * buffer. ++ */ ++ drm_bo_type_device, ++ /* ++ * drm_bo_type_user are buffers of pages that already exist ++ * in the process address space. They are more limited than ++ * drm_bo_type_device buffers in that they must always ++ * remain cached (as we assume the user pages are mapped cached), ++ * and they are not sharable to other processes through DRM ++ * (although, regular shared memory should still work fine). ++ */ ++ drm_bo_type_user, ++ /* ++ * drm_bo_type_kernel are buffers that exist solely for use ++ * within the kernel. The pages cannot be mapped into the ++ * process. One obvious use would be for the ring ++ * buffer where user access would not (ideally) be required. ++ */ ++ drm_bo_type_kernel, ++}; ++ ++struct drm_buffer_object { ++ struct drm_device *dev; ++ ++ /* ++ * If there is a possibility that the usage variable is zero, ++ * then dev->struct_mutext should be locked before incrementing it. ++ */ ++ ++ atomic_t usage; ++ unsigned long buffer_start; ++ enum drm_bo_type type; ++ unsigned long offset; ++ atomic_t mapped; ++ struct drm_bo_mem_reg mem; ++ ++ struct list_head lru; ++ struct list_head ddestroy; ++ ++ uint32_t fence_type; ++ uint32_t fence_class; ++ uint32_t new_fence_type; ++ uint32_t new_fence_class; ++ struct drm_fence_object *fence; ++ uint32_t priv_flags; ++ wait_queue_head_t event_queue; ++ struct mutex mutex; ++ unsigned long num_pages; ++ ++ /* For pinned buffers */ ++ struct drm_mm_node *pinned_node; ++ uint32_t pinned_mem_type; ++ struct list_head pinned_lru; ++ ++ /* For vm */ ++ struct drm_ttm *ttm; ++ struct drm_map_list map_list; ++ uint32_t memory_type; ++ unsigned long bus_offset; ++ uint32_t vm_flags; ++ void *iomap; ++ ++#ifdef DRM_ODD_MM_COMPAT ++ /* dev->struct_mutex only protected. */ ++ struct list_head vma_list; ++ struct list_head p_mm_list; ++#endif ++ ++}; ++ ++#define _DRM_BO_FLAG_UNFENCED 0x00000001 ++#define _DRM_BO_FLAG_EVICTED 0x00000002 ++ ++/* ++ * This flag indicates that a flag called with bo->mutex held has ++ * temporarily released the buffer object mutex, (usually to wait for something). ++ * and thus any post-lock validation needs to be rerun. ++ */ ++ ++#define _DRM_BO_FLAG_UNLOCKED 0x00000004 ++ ++struct drm_mem_type_manager { ++ int has_type; ++ int use_type; ++ int kern_init_type; ++ struct drm_mm manager; ++ struct list_head lru; ++ struct list_head pinned; ++ uint32_t flags; ++ uint32_t drm_bus_maptype; ++ unsigned long gpu_offset; ++ unsigned long io_offset; ++ unsigned long io_size; ++ void *io_addr; ++ uint64_t size; /* size of managed area for reporting to userspace */ ++}; ++ ++struct drm_bo_lock { ++ // struct drm_user_object base; ++ wait_queue_head_t queue; ++ atomic_t write_lock_pending; ++ atomic_t readers; ++}; ++ ++#define _DRM_FLAG_MEMTYPE_FIXED 0x00000001 /* Fixed (on-card) PCI memory */ ++#define _DRM_FLAG_MEMTYPE_MAPPABLE 0x00000002 /* Memory mappable */ ++#define _DRM_FLAG_MEMTYPE_CACHED 0x00000004 /* Cached binding */ ++#define _DRM_FLAG_NEEDS_IOREMAP 0x00000008 /* Fixed memory needs ioremap ++ before kernel access. */ ++#define _DRM_FLAG_MEMTYPE_CMA 0x00000010 /* Can't map aperture */ ++#define _DRM_FLAG_MEMTYPE_CSELECT 0x00000020 /* Select caching */ ++ ++struct drm_buffer_manager { ++ struct drm_bo_lock bm_lock; ++ struct mutex evict_mutex; ++ int nice_mode; ++ int initialized; ++ struct drm_file *last_to_validate; ++ struct drm_mem_type_manager man[DRM_BO_MEM_TYPES]; ++ struct list_head unfenced; ++ struct list_head ddestroy; ++ struct delayed_work wq; ++ uint32_t fence_type; ++ unsigned long cur_pages; ++ atomic_t count; ++ struct page *dummy_read_page; ++}; ++ ++struct drm_bo_driver { ++ const uint32_t *mem_type_prio; ++ const uint32_t *mem_busy_prio; ++ uint32_t num_mem_type_prio; ++ uint32_t num_mem_busy_prio; ++ struct drm_ttm_backend *(*create_ttm_backend_entry) ++ (struct drm_device *dev); ++ int (*fence_type) (struct drm_buffer_object *bo, uint32_t *fclass, ++ uint32_t *type); ++ int (*invalidate_caches) (struct drm_device *dev, uint64_t flags); ++ int (*init_mem_type) (struct drm_device *dev, uint32_t type, ++ struct drm_mem_type_manager *man); ++ /* ++ * evict_flags: ++ * ++ * @bo: the buffer object to be evicted ++ * ++ * Return the bo flags for a buffer which is not mapped to the hardware. ++ * These will be placed in proposed_flags so that when the move is ++ * finished, they'll end up in bo->mem.flags ++ */ ++ uint64_t(*evict_flags) (struct drm_buffer_object *bo); ++ /* ++ * move: ++ * ++ * @bo: the buffer to move ++ * ++ * @evict: whether this motion is evicting the buffer from ++ * the graphics address space ++ * ++ * @no_wait: whether this should give up and return -EBUSY ++ * if this move would require sleeping ++ * ++ * @new_mem: the new memory region receiving the buffer ++ * ++ * Move a buffer between two memory regions. ++ */ ++ int (*move) (struct drm_buffer_object *bo, ++ int evict, int no_wait, struct drm_bo_mem_reg *new_mem); ++ /* ++ * ttm_cache_flush ++ */ ++ void (*ttm_cache_flush)(struct drm_ttm *ttm); ++ ++ /* ++ * command_stream_barrier ++ * ++ * @dev: The drm device. ++ * ++ * @bo: The buffer object to validate. ++ * ++ * @new_fence_class: The new fence class for the buffer object. ++ * ++ * @new_fence_type: The new fence type for the buffer object. ++ * ++ * @no_wait: whether this should give up and return -EBUSY ++ * if this operation would require sleeping ++ * ++ * Insert a command stream barrier that makes sure that the ++ * buffer is idle once the commands associated with the ++ * current validation are starting to execute. If an error ++ * condition is returned, or the function pointer is NULL, ++ * the drm core will force buffer idle ++ * during validation. ++ */ ++ ++ int (*command_stream_barrier) (struct drm_buffer_object *bo, ++ uint32_t new_fence_class, ++ uint32_t new_fence_type, ++ int no_wait); ++}; ++ ++/* ++ * buffer objects (drm_bo.c) ++ */ ++int drm_bo_do_validate(struct drm_buffer_object *bo, ++ uint64_t flags, uint64_t mask, uint32_t hint, ++ uint32_t fence_class); ++extern int drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, int pin); ++extern int drm_bo_driver_finish(struct drm_device *dev); ++extern int drm_bo_driver_init(struct drm_device *dev); ++extern int drm_bo_pci_offset(struct drm_device *dev, ++ struct drm_bo_mem_reg *mem, ++ unsigned long *bus_base, ++ unsigned long *bus_offset, ++ unsigned long *bus_size); ++extern int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg *mem); ++ ++extern int drm_bo_add_user_object(struct drm_file *file_priv, ++ struct drm_buffer_object *bo, int shareable); ++extern void drm_bo_usage_deref_locked(struct drm_buffer_object **bo); ++extern void drm_bo_usage_deref_unlocked(struct drm_buffer_object **bo); ++extern void drm_putback_buffer_objects(struct drm_device *dev); ++extern int drm_fence_buffer_objects(struct drm_device *dev, ++ struct list_head *list, ++ uint32_t fence_flags, ++ struct drm_fence_object *fence, ++ struct drm_fence_object **used_fence); ++extern void drm_bo_add_to_lru(struct drm_buffer_object *bo); ++extern int drm_buffer_object_create(struct drm_device *dev, unsigned long size, ++ enum drm_bo_type type, uint64_t flags, ++ uint32_t hint, uint32_t page_alignment, ++ unsigned long buffer_start, ++ struct drm_buffer_object **bo); ++extern int drm_bo_wait(struct drm_buffer_object *bo, int lazy, int interruptible, ++ int no_wait, int check_unfenced); ++extern int drm_bo_mem_space(struct drm_buffer_object *bo, ++ struct drm_bo_mem_reg *mem, int no_wait); ++extern int drm_bo_move_buffer(struct drm_buffer_object *bo, ++ uint64_t new_mem_flags, ++ int no_wait, int move_unfenced); ++extern int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type, int kern_clean); ++extern int drm_bo_init_mm(struct drm_device *dev, unsigned type, ++ unsigned long p_offset, unsigned long p_size, ++ int kern_init); ++extern struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file *file_priv, ++ uint32_t handle, ++ int check_owner); ++extern int drm_bo_evict_cached(struct drm_buffer_object *bo); ++ ++extern void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo); ++extern void drm_bo_evict_mm(struct drm_device *dev, int mem_type, int no_wait); ++/* ++ * Buffer object memory move- and map helpers. ++ * drm_bo_move.c ++ */ ++ ++extern int drm_bo_add_ttm(struct drm_buffer_object *bo); ++extern int drm_bo_move_ttm(struct drm_buffer_object *bo, ++ int evict, int no_wait, ++ struct drm_bo_mem_reg *new_mem); ++extern int drm_bo_move_memcpy(struct drm_buffer_object *bo, ++ int evict, ++ int no_wait, struct drm_bo_mem_reg *new_mem); ++extern int drm_bo_move_zero(struct drm_buffer_object *bo, ++ int evict, int no_wait, struct drm_bo_mem_reg *new_mem); ++extern int drm_bo_move_accel_cleanup(struct drm_buffer_object *bo, ++ int evict, int no_wait, ++ uint32_t fence_class, uint32_t fence_type, ++ uint32_t fence_flags, ++ struct drm_bo_mem_reg *new_mem); ++extern int drm_bo_same_page(unsigned long offset, unsigned long offset2); ++extern unsigned long drm_bo_offset_end(unsigned long offset, ++ unsigned long end); ++ ++struct drm_bo_kmap_obj { ++ void *virtual; ++ struct page *page; ++ enum { ++ bo_map_iomap, ++ bo_map_vmap, ++ bo_map_kmap, ++ bo_map_premapped, ++ } bo_kmap_type; ++}; ++ ++static inline void *drm_bmo_virtual(struct drm_bo_kmap_obj *map, int *is_iomem) ++{ ++ *is_iomem = (map->bo_kmap_type == bo_map_iomap || ++ map->bo_kmap_type == bo_map_premapped); ++ return map->virtual; ++} ++extern void drm_bo_kunmap(struct drm_bo_kmap_obj *map); ++extern int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page, ++ unsigned long num_pages, struct drm_bo_kmap_obj *map); ++extern int drm_bo_pfn_prot(struct drm_buffer_object *bo, ++ unsigned long dst_offset, ++ unsigned long *pfn, ++ pgprot_t *prot); ++ ++ ++/* ++ * drm_regman.c ++ */ ++ ++struct drm_reg { ++ struct list_head head; ++ struct drm_fence_object *fence; ++ uint32_t fence_type; ++ uint32_t new_fence_type; ++}; ++ ++struct drm_reg_manager { ++ struct list_head free; ++ struct list_head lru; ++ struct list_head unfenced; ++ ++ int (*reg_reusable)(const struct drm_reg *reg, const void *data); ++ void (*reg_destroy)(struct drm_reg *reg); ++}; ++ ++extern int drm_regs_alloc(struct drm_reg_manager *manager, ++ const void *data, ++ uint32_t fence_class, ++ uint32_t fence_type, ++ int interruptible, ++ int no_wait, ++ struct drm_reg **reg); ++ ++extern void drm_regs_fence(struct drm_reg_manager *regs, ++ struct drm_fence_object *fence); ++ ++extern void drm_regs_free(struct drm_reg_manager *manager); ++extern void drm_regs_add(struct drm_reg_manager *manager, struct drm_reg *reg); ++extern void drm_regs_init(struct drm_reg_manager *manager, ++ int (*reg_reusable)(const struct drm_reg *, ++ const void *), ++ void (*reg_destroy)(struct drm_reg *)); ++ ++extern int drm_mem_reg_ioremap(struct drm_device *dev, struct drm_bo_mem_reg * mem, ++ void **virtual); ++extern void drm_mem_reg_iounmap(struct drm_device *dev, struct drm_bo_mem_reg * mem, ++ void *virtual); ++ ++/* ++ * drm_page_alloc. ++ */ ++extern int drm_page_alloc_init(void); ++extern void drm_page_alloc_fini(void); ++extern struct page *drm_get_page(int cached); ++extern void drm_put_page(struct page *page, int cached); ++ ++#ifdef CONFIG_DEBUG_MUTEXES ++#define DRM_ASSERT_LOCKED(_mutex) \ ++ BUG_ON(!mutex_is_locked(_mutex) || \ ++ ((_mutex)->owner != current_thread_info())) ++#else ++#define DRM_ASSERT_LOCKED(_mutex) ++#endif ++#endif +diff -Naur linux-2.6.29.1/include/drm/drmP.h linux-2.6.29.1.patch/include/drm/drmP.h +--- linux-2.6.29.1/include/drm/drmP.h 2009-04-26 02:52:17.319736663 +0200 ++++ linux-2.6.29.1.patch/include/drm/drmP.h 2009-04-26 02:57:31.446980807 +0200 +@@ -147,9 +147,23 @@ + #define DRM_MEM_CTXLIST 21 + #define DRM_MEM_MM 22 + #define DRM_MEM_HASHTAB 23 ++#define DRM_MEM_OBJECTS 24 ++#define DRM_MEM_FENCE 25 ++#define DRM_MEM_TTM 26 ++#define DRM_MEM_BUFOBJ 27 + + #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) + #define DRM_MAP_HASH_OFFSET 0x10000000 ++#define DRM_MAP_HASH_ORDER 12 ++#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1) ++#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16) ++/* ++ * This should be small enough to allow the use of kmalloc for hash tables ++ * instead of vmalloc. ++ */ ++ ++#define DRM_FILE_HASH_ORDER 8 ++#define DRM_MM_INIT_MAX_PAGES 256 + + /*@}*/ + +@@ -665,6 +679,8 @@ + void *driver_priv; /**< Private structure for driver to use */ + }; + ++#include "drm_objects.h" ++ + /** + * DRM driver structure. This structure represent the common code for + * a family of cards. There will one drm_device for each card present +@@ -784,6 +800,8 @@ + + /* Driver private ops for this object */ + struct vm_operations_struct *gem_vm_ops; ++ struct drm_fence_driver *fence_driver; ++ struct drm_bo_driver *bo_driver; + + int major; + int minor; +@@ -906,7 +924,10 @@ + /*@{ */ + struct list_head maplist; /**< Linked list of regions */ + int map_count; /**< Number of mappable regions */ +- struct drm_open_hash map_hash; /**< User token hash table for maps */ ++ struct drm_open_hash map_hash; /**< User token hash table for maps */ ++ struct drm_mm offset_manager; /**< User token manager */ ++ struct address_space *dev_mapping; /**< For unmap_mapping_range() */ ++ struct page *ttm_dummy_page; + + /** \name Context handle management */ + /*@{ */ +@@ -917,6 +938,7 @@ + struct idr ctx_idr; + + struct list_head vmalist; /**< List of vmas (for debugging) */ ++ struct drm_hw_lock default_lock; + + /*@} */ + +@@ -988,7 +1010,6 @@ + int num_crtcs; /**< Number of CRTCs on this device */ + void *dev_private; /**< device private data */ + void *mm_private; +- struct address_space *dev_mapping; + struct drm_sigdata sigdata; /**< For block_all_signals */ + sigset_t sigmask; + +@@ -998,6 +1019,9 @@ + struct drm_minor *control; /**< Control node for card */ + struct drm_minor *primary; /**< render type primary screen head */ + ++ struct drm_fence_manager fm; ++ struct drm_buffer_manager bm; ++ + /** \name Drawable information */ + /*@{ */ + spinlock_t drw_lock; +@@ -1020,8 +1044,28 @@ + uint32_t invalidate_domains; /* domains pending invalidation */ + uint32_t flush_domains; /* domains pending flush */ + /*@} */ ++}; + ++#if __OS_HAS_AGP ++struct drm_agp_ttm_backend { ++ struct drm_ttm_backend backend; ++ DRM_AGP_MEM *mem; ++ struct agp_bridge_data *bridge; ++ int populated; ++}; ++#endif ++struct ati_pcigart_ttm_backend { ++ struct drm_ttm_backend backend; ++ int populated; ++ void (*gart_flush_fn)(struct drm_device *dev); ++ struct drm_ati_pcigart_info *gart_info; ++ unsigned long offset; ++ struct page **pages; ++ int num_pages; ++ int bound; ++ struct drm_device *dev; + }; ++extern struct drm_ttm_backend *ati_pcigart_init_ttm(struct drm_device *dev, struct drm_ati_pcigart_info *info, void (*gart_flush_fn)(struct drm_device *dev)); + + static inline int drm_dev_to_irq(struct drm_device *dev) + { +@@ -1131,6 +1175,17 @@ + uint32_t type); + extern int drm_unbind_agp(DRM_AGP_MEM * handle); + ++extern void drm_free_memctl(size_t size); ++extern int drm_alloc_memctl(size_t size); ++extern void drm_query_memctl(uint64_t *cur_used, ++ uint64_t *emer_used, ++ uint64_t *low_threshold, ++ uint64_t *high_threshold, ++ uint64_t *emer_threshold); ++extern void drm_init_memctl(size_t low_threshold, ++ size_t high_threshold, ++ size_t unit_size); ++ + /* Misc. IOCTL support (drm_ioctl.h) */ + extern int drm_irq_by_busid(struct drm_device *dev, void *data, + struct drm_file *file_priv); +@@ -1301,6 +1356,7 @@ + extern int drm_agp_free_memory(DRM_AGP_MEM * handle); + extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start); + extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); ++extern struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev); + extern void drm_agp_chipset_flush(struct drm_device *dev); + + /* Stub support (drm_stub.h) */ +@@ -1349,6 +1405,7 @@ + extern int drm_vblank_info(struct seq_file *m, void *data); + extern int drm_clients_info(struct seq_file *m, void* data); + extern int drm_gem_name_info(struct seq_file *m, void *data); ++extern int drm_page_alloc_info(struct seq_file *m, void *data); + extern int drm_gem_object_info(struct seq_file *m, void* data); + + #if DRM_DEBUG_CODE +@@ -1368,6 +1425,8 @@ + struct drm_ati_pcigart_info * gart_info); + extern int drm_ati_pcigart_cleanup(struct drm_device *dev, + struct drm_ati_pcigart_info * gart_info); ++extern int drm_ati_alloc_pcigart_table(struct drm_device *dev, ++ struct drm_ati_pcigart_info *gart_info); + + extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size, + size_t align, dma_addr_t maxaddr); +@@ -1525,6 +1584,39 @@ + extern void *drm_calloc(size_t nmemb, size_t size, int area); + #endif + ++/* ++ * Accounting variants of standard calls. ++ */ ++ ++static inline void *drm_ctl_alloc(size_t size, int area) ++{ ++ void *ret; ++ if (drm_alloc_memctl(size)) ++ return NULL; ++ ret = drm_alloc(size, area); ++ if (!ret) ++ drm_free_memctl(size); ++ return ret; ++} ++ ++static inline void *drm_ctl_calloc(size_t nmemb, size_t size, int area) ++{ ++ void *ret; ++ ++ if (drm_alloc_memctl(nmemb*size)) ++ return NULL; ++ ret = drm_calloc(nmemb, size, area); ++ if (!ret) ++ drm_free_memctl(nmemb*size); ++ return ret; ++} ++ ++static inline void drm_ctl_free(void *pt, size_t size, int area) ++{ ++ drm_free(pt, size, area); ++ drm_free_memctl(size); ++} ++ + /*@}*/ + + #endif /* __KERNEL__ */ +diff -Naur linux-2.6.29.1/include/drm/radeon_drm.h linux-2.6.29.1.patch/include/drm/radeon_drm.h +--- linux-2.6.29.1/include/drm/radeon_drm.h 2009-04-26 02:52:17.327736336 +0200 ++++ linux-2.6.29.1.patch/include/drm/radeon_drm.h 2009-04-26 02:57:40.277974980 +0200 +@@ -496,6 +496,16 @@ + #define DRM_RADEON_SETPARAM 0x19 + #define DRM_RADEON_SURF_ALLOC 0x1a + #define DRM_RADEON_SURF_FREE 0x1b ++/* KMS ioctl */ ++#define DRM_RADEON_GEM_INFO 0x1c ++#define DRM_RADEON_GEM_CREATE 0x1d ++#define DRM_RADEON_GEM_MMAP 0x1e ++#define DRM_RADEON_GEM_PREAD 0x21 ++#define DRM_RADEON_GEM_PWRITE 0x22 ++#define DRM_RADEON_GEM_SET_DOMAIN 0x23 ++#define DRM_RADEON_GEM_WAIT_IDLE 0x24 ++#define DRM_RADEON_CS 0x26 ++#define DRM_RADEON_INFO 0x27 + + #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) + #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) +@@ -524,6 +534,17 @@ + #define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t) + #define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t) + #define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t) ++/* KMS */ ++#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info) ++#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create) ++#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap) ++#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread) ++#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite) ++#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) ++#define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle) ++#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) ++#define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info) ++ + + typedef struct drm_radeon_init { + enum { +@@ -682,6 +703,7 @@ + #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ + #define RADEON_PARAM_FB_LOCATION 14 /* FB location */ + #define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */ ++#define RADEON_PARAM_DEVICE_ID 16 + + typedef struct drm_radeon_getparam { + int param; +@@ -751,4 +773,112 @@ + #define DRM_RADEON_VBLANK_CRTC1 1 + #define DRM_RADEON_VBLANK_CRTC2 2 + ++/* ++ * Kernel modesetting world below. ++ */ ++#define RADEON_GEM_DOMAIN_CPU 0x1 ++#define RADEON_GEM_DOMAIN_GTT 0x2 ++#define RADEON_GEM_DOMAIN_VRAM 0x4 ++ ++struct drm_radeon_gem_info { ++ uint64_t gart_size; ++ uint64_t vram_size; ++ uint64_t vram_visible; ++}; ++ ++#define RADEON_GEM_NO_BACKING_STORE 1 ++ ++struct drm_radeon_gem_create { ++ uint64_t size; ++ uint64_t alignment; ++ uint32_t handle; ++ uint32_t initial_domain; ++ uint32_t flags; ++}; ++ ++struct drm_radeon_gem_mmap { ++ uint32_t handle; ++ uint32_t pad; ++ uint64_t offset; ++ uint64_t size; ++ uint64_t addr_ptr; ++}; ++ ++struct drm_radeon_gem_set_domain { ++ uint32_t handle; ++ uint32_t read_domains; ++ uint32_t write_domain; ++}; ++ ++struct drm_radeon_gem_wait_idle { ++ uint32_t handle; ++ uint32_t pad; ++}; ++ ++struct drm_radeon_gem_busy { ++ uint32_t handle; ++ uint32_t busy; ++}; ++ ++struct drm_radeon_gem_pread { ++ /** Handle for the object being read. */ ++ uint32_t handle; ++ uint32_t pad; ++ /** Offset into the object to read from */ ++ uint64_t offset; ++ /** Length of data to read */ ++ uint64_t size; ++ /** Pointer to write the data into. */ ++ /* void *, but pointers are not 32/64 compatible */ ++ uint64_t data_ptr; ++}; ++ ++struct drm_radeon_gem_pwrite { ++ /** Handle for the object being written to. */ ++ uint32_t handle; ++ uint32_t pad; ++ /** Offset into the object to write to */ ++ uint64_t offset; ++ /** Length of data to write */ ++ uint64_t size; ++ /** Pointer to read the data from. */ ++ /* void *, but pointers are not 32/64 compatible */ ++ uint64_t data_ptr; ++}; ++ ++#define RADEON_CHUNK_ID_RELOCS 0x01 ++#define RADEON_CHUNK_ID_IB 0x02 ++ ++struct drm_radeon_cs_chunk { ++ uint32_t chunk_id; ++ uint32_t length_dw; ++ uint64_t chunk_data; ++}; ++ ++struct drm_radeon_cs_reloc { ++ uint32_t handle; ++ uint32_t read_domains; ++ uint32_t write_domain; ++ uint32_t flags; ++}; ++ ++struct drm_radeon_cs { ++ uint32_t num_chunks; ++ uint32_t cs_id; ++ /* this points to uint64_t * which point to cs chunks */ ++ uint64_t chunks; ++ /* updates to the limits after this CS ioctl */ ++ uint64_t gart_limit; ++ uint64_t vram_limit; ++}; ++ ++#define RADEON_INFO_DEVICE_ID 0x00 ++#define RADEON_INFO_NUM_GB_PIPES 0x01 ++ ++struct drm_radeon_info { ++ uint32_t request; ++ uint32_t pad; ++ uint64_t value; ++}; ++ + #endif diff --git a/packages/linux/patches/1814_drm-nouveau.diff b/packages/linux/patches/1814_drm-nouveau.diff new file mode 100644 index 0000000000..01544208c9 --- /dev/null +++ b/packages/linux/patches/1814_drm-nouveau.diff @@ -0,0 +1,49436 @@ +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index a74980b..36582ff 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -133,3 +133,18 @@ config DRM_SAVAGE + help + Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister + chipset. If M is selected the module will be called savage. ++ ++config DRM_NOUVEAU ++ tristate "Nouveau (nVidia) cards" ++ depends on DRM ++ help ++ Choose this option for open-source nVidia support. ++ ++config DRM_NOUVEAU_KMS ++ bool "Enable modesetting on nouveau by default" ++ depends on DRM_NOUVEAU ++ help ++ Choose this option if you want kernel modesetting enabled by default, ++ and you have a new enough userspace to support this. Running old ++ userspaces with this enabled will cause pain. ++ +diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile +index d6788df..97aa0c8 100644 +--- a/drivers/gpu/drm/Makefile ++++ b/drivers/gpu/drm/Makefile +@@ -27,4 +27,5 @@ obj-$(CONFIG_DRM_I915) += i915/ + obj-$(CONFIG_DRM_SIS) += sis/ + obj-$(CONFIG_DRM_SAVAGE)+= savage/ + obj-$(CONFIG_DRM_VIA) +=via/ ++obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/ + +diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c +index 4d2161f..ac503e2 100644 +--- a/drivers/gpu/drm/drm_bufs.c ++++ b/drivers/gpu/drm/drm_bufs.c +@@ -51,38 +51,24 @@ resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resour + + EXPORT_SYMBOL(drm_get_resource_len); + +-static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, +- struct drm_local_map *map) ++struct drm_map_list *drm_find_matching_map(struct drm_device *dev, ++ struct drm_local_map *map) + { + struct drm_map_list *entry; + list_for_each_entry(entry, &dev->maplist, head) { +- /* +- * Because the kernel-userspace ABI is fixed at a 32-bit offset +- * while PCI resources may live above that, we ignore the map +- * offset for maps of type _DRM_FRAMEBUFFER or _DRM_REGISTERS. +- * It is assumed that each driver will have only one resource of +- * each type. +- */ + if (!entry->map || + map->type != entry->map->type || + entry->master != dev->primary->master) + continue; +- switch (map->type) { +- case _DRM_SHM: +- if (map->flags != _DRM_CONTAINS_LOCK) +- break; +- case _DRM_REGISTERS: +- case _DRM_FRAME_BUFFER: +- return entry; +- default: /* Make gcc happy */ +- ; +- } +- if (entry->map->offset == map->offset) ++ ++ if (entry->map->offset == map->offset || ++ (map->type == _DRM_SHM && map->flags & _DRM_CONTAINS_LOCK)) + return entry; + } + + return NULL; + } ++EXPORT_SYMBOL(drm_find_matching_map); + + static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash, + unsigned long user_token, int hashed_handle, int shm) +@@ -349,7 +335,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, + /* We do it here so that dev->struct_mutex protects the increment */ + user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle : + map->offset; +- ret = drm_map_handle(dev, &list->hash, user_token, 0, ++ ret = drm_map_handle(dev, &list->hash, user_token, 1, + (map->type == _DRM_SHM)); + if (ret) { + if (map->type == _DRM_REGISTERS) +diff --git a/drivers/gpu/drm/drm_fence.c b/drivers/gpu/drm/drm_fence.c +index f1c386c..fd62fd9 100644 +--- a/drivers/gpu/drm/drm_fence.c ++++ b/drivers/gpu/drm/drm_fence.c +@@ -369,7 +369,7 @@ int drm_fence_object_wait(struct drm_fence_object *fence, + struct drm_fence_manager *fm = &dev->fm; + struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class]; + int ret = 0; +- unsigned long _end = 3 * DRM_HZ; ++ unsigned long _end = jiffies + 3 * DRM_HZ; + + if (mask & ~fence->type) { + DRM_ERROR("Wait trying to extend fence type" +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 4984aa8..dee9b40 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -280,48 +280,58 @@ drm_gem_close_ioctl(struct drm_device *dev, void *data, + * is freed, the name goes away. + */ + int +-drm_gem_flink_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv) ++drm_gem_object_name(struct drm_device *dev, struct drm_gem_object *obj, ++ uint64_t *name) + { +- struct drm_gem_flink *args = data; +- struct drm_gem_object *obj; + int ret; + +- if (!(dev->driver->driver_features & DRIVER_GEM)) +- return -ENODEV; +- +- obj = drm_gem_object_lookup(dev, file_priv, args->handle); +- if (obj == NULL) +- return -EBADF; +- + again: +- if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) { +- ret = -ENOMEM; +- goto err; +- } ++ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) ++ return -ENOMEM; + + spin_lock(&dev->object_name_lock); + if (!obj->name) { + ret = idr_get_new_above(&dev->object_name_idr, obj, 1, + &obj->name); +- args->name = (uint64_t) obj->name; ++ *name = (uint64_t) obj->name; + spin_unlock(&dev->object_name_lock); + + if (ret == -EAGAIN) + goto again; + + if (ret != 0) +- goto err; ++ return ret; + + /* Allocate a reference for the name table. */ + drm_gem_object_reference(obj); + } else { +- args->name = (uint64_t) obj->name; ++ *name = (uint64_t) obj->name; + spin_unlock(&dev->object_name_lock); +- ret = 0; + } + +-err: ++ return 0; ++} ++EXPORT_SYMBOL(drm_gem_object_name); ++ ++int ++drm_gem_flink_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_gem_flink *args = data; ++ struct drm_gem_object *obj; ++ uint64_t name; ++ int ret; ++ ++ if (!(dev->driver->driver_features & DRIVER_GEM)) ++ return -ENODEV; ++ ++ obj = drm_gem_object_lookup(dev, file_priv, args->handle); ++ if (obj == NULL) ++ return -EBADF; ++ ++ ret = drm_gem_object_name(dev, obj, &name); ++ args->name = name; ++ + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); +diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c +index 5d45cbf..e3b0a76 100644 +--- a/drivers/gpu/drm/drm_stub.c ++++ b/drivers/gpu/drm/drm_stub.c +@@ -406,14 +406,14 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, + if (dev->driver->load) { + ret = dev->driver->load(dev, ent->driver_data); + if (ret) +- goto err_g3; ++ goto err_g4; + } + + /* setup the grouping for the legacy output */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group); + if (ret) +- goto err_g3; ++ goto err_g4; + } + + list_add_tail(&dev->driver_item, &driver->device_list); +@@ -424,8 +424,11 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, + + return 0; + +-err_g3: ++err_g4: + drm_put_minor(&dev->primary); ++err_g3: ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_put_minor(&dev->control); + err_g2: + pci_disable_device(pdev); + err_g1: +@@ -507,11 +510,11 @@ void drm_put_dev(struct drm_device *dev) + dev->agp = NULL; + } + +- drm_ht_remove(&dev->map_hash); +- drm_ctxbitmap_cleanup(dev); +- + list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) + drm_rmmap(dev, r_list->map); ++ drm_ht_remove(&dev->map_hash); ++ ++ drm_ctxbitmap_cleanup(dev); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_put_minor(&dev->control); +diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile +new file mode 100644 +index 0000000..06483d0 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/Makefile +@@ -0,0 +1,24 @@ ++# ++# Makefile for the drm device driver. This driver provides support for the ++# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ++ ++ccflags-y := -Iinclude/drm ++nouveau-y := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ ++ nouveau_object.o nouveau_irq.o nouveau_notifier.o \ ++ nouveau_swmthd.o nouveau_sgdma.o nouveau_dma.o \ ++ nouveau_bo.o nouveau_fence.o nouveau_gem.o \ ++ nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ ++ nouveau_display.o nouveau_fbcon.o nouveau_backlight.o \ ++ nv04_timer.o \ ++ nv04_mc.o nv40_mc.o nv50_mc.o \ ++ nv04_fb.o nv10_fb.o nv40_fb.o \ ++ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ ++ nv04_graph.o nv10_graph.o nv20_graph.o \ ++ nv40_graph.o nv50_graph.o \ ++ nv04_instmem.o nv50_instmem.o \ ++ nv50_crtc.o nv50_dac.o nv50_sor.o nv50_connector.o \ ++ nv50_cursor.o nv50_display.o nv50_fbcon.o ++ ++nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o ++ ++obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o +diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c +new file mode 100644 +index 0000000..e3d354f +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c +@@ -0,0 +1,152 @@ ++/* ++ * Copyright (C) 2009 Red Hat ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++/* ++ * Authors: ++ * Matthew Garrett ++ * ++ * Register locations derived from NVClock by Roderick Colenbrander ++ */ ++ ++#include ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nouveau_reg.h" ++ ++static int nv40_get_intensity(struct backlight_device *bd) ++{ ++ struct drm_device *dev = bl_get_data(bd); ++ int val = (nv_rd32(NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK) >> 16; ++ ++ return val; ++} ++ ++static int nv40_set_intensity(struct backlight_device *bd) ++{ ++ struct drm_device *dev = bl_get_data(bd); ++ int val = bd->props.brightness; ++ int reg = nv_rd32(NV40_PMC_BACKLIGHT); ++ ++ nv_wr32(NV40_PMC_BACKLIGHT, ++ (val << 16) | (reg & ~NV40_PMC_BACKLIGHT_MASK)); ++ ++ return 0; ++} ++ ++static struct backlight_ops nv40_bl_ops = { ++ .options = BL_CORE_SUSPENDRESUME, ++ .get_brightness = nv40_get_intensity, ++ .update_status = nv40_set_intensity, ++}; ++ ++static int nv50_get_intensity(struct backlight_device *bd) ++{ ++ struct drm_device *dev = bl_get_data(bd); ++ ++ return nv_rd32(NV50_PDISPLAY_BACKLIGHT); ++} ++ ++static int nv50_set_intensity(struct backlight_device *bd) ++{ ++ struct drm_device *dev = bl_get_data(bd); ++ int val = bd->props.brightness; ++ ++ nv_wr32(NV50_PDISPLAY_BACKLIGHT, val | NV50_PDISPLAY_BACKLIGHT_ENABLE); ++ ++ return 0; ++} ++ ++static struct backlight_ops nv50_bl_ops = { ++ .options = BL_CORE_SUSPENDRESUME, ++ .get_brightness = nv50_get_intensity, ++ .update_status = nv50_set_intensity, ++}; ++ ++static int nouveau_nv40_backlight_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct backlight_device *bd; ++ ++ if (!(nv_rd32(NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)) ++ return 0; ++ ++ bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, ++ &nv40_bl_ops); ++ if (IS_ERR(bd)) ++ return PTR_ERR(bd); ++ ++ dev_priv->backlight = bd; ++ bd->props.max_brightness = 31; ++ bd->props.brightness = nv40_get_intensity(bd); ++ backlight_update_status(bd); ++ ++ return 0; ++} ++ ++static int nouveau_nv50_backlight_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct backlight_device *bd; ++ ++ if (!nv_rd32(NV50_PDISPLAY_BACKLIGHT)) ++ return 0; ++ ++ bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, ++ &nv50_bl_ops); ++ if (IS_ERR(bd)) ++ return PTR_ERR(bd); ++ ++ dev_priv->backlight = bd; ++ bd->props.max_brightness = 1025; ++ bd->props.brightness = nv50_get_intensity(bd); ++ backlight_update_status(bd); ++ return 0; ++} ++ ++int nouveau_backlight_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ switch (dev_priv->card_type) { ++ case NV_40: ++ case NV_44: ++ return nouveau_nv40_backlight_init(dev); ++ break; ++ case NV_50: ++ return nouveau_nv50_backlight_init(dev); ++ break; ++ } ++ return 0; ++} ++ ++void nouveau_backlight_exit(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->backlight) ++ backlight_device_unregister(dev_priv->backlight); ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c +new file mode 100644 +index 0000000..fd3e08a +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_bios.c +@@ -0,0 +1,4577 @@ ++/* ++ * Copyright 2005-2006 Erik Waling ++ * Copyright 2006 Stephane Marchesin ++ * Copyright 2007-2009 Stuart Bennett ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF ++ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_hw.h" ++ ++/* these defines are made up */ ++#define NV_CIO_CRE_44_HEADA 0x0 ++#define NV_CIO_CRE_44_HEADB 0x3 ++#define FEATURE_MOBILE 0x10 /* also FEATURE_QUADRO for BMP */ ++#define LEGACY_I2C_CRT 0x80 ++ ++#define EDID1_LEN 128 ++ ++#define BIOSLOG(sip, fmt, arg...) NV_DEBUG(sip, fmt, ##arg) ++#define LOG_OLD_VALUE(x) //x ++ ++#define BIOS_USLEEP(n) msleep((n)/1000) ++ ++#define ROM16(x) le16_to_cpu(*(uint16_t *)&(x)) ++#define ROM32(x) le32_to_cpu(*(uint32_t *)&(x)) ++ ++static int crtchead = 0; ++ ++/* this will need remembering across a suspend */ ++static uint32_t saved_nv_pfb_cfg0; ++ ++typedef struct { ++ bool execute; ++ bool repeat; ++} init_exec_t; ++ ++static bool nv_cksum(const uint8_t *data, unsigned int length) ++{ ++ /* there's a few checksums in the BIOS, so here's a generic checking function */ ++ int i; ++ uint8_t sum = 0; ++ ++ for (i = 0; i < length; i++) ++ sum += data[i]; ++ ++ if (sum) ++ return true; ++ ++ return false; ++} ++ ++static int ++score_vbios(struct drm_device *dev, const uint8_t *data, const bool writeable) ++{ ++ if (!(data[0] == 0x55 && data[1] == 0xAA)) { ++ NV_TRACEWARN(dev, "... BIOS signature not found\n"); ++ return 0; ++ } ++ ++ if (nv_cksum(data, data[2] * 512)) { ++ NV_TRACEWARN(dev, "... BIOS checksum invalid\n"); ++ /* if a ro image is somewhat bad, it's probably all rubbish */ ++ return writeable ? 2 : 1; ++ } else ++ NV_TRACE(dev, "... appears to be valid\n"); ++ ++ return 3; ++} ++ ++static void load_vbios_prom(struct drm_device *dev, uint8_t *data) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t pci_nv_20, save_pci_nv_20; ++ int pcir_ptr; ++ int i; ++ ++ if (dev_priv->card_type >= NV_50) ++ pci_nv_20 = 0x88050; ++ else ++ pci_nv_20 = NV_PBUS_PCI_NV_20; ++ ++ /* enable ROM access */ ++ save_pci_nv_20 = nvReadMC(dev, pci_nv_20); ++ nvWriteMC(dev, pci_nv_20, ++ save_pci_nv_20 & ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED); ++ ++ /* bail if no rom signature */ ++ if (nv_rd08(NV_PROM_OFFSET) != 0x55 || ++ nv_rd08(NV_PROM_OFFSET + 1) != 0xaa) ++ goto out; ++ ++ /* additional check (see note below) - read PCI record header */ ++ pcir_ptr = nv_rd08(NV_PROM_OFFSET + 0x18) | ++ nv_rd08(NV_PROM_OFFSET + 0x19) << 8; ++ if (nv_rd08(NV_PROM_OFFSET + pcir_ptr) != 'P' || ++ nv_rd08(NV_PROM_OFFSET + pcir_ptr + 1) != 'C' || ++ nv_rd08(NV_PROM_OFFSET + pcir_ptr + 2) != 'I' || ++ nv_rd08(NV_PROM_OFFSET + pcir_ptr + 3) != 'R') ++ goto out; ++ ++ /* on some 6600GT/6800LE prom reads are messed up. nvclock alleges a ++ * a good read may be obtained by waiting or re-reading (cargocult: 5x) ++ * each byte. we'll hope pramin has something usable instead ++ */ ++ for (i = 0; i < NV_PROM_SIZE; i++) ++ data[i] = nv_rd08(NV_PROM_OFFSET + i); ++ ++out: ++ /* disable ROM access */ ++ nvWriteMC(dev, pci_nv_20, ++ save_pci_nv_20 | NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED); ++} ++ ++static void load_vbios_pramin(struct drm_device *dev, uint8_t *data) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t old_bar0_pramin = 0; ++ int i; ++ ++ if (dev_priv->card_type >= NV_50) { ++ uint32_t vbios_vram = (nv_rd32(0x619f04) & ~0xff) << 8; ++ ++ if (!vbios_vram) ++ vbios_vram = (nv_rd32(0x1700) << 16) + 0xf0000; ++ ++ old_bar0_pramin = nv_rd32(0x1700); ++ nv_wr32(0x1700, vbios_vram >> 16); ++ } ++ ++ /* bail if no rom signature */ ++ if (nv_rd08(NV_PRAMIN_OFFSET) != 0x55 || ++ nv_rd08(NV_PRAMIN_OFFSET + 1) != 0xaa) ++ goto out; ++ ++ for (i = 0; i < NV_PROM_SIZE; i++) ++ data[i] = nv_rd08(NV_PRAMIN_OFFSET + i); ++ ++out: ++ if (dev_priv->card_type >= NV_50) ++ nv_wr32(0x1700, old_bar0_pramin); ++} ++ ++static void load_vbios_pci(struct drm_device *dev, uint8_t *data) ++{ ++ void __iomem *rom = NULL; ++ size_t rom_len; ++ int ret; ++ ++ ret = pci_enable_rom(dev->pdev); ++ if (ret) ++ return; ++ ++ rom = pci_map_rom(dev->pdev, &rom_len); ++ if (!rom) ++ goto out; ++ memcpy(data, rom, rom_len); ++ pci_unmap_rom(dev->pdev, rom); ++ ++out: ++ pci_disable_rom(dev->pdev); ++} ++ ++static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) ++{ ++ struct methods { ++ const char desc[8]; ++ void (*loadbios)(struct drm_device *, uint8_t *); ++ const bool rw; ++ int score; ++ } method[] = { ++ { "PROM", load_vbios_prom, false }, ++ { "PRAMIN", load_vbios_pramin, true }, ++ { "PCI ROM", load_vbios_pci, true } ++ }; ++ int i, testscore = 3; ++ ++ for (i = 0; i < sizeof(method) / sizeof(struct methods); i++) { ++ NV_TRACE(dev, "Attempting to load BIOS image from %s\n", ++ method[i].desc); ++ data[0] = data[1] = 0; /* avoid reuse of previous image */ ++ method[i].loadbios(dev, data); ++ method[i].score = score_vbios(dev, data, method[i].rw); ++ if (method[i].score == testscore) ++ return true; ++ } ++ ++ while (--testscore > 0) ++ for (i = 0; i < sizeof(method) / sizeof(struct methods); i++) ++ if (method[i].score == testscore) { ++ NV_TRACE(dev, "Using BIOS image from %s\n", ++ method[i].desc); ++ method[i].loadbios(dev, data); ++ return true; ++ } ++ ++ NV_ERROR(dev, "No valid BIOS image found\n"); ++ ++ return false; ++} ++ ++typedef struct { ++ char* name; ++ uint8_t id; ++ int length; ++ int length_offset; ++ int length_multiplier; ++ bool (*handler)(struct drm_device *dev, struct nvbios *, uint16_t, init_exec_t *); ++} init_tbl_entry_t; ++ ++typedef struct { ++ uint8_t id[2]; ++ uint16_t length; ++ uint16_t offset; ++} bit_entry_t; ++ ++static int parse_init_table(struct drm_device *dev, struct nvbios *bios, unsigned int offset, init_exec_t *iexec); ++ ++#define MACRO_INDEX_SIZE 2 ++#define MACRO_SIZE 8 ++#define CONDITION_SIZE 12 ++#define IO_FLAG_CONDITION_SIZE 9 ++#define IO_CONDITION_SIZE 5 ++#define MEM_INIT_SIZE 66 ++ ++static void still_alive(void) ++{ ++// sync(); ++// BIOS_USLEEP(2000); ++} ++ ++static int valid_reg(struct drm_device *dev, uint32_t reg) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* C51 has misaligned regs on purpose. Marvellous */ ++ if (reg & 0x2 || (reg & 0x1 && dev_priv->VBIOS.pub.chip_version != 0x51)) { ++ NV_ERROR(dev, "========== misaligned reg 0x%08X ==========\n", ++ reg); ++ return 0; ++ } ++ /* warn on C51 regs that haven't been verified accessible in mmiotracing */ ++ if (reg & 0x1 && dev_priv->VBIOS.pub.chip_version == 0x51 && ++ reg != 0x130d && reg != 0x1311 && reg != 0x60081d) ++ NV_WARN(dev, "=== C51 misaligned reg 0x%08X not verified ===\n", ++ reg); ++ ++ #define WITHIN(x,y,z) ((x>=y)&&(x<=y+z)) ++ if (WITHIN(reg,NV_PMC_OFFSET,NV_PMC_SIZE)) ++ return 1; ++ if (WITHIN(reg,NV_PBUS_OFFSET,NV_PBUS_SIZE)) ++ return 1; ++ if (WITHIN(reg,NV_PFIFO_OFFSET,NV_PFIFO_SIZE)) ++ return 1; ++ /* maybe a little large, but it will do for the moment. */ ++ if (dev_priv->VBIOS.pub.chip_version >= 0x80 && WITHIN(reg, 0x1000, 0xEFFF)) ++ return 1; ++ if (dev_priv->VBIOS.pub.chip_version >= 0x30 && WITHIN(reg,0x4000,0x600)) ++ return 1; ++ if (dev_priv->VBIOS.pub.chip_version >= 0x40 && WITHIN(reg,0xc000,0x48)) ++ return 1; ++ if (dev_priv->VBIOS.pub.chip_version >= 0x17 && reg == 0x0000d204) ++ return 1; ++ if (dev_priv->VBIOS.pub.chip_version >= 0x40) { ++ if (reg == 0x00011014 || reg == 0x00020328) ++ return 1; ++ if (WITHIN(reg,0x88000,NV_PBUS_SIZE)) /* new PBUS */ ++ return 1; ++ } ++ if (dev_priv->VBIOS.pub.chip_version >= 0x80) { ++ /* No clue what they do, but because they are outside normal ranges we'd ++ * better list them seperately. */ ++ if (reg == 0x00020018 || reg == 0x0002004C || reg == 0x00020060 || ++ reg == 0x00021218 || reg == 0x0002130C || reg == 0x00089008 || ++ reg == 0x00089028) ++ return 1; ++ } ++ if (WITHIN(reg,NV_PFB_OFFSET,NV_PFB_SIZE)) ++ return 1; ++ if (WITHIN(reg,NV_PEXTDEV_OFFSET,NV_PEXTDEV_SIZE)) ++ return 1; ++ if (WITHIN(reg,NV_PCRTC0_OFFSET,NV_PCRTC0_SIZE * 2)) ++ return 1; ++ if (dev_priv->VBIOS.pub.chip_version >= 0x80 && WITHIN(reg, NV50_DISPLAY_OFFSET, NV50_DISPLAY_SIZE)) ++ return 1; ++ if (WITHIN(reg,NV_PRAMDAC0_OFFSET,NV_PRAMDAC0_SIZE * 2)) ++ return 1; ++ if (dev_priv->VBIOS.pub.chip_version >= 0x17 && reg == 0x0070fff0) ++ return 1; ++ if (dev_priv->VBIOS.pub.chip_version == 0x51 && WITHIN(reg,NV_PRAMIN_OFFSET,NV_PRAMIN_SIZE)) ++ return 1; ++ #undef WITHIN ++ ++ NV_ERROR(dev, "========== unknown reg 0x%08X ==========\n", reg); ++ ++ return 0; ++} ++ ++static bool valid_idx_port(struct drm_device *dev, uint16_t port) ++{ ++ /* if adding more ports here, the read/write functions below will need ++ * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is ++ * used for the port in question ++ */ ++ if (port == NV_CIO_CRX__COLOR) ++ return true; ++ if (port == NV_VIO_SRX) ++ return true; ++ ++ NV_ERROR(dev, "========== unknown indexed io port 0x%04X ==========\n", ++ port); ++ ++ return false; ++} ++ ++static bool valid_port(struct drm_device *dev, uint16_t port) ++{ ++ /* if adding more ports here, the read/write functions below will need ++ * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is ++ * used for the port in question ++ */ ++ if (port == NV_VIO_VSE2) ++ return true; ++ ++ NV_ERROR(dev, "========== unknown io port 0x%04X ==========\n", port); ++ ++ return false; ++} ++ ++static uint32_t bios_rd32(struct drm_device *dev, uint32_t reg) ++{ ++ uint32_t data; ++ ++ if (!valid_reg(dev, reg)) ++ return 0; ++ ++ /* C51 sometimes uses regs with bit0 set in the address. For these ++ * cases there should exist a translation in a BIOS table to an IO ++ * port address which the BIOS uses for accessing the reg ++ * ++ * These only seem to appear for the power control regs to a flat panel, ++ * and the GPIO regs at 0x60081*. In C51 mmio traces the normal regs ++ * for 0x1308 and 0x1310 are used - hence the mask below. An S3 ++ * suspend-resume mmio trace from a C51 will be required to see if this ++ * is true for the power microcode in 0x14.., or whether the direct IO ++ * port access method is needed ++ */ ++ if (reg & 0x1) ++ reg &= ~0x1; ++ ++ data = nv_rd32(reg); ++ ++ BIOSLOG(dev, " Read: Reg: 0x%08X, Data: 0x%08X\n", reg, data); ++ ++ return data; ++} ++ ++static void bios_wr32(struct drm_device *dev, uint32_t reg, uint32_t data) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (!valid_reg(dev, reg)) ++ return; ++ ++ /* see note in bios_rd32 */ ++ if (reg & 0x1) ++ reg &= 0xfffffffe; ++ ++ LOG_OLD_VALUE(bios_rd32(dev, reg)); ++ BIOSLOG(dev, " Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data); ++ ++ if (dev_priv->VBIOS.execute) { ++ still_alive(); ++ nv_wr32(reg, data); ++ } ++} ++ ++static uint8_t bios_idxprt_rd(struct drm_device *dev, uint16_t port, uint8_t index) ++{ ++ uint8_t data; ++ ++ if (!valid_idx_port(dev, port)) ++ return 0; ++ ++ if (port == NV_VIO_SRX) ++ data = NVReadVgaSeq(dev, crtchead, index); ++ else /* assume NV_CIO_CRX__COLOR */ ++ data = NVReadVgaCrtc(dev, crtchead, index); ++ ++ BIOSLOG(dev, " Indexed IO read: Port: 0x%04X, Index: 0x%02X, Head: 0x%02X, Data: 0x%02X\n", ++ port, index, crtchead, data); ++ ++ return data; ++} ++ ++static void bios_idxprt_wr(struct drm_device *dev, uint16_t port, uint8_t index, uint8_t data) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (!valid_idx_port(dev, port)) ++ return; ++ ++ /* The current head is maintained in a file scope variable crtchead. ++ * We trap changes to CR44 and update the head variable and hence the ++ * register set written. ++ * As CR44 only exists on CRTC0, we update crtchead to head0 in advance ++ * of the write, and to head1 after the write ++ */ ++ if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 && data != NV_CIO_CRE_44_HEADB) ++ crtchead = 0; ++ ++ LOG_OLD_VALUE(bios_idxprt_rd(dev, port, index)); ++ BIOSLOG(dev, " Indexed IO write: Port: 0x%04X, Index: 0x%02X, Head: 0x%02X, Data: 0x%02X\n", ++ port, index, crtchead, data); ++ ++ if (dev_priv->VBIOS.execute) { ++ still_alive(); ++ if (port == NV_VIO_SRX) ++ NVWriteVgaSeq(dev, crtchead, index, data); ++ else /* assume NV_CIO_CRX__COLOR */ ++ NVWriteVgaCrtc(dev, crtchead, index, data); ++ } ++ ++ if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 && data == NV_CIO_CRE_44_HEADB) ++ crtchead = 1; ++} ++ ++static uint8_t bios_port_rd(struct drm_device *dev, uint16_t port) ++{ ++ uint8_t data; ++ ++ if (!valid_port(dev, port)) ++ return 0; ++ ++ data = NVReadPRMVIO(dev, crtchead, NV_PRMVIO0_OFFSET + port); ++ ++ BIOSLOG(dev, " IO read: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", ++ port, crtchead, data); ++ ++ return data; ++} ++ ++static void bios_port_wr(struct drm_device *dev, uint16_t port, uint8_t data) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (!valid_port(dev, port)) ++ return; ++ ++ LOG_OLD_VALUE(bios_port_rd(dev, port)); ++ BIOSLOG(dev, " IO write: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", ++ port, crtchead, data); ++ ++ if (dev_priv->VBIOS.execute) { ++ still_alive(); ++ NVWritePRMVIO(dev, crtchead, NV_PRMVIO0_OFFSET + port, data); ++ } ++} ++ ++static bool io_flag_condition_met(struct drm_device *dev, struct nvbios *bios, uint16_t offset, uint8_t cond) ++{ ++ /* The IO flag condition entry has 2 bytes for the CRTC port; 1 byte ++ * for the CRTC index; 1 byte for the mask to apply to the value ++ * retrieved from the CRTC; 1 byte for the shift right to apply to the ++ * masked CRTC value; 2 bytes for the offset to the flag array, to ++ * which the shifted value is added; 1 byte for the mask applied to the ++ * value read from the flag array; and 1 byte for the value to compare ++ * against the masked byte from the flag table. ++ */ ++ ++ uint16_t condptr = bios->io_flag_condition_tbl_ptr + cond * IO_FLAG_CONDITION_SIZE; ++ uint16_t crtcport = ROM16(bios->data[condptr]); ++ uint8_t crtcindex = bios->data[condptr + 2]; ++ uint8_t mask = bios->data[condptr + 3]; ++ uint8_t shift = bios->data[condptr + 4]; ++ uint16_t flagarray = ROM16(bios->data[condptr + 5]); ++ uint8_t flagarraymask = bios->data[condptr + 7]; ++ uint8_t cmpval = bios->data[condptr + 8]; ++ uint8_t data; ++ ++ BIOSLOG(dev, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Shift: 0x%02X, FlagArray: 0x%04X, FAMask: 0x%02X, Cmpval: 0x%02X\n", ++ offset, crtcport, crtcindex, mask, shift, flagarray, flagarraymask, cmpval); ++ ++ data = bios_idxprt_rd(dev, crtcport, crtcindex); ++ ++ data = bios->data[flagarray + ((data & mask) >> shift)]; ++ data &= flagarraymask; ++ ++ BIOSLOG(dev, "0x%04X: Checking if 0x%02X equals 0x%02X\n", offset, data, cmpval); ++ ++ return (data == cmpval); ++} ++ ++static bool bios_condition_met(struct drm_device *dev, struct nvbios *bios, uint16_t offset, uint8_t cond) ++{ ++ /* The condition table entry has 4 bytes for the address of the ++ * register to check, 4 bytes for a mask to apply to the register and ++ * 4 for a test comparison value ++ */ ++ ++ uint16_t condptr = bios->condition_tbl_ptr + cond * CONDITION_SIZE; ++ uint32_t reg = ROM32(bios->data[condptr]); ++ uint32_t mask = ROM32(bios->data[condptr + 4]); ++ uint32_t cmpval = ROM32(bios->data[condptr + 8]); ++ uint32_t data; ++ ++ BIOSLOG(dev, "0x%04X: Cond: 0x%02X, Reg: 0x%08X, Mask: 0x%08X\n", ++ offset, cond, reg, mask); ++ ++ data = bios_rd32(dev, reg) & mask; ++ ++ BIOSLOG(dev, "0x%04X: Checking if 0x%08X equals 0x%08X\n", ++ offset, data, cmpval); ++ ++ return (data == cmpval); ++} ++ ++static bool io_condition_met(struct drm_device *dev, struct nvbios *bios, uint16_t offset, uint8_t cond) ++{ ++ /* The IO condition entry has 2 bytes for the IO port address; 1 byte ++ * for the index to write to io_port; 1 byte for the mask to apply to ++ * the byte read from io_port+1; and 1 byte for the value to compare ++ * against the masked byte. ++ */ ++ ++ uint16_t condptr = bios->io_condition_tbl_ptr + cond * IO_CONDITION_SIZE; ++ uint16_t io_port = ROM16(bios->data[condptr]); ++ uint8_t port_index = bios->data[condptr + 2]; ++ uint8_t mask = bios->data[condptr + 3]; ++ uint8_t cmpval = bios->data[condptr + 4]; ++ ++ uint8_t data = bios_idxprt_rd(dev, io_port, port_index) & mask; ++ ++ BIOSLOG(dev, "0x%04X: Checking if 0x%02X equals 0x%02X\n", ++ offset, data, cmpval); ++ ++ return (data == cmpval); ++} ++ ++static int setPLL(struct drm_device *dev, struct nvbios *bios, uint32_t reg, uint32_t clk) ++{ ++ /* clk in kHz */ ++ struct pll_lims pll_lim; ++ int ret; ++ struct nouveau_pll_vals pllvals; ++ ++ /* high regs (such as in the mac g5 table) are not -= 4 */ ++ if ((ret = get_pll_limits(dev, reg > 0x405c ? reg : reg - 4, &pll_lim))) ++ return ret; ++ ++ if (!(clk = nouveau_calc_pll_mnp(dev, &pll_lim, clk, &pllvals))) ++ return -ERANGE; ++ ++ if (bios->execute) { ++ still_alive(); ++ nouveau_hw_setpll(dev, reg, &pllvals); ++ } ++ ++ return 0; ++} ++ ++static int dcb_entry_idx_from_crtchead(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* for the results of this function to be correct, CR44 must have been ++ * set (using bios_idxprt_wr to set crtchead), CR58 set for CR57 = 0, ++ * and the DCB table parsed, before the script calling the function is ++ * run. run_digital_op_script is example of how to do such setup ++ */ ++ ++ uint8_t dcb_entry = NVReadVgaCrtc5758(dev, crtchead, 0); ++ ++ if (dcb_entry > dev_priv->VBIOS.bdcb.dcb.entries) { ++ NV_ERROR(dev, "CR58 doesn't have a valid DCB entry currently " ++ "(%02X)\n", dcb_entry); ++ dcb_entry = 0x7f; /* unused / invalid marker */ ++ } ++ ++ return dcb_entry; ++} ++ ++static int init_dcb_i2c_entry(struct drm_device *dev, struct nvbios *bios, int index); ++ ++static int ++create_i2c_device(struct drm_device *dev, struct nvbios *bios, int i2c_index, ++ struct nouveau_i2c_chan **chan) ++{ ++ struct bios_parsed_dcb *bdcb = &bios->bdcb; ++ int ret; ++ ++ if (i2c_index == 0xff) { ++ /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */ ++ int idx = dcb_entry_idx_from_crtchead(dev), shift = 0; ++ int default_indices = bdcb->i2c_default_indices; ++ ++ if (idx != 0x7f && bdcb->dcb.entry[idx].i2c_upper_default) ++ shift = 4; ++ ++ i2c_index = (default_indices >> shift) & 0xf; ++ } ++ if (i2c_index == 0x80) /* g80+ */ ++ i2c_index = bdcb->i2c_default_indices & 0xf; ++ ++ if ((ret = init_dcb_i2c_entry(dev, bios, i2c_index))) ++ return ret; ++ ++ *chan = bdcb->dcb.i2c[i2c_index].chan; ++ return 0; ++} ++ ++static uint32_t get_tmds_index_reg(struct drm_device *dev, uint8_t mlv) ++{ ++ /* For mlv < 0x80, it is an index into a table of TMDS base addresses ++ * For mlv == 0x80 use the "or" value of the dcb_entry indexed by CR58 for CR57 = 0 ++ * to index a table of offsets to the basic 0x6808b0 address ++ * For mlv == 0x81 use the "or" value of the dcb_entry indexed by CR58 for CR57 = 0 ++ * to index a table of offsets to the basic 0x6808b0 address, and then flip the offset by 8 ++ */ ++ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ const int pramdac_offset[13] = {0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000}; ++ const uint32_t pramdac_table[4] = {0x6808b0, 0x6808b8, 0x6828b0, 0x6828b8}; ++ ++ if (mlv >= 0x80) { ++ int dcb_entry, dacoffset; ++ ++ /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */ ++ if ((dcb_entry = dcb_entry_idx_from_crtchead(dev)) == 0x7f) ++ return 0; ++ dacoffset = pramdac_offset[dev_priv->VBIOS.bdcb.dcb.entry[dcb_entry].or]; ++ if (mlv == 0x81) ++ dacoffset ^= 8; ++ return (0x6808b0 + dacoffset); ++ } else { ++ if (mlv > (sizeof(pramdac_table) / sizeof(uint32_t))) { ++ NV_ERROR(dev, "Magic Lookup Value too big (%02X)\n", mlv); ++ return 0; ++ } ++ return pramdac_table[mlv]; ++ } ++} ++ ++static bool init_io_restrict_prog(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_IO_RESTRICT_PROG opcode: 0x32 ('2') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): CRTC port ++ * offset + 3 (8 bit): CRTC index ++ * offset + 4 (8 bit): mask ++ * offset + 5 (8 bit): shift ++ * offset + 6 (8 bit): count ++ * offset + 7 (32 bit): register ++ * offset + 11 (32 bit): configuration 1 ++ * ... ++ * ++ * Starting at offset + 11 there are "count" 32 bit values. ++ * To find out which value to use read index "CRTC index" on "CRTC port", ++ * AND this value with "mask" and then bit shift right "shift" bits. ++ * Read the appropriate value using this index and write to "register" ++ */ ++ ++ uint16_t crtcport = ROM16(bios->data[offset + 1]); ++ uint8_t crtcindex = bios->data[offset + 3]; ++ uint8_t mask = bios->data[offset + 4]; ++ uint8_t shift = bios->data[offset + 5]; ++ uint8_t count = bios->data[offset + 6]; ++ uint32_t reg = ROM32(bios->data[offset + 7]); ++ uint8_t config; ++ uint32_t configval; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", ++ offset, crtcport, crtcindex, mask, shift, count, reg); ++ ++ config = (bios_idxprt_rd(dev, crtcport, crtcindex) & mask) >> shift; ++ if (config > count) { ++ NV_ERROR(dev, ++ "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", ++ offset, config, count); ++ return false; ++ } ++ ++ configval = ROM32(bios->data[offset + 11 + config * 4]); ++ ++ BIOSLOG(dev, "0x%04X: Writing config %02X\n", offset, config); ++ ++ bios_wr32(dev, reg, configval); ++ ++ return true; ++} ++ ++static bool init_repeat(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_REPEAT opcode: 0x33 ('3') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): count ++ * ++ * Execute script following this opcode up to INIT_REPEAT_END ++ * "count" times ++ */ ++ ++ uint8_t count = bios->data[offset + 1]; ++ uint8_t i; ++ ++ /* no iexec->execute check by design */ ++ ++ BIOSLOG(dev, "0x%04X: Repeating following segment %d times\n", offset, count); ++ ++ iexec->repeat = true; ++ ++ /* count - 1, as the script block will execute once when we leave this ++ * opcode -- this is compatible with bios behaviour as: ++ * a) the block is always executed at least once, even if count == 0 ++ * b) the bios interpreter skips to the op following INIT_END_REPEAT, ++ * while we don't ++ */ ++ for (i = 0; i < count - 1; i++) ++ parse_init_table(dev, bios, offset + 2, iexec); ++ ++ iexec->repeat = false; ++ ++ return true; ++} ++ ++static bool init_io_restrict_pll(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_IO_RESTRICT_PLL opcode: 0x34 ('4') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): CRTC port ++ * offset + 3 (8 bit): CRTC index ++ * offset + 4 (8 bit): mask ++ * offset + 5 (8 bit): shift ++ * offset + 6 (8 bit): IO flag condition index ++ * offset + 7 (8 bit): count ++ * offset + 8 (32 bit): register ++ * offset + 12 (16 bit): frequency 1 ++ * ... ++ * ++ * Starting at offset + 12 there are "count" 16 bit frequencies (10kHz). ++ * Set PLL register "register" to coefficients for frequency n, ++ * selected by reading index "CRTC index" of "CRTC port" ANDed with ++ * "mask" and shifted right by "shift". If "IO flag condition index" > 0, ++ * and condition met, double frequency before setting it. ++ */ ++ ++ uint16_t crtcport = ROM16(bios->data[offset + 1]); ++ uint8_t crtcindex = bios->data[offset + 3]; ++ uint8_t mask = bios->data[offset + 4]; ++ uint8_t shift = bios->data[offset + 5]; ++ int8_t io_flag_condition_idx = bios->data[offset + 6]; ++ uint8_t count = bios->data[offset + 7]; ++ uint32_t reg = ROM32(bios->data[offset + 8]); ++ uint8_t config; ++ uint16_t freq; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Shift: 0x%02X, IO Flag Condition: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", ++ offset, crtcport, crtcindex, mask, shift, io_flag_condition_idx, count, reg); ++ ++ config = (bios_idxprt_rd(dev, crtcport, crtcindex) & mask) >> shift; ++ if (config > count) { ++ NV_ERROR(dev, ++ "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", ++ offset, config, count); ++ return false; ++ } ++ ++ freq = ROM16(bios->data[offset + 12 + config * 2]); ++ ++ if (io_flag_condition_idx > 0) { ++ if (io_flag_condition_met(dev, bios, offset, io_flag_condition_idx)) { ++ BIOSLOG(dev, "0x%04X: Condition fulfilled -- frequency doubled\n", offset); ++ freq *= 2; ++ } else ++ BIOSLOG(dev, "0x%04X: Condition not fulfilled -- frequency unchanged\n", offset); ++ } ++ ++ BIOSLOG(dev, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n", ++ offset, reg, config, freq); ++ ++ setPLL(dev, bios, reg, freq * 10); ++ ++ return true; ++} ++ ++static bool init_end_repeat(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_END_REPEAT opcode: 0x36 ('6') ++ * ++ * offset (8 bit): opcode ++ * ++ * Marks the end of the block for INIT_REPEAT to repeat ++ */ ++ ++ /* no iexec->execute check by design */ ++ ++ /* iexec->repeat flag necessary to go past INIT_END_REPEAT opcode when ++ * we're not in repeat mode ++ */ ++ if (iexec->repeat) ++ return false; ++ ++ return true; ++} ++ ++static bool init_copy(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_COPY opcode: 0x37 ('7') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): register ++ * offset + 5 (8 bit): shift ++ * offset + 6 (8 bit): srcmask ++ * offset + 7 (16 bit): CRTC port ++ * offset + 9 (8 bit): CRTC index ++ * offset + 10 (8 bit): mask ++ * ++ * Read index "CRTC index" on "CRTC port", AND with "mask", OR with ++ * (REGVAL("register") >> "shift" & "srcmask") and write-back to CRTC port ++ */ ++ ++ uint32_t reg = ROM32(bios->data[offset + 1]); ++ uint8_t shift = bios->data[offset + 5]; ++ uint8_t srcmask = bios->data[offset + 6]; ++ uint16_t crtcport = ROM16(bios->data[offset + 7]); ++ uint8_t crtcindex = bios->data[offset + 9]; ++ uint8_t mask = bios->data[offset + 10]; ++ uint32_t data; ++ uint8_t crtcdata; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Reg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%02X, Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X\n", ++ offset, reg, shift, srcmask, crtcport, crtcindex, mask); ++ ++ data = bios_rd32(dev, reg); ++ ++ if (shift < 0x80) ++ data >>= shift; ++ else ++ data <<= (0x100 - shift); ++ ++ data &= srcmask; ++ ++ crtcdata = (bios_idxprt_rd(dev, crtcport, crtcindex) & mask) | (uint8_t)data; ++ bios_idxprt_wr(dev, crtcport, crtcindex, crtcdata); ++ ++ return true; ++} ++ ++static bool init_not(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_NOT opcode: 0x38 ('8') ++ * ++ * offset (8 bit): opcode ++ * ++ * Invert the current execute / no-execute condition (i.e. "else") ++ */ ++ if (iexec->execute) ++ BIOSLOG(dev, "0x%04X: ------ Skipping following commands ------\n", offset); ++ else ++ BIOSLOG(dev, "0x%04X: ------ Executing following commands ------\n", offset); ++ ++ iexec->execute = !iexec->execute; ++ return true; ++} ++ ++static bool init_io_flag_condition(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_IO_FLAG_CONDITION opcode: 0x39 ('9') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): condition number ++ * ++ * Check condition "condition number" in the IO flag condition table. ++ * If condition not met skip subsequent opcodes until condition is ++ * inverted (INIT_NOT), or we hit INIT_RESUME ++ */ ++ ++ uint8_t cond = bios->data[offset + 1]; ++ ++ if (!iexec->execute) ++ return true; ++ ++ if (io_flag_condition_met(dev, bios, offset, cond)) ++ BIOSLOG(dev, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); ++ else { ++ BIOSLOG(dev, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool init_idx_addr_latched(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_INDEX_ADDRESS_LATCHED opcode: 0x49 ('I') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): control register ++ * offset + 5 (32 bit): data register ++ * offset + 9 (32 bit): mask ++ * offset + 13 (32 bit): data ++ * offset + 17 (8 bit): count ++ * offset + 18 (8 bit): address 1 ++ * offset + 19 (8 bit): data 1 ++ * ... ++ * ++ * For each of "count" address and data pairs, write "data n" to "data register", ++ * read the current value of "control register", and write it back once ANDed ++ * with "mask", ORed with "data", and ORed with "address n" ++ */ ++ ++ uint32_t controlreg = ROM32(bios->data[offset + 1]); ++ uint32_t datareg = ROM32(bios->data[offset + 5]); ++ uint32_t mask = ROM32(bios->data[offset + 9]); ++ uint32_t data = ROM32(bios->data[offset + 13]); ++ uint8_t count = bios->data[offset + 17]; ++ uint32_t value; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n", ++ offset, controlreg, datareg, mask, data, count); ++ ++ for (i = 0; i < count; i++) { ++ uint8_t instaddress = bios->data[offset + 18 + i * 2]; ++ uint8_t instdata = bios->data[offset + 19 + i * 2]; ++ ++ BIOSLOG(dev, "0x%04X: Address: 0x%02X, Data: 0x%02X\n", offset, instaddress, instdata); ++ ++ bios_wr32(dev, datareg, instdata); ++ value = (bios_rd32(dev, controlreg) & mask) | data | instaddress; ++ bios_wr32(dev, controlreg, value); ++ } ++ ++ return true; ++} ++ ++static bool init_io_restrict_pll2(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_IO_RESTRICT_PLL2 opcode: 0x4A ('J') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): CRTC port ++ * offset + 3 (8 bit): CRTC index ++ * offset + 4 (8 bit): mask ++ * offset + 5 (8 bit): shift ++ * offset + 6 (8 bit): count ++ * offset + 7 (32 bit): register ++ * offset + 11 (32 bit): frequency 1 ++ * ... ++ * ++ * Starting at offset + 11 there are "count" 32 bit frequencies (kHz). ++ * Set PLL register "register" to coefficients for frequency n, ++ * selected by reading index "CRTC index" of "CRTC port" ANDed with ++ * "mask" and shifted right by "shift". ++ */ ++ ++ uint16_t crtcport = ROM16(bios->data[offset + 1]); ++ uint8_t crtcindex = bios->data[offset + 3]; ++ uint8_t mask = bios->data[offset + 4]; ++ uint8_t shift = bios->data[offset + 5]; ++ uint8_t count = bios->data[offset + 6]; ++ uint32_t reg = ROM32(bios->data[offset + 7]); ++ uint8_t config; ++ uint32_t freq; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", ++ offset, crtcport, crtcindex, mask, shift, count, reg); ++ ++ if (!reg) ++ return true; ++ ++ config = (bios_idxprt_rd(dev, crtcport, crtcindex) & mask) >> shift; ++ if (config > count) { ++ NV_ERROR(dev, ++ "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", ++ offset, config, count); ++ return false; ++ } ++ ++ freq = ROM32(bios->data[offset + 11 + config * 4]); ++ ++ BIOSLOG(dev, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n", ++ offset, reg, config, freq); ++ ++ setPLL(dev, bios, reg, freq); ++ ++ return true; ++} ++ ++static bool init_pll2(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_PLL2 opcode: 0x4B ('K') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): register ++ * offset + 5 (32 bit): freq ++ * ++ * Set PLL register "register" to coefficients for frequency "freq" ++ */ ++ ++ uint32_t reg = ROM32(bios->data[offset + 1]); ++ uint32_t freq = ROM32(bios->data[offset + 5]); ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n", ++ offset, reg, freq); ++ ++ setPLL(dev, bios, reg, freq); ++ ++ return true; ++} ++ ++static bool init_i2c_byte(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_I2C_BYTE opcode: 0x4C ('L') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): DCB I2C table entry index ++ * offset + 2 (8 bit): I2C slave address ++ * offset + 3 (8 bit): count ++ * offset + 4 (8 bit): I2C register 1 ++ * offset + 5 (8 bit): mask 1 ++ * offset + 6 (8 bit): data 1 ++ * ... ++ * ++ * For each of "count" registers given by "I2C register n" on the device ++ * addressed by "I2C slave address" on the I2C bus given by ++ * "DCB I2C table entry index", read the register, AND the result with ++ * "mask n" and OR it with "data n" before writing it back to the device ++ */ ++ ++ uint8_t i2c_index = bios->data[offset + 1]; ++ uint8_t i2c_address = bios->data[offset + 2]; ++ uint8_t count = bios->data[offset + 3]; ++ struct nouveau_i2c_chan *chan; ++ struct i2c_msg msg; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, Count: 0x%02X\n", ++ offset, i2c_index, i2c_address, count); ++ ++ if (create_i2c_device(dev, bios, i2c_index, &chan)) ++ return false; ++ ++ for (i = 0; i < count; i++) { ++ uint8_t i2c_reg = bios->data[offset + 4 + i * 3]; ++ uint8_t mask = bios->data[offset + 5 + i * 3]; ++ uint8_t data = bios->data[offset + 6 + i * 3]; ++ uint8_t value; ++ ++ msg.addr = i2c_address; ++ msg.flags = I2C_M_RD; ++ msg.len = 1; ++ msg.buf = &value; ++ if (i2c_transfer(&chan->adapter, &msg, 1) != 1) ++ return false; ++ ++ BIOSLOG(dev, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", ++ offset, i2c_reg, value, mask, data); ++ ++ value = (value & mask) | data; ++ ++ if (bios->execute) { ++ msg.addr = i2c_address; ++ msg.flags = 0; ++ msg.len = 1; ++ msg.buf = &value; ++ if (i2c_transfer(&chan->adapter, &msg, 1) != 1) ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++static bool init_zm_i2c_byte(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_ZM_I2C_BYTE opcode: 0x4D ('M') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): DCB I2C table entry index ++ * offset + 2 (8 bit): I2C slave address ++ * offset + 3 (8 bit): count ++ * offset + 4 (8 bit): I2C register 1 ++ * offset + 5 (8 bit): data 1 ++ * ... ++ * ++ * For each of "count" registers given by "I2C register n" on the device ++ * addressed by "I2C slave address" on the I2C bus given by ++ * "DCB I2C table entry index", set the register to "data n" ++ */ ++ ++ uint8_t i2c_index = bios->data[offset + 1]; ++ uint8_t i2c_address = bios->data[offset + 2]; ++ uint8_t count = bios->data[offset + 3]; ++ struct nouveau_i2c_chan *chan; ++ struct i2c_msg msg; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, Count: 0x%02X\n", ++ offset, i2c_index, i2c_address, count); ++ ++ if (create_i2c_device(dev, bios, i2c_index, &chan)) ++ return false; ++ ++ for (i = 0; i < count; i++) { ++ uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; ++ uint8_t data = bios->data[offset + 5 + i * 2]; ++ ++ BIOSLOG(dev, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n", ++ offset, i2c_reg, data); ++ ++ if (bios->execute) { ++ msg.addr = i2c_address; ++ msg.flags = 0; ++ msg.len = 1; ++ msg.buf = &data; ++ if (i2c_transfer(&chan->adapter, &msg, 1) != 1) ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++static bool init_zm_i2c(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_ZM_I2C opcode: 0x4E ('N') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): DCB I2C table entry index ++ * offset + 2 (8 bit): I2C slave address ++ * offset + 3 (8 bit): count ++ * offset + 4 (8 bit): data 1 ++ * ... ++ * ++ * Send "count" bytes ("data n") to the device addressed by "I2C slave ++ * address" on the I2C bus given by "DCB I2C table entry index" ++ */ ++ ++ uint8_t i2c_index = bios->data[offset + 1]; ++ uint8_t i2c_address = bios->data[offset + 2]; ++ uint8_t count = bios->data[offset + 3]; ++ struct nouveau_i2c_chan *chan; ++ struct i2c_msg msg; ++ uint8_t data[256]; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, Count: 0x%02X\n", ++ offset, i2c_index, i2c_address, count); ++ ++ if (create_i2c_device(dev, bios, i2c_index, &chan)) ++ return false; ++ ++ for (i = 0; i < count; i++) { ++ data[i] = bios->data[offset + 4 + i]; ++ ++ BIOSLOG(dev, "0x%04X: Data: 0x%02X\n", offset, data[i]); ++ } ++ ++ if (bios->execute) { ++ msg.addr = i2c_address; ++ msg.flags = 0; ++ msg.len = count; ++ msg.buf = data; ++ if (i2c_transfer(&chan->adapter, &msg, 1) != 1) ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool init_tmds(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_TMDS opcode: 0x4F ('O') (non-canon name) ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): magic lookup value ++ * offset + 2 (8 bit): TMDS address ++ * offset + 3 (8 bit): mask ++ * offset + 4 (8 bit): data ++ * ++ * Read the data reg for TMDS address "TMDS address", AND it with mask ++ * and OR it with data, then write it back ++ * "magic lookup value" determines which TMDS base address register is used -- ++ * see get_tmds_index_reg() ++ */ ++ ++ uint8_t mlv = bios->data[offset + 1]; ++ uint32_t tmdsaddr = bios->data[offset + 2]; ++ uint8_t mask = bios->data[offset + 3]; ++ uint8_t data = bios->data[offset + 4]; ++ uint32_t reg, value; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", ++ offset, mlv, tmdsaddr, mask, data); ++ ++ if (!(reg = get_tmds_index_reg(dev, mlv))) ++ return false; ++ ++ bios_wr32(dev, reg, tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); ++ value = (bios_rd32(dev, reg + 4) & mask) | data; ++ bios_wr32(dev, reg + 4, value); ++ bios_wr32(dev, reg, tmdsaddr); ++ ++ return true; ++} ++ ++static bool init_zm_tmds_group(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_ZM_TMDS_GROUP opcode: 0x50 ('P') (non-canon name) ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): magic lookup value ++ * offset + 2 (8 bit): count ++ * offset + 3 (8 bit): addr 1 ++ * offset + 4 (8 bit): data 1 ++ * ... ++ * ++ * For each of "count" TMDS address and data pairs write "data n" to "addr n" ++ * "magic lookup value" determines which TMDS base address register is used -- ++ * see get_tmds_index_reg() ++ */ ++ ++ uint8_t mlv = bios->data[offset + 1]; ++ uint8_t count = bios->data[offset + 2]; ++ uint32_t reg; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n", ++ offset, mlv, count); ++ ++ if (!(reg = get_tmds_index_reg(dev, mlv))) ++ return false; ++ ++ for (i = 0; i < count; i++) { ++ uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; ++ uint8_t tmdsdata = bios->data[offset + 4 + i * 2]; ++ ++ bios_wr32(dev, reg + 4, tmdsdata); ++ bios_wr32(dev, reg, tmdsaddr); ++ } ++ ++ return true; ++} ++ ++static bool init_cr_idx_adr_latch(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_CR_INDEX_ADDRESS_LATCHED opcode: 0x51 ('Q') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): CRTC index1 ++ * offset + 2 (8 bit): CRTC index2 ++ * offset + 3 (8 bit): baseaddr ++ * offset + 4 (8 bit): count ++ * offset + 5 (8 bit): data 1 ++ * ... ++ * ++ * For each of "count" address and data pairs, write "baseaddr + n" to ++ * "CRTC index1" and "data n" to "CRTC index2" ++ * Once complete, restore initial value read from "CRTC index1" ++ */ ++ uint8_t crtcindex1 = bios->data[offset + 1]; ++ uint8_t crtcindex2 = bios->data[offset + 2]; ++ uint8_t baseaddr = bios->data[offset + 3]; ++ uint8_t count = bios->data[offset + 4]; ++ uint8_t oldaddr, data; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, BaseAddr: 0x%02X, Count: 0x%02X\n", ++ offset, crtcindex1, crtcindex2, baseaddr, count); ++ ++ oldaddr = bios_idxprt_rd(dev, NV_CIO_CRX__COLOR, crtcindex1); ++ ++ for (i = 0; i < count; i++) { ++ bios_idxprt_wr(dev, NV_CIO_CRX__COLOR, crtcindex1, baseaddr + i); ++ ++ data = bios->data[offset + 5 + i]; ++ bios_idxprt_wr(dev, NV_CIO_CRX__COLOR, crtcindex2, data); ++ } ++ ++ bios_idxprt_wr(dev, NV_CIO_CRX__COLOR, crtcindex1, oldaddr); ++ ++ return true; ++} ++ ++static bool init_cr(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_CR opcode: 0x52 ('R') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): CRTC index ++ * offset + 2 (8 bit): mask ++ * offset + 3 (8 bit): data ++ * ++ * Assign the value of at "CRTC index" ANDed with mask and ORed with data ++ * back to "CRTC index" ++ */ ++ ++ uint8_t crtcindex = bios->data[offset + 1]; ++ uint8_t mask = bios->data[offset + 2]; ++ uint8_t data = bios->data[offset + 3]; ++ uint8_t value; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", ++ offset, crtcindex, mask, data); ++ ++ value = (bios_idxprt_rd(dev, NV_CIO_CRX__COLOR, crtcindex) & mask) | data; ++ bios_idxprt_wr(dev, NV_CIO_CRX__COLOR, crtcindex, value); ++ ++ return true; ++} ++ ++static bool init_zm_cr(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_ZM_CR opcode: 0x53 ('S') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): CRTC index ++ * offset + 2 (8 bit): value ++ * ++ * Assign "value" to CRTC register with index "CRTC index". ++ */ ++ ++ uint8_t crtcindex = ROM32(bios->data[offset + 1]); ++ uint8_t data = bios->data[offset + 2]; ++ ++ if (!iexec->execute) ++ return true; ++ ++ bios_idxprt_wr(dev, NV_CIO_CRX__COLOR, crtcindex, data); ++ ++ return true; ++} ++ ++static bool init_zm_cr_group(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_ZM_CR_GROUP opcode: 0x54 ('T') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): count ++ * offset + 2 (8 bit): CRTC index 1 ++ * offset + 3 (8 bit): value 1 ++ * ... ++ * ++ * For "count", assign "value n" to CRTC register with index "CRTC index n". ++ */ ++ ++ uint8_t count = bios->data[offset + 1]; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ for (i = 0; i < count; i++) ++ init_zm_cr(dev, bios, offset + 2 + 2 * i - 1, iexec); ++ ++ return true; ++} ++ ++static bool init_condition_time(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_CONDITION_TIME opcode: 0x56 ('V') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): condition number ++ * offset + 2 (8 bit): retries / 50 ++ * ++ * Check condition "condition number" in the condition table. ++ * Bios code then sleeps for 2ms if the condition is not met, and ++ * repeats up to "retries" times, but on one C51 this has proved ++ * insufficient. In mmiotraces the driver sleeps for 20ms, so we do ++ * this, and bail after "retries" times, or 2s, whichever is less. ++ * If still not met after retries, clear execution flag for this table. ++ */ ++ ++ uint8_t cond = bios->data[offset + 1]; ++ uint16_t retries = bios->data[offset + 2] * 50; ++ ++ if (!iexec->execute) ++ return true; ++ ++ if (retries > 100) ++ retries = 100; ++ ++ BIOSLOG(dev, "0x%04X: Condition: 0x%02X, Retries: 0x%02X\n", offset, cond, retries); ++ ++ for (; retries > 0; retries--) ++ if (bios_condition_met(dev, bios, offset, cond)) { ++ BIOSLOG(dev, "0x%04X: Condition met, continuing\n", offset); ++ break; ++ } else { ++ BIOSLOG(dev, "0x%04X: Condition not met, sleeping for 20ms\n", offset); ++ BIOS_USLEEP(20000); ++ } ++ ++ if (!bios_condition_met(dev, bios, offset, cond)) { ++ NV_WARN(dev, "0x%04X: Condition still not met after %dms, " ++ "skiping following opcodes\n", offset, 20 * retries); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool init_zm_reg_sequence(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_ZM_REG_SEQUENCE opcode: 0x58 ('X') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): base register ++ * offset + 5 (8 bit): count ++ * offset + 6 (32 bit): value 1 ++ * ... ++ * ++ * Starting at offset + 6 there are "count" 32 bit values. ++ * For "count" iterations set "base register" + 4 * current_iteration ++ * to "value current_iteration" ++ */ ++ ++ uint32_t basereg = ROM32(bios->data[offset + 1]); ++ uint32_t count = bios->data[offset + 5]; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n", offset, basereg, count); ++ ++ for (i = 0; i < count; i++) { ++ uint32_t reg = basereg + i * 4; ++ uint32_t data = ROM32(bios->data[offset + 6 + i * 4]); ++ ++ bios_wr32(dev, reg, data); ++ } ++ ++ return true; ++} ++ ++static bool init_sub_direct(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_SUB_DIRECT opcode: 0x5B ('[') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): subroutine offset (in bios) ++ * ++ * Calls a subroutine that will execute commands until INIT_DONE ++ * is found. ++ */ ++ ++ uint16_t sub_offset = ROM16(bios->data[offset + 1]); ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Executing subroutine at 0x%04X\n", offset, sub_offset); ++ ++ parse_init_table(dev, bios, sub_offset, iexec); ++ ++ BIOSLOG(dev, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset); ++ ++ return true; ++} ++ ++static bool init_copy_nv_reg(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_COPY_NV_REG opcode: 0x5F ('_') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): src reg ++ * offset + 5 (8 bit): shift ++ * offset + 6 (32 bit): src mask ++ * offset + 10 (32 bit): xor ++ * offset + 14 (32 bit): dst reg ++ * offset + 18 (32 bit): dst mask ++ * ++ * Shift REGVAL("src reg") right by (signed) "shift", AND result with ++ * "src mask", then XOR with "xor". Write this OR'd with ++ * (REGVAL("dst reg") AND'd with "dst mask") to "dst reg" ++ */ ++ ++ uint32_t srcreg = *((uint32_t *)(&bios->data[offset + 1])); ++ uint8_t shift = bios->data[offset + 5]; ++ uint32_t srcmask = *((uint32_t *)(&bios->data[offset + 6])); ++ uint32_t xor = *((uint32_t *)(&bios->data[offset + 10])); ++ uint32_t dstreg = *((uint32_t *)(&bios->data[offset + 14])); ++ uint32_t dstmask = *((uint32_t *)(&bios->data[offset + 18])); ++ uint32_t srcvalue, dstvalue; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: SrcReg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%08X, Xor: 0x%08X, DstReg: 0x%08X, DstMask: 0x%08X\n", ++ offset, srcreg, shift, srcmask, xor, dstreg, dstmask); ++ ++ srcvalue = bios_rd32(dev, srcreg); ++ ++ if (shift < 0x80) ++ srcvalue >>= shift; ++ else ++ srcvalue <<= (0x100 - shift); ++ ++ srcvalue = (srcvalue & srcmask) ^ xor; ++ ++ dstvalue = bios_rd32(dev, dstreg) & dstmask; ++ ++ bios_wr32(dev, dstreg, dstvalue | srcvalue); ++ ++ return true; ++} ++ ++static bool init_zm_index_io(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_ZM_INDEX_IO opcode: 0x62 ('b') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): CRTC port ++ * offset + 3 (8 bit): CRTC index ++ * offset + 4 (8 bit): data ++ * ++ * Write "data" to index "CRTC index" of "CRTC port" ++ */ ++ uint16_t crtcport = ROM16(bios->data[offset + 1]); ++ uint8_t crtcindex = bios->data[offset + 3]; ++ uint8_t data = bios->data[offset + 4]; ++ ++ if (!iexec->execute) ++ return true; ++ ++ bios_idxprt_wr(dev, crtcport, crtcindex, data); ++ ++ return true; ++} ++ ++static bool init_compute_mem(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_COMPUTE_MEM opcode: 0x63 ('c') ++ * ++ * offset (8 bit): opcode ++ * ++ * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so ++ * that the hardware can correctly calculate how much VRAM it has ++ * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C)) ++ * ++ * The implementation of this opcode in general consists of two parts: ++ * 1) determination of the memory bus width ++ * 2) determination of how many of the card's RAM pads have ICs attached ++ * ++ * 1) is done by a cunning combination of writes to offsets 0x1c and ++ * 0x3c in the framebuffer, and seeing whether the written values are ++ * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0 ++ * ++ * 2) is done by a cunning combination of writes to an offset slightly ++ * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing ++ * if the test pattern can be read back. This then affects bits 12-15 of ++ * NV_PFB_CFG0 ++ * ++ * In this context a "cunning combination" may include multiple reads ++ * and writes to varying locations, often alternating the test pattern ++ * and 0, doubtless to make sure buffers are filled, residual charges ++ * on tracks are removed etc. ++ * ++ * Unfortunately, the "cunning combination"s mentioned above, and the ++ * changes to the bits in NV_PFB_CFG0 differ with nearly every bios ++ * trace I have. ++ * ++ * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which ++ * we started was correct, and use that instead ++ */ ++ ++ /* no iexec->execute check by design */ ++ ++ /* on every card I've seen, this step gets done for us earlier in the init scripts ++ uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01); ++ bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20); ++ */ ++ ++ /* this also has probably been done in the scripts, but an mmio trace of ++ * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write) ++ */ ++ bios_wr32(dev, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1); ++ ++ /* write back the saved configuration value */ ++ bios_wr32(dev, NV_PFB_CFG0, saved_nv_pfb_cfg0); ++ ++ return true; ++} ++ ++static bool init_reset(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_RESET opcode: 0x65 ('e') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): register ++ * offset + 5 (32 bit): value1 ++ * offset + 9 (32 bit): value2 ++ * ++ * Assign "value1" to "register", then assign "value2" to "register" ++ */ ++ ++ uint32_t reg = ROM32(bios->data[offset + 1]); ++ uint32_t value1 = ROM32(bios->data[offset + 5]); ++ uint32_t value2 = ROM32(bios->data[offset + 9]); ++ uint32_t pci_nv_19, pci_nv_20; ++ ++ /* no iexec->execute check by design */ ++ ++ pci_nv_19 = bios_rd32(dev, NV_PBUS_PCI_NV_19); ++ bios_wr32(dev, NV_PBUS_PCI_NV_19, 0); ++ bios_wr32(dev, reg, value1); ++ ++ BIOS_USLEEP(10); ++ ++ bios_wr32(dev, reg, value2); ++ bios_wr32(dev, NV_PBUS_PCI_NV_19, pci_nv_19); ++ ++ pci_nv_20 = bios_rd32(dev, NV_PBUS_PCI_NV_20); ++ pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED; /* 0xfffffffe */ ++ bios_wr32(dev, NV_PBUS_PCI_NV_20, pci_nv_20); ++ ++ return true; ++} ++ ++static bool init_configure_mem(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_CONFIGURE_MEM opcode: 0x66 ('f') ++ * ++ * offset (8 bit): opcode ++ * ++ * Equivalent to INIT_DONE on bios version 3 or greater. ++ * For early bios versions, sets up the memory registers, using values ++ * taken from the memory init table ++ */ ++ ++ /* no iexec->execute check by design */ ++ ++ uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(dev, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4); ++ uint16_t seqtbloffs = bios->legacy.sdr_seq_tbl_ptr, meminitdata = meminitoffs + 6; ++ uint32_t reg, data; ++ ++ if (bios->major_version > 2) ++ return false; ++ ++ bios_idxprt_wr(dev, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, ++ bios_idxprt_rd(dev, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); ++ ++ if (bios->data[meminitoffs] & 1) ++ seqtbloffs = bios->legacy.ddr_seq_tbl_ptr; ++ ++ for (reg = ROM32(bios->data[seqtbloffs]); ++ reg != 0xffffffff; ++ reg = ROM32(bios->data[seqtbloffs += 4])) { ++ ++ switch (reg) { ++ case NV_PFB_PRE: ++ data = NV_PFB_PRE_CMD_PRECHARGE; ++ break; ++ case NV_PFB_PAD: ++ data = NV_PFB_PAD_CKE_NORMAL; ++ break; ++ case NV_PFB_REF: ++ data = NV_PFB_REF_CMD_REFRESH; ++ break; ++ default: ++ data = ROM32(bios->data[meminitdata]); ++ meminitdata += 4; ++ if (data == 0xffffffff) ++ continue; ++ } ++ ++ bios_wr32(dev, reg, data); ++ } ++ ++ return true; ++} ++ ++static bool init_configure_clk(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_CONFIGURE_CLK opcode: 0x67 ('g') ++ * ++ * offset (8 bit): opcode ++ * ++ * Equivalent to INIT_DONE on bios version 3 or greater. ++ * For early bios versions, sets up the NVClk and MClk PLLs, using ++ * values taken from the memory init table ++ */ ++ ++ /* no iexec->execute check by design */ ++ ++ uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(dev, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4); ++ int clock; ++ ++ if (bios->major_version > 2) ++ return false; ++ ++ clock = ROM16(bios->data[meminitoffs + 4]) * 10; ++ setPLL(dev, bios, NV_PRAMDAC_NVPLL_COEFF, clock); ++ ++ clock = ROM16(bios->data[meminitoffs + 2]) * 10; ++ if (bios->data[meminitoffs] & 1) /* DDR */ ++ clock *= 2; ++ setPLL(dev, bios, NV_PRAMDAC_MPLL_COEFF, clock); ++ ++ return true; ++} ++ ++static bool init_configure_preinit(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_CONFIGURE_PREINIT opcode: 0x68 ('h') ++ * ++ * offset (8 bit): opcode ++ * ++ * Equivalent to INIT_DONE on bios version 3 or greater. ++ * For early bios versions, does early init, loading ram and crystal ++ * configuration from straps into CR3C ++ */ ++ ++ /* no iexec->execute check by design */ ++ ++ uint32_t straps = bios_rd32(dev, NV_PEXTDEV_BOOT_0); ++ uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); ++ ++ if (bios->major_version > 2) ++ return false; ++ ++ bios_idxprt_wr(dev, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX, cr3c); ++ ++ return true; ++} ++ ++static bool init_io(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_IO opcode: 0x69 ('i') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): CRTC port ++ * offset + 3 (8 bit): mask ++ * offset + 4 (8 bit): data ++ * ++ * Assign ((IOVAL("crtc port") & "mask") | "data") to "crtc port" ++ */ ++ ++ uint16_t crtcport = ROM16(bios->data[offset + 1]); ++ uint8_t mask = bios->data[offset + 3]; ++ uint8_t data = bios->data[offset + 4]; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n", ++ offset, crtcport, mask, data); ++ ++ bios_port_wr(dev, crtcport, (bios_port_rd(dev, crtcport) & mask) | data); ++ ++ return true; ++} ++ ++static bool init_sub(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_SUB opcode: 0x6B ('k') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): script number ++ * ++ * Execute script number "script number", as a subroutine ++ */ ++ ++ uint8_t sub = bios->data[offset + 1]; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Calling script %d\n", offset, sub); ++ ++ parse_init_table(dev, bios, ++ ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]), ++ iexec); ++ ++ BIOSLOG(dev, "0x%04X: End of script %d\n", offset, sub); ++ ++ return true; ++} ++ ++static bool init_ram_condition(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_RAM_CONDITION opcode: 0x6D ('m') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): mask ++ * offset + 2 (8 bit): cmpval ++ * ++ * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval". ++ * If condition not met skip subsequent opcodes until condition is ++ * inverted (INIT_NOT), or we hit INIT_RESUME ++ */ ++ ++ uint8_t mask = bios->data[offset + 1]; ++ uint8_t cmpval = bios->data[offset + 2]; ++ uint8_t data; ++ ++ if (!iexec->execute) ++ return true; ++ ++ data = bios_rd32(dev, NV_PFB_BOOT_0) & mask; ++ ++ BIOSLOG(dev, "0x%04X: Checking if 0x%08X equals 0x%08X\n", offset, data, cmpval); ++ ++ if (data == cmpval) ++ BIOSLOG(dev, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); ++ else { ++ BIOSLOG(dev, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool init_nv_reg(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_NV_REG opcode: 0x6E ('n') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): register ++ * offset + 5 (32 bit): mask ++ * offset + 9 (32 bit): data ++ * ++ * Assign ((REGVAL("register") & "mask") | "data") to "register" ++ */ ++ ++ uint32_t reg = ROM32(bios->data[offset + 1]); ++ uint32_t mask = ROM32(bios->data[offset + 5]); ++ uint32_t data = ROM32(bios->data[offset + 9]); ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n", offset, reg, mask, data); ++ ++ bios_wr32(dev, reg, (bios_rd32(dev, reg) & mask) | data); ++ ++ return true; ++} ++ ++static bool init_macro(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_MACRO opcode: 0x6F ('o') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): macro number ++ * ++ * Look up macro index "macro number" in the macro index table. ++ * The macro index table entry has 1 byte for the index in the macro table, ++ * and 1 byte for the number of times to repeat the macro. ++ * The macro table entry has 4 bytes for the register address and ++ * 4 bytes for the value to write to that register ++ */ ++ ++ uint8_t macro_index_tbl_idx = bios->data[offset + 1]; ++ uint16_t tmp = bios->macro_index_tbl_ptr + (macro_index_tbl_idx * MACRO_INDEX_SIZE); ++ uint8_t macro_tbl_idx = bios->data[tmp]; ++ uint8_t count = bios->data[tmp + 1]; ++ uint32_t reg, data; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, Count: 0x%02X\n", ++ offset, macro_index_tbl_idx, macro_tbl_idx, count); ++ ++ for (i = 0; i < count; i++) { ++ uint16_t macroentryptr = bios->macro_tbl_ptr + (macro_tbl_idx + i) * MACRO_SIZE; ++ ++ reg = ROM32(bios->data[macroentryptr]); ++ data = ROM32(bios->data[macroentryptr + 4]); ++ ++ bios_wr32(dev, reg, data); ++ } ++ ++ return true; ++} ++ ++static bool init_done(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_DONE opcode: 0x71 ('q') ++ * ++ * offset (8 bit): opcode ++ * ++ * End the current script ++ */ ++ ++ /* mild retval abuse to stop parsing this table */ ++ return false; ++} ++ ++static bool init_resume(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_RESUME opcode: 0x72 ('r') ++ * ++ * offset (8 bit): opcode ++ * ++ * End the current execute / no-execute condition ++ */ ++ ++ if (iexec->execute) ++ return true; ++ ++ iexec->execute = true; ++ BIOSLOG(dev, "0x%04X: ---- Executing following commands ----\n", offset); ++ ++ return true; ++} ++ ++static bool init_time(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_TIME opcode: 0x74 ('t') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): time ++ * ++ * Sleep for "time" microseconds. ++ */ ++ ++ uint16_t time = ROM16(bios->data[offset + 1]); ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Sleeping for 0x%04X microseconds\n", offset, time); ++ ++ BIOS_USLEEP(time); ++ ++ return true; ++} ++ ++static bool init_condition(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_CONDITION opcode: 0x75 ('u') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): condition number ++ * ++ * Check condition "condition number" in the condition table. ++ * If condition not met skip subsequent opcodes until condition is ++ * inverted (INIT_NOT), or we hit INIT_RESUME ++ */ ++ ++ uint8_t cond = bios->data[offset + 1]; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Condition: 0x%02X\n", offset, cond); ++ ++ if (bios_condition_met(dev, bios, offset, cond)) ++ BIOSLOG(dev, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); ++ else { ++ BIOSLOG(dev, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool init_io_condition(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_IO_CONDITION opcode: 0x76 ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): condition number ++ * ++ * Check condition "condition number" in the io condition table. ++ * If condition not met skip subsequent opcodes until condition is ++ * inverted (INIT_NOT), or we hit INIT_RESUME ++ */ ++ ++ uint8_t cond = bios->data[offset + 1]; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: IO condition: 0x%02X\n", offset, cond); ++ ++ if (io_condition_met(dev, bios, offset, cond)) ++ BIOSLOG(dev, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); ++ else { ++ BIOSLOG(dev, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool init_index_io(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_INDEX_IO opcode: 0x78 ('x') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): CRTC port ++ * offset + 3 (8 bit): CRTC index ++ * offset + 4 (8 bit): mask ++ * offset + 5 (8 bit): data ++ * ++ * Read value at index "CRTC index" on "CRTC port", AND with "mask", OR with "data", write-back ++ */ ++ ++ uint16_t crtcport = ROM16(bios->data[offset + 1]); ++ uint8_t crtcindex = bios->data[offset + 3]; ++ uint8_t mask = bios->data[offset + 4]; ++ uint8_t data = bios->data[offset + 5]; ++ uint8_t value; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", ++ offset, crtcport, crtcindex, mask, data); ++ ++ value = (bios_idxprt_rd(dev, crtcport, crtcindex) & mask) | data; ++ bios_idxprt_wr(dev, crtcport, crtcindex, value); ++ ++ return true; ++} ++ ++static bool init_pll(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_PLL opcode: 0x79 ('y') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): register ++ * offset + 5 (16 bit): freq ++ * ++ * Set PLL register "register" to coefficients for frequency (10kHz) "freq" ++ */ ++ ++ uint32_t reg = ROM32(bios->data[offset + 1]); ++ uint16_t freq = ROM16(bios->data[offset + 5]); ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(dev, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq); ++ ++ setPLL(dev, bios, reg, freq * 10); ++ ++ return true; ++} ++ ++static bool init_zm_reg(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_ZM_REG opcode: 0x7A ('z') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): register ++ * offset + 5 (32 bit): value ++ * ++ * Assign "value" to "register" ++ */ ++ ++ uint32_t reg = ROM32(bios->data[offset + 1]); ++ uint32_t value = ROM32(bios->data[offset + 5]); ++ ++ if (!iexec->execute) ++ return true; ++ ++ bios_wr32(dev, reg, value); ++ ++ return true; ++} ++ ++static bool init_8e(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_8E opcode: 0x8E ('') ++ * ++ * offset (8 bit): opcode ++ * ++ * The purpose of this opcode is unclear (being for nv50 cards), and ++ * the literal functionality can be seen in the code below. ++ * ++ * A brief synopsis is that for each entry in a table pointed to by the ++ * DCB table header, depending on the settings of various bits, various ++ * other bits in registers 0xe100, 0xe104, and 0xe108, are set or ++ * cleared. ++ */ ++ ++ uint8_t headerlen = bios->data[bios->bdcb.init8e_table_ptr + 1]; ++ uint8_t entries = bios->data[bios->bdcb.init8e_table_ptr + 2]; ++ uint8_t recordlen = bios->data[bios->bdcb.init8e_table_ptr + 3]; ++ int i; ++ ++ if (bios->bdcb.version != 0x40) { ++ NV_ERROR(dev, "DCB table not version 4.0\n"); ++ return false; ++ } ++ if (!bios->bdcb.init8e_table_ptr) { ++ NV_WARN(dev, "Invalid pointer to INIT_8E table\n"); ++ return false; ++ } ++ ++ for (i = 0; i < entries; i++) { ++ uint32_t entry = ROM32(bios->data[bios->bdcb.init8e_table_ptr + headerlen + recordlen * i]); ++ int shift = (entry & 0x1f) * 4; ++ uint32_t mask; ++ uint32_t reg = 0xe104; ++ uint32_t data; ++ ++ if ((entry & 0xff00) == 0xff00) ++ continue; ++ ++ if (shift >= 32) { ++ reg += 4; ++ shift -= 32; ++ } ++ shift %= 32; ++ ++ mask = ~(3 << shift); ++ if (entry & (1 << 24)) ++ data = (entry >> 21); ++ else ++ data = (entry >> 19); ++ data = ((data & 3) ^ 2) << shift; ++ ++ BIOSLOG(dev, "0x%04X: Entry: 0x%08X, Reg: 0x%08X, Shift: 0x%02X, Mask: 0x%08X, Data: 0x%08X\n", ++ offset, entry, reg, shift, mask, data); ++ ++ bios_wr32(dev, reg, (bios_rd32(dev, reg) & mask) | data); ++ ++ reg = 0xe100; ++ shift = entry & 0x1f; ++ ++ mask = ~(1 << 16 | 1); ++ mask = mask << shift | mask >> (32 - shift); ++ data = 0; ++ if ((entry & (3 << 25)) == (1 << 25)) ++ data |= 1; ++ if ((entry & (3 << 25)) == (2 << 25)) ++ data |= 0x10000; ++ data <<= shift; ++ ++ BIOSLOG(dev, "0x%04X: Entry: 0x%08X, Reg: 0x%08X, Shift: 0x%02X, Mask: 0x%08X, Data: 0x%08X\n", ++ offset, entry, reg, shift, mask, data); ++ ++ bios_wr32(dev, reg, (bios_rd32(dev, reg) & mask) | data); ++ } ++ ++ return true; ++} ++ ++/* hack to avoid moving the itbl_entry array before this function */ ++int init_ram_restrict_zm_reg_group_blocklen = 0; ++ ++static bool init_ram_restrict_zm_reg_group(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_RAM_RESTRICT_ZM_REG_GROUP opcode: 0x8F ('') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): reg ++ * offset + 5 (8 bit): regincrement ++ * offset + 6 (8 bit): count ++ * offset + 7 (32 bit): value 1,1 ++ * ... ++ * ++ * Use the RAMCFG strap of PEXTDEV_BOOT as an index into the table at ++ * ram_restrict_table_ptr. The value read from here is 'n', and ++ * "value 1,n" gets written to "reg". This repeats "count" times and on ++ * each iteration 'm', "reg" increases by "regincrement" and ++ * "value m,n" is used. The extent of n is limited by a number read ++ * from the 'M' BIT table, herein called "blocklen" ++ */ ++ ++ uint32_t reg = ROM32(bios->data[offset + 1]); ++ uint8_t regincrement = bios->data[offset + 5]; ++ uint8_t count = bios->data[offset + 6]; ++ uint32_t strap_ramcfg, data; ++ uint16_t blocklen; ++ uint8_t index; ++ int i; ++ ++ /* previously set by 'M' BIT table */ ++ blocklen = init_ram_restrict_zm_reg_group_blocklen; ++ ++ if (!iexec->execute) ++ return true; ++ ++ if (!blocklen) { ++ NV_ERROR(dev, "0x%04X: Zero block length - has the M table " ++ "been parsed?\n", offset); ++ return false; ++ } ++ ++ strap_ramcfg = (bios_rd32(dev, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; ++ index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg]; ++ ++ BIOSLOG(dev, "0x%04X: Reg: 0x%08X, RegIncrement: 0x%02X, Count: 0x%02X, StrapRamCfg: 0x%02X, Index: 0x%02X\n", ++ offset, reg, regincrement, count, strap_ramcfg, index); ++ ++ for (i = 0; i < count; i++) { ++ data = ROM32(bios->data[offset + 7 + index * 4 + blocklen * i]); ++ ++ bios_wr32(dev, reg, data); ++ ++ reg += regincrement; ++ } ++ ++ return true; ++} ++ ++static bool init_copy_zm_reg(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_COPY_ZM_REG opcode: 0x90 ('') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): src reg ++ * offset + 5 (32 bit): dst reg ++ * ++ * Put contents of "src reg" into "dst reg" ++ */ ++ ++ uint32_t srcreg = ROM32(bios->data[offset + 1]); ++ uint32_t dstreg = ROM32(bios->data[offset + 5]); ++ ++ if (!iexec->execute) ++ return true; ++ ++ bios_wr32(dev, dstreg, bios_rd32(dev, srcreg)); ++ ++ return true; ++} ++ ++static bool init_zm_reg_group_addr_latched(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_ZM_REG_GROUP_ADDRESS_LATCHED opcode: 0x91 ('') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): dst reg ++ * offset + 5 (8 bit): count ++ * offset + 6 (32 bit): data 1 ++ * ... ++ * ++ * For each of "count" values write "data n" to "dst reg" ++ */ ++ ++ uint32_t reg = ROM32(bios->data[offset + 1]); ++ uint8_t count = bios->data[offset + 5]; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ for (i = 0; i < count; i++) { ++ uint32_t data = ROM32(bios->data[offset + 6 + 4 * i]); ++ bios_wr32(dev, reg, data); ++ } ++ ++ return true; ++} ++ ++static bool init_reserved(struct drm_device *dev, struct nvbios *bios, uint16_t offset, init_exec_t *iexec) ++{ ++ /* INIT_RESERVED opcode: 0x92 ('') ++ * ++ * offset (8 bit): opcode ++ * ++ * Seemingly does nothing ++ */ ++ ++ return true; ++} ++ ++static init_tbl_entry_t itbl_entry[] = { ++ /* command name , id , length , offset , mult , command handler */ ++ /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */ ++ { "INIT_IO_RESTRICT_PROG" , 0x32, 11 , 6 , 4 , init_io_restrict_prog }, ++ { "INIT_REPEAT" , 0x33, 2 , 0 , 0 , init_repeat }, ++ { "INIT_IO_RESTRICT_PLL" , 0x34, 12 , 7 , 2 , init_io_restrict_pll }, ++ { "INIT_END_REPEAT" , 0x36, 1 , 0 , 0 , init_end_repeat }, ++ { "INIT_COPY" , 0x37, 11 , 0 , 0 , init_copy }, ++ { "INIT_NOT" , 0x38, 1 , 0 , 0 , init_not }, ++ { "INIT_IO_FLAG_CONDITION" , 0x39, 2 , 0 , 0 , init_io_flag_condition }, ++ { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, 18 , 17 , 2 , init_idx_addr_latched }, ++ { "INIT_IO_RESTRICT_PLL2" , 0x4A, 11 , 6 , 4 , init_io_restrict_pll2 }, ++ { "INIT_PLL2" , 0x4B, 9 , 0 , 0 , init_pll2 }, ++ { "INIT_I2C_BYTE" , 0x4C, 4 , 3 , 3 , init_i2c_byte }, ++ { "INIT_ZM_I2C_BYTE" , 0x4D, 4 , 3 , 2 , init_zm_i2c_byte }, ++ { "INIT_ZM_I2C" , 0x4E, 4 , 3 , 1 , init_zm_i2c }, ++ { "INIT_TMDS" , 0x4F, 5 , 0 , 0 , init_tmds }, ++ { "INIT_ZM_TMDS_GROUP" , 0x50, 3 , 2 , 2 , init_zm_tmds_group }, ++ { "INIT_CR_INDEX_ADDRESS_LATCHED" , 0x51, 5 , 4 , 1 , init_cr_idx_adr_latch }, ++ { "INIT_CR" , 0x52, 4 , 0 , 0 , init_cr }, ++ { "INIT_ZM_CR" , 0x53, 3 , 0 , 0 , init_zm_cr }, ++ { "INIT_ZM_CR_GROUP" , 0x54, 2 , 1 , 2 , init_zm_cr_group }, ++ { "INIT_CONDITION_TIME" , 0x56, 3 , 0 , 0 , init_condition_time }, ++ { "INIT_ZM_REG_SEQUENCE" , 0x58, 6 , 5 , 4 , init_zm_reg_sequence }, ++ /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ ++ { "INIT_SUB_DIRECT" , 0x5B, 3 , 0 , 0 , init_sub_direct }, ++ { "INIT_COPY_NV_REG" , 0x5F, 22 , 0 , 0 , init_copy_nv_reg }, ++ { "INIT_ZM_INDEX_IO" , 0x62, 5 , 0 , 0 , init_zm_index_io }, ++ { "INIT_COMPUTE_MEM" , 0x63, 1 , 0 , 0 , init_compute_mem }, ++ { "INIT_RESET" , 0x65, 13 , 0 , 0 , init_reset }, ++ { "INIT_CONFIGURE_MEM" , 0x66, 1 , 0 , 0 , init_configure_mem }, ++ { "INIT_CONFIGURE_CLK" , 0x67, 1 , 0 , 0 , init_configure_clk }, ++ { "INIT_CONFIGURE_PREINIT" , 0x68, 1 , 0 , 0 , init_configure_preinit }, ++ { "INIT_IO" , 0x69, 5 , 0 , 0 , init_io }, ++ { "INIT_SUB" , 0x6B, 2 , 0 , 0 , init_sub }, ++ { "INIT_RAM_CONDITION" , 0x6D, 3 , 0 , 0 , init_ram_condition }, ++ { "INIT_NV_REG" , 0x6E, 13 , 0 , 0 , init_nv_reg }, ++ { "INIT_MACRO" , 0x6F, 2 , 0 , 0 , init_macro }, ++ { "INIT_DONE" , 0x71, 1 , 0 , 0 , init_done }, ++ { "INIT_RESUME" , 0x72, 1 , 0 , 0 , init_resume }, ++ /* INIT_RAM_CONDITION2 (0x73, 9, 0, 0) removed due to no example of use */ ++ { "INIT_TIME" , 0x74, 3 , 0 , 0 , init_time }, ++ { "INIT_CONDITION" , 0x75, 2 , 0 , 0 , init_condition }, ++ { "INIT_IO_CONDITION" , 0x76, 2 , 0 , 0 , init_io_condition }, ++ { "INIT_INDEX_IO" , 0x78, 6 , 0 , 0 , init_index_io }, ++ { "INIT_PLL" , 0x79, 7 , 0 , 0 , init_pll }, ++ { "INIT_ZM_REG" , 0x7A, 9 , 0 , 0 , init_zm_reg }, ++ { "INIT_8E" , 0x8E, 1 , 0 , 0 , init_8e }, ++ /* INIT_RAM_RESTRICT_ZM_REG_GROUP's mult is loaded by M table in BIT */ ++ { "INIT_RAM_RESTRICT_ZM_REG_GROUP" , 0x8F, 7 , 6 , 0 , init_ram_restrict_zm_reg_group }, ++ { "INIT_COPY_ZM_REG" , 0x90, 9 , 0 , 0 , init_copy_zm_reg }, ++ { "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, 6 , 5 , 4 , init_zm_reg_group_addr_latched }, ++ { "INIT_RESERVED" , 0x92, 1 , 0 , 0 , init_reserved }, ++ { 0 , 0 , 0 , 0 , 0 , 0 } ++}; ++ ++static unsigned int get_init_table_entry_length(struct nvbios *bios, unsigned int offset, int i) ++{ ++ /* Calculates the length of a given init table entry. */ ++ return itbl_entry[i].length + bios->data[offset + itbl_entry[i].length_offset]*itbl_entry[i].length_multiplier; ++} ++ ++#define MAX_TABLE_OPS 1000 ++ ++static int parse_init_table(struct drm_device *dev, struct nvbios *bios, unsigned int offset, init_exec_t *iexec) ++{ ++ /* Parses all commands in an init table. ++ * ++ * We start out executing all commands found in the init table. Some ++ * opcodes may change the status of iexec->execute to SKIP, which will ++ * cause the following opcodes to perform no operation until the value ++ * is changed back to EXECUTE. ++ */ ++ ++ int count = 0, i; ++ uint8_t id; ++ ++ /* Loop until INIT_DONE causes us to break out of the loop ++ * (or until offset > bios length just in case... ) ++ * (and no more than MAX_TABLE_OPS iterations, just in case... ) */ ++ while ((offset < bios->length) && (count++ < MAX_TABLE_OPS)) { ++ id = bios->data[offset]; ++ ++ /* Find matching id in itbl_entry */ ++ for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != id); i++) ++ ; ++ ++ if (itbl_entry[i].name) { ++ BIOSLOG(dev, "0x%04X: [ (0x%02X) - %s ]\n", ++ offset, itbl_entry[i].id, itbl_entry[i].name); ++ ++ /* execute eventual command handler */ ++ if (itbl_entry[i].handler) ++ if (!(*itbl_entry[i].handler)(dev, bios, offset, iexec)) ++ break; ++ } else { ++ NV_ERROR(dev, "0x%04X: Init table command not found: " ++ "0x%02X\n", offset, id); ++ return -ENOENT; ++ } ++ ++ /* Add the offset of the current command including all data ++ * of that command. The offset will then be pointing on the ++ * next op code. ++ */ ++ offset += get_init_table_entry_length(bios, offset, i); ++ } ++ ++ if (offset >= bios->length) ++ NV_WARN(dev, ++ "Offset 0x%04X greater than known bios image length. " ++ "Corrupt image?\n", offset); ++ if (count >= MAX_TABLE_OPS) ++ NV_WARN(dev, "More than %d opcodes to a table is unlikely, " ++ "is the bios image corrupt?\n", MAX_TABLE_OPS); ++ ++ return 0; ++} ++ ++static void parse_init_tables(struct drm_device *dev, struct nvbios *bios) ++{ ++ /* Loops and calls parse_init_table() for each present table. */ ++ ++ int i = 0; ++ uint16_t table; ++ init_exec_t iexec = {true, false}; ++ ++ if (bios->old_style_init) { ++ if (bios->init_script_tbls_ptr) ++ parse_init_table(dev, bios, bios->init_script_tbls_ptr, &iexec); ++ if (bios->extra_init_script_tbl_ptr) ++ parse_init_table(dev, bios, bios->extra_init_script_tbl_ptr, &iexec); ++ ++ return; ++ } ++ ++ while ((table = ROM16(bios->data[bios->init_script_tbls_ptr + i]))) { ++ NV_INFO(dev, "Parsing VBIOS init table %d at offset 0x%04X\n", ++ i / 2, table); ++ BIOSLOG(dev, "0x%04X: ------ Executing following commands ------\n", table); ++ ++ parse_init_table(dev, bios, table, &iexec); ++ i += 2; ++ } ++} ++ ++static void link_head_and_output(struct drm_device *dev, struct dcb_entry *dcbent, int head, bool dl) ++{ ++ /* The BIOS scripts don't do this for us, sadly ++ * Luckily we do know the values ;-) ++ * ++ * head < 0 indicates we wish to force a setting with the overrideval ++ * (for VT restore etc.) ++ */ ++ ++ int ramdac = (dcbent->or & OUTPUT_C) >> 2; ++ uint8_t tmds04 = 0x80; ++ ++ if (head != ramdac) ++ tmds04 = 0x88; ++ ++ if (dcbent->type == OUTPUT_LVDS) ++ tmds04 |= 0x01; ++ ++ nv_write_tmds(dev, dcbent->or, 0, 0x04, tmds04); ++ ++ if (dl) /* dual link */ ++ nv_write_tmds(dev, dcbent->or, 1, 0x04, tmds04 ^ 0x08); ++} ++ ++static uint16_t clkcmptable(struct nvbios *bios, uint16_t clktable, int pxclk) ++{ ++ int compare_record_len, i = 0; ++ uint16_t compareclk, scriptptr = 0; ++ ++ if (bios->major_version < 5) /* pre BIT */ ++ compare_record_len = 3; ++ else ++ compare_record_len = 4; ++ ++ do { ++ compareclk = ROM16(bios->data[clktable + compare_record_len * i]); ++ if (pxclk >= compareclk * 10) { ++ if (bios->major_version < 5) { ++ uint8_t tmdssub = bios->data[clktable + 2 + compare_record_len * i]; ++ scriptptr = ROM16(bios->data[bios->init_script_tbls_ptr + tmdssub * 2]); ++ } else ++ scriptptr = ROM16(bios->data[clktable + 2 + compare_record_len * i]); ++ break; ++ } ++ i++; ++ } while (compareclk); ++ ++ return scriptptr; ++} ++ ++static void run_digital_op_script(struct drm_device *dev, uint16_t scriptptr, struct dcb_entry *dcbent, int head, bool dl) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ init_exec_t iexec = {true, false}; ++ ++ NV_TRACE(dev, "0x%04X: Parsing digital output script table\n", ++ scriptptr); ++ bios_idxprt_wr(dev, NV_CIO_CRX__COLOR, NV_CIO_CRE_44, ++ head ? NV_CIO_CRE_44_HEADB : NV_CIO_CRE_44_HEADA); ++ /* note: if dcb entries have been merged, index may be misleading */ ++ NVWriteVgaCrtc5758(dev, head, 0, dcbent->index); ++ parse_init_table(dev, bios, scriptptr, &iexec); ++ ++ link_head_and_output(dev, dcbent, head, dl); ++} ++ ++static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & OUTPUT_C ? 1 : 0); ++ uint16_t scriptofs = ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]); ++ ++ if (!bios->fp.xlated_entry || !sub || !scriptofs) ++ return -EINVAL; ++ ++ run_digital_op_script(dev, scriptofs, dcbent, head, bios->fp.dual_link); ++ ++ if (script == LVDS_PANEL_OFF) ++ /* off-on delay in ms */ ++ BIOS_USLEEP(ROM16(bios->data[bios->fp.xlated_entry + 7])); ++#ifdef __powerpc__ ++ /* Powerbook specific quirks */ ++ if (script == LVDS_RESET && ((dev->pci_device & 0xffff) == 0x0179 || (dev->pci_device & 0xffff) == 0x0329)) ++ nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); ++ if ((dev->pci_device & 0xffff) == 0x0179 || (dev->pci_device & 0xffff) == 0x0189 || (dev->pci_device & 0xffff) == 0x0329) { ++ if (script == LVDS_PANEL_ON) { ++ bios_wr32(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, bios_rd32(dev, NV_PBUS_DEBUG_DUALHEAD_CTL) | (1 << 31)); ++ bios_wr32(dev, NV_PCRTC_GPIO_EXT, bios_rd32(dev, NV_PCRTC_GPIO_EXT) | 1); ++ } ++ if (script == LVDS_PANEL_OFF) { ++ bios_wr32(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, bios_rd32(dev, NV_PBUS_DEBUG_DUALHEAD_CTL) & ~(1 << 31)); ++ bios_wr32(dev, NV_PCRTC_GPIO_EXT, bios_rd32(dev, NV_PCRTC_GPIO_EXT) & ~3); ++ } ++ } ++#endif ++ ++ return 0; ++} ++ ++static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk) ++{ ++ /* The BIT LVDS table's header has the information to setup the ++ * necessary registers. Following the standard 4 byte header are: ++ * A bitmask byte and a dual-link transition pxclk value for use in ++ * selecting the init script when not using straps; 4 script pointers ++ * for panel power, selected by output and on/off; and 8 table pointers ++ * for panel init, the needed one determined by output, and bits in the ++ * conf byte. These tables are similar to the TMDS tables, consisting ++ * of a list of pxclks and script pointers. ++ */ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ unsigned int outputset = (dcbent->or == 4) ? 1 : 0; ++ uint16_t scriptptr = 0, clktable; ++ uint8_t clktableptr = 0; ++ ++ /* for now we assume version 3.0 table - g80 support will need some changes */ ++ ++ switch (script) { ++ case LVDS_INIT: ++ return -ENOSYS; ++ case LVDS_BACKLIGHT_ON: ++ case LVDS_PANEL_ON: ++ scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 7 + outputset * 2]); ++ break; ++ case LVDS_BACKLIGHT_OFF: ++ case LVDS_PANEL_OFF: ++ scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]); ++ break; ++ case LVDS_RESET: ++ if (dcbent->lvdsconf.use_straps_for_mode) { ++ if (bios->fp.dual_link) ++ clktableptr += 2; ++ if (bios->fp.BITbit1) ++ clktableptr++; ++ } else { ++ /* using EDID */ ++ uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; ++ int fallbackcmpval = (dcbent->or == 4) ? 4 : 1; ++ ++ if (bios->fp.dual_link) { ++ clktableptr += 2; ++ fallbackcmpval *= 2; ++ } ++ if (fallbackcmpval & fallback) ++ clktableptr++; ++ } ++ ++ /* adding outputset * 8 may not be correct */ ++ clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]); ++ if (!clktable) { ++ NV_ERROR(dev, "Pixel clock comparison table not found\n"); ++ return -ENOENT; ++ } ++ scriptptr = clkcmptable(bios, clktable, pxclk); ++ } ++ ++ if (!scriptptr) { ++ NV_ERROR(dev, "LVDS output init script not found\n"); ++ return -ENOENT; ++ } ++ run_digital_op_script(dev, scriptptr, dcbent, head, bios->fp.dual_link); ++ ++ return 0; ++} ++ ++int call_lvds_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk) ++{ ++ /* LVDS operations are multiplexed in an effort to present a single API ++ * which works with two vastly differing underlying structures. ++ * This acts as the demux ++ */ ++ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer]; ++ uint32_t sel_clk_binding, sel_clk; ++ int ret; ++ ++ if (bios->fp.last_script_invoc == (script << 1 | head) || !lvds_ver || ++ (lvds_ver >= 0x30 && script == LVDS_INIT)) ++ return 0; ++ ++ if (!bios->fp.lvds_init_run) { ++ bios->fp.lvds_init_run = true; ++ call_lvds_script(dev, dcbent, head, LVDS_INIT, pxclk); ++ } ++ ++ if (script == LVDS_PANEL_ON && bios->fp.reset_after_pclk_change) ++ call_lvds_script(dev, dcbent, head, LVDS_RESET, pxclk); ++ if (script == LVDS_RESET && bios->fp.power_off_for_reset) ++ call_lvds_script(dev, dcbent, head, LVDS_PANEL_OFF, pxclk); ++ ++ NV_TRACE(dev, "Calling LVDS script %d:\n", script); ++ ++ /* don't let script change pll->head binding */ ++ sel_clk_binding = bios_rd32(dev, NV_PRAMDAC_SEL_CLK) & 0x50000; ++ ++ if (lvds_ver < 0x30) ++ ret = call_lvds_manufacturer_script(dev, dcbent, head, script); ++ else ++ ret = run_lvds_table(dev, dcbent, head, script, pxclk); ++ ++ bios->fp.last_script_invoc = (script << 1 | head); ++ ++ sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000; ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding); ++ /* some scripts set a value in NV_PBUS_POWERCTRL_2 and break video overlay */ ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0); ++ ++ return ret; ++} ++ ++struct lvdstableheader { ++ uint8_t lvds_ver, headerlen, recordlen; ++}; ++ ++static int parse_lvds_manufacturer_table_header(struct drm_device *dev, struct nvbios *bios, struct lvdstableheader *lth) ++{ ++ /* BMP version (0xa) LVDS table has a simple header of version and ++ * record length. The BIT LVDS table has the typical BIT table header: ++ * version byte, header length byte, record length byte, and a byte for ++ * the maximum number of records that can be held in the table */ ++ ++ uint8_t lvds_ver, headerlen, recordlen; ++ ++ memset(lth, 0, sizeof(struct lvdstableheader)); ++ ++ if (bios->fp.lvdsmanufacturerpointer == 0x0) { ++ NV_ERROR(dev, "Pointer to LVDS manufacturer table invalid\n"); ++ return -EINVAL; ++ } ++ ++ lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer]; ++ ++ switch (lvds_ver) { ++ case 0x0a: /* pre NV40 */ ++ headerlen = 2; ++ recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1]; ++ break; ++ case 0x30: /* NV4x */ ++ headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1]; ++ if (headerlen < 0x1f) { ++ NV_ERROR(dev, "LVDS table header not understood\n"); ++ return -EINVAL; ++ } ++ recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2]; ++ break; ++ case 0x40: /* G80/G90 */ ++ headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1]; ++ if (headerlen < 0x7) { ++ NV_ERROR(dev, "LVDS table header not understood\n"); ++ return -EINVAL; ++ } ++ recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2]; ++ break; ++ default: ++ NV_ERROR(dev, ++ "LVDS table revision %d.%d not currently supported\n", ++ lvds_ver >> 4, lvds_ver & 0xf); ++ return -ENOSYS; ++ } ++ ++ lth->lvds_ver = lvds_ver; ++ lth->headerlen = headerlen; ++ lth->recordlen = recordlen; ++ ++ return 0; ++} ++ ++static int get_fp_strap(struct drm_device *dev, struct nvbios *bios) ++{ ++ /* the fp strap is normally dictated by the "User Strap" in ++ * PEXTDEV_BOOT_0[20:16], but on BMP cards when bit 2 of the ++ * Internal_Flags struct at 0x48 is set, the user strap gets overriden ++ * by the PCI subsystem ID during POST, but not before the previous user ++ * strap has been committed to CR58 for CR57=0xf on head A, which may be ++ * read and used instead ++ */ ++ ++ if (bios->major_version < 5 && bios->data[0x48] & 0x4) ++ return (NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf); ++ ++ return ((bios_rd32(dev, NV_PEXTDEV_BOOT_0) >> 16) & 0xf); ++} ++ ++static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios) ++{ ++ uint8_t *fptable; ++ uint8_t fptable_ver, headerlen = 0, recordlen, fpentries = 0xf, fpindex; ++ int ret, ofs, fpstrapping; ++ struct lvdstableheader lth; ++ ++ if (bios->fp.fptablepointer == 0x0) { ++ /* Apple cards don't have the fp table; the laptops use DDC */ ++#ifndef __powerpc__ ++ NV_ERROR(dev, "Pointer to flat panel table invalid\n"); ++ if (bios->pub.chip_version != 0x67) /* sigh, IGPs */ ++ return -EINVAL; ++#endif ++ bios->pub.digital_min_front_porch = 0x4b; ++ return 0; ++ } ++ ++ fptable = &bios->data[bios->fp.fptablepointer]; ++ fptable_ver = fptable[0]; ++ ++ switch (fptable_ver) { ++ /* BMP version 0x5.0x11 BIOSen have version 1 like tables, but no version field, ++ * and miss one of the spread spectrum/PWM bytes. ++ * This could affect early GF2Go parts (not seen any appropriate ROMs though). ++ * Here we assume that a version of 0x05 matches this case (combining with a ++ * BMP version check would be better), as the common case for the panel type ++ * field is 0x0005, and that is in fact what we are reading the first byte of. */ ++ case 0x05: /* some NV10, 11, 15, 16 */ ++ recordlen = 42; ++ ofs = -1; ++ break; ++ case 0x10: /* some NV15/16, and NV11+ */ ++ recordlen = 44; ++ ofs = 0; ++ break; ++ case 0x20: /* NV40+ */ ++ headerlen = fptable[1]; ++ recordlen = fptable[2]; ++ fpentries = fptable[3]; ++ /* fptable[4] is the minimum RAMDAC_FP_HCRTC->RAMDAC_FP_HSYNC_START gap */ ++ bios->pub.digital_min_front_porch = fptable[4]; ++ ofs = -7; ++ break; ++ default: ++ NV_ERROR(dev, ++ "FP table revision %d.%d not currently supported\n", ++ fptable_ver >> 4, fptable_ver & 0xf); ++ return -ENOSYS; ++ } ++ ++ if (!bios->is_mobile) /* !mobile only needs digital_min_front_porch */ ++ return 0; ++ ++ if ((ret = parse_lvds_manufacturer_table_header(dev, bios, <h))) ++ return ret; ++ ++ if (lth.lvds_ver == 0x30 || lth.lvds_ver == 0x40) { ++ bios->fp.fpxlatetableptr = bios->fp.lvdsmanufacturerpointer + lth.headerlen + 1; ++ bios->fp.xlatwidth = lth.recordlen; ++ } ++ if (bios->fp.fpxlatetableptr == 0x0) { ++ NV_ERROR(dev, "Pointer to flat panel xlat table invalid\n"); ++ return -EINVAL; ++ } ++ ++ fpstrapping = get_fp_strap(dev, bios); ++ ++ if (lth.lvds_ver == 0x40) { ++ /* Query all modes and find one with a matching clock. */ ++ /* Note that this only serves as a backup solution if ddc fails. */ ++ ++ uint32_t clock, needed_clock; ++ int i, index = 0xf, matches = 0; ++ needed_clock = bios_rd32(dev, 0x00616404) & 0xFFFFF; ++ NV_TRACE(dev, "LVDS clock seems to be %d KHz.\n", needed_clock); ++ ++ for (i = 0; i < fpentries; i++) { ++ clock = ROM16(fptable[headerlen + recordlen * i]) * 10; ++ if (clock == needed_clock) { ++ matches++; ++ index = i; ++ } ++ } ++ ++ if (matches == 1) ++ NV_TRACE(dev, "Found a mode with matching clock\n"); ++ else ++ NV_TRACE(dev, "Found %d modes, this is not useful\n", matches); ++ ++ if (matches != 1) ++ index = 0xF; ++ ++ fpindex = bios->data[bios->fp.fpxlatetableptr + index * bios->fp.xlatwidth]; ++ /* strapping only set as a hack for DDC test below */ ++ fpstrapping = fpindex & 0xf; ++ } else ++ fpindex = bios->data[bios->fp.fpxlatetableptr + fpstrapping * bios->fp.xlatwidth]; ++ ++ if (fpindex > fpentries) { ++ NV_ERROR(dev, "Bad flat panel table index\n"); ++ return -ENOENT; ++ } ++ ++ /* nv4x cards need both a strap value and fpindex of 0xf to use DDC */ ++ if (lth.lvds_ver > 0x10) ++ bios->pub.fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf; ++ ++ /* if either the strap or xlated fpindex value are 0xf there is no ++ * panel using a strap-derived bios mode present. this condition ++ * includes, but is different from, the DDC panel indicator above ++ */ ++ if (fpstrapping == 0xf || fpindex == 0xf) ++ return 0; ++ ++ bios->fp.mode_ptr = bios->fp.fptablepointer + headerlen + ++ recordlen * fpindex + ofs; ++ ++ NV_TRACE(dev, "BIOS FP mode: %dx%d (%dkHz pixel clock)\n", ++ ROM16(bios->data[bios->fp.mode_ptr + 11]) + 1, ++ ROM16(bios->data[bios->fp.mode_ptr + 25]) + 1, ++ ROM16(bios->data[bios->fp.mode_ptr + 7]) * 10); ++ ++ return 0; ++} ++ ++bool nouveau_bios_fp_mode(struct drm_device *dev, struct drm_display_mode *mode) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ uint8_t *mode_entry = &bios->data[bios->fp.mode_ptr]; ++ ++ if (!mode) /* just checking whether we can produce a mode */ ++ return bios->fp.mode_ptr; ++ ++ memset(mode, 0, sizeof(struct drm_display_mode)); ++ /* for version 1.0 (version in byte 0): ++ * bytes 1-2 are "panel type", including bits on whether Colour/mono, ++ * single/dual link, and type (TFT etc.) ++ * bytes 3-6 are bits per colour in RGBX */ ++ mode->clock = ROM16(mode_entry[7]) * 10; ++ /* bytes 9-10 is HActive */ ++ mode->hdisplay = ROM16(mode_entry[11]) + 1; ++ /* bytes 13-14 is HValid Start ++ * bytes 15-16 is HValid End */ ++ mode->hsync_start = ROM16(mode_entry[17]) + 1; ++ mode->hsync_end = ROM16(mode_entry[19]) + 1; ++ mode->htotal = ROM16(mode_entry[21]) + 1; ++ /* bytes 23-24, 27-30 similarly, but vertical */ ++ mode->vdisplay = ROM16(mode_entry[25]) + 1; ++ mode->vsync_start = ROM16(mode_entry[31]) + 1; ++ mode->vsync_end = ROM16(mode_entry[33]) + 1; ++ mode->vtotal = ROM16(mode_entry[35]) + 1; ++ mode->flags |= (mode_entry[37] & 0x10) ? ++ DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; ++ mode->flags |= (mode_entry[37] & 0x1) ? ++ DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; ++ /* bytes 38-39 relate to spread spectrum settings ++ * bytes 40-43 are something to do with PWM */ ++ ++ return bios->fp.mode_ptr; ++} ++ ++int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, bool *if_is_24bit) ++{ ++ /* The LVDS table header is (mostly) described in ++ * parse_lvds_manufacturer_table_header(): the BIT header additionally ++ * contains the dual-link transition pxclk (in 10s kHz), at byte 5 - if ++ * straps are not being used for the panel, this specifies the frequency ++ * at which modes should be set up in the dual link style. ++ * ++ * Following the header, the BMP (ver 0xa) table has several records, ++ * indexed by a seperate xlat table, indexed in turn by the fp strap in ++ * EXTDEV_BOOT. Each record had a config byte, followed by 6 script ++ * numbers for use by INIT_SUB which controlled panel init and power, ++ * and finally a dword of ms to sleep between power off and on ++ * operations. ++ * ++ * In the BIT versions, the table following the header serves as an ++ * integrated config and xlat table: the records in the table are ++ * indexed by the FP strap nibble in EXTDEV_BOOT, and each record has ++ * two bytes - the first as a config byte, the second for indexing the ++ * fp mode table pointed to by the BIT 'D' table ++ * ++ * DDC is not used until after card init, so selecting the correct table ++ * entry and setting the dual link flag for EDID equipped panels, ++ * requiring tests against the native-mode pixel clock, cannot be done ++ * until later, when this function should be called with non-zero pxclk ++ */ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ int fpstrapping = get_fp_strap(dev, bios), lvdsmanufacturerindex = 0; ++ struct lvdstableheader lth; ++ uint16_t lvdsofs; ++ int ret; ++ ++ if ((ret = parse_lvds_manufacturer_table_header(dev, bios, <h))) ++ return ret; ++ ++ switch (lth.lvds_ver) { ++ case 0x0a: /* pre NV40 */ ++ lvdsmanufacturerindex = bios->data[bios->fp.fpxlatemanufacturertableptr + fpstrapping]; ++ ++ /* we're done if this isn't the EDID panel case */ ++ if (!pxclk) ++ break; ++ ++ /* change in behaviour guessed at nv30; see datapoints below */ ++ if (bios->pub.chip_version < 0x30) { ++ /* nv17 behaviour */ ++ /* it seems the old style lvds script pointer is reused ++ * to select 18/24 bit colour depth for EDID panels */ ++ lvdsmanufacturerindex = (bios->legacy.lvds_single_a_script_ptr & 1) ? 2 : 0; ++ if (pxclk >= bios->fp.duallink_transition_clk) ++ lvdsmanufacturerindex++; ++ } else { ++ /* nv31, nv34 behaviour */ ++ lvdsmanufacturerindex = 0; ++ if (pxclk >= bios->fp.duallink_transition_clk) ++ lvdsmanufacturerindex = 2; ++ if (pxclk >= 140000) ++ lvdsmanufacturerindex = 3; ++ } ++ ++ /* nvidia set the high nibble of (cr57=f, cr58) to ++ * lvdsmanufacturerindex in this case; we don't */ ++ break; ++ case 0x30: /* NV4x */ ++ case 0x40: /* G80/G90 */ ++ lvdsmanufacturerindex = fpstrapping; ++ break; ++ default: ++ NV_ERROR(dev, "LVDS table revision not currently supported\n"); ++ return -ENOSYS; ++ } ++ ++ lvdsofs = bios->fp.xlated_entry = bios->fp.lvdsmanufacturerpointer + lth.headerlen + lth.recordlen * lvdsmanufacturerindex; ++ switch (lth.lvds_ver) { ++ case 0x0a: ++ bios->fp.power_off_for_reset = bios->data[lvdsofs] & 1; ++ bios->fp.reset_after_pclk_change = bios->data[lvdsofs] & 2; ++ bios->fp.dual_link = bios->data[lvdsofs] & 4; ++ bios->fp.link_c_increment = bios->data[lvdsofs] & 8; ++ *if_is_24bit = bios->data[lvdsofs] & 16; ++ break; ++ case 0x30: ++ /* My money would be on there being a 24 bit interface bit in this table, ++ * but I have no example of a laptop bios with a 24 bit panel to confirm that. ++ * Hence we shout loudly if any bit other than bit 0 is set (I've not even ++ * seen bit 1) ++ */ ++ if (bios->data[lvdsofs] > 1) ++ NV_ERROR(dev, ++ "You have a very unusual laptop display; please report it\n"); ++ /* no sign of the "power off for reset" or "reset for panel on" bits, but it's safer to assume we should */ ++ bios->fp.power_off_for_reset = true; ++ bios->fp.reset_after_pclk_change = true; ++ /* it's ok lvdsofs is wrong for nv4x edid case; dual_link is ++ * over-written, and BITbit1 isn't used */ ++ bios->fp.dual_link = bios->data[lvdsofs] & 1; ++ bios->fp.BITbit1 = bios->data[lvdsofs] & 2; ++ bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; ++#if 0 // currently unused ++ break; ++ case 0x40: ++ /* fairly sure, but not 100% */ ++ bios->fp.dual_link = bios->data[lvdsofs] & 1; ++ bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; ++ break; ++#endif ++ } ++ ++ /* set dual_link flag for EDID case */ ++ if (pxclk) ++ bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk); ++ ++ *dl = bios->fp.dual_link; ++ ++ return 0; ++} ++ ++int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, int pxclk) ++{ ++ /* the pxclk parameter is in kHz ++ * ++ * This runs the TMDS regs setting code found on BIT bios cards ++ * ++ * For ffs(or) == 1 use the first table, for ffs(or) == 2 and ++ * ffs(or) == 3, use the second. ++ */ ++ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ uint16_t clktable = 0, scriptptr; ++ uint32_t sel_clk_binding, sel_clk; ++ ++ if (dcbent->location != DCB_LOC_ON_CHIP) ++ return 0; ++ ++ switch (ffs(dcbent->or)) { ++ case 1: ++ clktable = bios->tmds.output0_script_ptr; ++ break; ++ case 2: ++ case 3: ++ clktable = bios->tmds.output1_script_ptr; ++ break; ++ } ++ ++ if (!clktable) { ++ NV_ERROR(dev, "Pixel clock comparison table not found\n"); ++ return -EINVAL; ++ } ++ ++ scriptptr = clkcmptable(bios, clktable, pxclk); ++ ++ if (!scriptptr) { ++ NV_ERROR(dev, "TMDS output init script not found\n"); ++ return -ENOENT; ++ } ++ ++ /* don't let script change pll->head binding */ ++ sel_clk_binding = bios_rd32(dev, NV_PRAMDAC_SEL_CLK) & 0x50000; ++ run_digital_op_script(dev, scriptptr, dcbent, head, pxclk >= 165000); ++ sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000; ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding); ++ ++ return 0; ++} ++ ++int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims *pll_lim) ++{ ++ /* PLL limits table ++ * ++ * Version 0x10: NV30, NV31 ++ * One byte header (version), one record of 24 bytes ++ * Version 0x11: NV36 - Not implemented ++ * Seems to have same record style as 0x10, but 3 records rather than 1 ++ * Version 0x20: Found on Geforce 6 cards ++ * Trivial 4 byte BIT header. 31 (0x1f) byte record length ++ * Version 0x21: Found on Geforce 7, 8 and some Geforce 6 cards ++ * 5 byte header, fifth byte of unknown purpose. 35 (0x23) byte record ++ * length in general, some (integrated) have an extra configuration byte ++ * Version 0x30: Found on Geforce 8, separates the register mapping ++ * from the limits tables. ++ */ ++ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ int cv = bios->pub.chip_version, pllindex = 0; ++ uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0; ++ uint32_t crystal_strap_mask, crystal_straps; ++ ++ if (!bios->pll_limit_tbl_ptr) { ++ if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 || ++ cv >= 0x40) { ++ NV_ERROR(dev, "Pointer to PLL limits table invalid\n"); ++ return -EINVAL; ++ } ++ } else ++ pll_lim_ver = bios->data[bios->pll_limit_tbl_ptr]; ++ ++ crystal_strap_mask = 1 << 6; ++ /* open coded dev->twoHeads test */ ++ if (cv > 0x10 && cv != 0x15 && cv != 0x1a && cv != 0x20) ++ crystal_strap_mask |= 1 << 22; ++ crystal_straps = nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & crystal_strap_mask; ++ ++ switch (pll_lim_ver) { ++ /* we use version 0 to indicate a pre limit table bios (single stage pll) ++ * and load the hard coded limits instead */ ++ case 0: ++ break; ++ case 0x10: ++ case 0x11: /* strictly v0x11 has 3 entries, but the last two don't seem to get used */ ++ headerlen = 1; ++ recordlen = 0x18; ++ entries = 1; ++ pllindex = 0; ++ break; ++ case 0x20: ++ case 0x21: ++ case 0x30: ++ headerlen = bios->data[bios->pll_limit_tbl_ptr + 1]; ++ recordlen = bios->data[bios->pll_limit_tbl_ptr + 2]; ++ entries = bios->data[bios->pll_limit_tbl_ptr + 3]; ++ break; ++ default: ++ NV_ERROR(dev, "PLL limits table revision 0x%X not currently " ++ "supported\n", pll_lim_ver); ++ return -ENOSYS; ++ } ++ ++ /* initialize all members to zero */ ++ memset(pll_lim, 0, sizeof(struct pll_lims)); ++ ++ if (pll_lim_ver == 0x10 || pll_lim_ver == 0x11) { ++ uint8_t *pll_rec = &bios->data[bios->pll_limit_tbl_ptr + headerlen + recordlen * pllindex]; ++ ++ pll_lim->vco1.minfreq = ROM32(pll_rec[0]); ++ pll_lim->vco1.maxfreq = ROM32(pll_rec[4]); ++ pll_lim->vco2.minfreq = ROM32(pll_rec[8]); ++ pll_lim->vco2.maxfreq = ROM32(pll_rec[12]); ++ pll_lim->vco1.min_inputfreq = ROM32(pll_rec[16]); ++ pll_lim->vco2.min_inputfreq = ROM32(pll_rec[20]); ++ pll_lim->vco1.max_inputfreq = pll_lim->vco2.max_inputfreq = INT_MAX; ++ ++ /* these values taken from nv30/31/36 */ ++ pll_lim->vco1.min_n = 0x1; ++ if (cv == 0x36) ++ pll_lim->vco1.min_n = 0x5; ++ pll_lim->vco1.max_n = 0xff; ++ pll_lim->vco1.min_m = 0x1; ++ pll_lim->vco1.max_m = 0xd; ++ pll_lim->vco2.min_n = 0x4; ++ /* on nv30, 31, 36 (i.e. all cards with two stage PLLs with this ++ * table version (apart from nv35)), N2 is compared to ++ * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and ++ * save a comparison ++ */ ++ pll_lim->vco2.max_n = 0x28; ++ if (cv == 0x30 || cv == 0x35) ++ /* only 5 bits available for N2 on nv30/35 */ ++ pll_lim->vco2.max_n = 0x1f; ++ pll_lim->vco2.min_m = 0x1; ++ pll_lim->vco2.max_m = 0x4; ++ } else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) { ++ uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen; ++ uint32_t reg = 0; /* default match */ ++ uint8_t *pll_rec; ++ int i; ++ ++ /* first entry is default match, if nothing better. warn if reg field nonzero */ ++ if (ROM32(bios->data[plloffs])) ++ NV_WARN(dev, "Default PLL limit entry has non-zero " ++ "register field\n"); ++ ++ if (limit_match > MAX_PLL_TYPES) ++ /* we've been passed a reg as the match */ ++ reg = limit_match; ++ else /* limit match is a pll type */ ++ for (i = 1; i < entries && !reg; i++) { ++ uint32_t cmpreg = ROM32(bios->data[plloffs + recordlen * i]); ++ ++ if (limit_match == NVPLL && ++ (cmpreg == NV_PRAMDAC_NVPLL_COEFF || cmpreg == 0x4000)) ++ reg = cmpreg; ++ if (limit_match == MPLL && ++ (cmpreg == NV_PRAMDAC_MPLL_COEFF || cmpreg == 0x4020)) ++ reg = cmpreg; ++ if (limit_match == VPLL1 && ++ (cmpreg == NV_PRAMDAC_VPLL_COEFF || cmpreg == 0x4010)) ++ reg = cmpreg; ++ if (limit_match == VPLL2 && ++ (cmpreg == NV_RAMDAC_VPLL2 || cmpreg == 0x4018)) ++ reg = cmpreg; ++ } ++ ++ for (i = 1; i < entries; i++) ++ if (ROM32(bios->data[plloffs + recordlen * i]) == reg) { ++ pllindex = i; ++ break; ++ } ++ ++ pll_rec = &bios->data[plloffs + recordlen * pllindex]; ++ ++ BIOSLOG(dev, "Loading PLL limits for reg 0x%08x\n", pllindex ? reg : 0); ++ ++ /* frequencies are stored in tables in MHz, kHz are more useful, so we convert */ ++ ++ /* What output frequencies can each VCO generate? */ ++ pll_lim->vco1.minfreq = ROM16(pll_rec[4]) * 1000; ++ pll_lim->vco1.maxfreq = ROM16(pll_rec[6]) * 1000; ++ pll_lim->vco2.minfreq = ROM16(pll_rec[8]) * 1000; ++ pll_lim->vco2.maxfreq = ROM16(pll_rec[10]) * 1000; ++ ++ /* What input frequencies do they accept (past the m-divider)? */ ++ pll_lim->vco1.min_inputfreq = ROM16(pll_rec[12]) * 1000; ++ pll_lim->vco2.min_inputfreq = ROM16(pll_rec[14]) * 1000; ++ pll_lim->vco1.max_inputfreq = ROM16(pll_rec[16]) * 1000; ++ pll_lim->vco2.max_inputfreq = ROM16(pll_rec[18]) * 1000; ++ ++ /* What values are accepted as multiplier and divider? */ ++ pll_lim->vco1.min_n = pll_rec[20]; ++ pll_lim->vco1.max_n = pll_rec[21]; ++ pll_lim->vco1.min_m = pll_rec[22]; ++ pll_lim->vco1.max_m = pll_rec[23]; ++ pll_lim->vco2.min_n = pll_rec[24]; ++ pll_lim->vco2.max_n = pll_rec[25]; ++ pll_lim->vco2.min_m = pll_rec[26]; ++ pll_lim->vco2.max_m = pll_rec[27]; ++ ++ pll_lim->max_log2p_bias = pll_rec[29]; ++ pll_lim->log2p_bias = pll_rec[30]; ++ ++ if (recordlen > 0x22) ++ pll_lim->refclk = ROM32(pll_rec[31]); ++ ++ if (recordlen > 0x23 && pll_rec[35]) ++ NV_WARN(dev, ++ "Bits set in PLL configuration byte (%x)\n", ++ pll_rec[35]); ++ ++ /* C51 special not seen elsewhere */ ++ if (cv == 0x51 && !pll_lim->refclk) { ++ uint32_t sel_clk = bios_rd32(dev, NV_PRAMDAC_SEL_CLK); ++ ++ if (((limit_match == NV_PRAMDAC_VPLL_COEFF || limit_match == VPLL1) && sel_clk & 0x20) || ++ ((limit_match == NV_RAMDAC_VPLL2 || limit_match == VPLL2) && sel_clk & 0x80)) { ++ if (bios_idxprt_rd(dev, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3) ++ pll_lim->refclk = 200000; ++ else ++ pll_lim->refclk = 25000; ++ } ++ } ++ } else if (pll_lim_ver) { /* ver 0x30 */ ++ uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen]; ++ uint8_t *record = NULL; ++ int i; ++ ++ BIOSLOG(dev, "Loading PLL limits for register 0x%08x\n", ++ limit_match); ++ ++ for (i = 0; i < entries; i++, entry += recordlen) { ++ if (ROM32(entry[3]) == limit_match) { ++ record = &bios->data[ROM16(entry[1])]; ++ break; ++ } ++ } ++ ++ if (!record) { ++ NV_ERROR(dev, "Register 0x%08x not found in PLL " ++ "limits table", limit_match); ++ return -ENOENT; ++ } ++ ++ pll_lim->vco1.minfreq = ROM16(record[0]) * 1000; ++ pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000; ++ pll_lim->vco2.minfreq = ROM16(record[4]) * 1000; ++ pll_lim->vco2.maxfreq = ROM16(record[6]) * 1000; ++ pll_lim->vco1.min_inputfreq = ROM16(record[8]) * 1000; ++ pll_lim->vco2.min_inputfreq = ROM16(record[10]) * 1000; ++ pll_lim->vco1.max_inputfreq = ROM16(record[12]) * 1000; ++ pll_lim->vco2.max_inputfreq = ROM16(record[14]) * 1000; ++ pll_lim->vco1.min_n = record[16]; ++ pll_lim->vco1.max_n = record[17]; ++ pll_lim->vco1.min_m = record[18]; ++ pll_lim->vco1.max_m = record[19]; ++ pll_lim->vco2.min_n = record[20]; ++ pll_lim->vco2.max_n = record[21]; ++ pll_lim->vco2.min_m = record[22]; ++ pll_lim->vco2.max_m = record[23]; ++ pll_lim->max_log2p_bias = record[25]; ++ pll_lim->log2p_bias = record[27]; ++ pll_lim->refclk = ROM32(record[28]); ++ } ++ ++ /* By now any valid limit table ought to have set a max frequency for ++ * vco1, so if it's zero it's either a pre limit table bios, or one ++ * with an empty limit table (seen on nv18) ++ */ ++ if (!pll_lim->vco1.maxfreq) { ++ pll_lim->vco1.minfreq = bios->fminvco; ++ pll_lim->vco1.maxfreq = bios->fmaxvco; ++ pll_lim->vco1.min_inputfreq = 0; ++ pll_lim->vco1.max_inputfreq = INT_MAX; ++ pll_lim->vco1.min_n = 0x1; ++ pll_lim->vco1.max_n = 0xff; ++ pll_lim->vco1.min_m = 0x1; ++ if (crystal_straps == 0) { ++ /* nv05 does this, nv11 doesn't, nv10 unknown */ ++ if (cv < 0x11) ++ pll_lim->vco1.min_m = 0x7; ++ pll_lim->vco1.max_m = 0xd; ++ } else { ++ if (cv < 0x11) ++ pll_lim->vco1.min_m = 0x8; ++ pll_lim->vco1.max_m = 0xe; ++ } ++ } ++ ++ if (!pll_lim->refclk) ++ switch (crystal_straps) { ++ case 0: ++ pll_lim->refclk = 13500; ++ break; ++ case (1 << 6): ++ pll_lim->refclk = 14318; ++ break; ++ case (1 << 22): ++ pll_lim->refclk = 27000; ++ break; ++ case (1 << 22 | 1 << 6): ++ pll_lim->refclk = 25000; ++ break; ++ } ++ ++#if 0 /* for easy debugging */ ++ ErrorF("pll.vco1.minfreq: %d\n", pll_lim->vco1.minfreq); ++ ErrorF("pll.vco1.maxfreq: %d\n", pll_lim->vco1.maxfreq); ++ ErrorF("pll.vco2.minfreq: %d\n", pll_lim->vco2.minfreq); ++ ErrorF("pll.vco2.maxfreq: %d\n", pll_lim->vco2.maxfreq); ++ ++ ErrorF("pll.vco1.min_inputfreq: %d\n", pll_lim->vco1.min_inputfreq); ++ ErrorF("pll.vco1.max_inputfreq: %d\n", pll_lim->vco1.max_inputfreq); ++ ErrorF("pll.vco2.min_inputfreq: %d\n", pll_lim->vco2.min_inputfreq); ++ ErrorF("pll.vco2.max_inputfreq: %d\n", pll_lim->vco2.max_inputfreq); ++ ++ ErrorF("pll.vco1.min_n: %d\n", pll_lim->vco1.min_n); ++ ErrorF("pll.vco1.max_n: %d\n", pll_lim->vco1.max_n); ++ ErrorF("pll.vco1.min_m: %d\n", pll_lim->vco1.min_m); ++ ErrorF("pll.vco1.max_m: %d\n", pll_lim->vco1.max_m); ++ ErrorF("pll.vco2.min_n: %d\n", pll_lim->vco2.min_n); ++ ErrorF("pll.vco2.max_n: %d\n", pll_lim->vco2.max_n); ++ ErrorF("pll.vco2.min_m: %d\n", pll_lim->vco2.min_m); ++ ErrorF("pll.vco2.max_m: %d\n", pll_lim->vco2.max_m); ++ ++ ErrorF("pll.max_log2p_bias: %d\n", pll_lim->max_log2p_bias); ++ ErrorF("pll.log2p_bias: %d\n", pll_lim->log2p_bias); ++ ++ ErrorF("pll.refclk: %d\n", pll_lim->refclk); ++#endif ++ ++ return 0; ++} ++ ++static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint16_t offset) ++{ ++ /* offset + 0 (8 bits): Micro version ++ * offset + 1 (8 bits): Minor version ++ * offset + 2 (8 bits): Chip version ++ * offset + 3 (8 bits): Major version ++ */ ++ ++ bios->major_version = bios->data[offset + 3]; ++ bios->pub.chip_version = bios->data[offset + 2]; ++ NV_TRACE(dev, "Bios version %02x.%02x.%02x.%02x\n", ++ bios->data[offset + 3], bios->data[offset + 2], ++ bios->data[offset + 1], bios->data[offset]); ++} ++ ++static void parse_script_table_pointers(struct nvbios *bios, uint16_t offset) ++{ ++ /* Parses the init table segment for pointers used in script execution. ++ * ++ * offset + 0 (16 bits): init script tables pointer ++ * offset + 2 (16 bits): macro index table pointer ++ * offset + 4 (16 bits): macro table pointer ++ * offset + 6 (16 bits): condition table pointer ++ * offset + 8 (16 bits): io condition table pointer ++ * offset + 10 (16 bits): io flag condition table pointer ++ * offset + 12 (16 bits): init function table pointer ++ */ ++ ++ bios->init_script_tbls_ptr = ROM16(bios->data[offset]); ++ bios->macro_index_tbl_ptr = ROM16(bios->data[offset + 2]); ++ bios->macro_tbl_ptr = ROM16(bios->data[offset + 4]); ++ bios->condition_tbl_ptr = ROM16(bios->data[offset + 6]); ++ bios->io_condition_tbl_ptr = ROM16(bios->data[offset + 8]); ++ bios->io_flag_condition_tbl_ptr = ROM16(bios->data[offset + 10]); ++ bios->init_function_tbl_ptr = ROM16(bios->data[offset + 12]); ++} ++ ++static int parse_bit_A_tbl_entry(struct drm_device *dev, struct nvbios *bios, bit_entry_t *bitentry) ++{ ++ /* Parses the load detect values for g80 cards. ++ * ++ * offset + 0 (16 bits): loadval table pointer ++ */ ++ ++ uint16_t load_table_ptr; ++ uint8_t version, headerlen, entrylen, num_entries; ++ ++ if (bitentry->length != 3) { ++ NV_ERROR(dev, "Do not understand BIT A table\n"); ++ return -EINVAL; ++ } ++ ++ load_table_ptr = ROM16(bios->data[bitentry->offset]); ++ ++ if (load_table_ptr == 0x0) { ++ NV_ERROR(dev, "Pointer to BIT loadval table invalid\n"); ++ return -EINVAL; ++ } ++ ++ version = bios->data[load_table_ptr]; ++ ++ if (version != 0x10) { ++ NV_ERROR(dev, "BIT loadval table version %d.%d not supported\n", ++ version >> 4, version & 0xF); ++ return -ENOSYS; ++ } ++ ++ headerlen = bios->data[load_table_ptr + 1]; ++ entrylen = bios->data[load_table_ptr + 2]; ++ num_entries = bios->data[load_table_ptr + 3]; ++ ++ if (headerlen != 4 || entrylen != 4 || num_entries != 2) { ++ NV_ERROR(dev, "Do not understand BIT loadval table\n"); ++ return -EINVAL; ++ } ++ ++ /* First entry is normal dac, 2nd tv-out perhaps? */ ++ bios->pub.dactestval = ROM32(bios->data[load_table_ptr + headerlen]) & 0x3ff; ++ ++ return 0; ++} ++ ++static int parse_bit_C_tbl_entry(struct drm_device *dev, struct nvbios *bios, bit_entry_t *bitentry) ++{ ++ /* offset + 8 (16 bits): PLL limits table pointer ++ * ++ * There's more in here, but that's unknown. ++ */ ++ ++ if (bitentry->length < 10) { ++ NV_ERROR(dev, "Do not understand BIT C table\n"); ++ return -EINVAL; ++ } ++ ++ bios->pll_limit_tbl_ptr = ROM16(bios->data[bitentry->offset + 8]); ++ ++ return 0; ++} ++ ++static int parse_bit_display_tbl_entry(struct drm_device *dev, struct nvbios *bios, bit_entry_t *bitentry) ++{ ++ /* Parses the flat panel table segment that the bit entry points to. ++ * Starting at bitentry->offset: ++ * ++ * offset + 0 (16 bits): ??? table pointer - seems to have 18 byte records beginning with a freq ++ * offset + 2 (16 bits): mode table pointer ++ */ ++ ++ if (bitentry->length != 4) { ++ NV_ERROR(dev, "Do not understand BIT display table\n"); ++ return -EINVAL; ++ } ++ ++ bios->fp.fptablepointer = ROM16(bios->data[bitentry->offset + 2]); ++ ++ return 0; ++} ++ ++static int parse_bit_init_tbl_entry(struct drm_device *dev, struct nvbios *bios, bit_entry_t *bitentry) ++{ ++ /* Parses the init table segment that the bit entry points to. ++ * ++ * See parse_script_table_pointers for layout ++ */ ++ ++ if (bitentry->length < 14) { ++ NV_ERROR(dev, "Do not understand init table\n"); ++ return -EINVAL; ++ } ++ ++ parse_script_table_pointers(bios, bitentry->offset); ++ ++ return 0; ++} ++ ++static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, bit_entry_t *bitentry) ++{ ++ /* BIT 'i' (info?) table ++ * ++ * offset + 0 (32 bits): BIOS version dword (as in B table) ++ * offset + 5 (8 bits): BIOS feature byte (same as for BMP?) ++ * offset + 13 (16 bits): pointer to table containing DAC load detection comparison values ++ * ++ * There's other things in the table, purpose unknown ++ */ ++ ++ uint16_t daccmpoffset; ++ uint8_t dacver, dacheaderlen; ++ ++ if (bitentry->length < 6) { ++ NV_ERROR(dev, "BIT i table too short for needed information\n"); ++ return -EINVAL; ++ } ++ ++ parse_bios_version(dev, bios, bitentry->offset); ++ ++ /* bit 4 seems to indicate a mobile bios (doesn't suffer from BMP's ++ * Quadro identity crisis), other bits possibly as for BMP feature byte ++ */ ++ bios->feature_byte = bios->data[bitentry->offset + 5]; ++ bios->is_mobile = bios->feature_byte & FEATURE_MOBILE; ++ ++ if (bitentry->length < 15) { ++ NV_WARN(dev, "BIT i table not long enough for DAC load " ++ "detection comparison table\n"); ++ return -EINVAL; ++ } ++ ++ daccmpoffset = ROM16(bios->data[bitentry->offset + 13]); ++ ++ /* doesn't exist on g80 */ ++ if (!daccmpoffset) ++ return 0; ++ ++ /* The first value in the table, following the header, is the comparison value ++ * Purpose of subsequent values unknown -- TV load detection? ++ */ ++ ++ dacver = bios->data[daccmpoffset]; ++ dacheaderlen = bios->data[daccmpoffset + 1]; ++ ++ if (dacver != 0x00 && dacver != 0x10) { ++ NV_WARN(dev, "DAC load detection comparison table version " ++ "%d.%d not known\n", dacver >> 4, dacver & 0xf); ++ return -ENOSYS; ++ } ++ ++ bios->pub.dactestval = ROM32(bios->data[daccmpoffset + dacheaderlen]); ++ ++ return 0; ++} ++ ++static int parse_bit_lvds_tbl_entry(struct drm_device *dev, struct nvbios *bios, bit_entry_t *bitentry) ++{ ++ /* Parses the LVDS table segment that the bit entry points to. ++ * Starting at bitentry->offset: ++ * ++ * offset + 0 (16 bits): LVDS strap xlate table pointer ++ */ ++ ++ if (bitentry->length != 2) { ++ NV_ERROR(dev, "Do not understand BIT LVDS table\n"); ++ return -EINVAL; ++ } ++ ++ /* no idea if it's still called the LVDS manufacturer table, but the concept's close enough */ ++ bios->fp.lvdsmanufacturerpointer = ROM16(bios->data[bitentry->offset]); ++ ++ return 0; ++} ++ ++static int parse_bit_M_tbl_entry(struct drm_device *dev, struct nvbios *bios, bit_entry_t *bitentry) ++{ ++ /* offset + 2 (8 bits): number of options in an INIT_RAM_RESTRICT_ZM_REG_GROUP opcode option set ++ * offset + 3 (16 bits): pointer to strap xlate table for RAM restrict option selection ++ * ++ * There's a bunch of bits in this table other than the RAM restrict ++ * stuff that we don't use - their use currently unknown ++ */ ++ ++ int i; ++ ++ /* Older bios versions don't have a sufficiently long table for what we want */ ++ if (bitentry->length < 0x5) ++ return 0; ++ ++ /* set up multiplier for INIT_RAM_RESTRICT_ZM_REG_GROUP */ ++ for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != 0x8f); i++) ++ ; ++ itbl_entry[i].length_multiplier = bios->data[bitentry->offset + 2] * 4; ++ init_ram_restrict_zm_reg_group_blocklen = itbl_entry[i].length_multiplier; ++ ++ bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 3]); ++ ++ return 0; ++} ++ ++static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios, bit_entry_t *bitentry) ++{ ++ /* Parses the pointer to the TMDS table ++ * ++ * Starting at bitentry->offset: ++ * ++ * offset + 0 (16 bits): TMDS table pointer ++ * ++ * The TMDS table is typically found just before the DCB table, with a ++ * characteristic signature of 0x11,0x13 (1.1 being version, 0x13 being ++ * length?) ++ * ++ * At offset +7 is a pointer to a script, which I don't know how to run yet ++ * At offset +9 is a pointer to another script, likewise ++ * Offset +11 has a pointer to a table where the first word is a pxclk ++ * frequency and the second word a pointer to a script, which should be ++ * run if the comparison pxclk frequency is less than the pxclk desired. ++ * This repeats for decreasing comparison frequencies ++ * Offset +13 has a pointer to a similar table ++ * The selection of table (and possibly +7/+9 script) is dictated by ++ * "or" from the DCB. ++ */ ++ ++ uint16_t tmdstableptr, script1, script2; ++ ++ if (bitentry->length != 2) { ++ NV_ERROR(dev, "Do not understand BIT TMDS table\n"); ++ return -EINVAL; ++ } ++ ++ tmdstableptr = ROM16(bios->data[bitentry->offset]); ++ ++ if (tmdstableptr == 0x0) { ++ NV_ERROR(dev, "Pointer to TMDS table invalid\n"); ++ return -EINVAL; ++ } ++ ++ /* nv50+ has v2.0, but we don't parse it atm */ ++ if (bios->data[tmdstableptr] != 0x11) { ++ NV_WARN(dev, ++ "TMDS table revision %d.%d not currently supported\n", ++ bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); ++ return -ENOSYS; ++ } ++ ++ /* These two scripts are odd: they don't seem to get run even when they are not stubbed */ ++ script1 = ROM16(bios->data[tmdstableptr + 7]); ++ script2 = ROM16(bios->data[tmdstableptr + 9]); ++ if (bios->data[script1] != 'q' || bios->data[script2] != 'q') ++ NV_WARN(dev, "TMDS table script pointers not stubbed\n"); ++ ++ bios->tmds.output0_script_ptr = ROM16(bios->data[tmdstableptr + 11]); ++ bios->tmds.output1_script_ptr = ROM16(bios->data[tmdstableptr + 13]); ++ ++ return 0; ++} ++ ++struct bit_table { ++ const char id; ++ int (* const parse_fn)(struct drm_device *, struct nvbios *, bit_entry_t *); ++}; ++ ++#define BIT_TABLE(id, funcid) ((struct bit_table){ id, parse_bit_##funcid##_tbl_entry }) ++ ++static int parse_bit_table(struct drm_device *dev, struct nvbios *bios, const uint16_t bitoffset, struct bit_table *table) ++{ ++ uint8_t maxentries = bios->data[bitoffset + 4]; ++ int i, offset; ++ bit_entry_t bitentry; ++ ++ for (i = 0, offset = bitoffset + 6; i < maxentries; i++, offset += 6) { ++ bitentry.id[0] = bios->data[offset]; ++ ++ if (bitentry.id[0] != table->id) ++ continue; ++ ++ bitentry.id[1] = bios->data[offset + 1]; ++ bitentry.length = ROM16(bios->data[offset + 2]); ++ bitentry.offset = ROM16(bios->data[offset + 4]); ++ ++ return table->parse_fn(dev, bios, &bitentry); ++ } ++ ++ NV_ERROR(dev, "BIT table '%c' not found\n", table->id); ++ ++ return -ENOSYS; ++} ++ ++static int parse_bit_structure(struct drm_device *dev, struct nvbios *bios, const uint16_t bitoffset) ++{ ++ int ret; ++ ++ /* the only restriction on parsing order currently is having 'i' first ++ * for use of bios->*_version or bios->feature_byte while parsing; ++ * functions shouldn't be actually *doing* anything apart from pulling ++ * data from the image into the bios struct, thus no interdependencies ++ */ ++ if ((ret = parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('i', i)))) /* info? */ ++ return ret; ++ if (bios->major_version >= 0x60) /* g80+ */ ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('A', A)); ++ if ((ret = parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('C', C)))) ++ return ret; ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('D', display)); ++ if ((ret = parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('I', init)))) ++ return ret; ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('M', M)); /* memory? */ ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('L', lvds)); ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('T', tmds)); ++ ++ return 0; ++} ++ ++static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsigned int offset) ++{ ++ /* Parses the BMP structure for useful things, but does not act on them ++ * ++ * offset + 5: BMP major version ++ * offset + 6: BMP minor version ++ * offset + 9: BMP feature byte ++ * offset + 10: BCD encoded BIOS version ++ * ++ * offset + 18: init script table pointer (for bios versions < 5.10h) ++ * offset + 20: extra init script table pointer (for bios versions < 5.10h) ++ * ++ * offset + 24: memory init table pointer (used on early bios versions) ++ * offset + 26: SDR memory sequencing setup data table ++ * offset + 28: DDR memory sequencing setup data table ++ * ++ * offset + 54: index of I2C CRTC pair to use for CRT output ++ * offset + 55: index of I2C CRTC pair to use for TV output ++ * offset + 56: index of I2C CRTC pair to use for flat panel output ++ * offset + 58: write CRTC index for I2C pair 0 ++ * offset + 59: read CRTC index for I2C pair 0 ++ * offset + 60: write CRTC index for I2C pair 1 ++ * offset + 61: read CRTC index for I2C pair 1 ++ * ++ * offset + 67: maximum internal PLL frequency (single stage PLL) ++ * offset + 71: minimum internal PLL frequency (single stage PLL) ++ * ++ * offset + 75: script table pointers, as described in parse_script_table_pointers ++ * ++ * offset + 89: TMDS single link output A table pointer ++ * offset + 91: TMDS single link output B table pointer ++ * offset + 95: LVDS single link output A table pointer ++ * offset + 105: flat panel timings table pointer ++ * offset + 107: flat panel strapping translation table pointer ++ * offset + 117: LVDS manufacturer panel config table pointer ++ * offset + 119: LVDS manufacturer strapping translation table pointer ++ * ++ * offset + 142: PLL limits table pointer ++ * ++ * offset + 156: minimum pixel clock for LVDS dual link ++ */ ++ ++ uint8_t *bmp = &bios->data[offset], bmp_version_major, bmp_version_minor; ++ uint16_t bmplength; ++ uint16_t legacy_scripts_offset, legacy_i2c_offset; ++ ++ /* load needed defaults in case we can't parse this info */ ++ bios->bdcb.dcb.i2c[0].write = NV_CIO_CRE_DDC_WR__INDEX; ++ bios->bdcb.dcb.i2c[0].read = NV_CIO_CRE_DDC_STATUS__INDEX; ++ bios->bdcb.dcb.i2c[1].write = NV_CIO_CRE_DDC0_WR__INDEX; ++ bios->bdcb.dcb.i2c[1].read = NV_CIO_CRE_DDC0_STATUS__INDEX; ++ bios->pub.digital_min_front_porch = 0x4b; ++ bios->fmaxvco = 256000; ++ bios->fminvco = 128000; ++ bios->fp.duallink_transition_clk = 90000; ++ ++ bmp_version_major = bmp[5]; ++ bmp_version_minor = bmp[6]; ++ ++ NV_TRACE(dev, "BMP version %d.%d\n", ++ bmp_version_major, bmp_version_minor); ++ ++ /* Make sure that 0x36 is blank and can't be mistaken for a DCB pointer on early versions */ ++ if (bmp_version_major < 5) ++ *(uint16_t *)&bios->data[0x36] = 0; ++ ++ /* Seems that the minor version was 1 for all major versions prior to 5 */ ++ /* Version 6 could theoretically exist, but I suspect BIT happened instead */ ++ if ((bmp_version_major < 5 && bmp_version_minor != 1) || bmp_version_major > 5) { ++ NV_ERROR(dev, "You have an unsupported BMP version. " ++ "Please send in your bios\n"); ++ return -ENOSYS; ++ } ++ ++ if (bmp_version_major == 0) /* nothing that's currently useful in this version */ ++ return 0; ++ else if (bmp_version_major == 1) ++ bmplength = 44; /* exact for 1.01 */ ++ else if (bmp_version_major == 2) ++ bmplength = 48; /* exact for 2.01 */ ++ else if (bmp_version_major == 3) ++ bmplength = 54; /* guessed - mem init tables added in this version */ ++ else if (bmp_version_major == 4 || bmp_version_minor < 0x1) /* don't know if 5.0 exists... */ ++ bmplength = 62; /* guessed - BMP I2C indices added in version 4*/ ++ else if (bmp_version_minor < 0x6) ++ bmplength = 67; /* exact for 5.01 */ ++ else if (bmp_version_minor < 0x10) ++ bmplength = 75; /* exact for 5.06 */ ++ else if (bmp_version_minor == 0x10) ++ bmplength = 89; /* exact for 5.10h */ ++ else if (bmp_version_minor < 0x14) ++ bmplength = 118; /* exact for 5.11h */ ++ else if (bmp_version_minor < 0x24) /* not sure of version where pll limits came in; ++ * certainly exist by 0x24 though */ ++ /* length not exact: this is long enough to get lvds members */ ++ bmplength = 123; ++ else if (bmp_version_minor < 0x27) ++ /* length not exact: this is long enough to get pll limit member */ ++ bmplength = 144; ++ else ++ /* length not exact: this is long enough to get dual link transition clock */ ++ bmplength = 158; ++ ++ /* checksum */ ++ if (nv_cksum(bmp, 8)) { ++ NV_ERROR(dev, "Bad BMP checksum\n"); ++ return -EINVAL; ++ } ++ ++ /* bit 4 seems to indicate either a mobile bios or a quadro card -- ++ * mobile behaviour consistent (nv11+), quadro only seen nv18gl-nv36gl ++ * (not nv10gl), bit 5 that the flat panel tables are present, and ++ * bit 6 a tv bios */ ++ bios->feature_byte = bmp[9]; ++ ++ parse_bios_version(dev, bios, offset + 10); ++ ++ if (bmp_version_major < 5 || bmp_version_minor < 0x10) ++ bios->old_style_init = true; ++ legacy_scripts_offset = 18; ++ if (bmp_version_major < 2) ++ legacy_scripts_offset -= 4; ++ bios->init_script_tbls_ptr = ROM16(bmp[legacy_scripts_offset]); ++ bios->extra_init_script_tbl_ptr = ROM16(bmp[legacy_scripts_offset + 2]); ++ ++ if (bmp_version_major > 2) { /* appears in BMP 3 */ ++ bios->legacy.mem_init_tbl_ptr = ROM16(bmp[24]); ++ bios->legacy.sdr_seq_tbl_ptr = ROM16(bmp[26]); ++ bios->legacy.ddr_seq_tbl_ptr = ROM16(bmp[28]); ++ } ++ ++ legacy_i2c_offset = 0x48; /* BMP version 2 & 3 */ ++ if (bmplength > 61) ++ legacy_i2c_offset = offset + 54; ++ bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset]; ++ bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1]; ++ bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2]; ++ bios->bdcb.dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; ++ bios->bdcb.dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; ++ bios->bdcb.dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; ++ bios->bdcb.dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7]; ++ ++ if (bmplength > 74) { ++ bios->fmaxvco = ROM32(bmp[67]); ++ bios->fminvco = ROM32(bmp[71]); ++ } ++ if (bmplength > 88) ++ parse_script_table_pointers(bios, offset + 75); ++ if (bmplength > 94) { ++ bios->tmds.output0_script_ptr = ROM16(bmp[89]); ++ bios->tmds.output1_script_ptr = ROM16(bmp[91]); ++ /* never observed in use with lvds scripts, but is reused for ++ * 18/24 bit panel interface default for EDID equipped panels ++ * (if_is_24bit not set directly to avoid any oscillation) */ ++ bios->legacy.lvds_single_a_script_ptr = ROM16(bmp[95]); ++ } ++ if (bmplength > 108) { ++ bios->fp.fptablepointer = ROM16(bmp[105]); ++ bios->fp.fpxlatetableptr = ROM16(bmp[107]); ++ bios->fp.xlatwidth = 1; ++ } ++ if (bmplength > 120) { ++ bios->fp.lvdsmanufacturerpointer = ROM16(bmp[117]); ++ bios->fp.fpxlatemanufacturertableptr = ROM16(bmp[119]); ++ } ++ if (bmplength > 143) ++ bios->pll_limit_tbl_ptr = ROM16(bmp[142]); ++ ++ if (bmplength > 157) ++ bios->fp.duallink_transition_clk = ROM16(bmp[156]) * 10; ++ ++ return 0; ++} ++ ++static uint16_t findstr(uint8_t *data, int n, const uint8_t *str, int len) ++{ ++ int i, j; ++ ++ for (i = 0; i <= (n - len); i++) { ++ for (j = 0; j < len; j++) ++ if (data[i + j] != str[j]) ++ break; ++ if (j == len) ++ return i; ++ } ++ ++ return 0; ++} ++ ++static int ++read_dcb_i2c_entry(struct drm_device *dev, int dcb_version, uint8_t *i2ctable, int index, struct dcb_i2c_entry *i2c) ++{ ++ uint8_t dcb_i2c_ver = dcb_version, headerlen = 0, entry_len = 4; ++ int i2c_entries = DCB_MAX_NUM_I2C_ENTRIES; ++ int recordoffset = 0, rdofs = 1, wrofs = 0; ++ uint8_t port_type = 0; ++ ++ if (!i2ctable) ++ return -EINVAL; ++ ++ if (dcb_version >= 0x30) { ++ if (i2ctable[0] != dcb_version) /* necessary? */ ++ NV_WARN(dev, ++ "DCB I2C table version mismatch (%02X vs %02X)\n", ++ i2ctable[0], dcb_version); ++ dcb_i2c_ver = i2ctable[0]; ++ headerlen = i2ctable[1]; ++ if (i2ctable[2] <= DCB_MAX_NUM_I2C_ENTRIES) ++ i2c_entries = i2ctable[2]; ++ else ++ NV_WARN(dev, ++ "DCB I2C table has more entries than indexable " ++ "(%d entries, max index 15)\n", i2ctable[2]); ++ entry_len = i2ctable[3]; ++ /* [4] is i2c_default_indices, read in parse_dcb_table() */ ++ } ++ /* it's your own fault if you call this function on a DCB 1.1 BIOS -- ++ * the test below is for DCB 1.2 ++ */ ++ if (dcb_version < 0x14) { ++ recordoffset = 2; ++ rdofs = 0; ++ wrofs = 1; ++ } ++ ++ if (index == 0xf) ++ return 0; ++ if (index > i2c_entries) { ++ NV_ERROR(dev, "DCB I2C index too big (%d > %d)\n", ++ index, i2ctable[2]); ++ return -ENOENT; ++ } ++ if (i2ctable[headerlen + entry_len * index + 3] == 0xff) { ++ NV_ERROR(dev, "DCB I2C entry invalid\n"); ++ return -EINVAL; ++ } ++ ++ if (dcb_i2c_ver >= 0x30) { ++ port_type = i2ctable[headerlen + recordoffset + 3 + entry_len * index]; ++ ++ /* fixup for chips using same address offset for read and write */ ++ if (port_type == 4) /* seen on C51 */ ++ rdofs = wrofs = 1; ++ if (port_type == 5) /* G80+ */ ++ rdofs = wrofs = 0; ++ } ++ if (dcb_i2c_ver >= 0x40 && port_type != 5) ++ NV_WARN(dev, "DCB I2C table has port type %d\n", port_type); ++ ++ i2c->port_type = port_type; ++ i2c->read = i2ctable[headerlen + recordoffset + rdofs + entry_len * index]; ++ i2c->write = i2ctable[headerlen + recordoffset + wrofs + entry_len * index]; ++ ++ return 0; ++} ++ ++static int ++init_dcb_i2c_entry(struct drm_device *dev, struct nvbios *bios, int index) ++{ ++ struct dcb_i2c_entry *i2c = &bios->bdcb.dcb.i2c[index]; ++ char adaptorname[11]; ++ int ret; ++ ++ if (i2c->chan) ++ return 0; ++ ++ if (bios->bdcb.version < 0x15) { ++ NV_ERROR(dev, "DCB table not version 1.5 or greater\n"); ++ return -ENOSYS; ++ } ++ ++ if (!bios->bdcb.i2c_table) { ++ NV_ERROR(dev, "No parsed DCB I2C port table\n"); ++ return -EINVAL; ++ } ++ ++ ret = read_dcb_i2c_entry(dev, bios->bdcb.version, bios->bdcb.i2c_table, ++ index, i2c); ++ if (ret) ++ return ret; ++ ++ snprintf(adaptorname, 11, "DCB-I2C-%d", index); ++ ret = nouveau_i2c_new(dev, adaptorname, index, &i2c->chan); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static struct dcb_entry * new_dcb_entry(struct parsed_dcb *dcb) ++{ ++ struct dcb_entry *entry = &dcb->entry[dcb->entries]; ++ ++ memset(entry, 0, sizeof (struct dcb_entry)); ++ entry->index = dcb->entries++; ++ ++ return entry; ++} ++ ++static void fabricate_vga_output(struct parsed_dcb *dcb, int i2c, int heads) ++{ ++ struct dcb_entry *entry = new_dcb_entry(dcb); ++ ++ entry->type = 0; ++ entry->i2c_index = i2c; ++ entry->heads = heads; ++ entry->location = DCB_LOC_ON_CHIP; ++ /* "or" mostly unused in early gen crt modesetting, 0 is fine */ ++} ++ ++static bool ++parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, ++ uint32_t conn, uint32_t conf, struct dcb_entry *entry) ++{ ++ entry->type = conn & 0xf; ++ entry->i2c_index = (conn >> 4) & 0xf; ++ entry->heads = (conn >> 8) & 0xf; ++ entry->bus = (conn >> 16) & 0xf; ++ entry->location = (conn >> 20) & 0xf; ++ entry->or = (conn >> 24) & 0xf; ++ /* Normal entries consist of a single bit, but dual link has the ++ * next most significant bit set too ++ */ ++ entry->duallink_possible = ++ ((1 << (ffs(entry->or) - 1)) * 3 == entry->or); ++ ++ switch (entry->type) { ++ case OUTPUT_ANALOG: ++ /* although the rest of a CRT conf dword is usually ++ * zeros, mac biosen have stuff there so we must mask ++ */ ++ entry->crtconf.maxfreq = (bdcb->version < 0x30) ? ++ (conf & 0xffff) * 10 : ++ (conf & 0xff) * 10000; ++ break; ++ case OUTPUT_LVDS: ++ { ++ uint32_t mask; ++ if (conf & 0x1) ++ entry->lvdsconf.use_straps_for_mode = true; ++ if (bdcb->version < 0x22) { ++ mask = ~0xd; ++ /* the laptop in bug 14567 lies and claims to not use ++ * straps when it does, so assume all DCB 2.0 laptops ++ * use straps, until a broken EDID using one is produced ++ */ ++ entry->lvdsconf.use_straps_for_mode = true; ++ /* both 0x4 and 0x8 show up in v2.0 tables; assume they ++ * mean the same thing (probably wrong, but might work) ++ */ ++ if (conf & 0x4 || conf & 0x8) ++ entry->lvdsconf.use_power_scripts = true; ++ } else { ++ mask = ~0x5; ++ if (conf & 0x4) ++ entry->lvdsconf.use_power_scripts = true; ++ } ++ if (conf & mask) { ++ /* I'm bored of getting this reported; left as a reminder for someone to fix it */ ++ if (bdcb->version >= 0x40) { ++ NV_WARN(dev, "G80+ LVDS not initialized by driver; ignoring conf bits\n"); ++ break; ++ } ++ NV_ERROR(dev, "Unknown LVDS configuration bits, " ++ "please report\n"); ++ /* cause output setting to fail, so message is seen */ ++ bdcb->dcb.entries = 0; ++ return false; ++ } ++ break; ++ } ++ case 0xe: ++ /* weird g80 mobile type that "nv" treats as a terminator */ ++ bdcb->dcb.entries--; ++ return false; ++ } ++ /* unsure what DCB version introduces this, 3.0? */ ++ if (conf & 0x100000) ++ entry->i2c_upper_default = true; ++ ++ return true; ++} ++ ++static bool ++parse_dcb15_entry(struct drm_device *dev, struct parsed_dcb *dcb, ++ uint32_t conn, uint32_t conf, struct dcb_entry *entry) ++{ ++ if (conn != 0xf0003f00 && conn != 0xf2247f10 && ++ conn != 0xf2204001 && conn != 0xf2204301 && conn != 0xf2204311 && conn != 0xf2208001 && conn != 0xf2244001 && conn != 0xf2244301 && conn != 0xf2244311 && conn != 0xf4204011 && conn != 0xf4208011 && conn != 0xf4248011 && ++ conn != 0xf2045ff2 && ++ conn != 0xf2045f14 && conn != 0xf207df14 && conn != 0xf2205004) { ++ NV_ERROR(dev, "Unknown DCB 1.5 entry, please report\n"); ++ ++ /* cause output setting to fail for !TV, so message is seen */ ++ if ((conn & 0xf) != 0x1) ++ dcb->entries = 0; ++ ++ return false; ++ } ++ /* most of the below is a "best guess" atm */ ++ entry->type = conn & 0xf; ++ if (entry->type == 2) ++ /* another way of specifying straps based lvds... */ ++ entry->type = OUTPUT_LVDS; ++ if (entry->type == 4) { /* digital */ ++ if (conn & 0x10) ++ entry->type = OUTPUT_LVDS; ++ else ++ entry->type = OUTPUT_TMDS; ++ } ++ /* what's in bits 5-13? could be some encoder maker thing, in tv case */ ++ entry->i2c_index = (conn >> 14) & 0xf; ++ /* raw heads field is in range 0-1, so move to 1-2 */ ++ entry->heads = ((conn >> 18) & 0x7) + 1; ++ entry->location = (conn >> 21) & 0xf; ++ /* unused: entry->bus = (conn >> 25) & 0x7; */ ++ /* set or to be same as heads -- hopefully safe enough */ ++ entry->or = entry->heads; ++ entry->duallink_possible = false; ++ ++ switch (entry->type) { ++ case OUTPUT_ANALOG: ++ entry->crtconf.maxfreq = (conf & 0xffff) * 10; ++ break; ++ case OUTPUT_LVDS: ++ /* this is probably buried in conn's unknown bits */ ++ /* this will upset EDID-ful models, if they exist */ ++ entry->lvdsconf.use_straps_for_mode = true; ++ entry->lvdsconf.use_power_scripts = true; ++ break; ++ case OUTPUT_TMDS: ++ /* invent a DVI-A output, by copying the fields of the DVI-D ++ * output; reported to work by math_b on an NV20(!) */ ++ fabricate_vga_output(dcb, entry->i2c_index, entry->heads); ++ } ++ ++ return true; ++} ++ ++static bool parse_dcb_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, ++ uint32_t conn, uint32_t conf) ++{ ++ struct dcb_entry *entry = new_dcb_entry(&bdcb->dcb); ++ bool ret; ++ ++ if (bdcb->version >= 0x20) ++ ret = parse_dcb20_entry(dev, bdcb, conn, conf, entry); ++ else ++ ret = parse_dcb15_entry(dev, &bdcb->dcb, conn, conf, entry); ++ if (!ret) ++ return ret; ++ ++ read_dcb_i2c_entry(dev, bdcb->version, bdcb->i2c_table, ++ entry->i2c_index, &bdcb->dcb.i2c[entry->i2c_index]); ++ ++ return true; ++} ++ ++void merge_like_dcb_entries(struct drm_device *dev, struct parsed_dcb *dcb) ++{ ++ /* DCB v2.0 lists each output combination separately. ++ * Here we merge compatible entries to have fewer outputs, with more options ++ */ ++ ++ int i, newentries = 0; ++ ++ for (i = 0; i < dcb->entries; i++) { ++ struct dcb_entry *ient = &dcb->entry[i]; ++ int j; ++ ++ for (j = i + 1; j < dcb->entries; j++) { ++ struct dcb_entry *jent = &dcb->entry[j]; ++ ++ if (jent->type == 100) /* already merged entry */ ++ continue; ++ ++ /* merge heads field when all other fields the same */ ++ if (jent->i2c_index == ient->i2c_index && ++ jent->type == ient->type && ++ jent->location == ient->location && ++ jent->or == ient->or) { ++ NV_TRACE(dev, "Merging DCB entries %d and %d\n", ++ i, j); ++ ient->heads |= jent->heads; ++ jent->type = 100; /* dummy value */ ++ } ++ } ++ } ++ ++ /* Compact entries merged into others out of dcb */ ++ for (i = 0; i < dcb->entries; i++) { ++ if (dcb->entry[i].type == 100) ++ continue; ++ ++ if (newentries != i) { ++ dcb->entry[newentries] = dcb->entry[i]; ++ dcb->entry[newentries].index = newentries; ++ } ++ newentries++; ++ } ++ ++ dcb->entries = newentries; ++} ++ ++static int parse_dcb_table(struct drm_device *dev, struct nvbios *bios) ++{ ++ struct bios_parsed_dcb *bdcb = &bios->bdcb; ++ struct parsed_dcb *dcb; ++ uint16_t dcbptr, i2ctabptr = 0; ++ uint8_t *dcbtable; ++ uint8_t headerlen = 0x4, entries = DCB_MAX_NUM_ENTRIES; ++ bool configblock = true; ++ int recordlength = 8, confofs = 4; ++ int i; ++ ++ dcb = bios->pub.dcb = &bdcb->dcb; ++ dcb->entries = 0; ++ ++ /* get the offset from 0x36 */ ++ dcbptr = ROM16(bios->data[0x36]); ++ ++ if (dcbptr == 0x0) { ++ NV_WARN(dev, "No output data (DCB) found in BIOS, " ++ "assuming a CRT output exists\n"); ++ /* this situation likely means a really old card, pre DCB */ ++ fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1); ++ return 0; ++ } ++ ++ dcbtable = &bios->data[dcbptr]; ++ ++ /* get DCB version */ ++ bdcb->version = dcbtable[0]; ++ NV_TRACE(dev, "Found Display Configuration Block version %d.%d\n", ++ bdcb->version >> 4, bdcb->version & 0xf); ++ ++ if (bdcb->version >= 0x20) { /* NV17+ */ ++ uint32_t sig; ++ ++ if (bdcb->version >= 0x30) { /* NV40+ */ ++ headerlen = dcbtable[1]; ++ entries = dcbtable[2]; ++ recordlength = dcbtable[3]; ++ i2ctabptr = ROM16(dcbtable[4]); ++ sig = ROM32(dcbtable[6]); ++ if (bdcb->version == 0x40) /* G80 */ ++ bdcb->init8e_table_ptr = ++ ROM16(dcbtable[10]); ++ } else { ++ i2ctabptr = ROM16(dcbtable[2]); ++ sig = ROM32(dcbtable[4]); ++ headerlen = 8; ++ } ++ ++ if (sig != 0x4edcbdcb) { ++ NV_ERROR(dev, "Bad Display Configuration Block " ++ "signature (%08X)\n", sig); ++ return -EINVAL; ++ } ++ } else if (bdcb->version >= 0x15) { /* some NV11 and NV20 */ ++ char sig[8] = { 0 }; ++ ++ strncpy(sig, (char *)&dcbtable[-7], 7); ++ i2ctabptr = ROM16(dcbtable[2]); ++ recordlength = 10; ++ confofs = 6; ++ ++ if (strcmp(sig, "DEV_REC")) { ++ NV_ERROR(dev, "Bad Display Configuration Block " ++ "signature (%s)\n", sig); ++ return -EINVAL; ++ } ++ } else { ++ /* v1.4 (some NV15/16, NV11+) seems the same as v1.5, but always ++ * has the same single (crt) entry, even when tv-out present, so ++ * the conclusion is this version cannot really be used. ++ * v1.2 tables (some NV6/10, and NV15+) normally have the same ++ * 5 entries, which are not specific to the card and so no use. ++ * v1.2 does have an I2C table that read_dcb_i2c_table can ++ * handle, but cards exist (nv11 in #14821) with a bad i2c table ++ * pointer, so use the indices parsed in parse_bmp_structure. ++ * v1.1 (NV5+, maybe some NV4) is entirely unhelpful ++ */ ++ NV_TRACEWARN(dev, "No useful information in BIOS output table; " ++ "assuming a CRT output exists\n"); ++ fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1); ++ return 0; ++ } ++ ++ if (!i2ctabptr) ++ NV_WARN(dev, "No pointer to DCB I2C port table\n"); ++ else { ++ bdcb->i2c_table = &bios->data[i2ctabptr]; ++ if (bdcb->version >= 0x30) ++ bdcb->i2c_default_indices = bdcb->i2c_table[4]; ++ } ++ ++ if (entries > DCB_MAX_NUM_ENTRIES) ++ entries = DCB_MAX_NUM_ENTRIES; ++ ++ for (i = 0; i < entries; i++) { ++ uint32_t connection, config = 0; ++ ++ connection = ROM32(dcbtable[headerlen + recordlength * i]); ++ if (configblock) ++ config = ROM32(dcbtable[headerlen + confofs + recordlength * i]); ++ ++ /* Should we allow discontinuous DCBs? Certainly DCB I2C tables can be discontinuous */ ++ if ((connection & 0x0000000f) == 0x0000000f) /* end of records */ ++ break; ++ if (connection == 0x00000000) /* seen on an NV11 with DCB v1.5 */ ++ break; ++ ++ NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n", ++ dcb->entries, connection, config); ++ ++ if (!parse_dcb_entry(dev, bdcb, connection, config)) ++ break; ++ } ++ ++ /* apart for v2.1+ not being known for requiring merging, this ++ * guarantees dcbent->index is the index of the entry in the rom image ++ */ ++ if (bdcb->version < 0x21) ++ merge_like_dcb_entries(dev, dcb); ++ ++ return (dcb->entries ? 0 : -ENXIO); ++} ++ ++static void fixup_legacy_i2c(struct nvbios *bios) ++{ ++ struct parsed_dcb *dcb = &bios->bdcb.dcb; ++ int i; ++ ++ for (i = 0; i < dcb->entries; i++) ++ if (dcb->entry[i].i2c_index == LEGACY_I2C_CRT) ++ dcb->entry[i].i2c_index = bios->legacy.i2c_indices.crt; ++} ++ ++static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bios, uint16_t hwsq_offset, int entry) ++{ ++ /* The header following the "HWSQ" signature has the number of entries, ++ * and the entry size ++ * ++ * An entry consists of a dword to write to the sequencer control reg ++ * (0x00001304), followed by the ucode bytes, written sequentially, ++ * starting at reg 0x00001400 ++ */ ++ ++ uint8_t bytes_to_write; ++ uint16_t hwsq_entry_offset; ++ int i; ++ ++ if (bios->data[hwsq_offset] <= entry) { ++ NV_ERROR(dev, "Too few entries in HW sequencer table for " ++ "requested entry\n"); ++ return -ENOENT; ++ } ++ ++ bytes_to_write = bios->data[hwsq_offset + 1]; ++ ++ if (bytes_to_write != 36) { ++ NV_ERROR(dev, "Unknown HW sequencer entry size\n"); ++ return -EINVAL; ++ } ++ ++ NV_TRACE(dev, "Loading NV17 power sequencing microcode\n"); ++ ++ hwsq_entry_offset = hwsq_offset + 2 + entry * bytes_to_write; ++ ++ /* set sequencer control */ ++ bios_wr32(dev, 0x00001304, ROM32(bios->data[hwsq_entry_offset])); ++ bytes_to_write -= 4; ++ ++ /* write ucode */ ++ for (i = 0; i < bytes_to_write; i += 4) ++ bios_wr32(dev, 0x00001400 + i, ROM32(bios->data[hwsq_entry_offset + i + 4])); ++ ++ /* twiddle NV_PBUS_DEBUG_4 */ ++ bios_wr32(dev, NV_PBUS_DEBUG_4, bios_rd32(dev, NV_PBUS_DEBUG_4) | 0x18); ++ ++ return 0; ++} ++ ++static int load_nv17_hw_sequencer_ucode(struct drm_device *dev, struct nvbios *bios) ++{ ++ /* BMP based cards, from NV17, need a microcode loading to correctly ++ * control the GPIO etc for LVDS panels ++ * ++ * BIT based cards seem to do this directly in the init scripts ++ * ++ * The microcode entries are found by the "HWSQ" signature. ++ */ ++ ++ const uint8_t hwsq_signature[] = { 'H', 'W', 'S', 'Q' }; ++ int hwsq_offset; ++ ++ if (!(hwsq_offset = findstr(bios->data, bios->length, hwsq_signature, ++ sizeof(hwsq_signature)))) ++ return 0; ++ ++ /* always use entry 0? */ ++ return load_nv17_hwsq_ucode_entry(dev, bios, ++ hwsq_offset + sizeof(hwsq_signature), 0); ++} ++ ++uint8_t * nouveau_bios_embedded_edid(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ const uint8_t edid_sig[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; ++ uint16_t offset = 0, newoffset; ++ int searchlen = NV_PROM_SIZE; ++ ++ if (bios->fp.edid) ++ return bios->fp.edid; ++ ++ while (searchlen) { ++ if (!(newoffset = findstr(&bios->data[offset], searchlen, edid_sig, 8))) ++ return NULL; ++ offset += newoffset; ++ if (!nv_cksum(&bios->data[offset], EDID1_LEN)) ++ break; ++ ++ searchlen -= offset; ++ offset++; ++ } ++ ++ NV_TRACE(dev, "Found EDID in BIOS\n"); ++ ++ return (bios->fp.edid = &bios->data[offset]); ++} ++ ++bool NVInitVBIOS(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ ++ memset(bios, 0, sizeof(struct nvbios)); ++ ++ if (!NVShadowVBIOS(dev, bios->data)) ++ return false; ++ ++ bios->length = bios->data[2] * 512; ++ if (bios->length > NV_PROM_SIZE) ++ bios->length = NV_PROM_SIZE; ++ ++ return true; ++} ++ ++int nouveau_parse_vbios_struct(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' }; ++ const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 }; ++ int offset; ++ ++ if ((offset = findstr(bios->data, bios->length, bit_signature, sizeof(bit_signature)))) { ++ NV_TRACE(dev, "BIT BIOS found\n"); ++ return parse_bit_structure(dev, bios, offset + 6); ++ } ++ if ((offset = findstr(bios->data, bios->length, bmp_signature, sizeof(bmp_signature)))) { ++ NV_TRACE(dev, "BMP BIOS found\n"); ++ return parse_bmp_structure(dev, bios, offset); ++ } ++ ++ NV_ERROR(dev, "No known BIOS signature found\n"); ++ ++ return -ENODEV; ++} ++ ++int nouveau_run_vbios_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ int ret = 0; ++ ++ NV_ERROR(dev, "FIXME twoHeads\n"); ++ ++ NVLockVgaCrtcs(dev, false); ++ if (1) //dev->twoHeads) ++ NVSetOwner(dev, crtchead); ++ ++ if (bios->major_version < 5) /* BMP only */ ++ load_nv17_hw_sequencer_ucode(dev, bios); ++ ++ parse_init_tables(dev, bios); ++ ++ if (bios->major_version < 5) ++ /* feature_byte on BMP is poor, but init always sets CR4B */ ++ bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40; ++ ++ /* all BIT systems need p_f_m_t for digital_min_front_porch */ ++ if (bios->is_mobile || bios->major_version >= 5) ++ ret = parse_fp_mode_table(dev, bios); ++ ++ NVLockVgaCrtcs(dev, true); ++ ++ return ret; ++} ++ ++int nouveau_parse_bios(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ uint32_t saved_nv_pextdev_boot_0; ++ int ret; ++ ++ if (!NVInitVBIOS(dev)) ++ return -ENODEV; ++ if ((ret = nouveau_parse_vbios_struct(dev))) ++ return ret; ++ if ((ret = parse_dcb_table(dev, bios))) ++ return ret; ++ fixup_legacy_i2c(bios); ++ ++ if (!bios->major_version) /* we don't run version 0 bios */ ++ return 0; ++ ++ /* these will need remembering across a suspend */ ++ saved_nv_pextdev_boot_0 = bios_rd32(dev, NV_PEXTDEV_BOOT_0); ++ saved_nv_pfb_cfg0 = bios_rd32(dev, NV_PFB_CFG0); ++ ++ /* init script execution disabled */ ++ bios->execute = false; ++ ++ bios_wr32(dev, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0); ++ ++ dev_priv->vbios = &bios->pub; ++ ++ if ((ret = nouveau_run_vbios_init(dev))) { ++ dev_priv->vbios = NULL; ++ return ret; ++ } ++ ++ /* allow subsequent scripts to execute */ ++ bios->execute = true; ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h +new file mode 100644 +index 0000000..03445b3 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_bios.h +@@ -0,0 +1,209 @@ ++/* ++ * Copyright 2007-2008 Nouveau Project ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef __NOUVEAU_BIOS_H__ ++#define __NOUVEAU_BIOS_H__ ++ ++#include "nvreg.h" ++#include "nouveau_i2c.h" ++ ++#define DCB_MAX_NUM_ENTRIES 16 ++#define DCB_MAX_NUM_I2C_ENTRIES 16 ++ ++#define DCB_LOC_ON_CHIP 0 ++ ++struct dcb_entry { ++ int index; /* may not be raw dcb index if merging has happened */ ++ uint8_t type; ++ uint8_t i2c_index; ++ uint8_t heads; ++ uint8_t bus; ++ uint8_t location; ++ uint8_t or; ++ bool duallink_possible; ++ union { ++ struct { ++ int maxfreq; ++ } crtconf; ++ struct { ++ bool use_straps_for_mode; ++ bool use_power_scripts; ++ } lvdsconf; ++ }; ++ bool i2c_upper_default; ++}; ++ ++struct dcb_i2c_entry { ++ uint8_t port_type; ++ uint8_t read, write; ++ struct nouveau_i2c_chan *chan; ++}; ++ ++struct parsed_dcb { ++ int entries; ++ struct dcb_entry entry[DCB_MAX_NUM_ENTRIES]; ++ struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES]; ++}; ++ ++struct bios_parsed_dcb { ++ uint8_t version; ++ ++ struct parsed_dcb dcb; ++ ++ uint16_t init8e_table_ptr; ++ uint8_t *i2c_table; ++ uint8_t i2c_default_indices; ++}; ++ ++enum nouveau_encoder_type ++{ ++ /* 0-3 match DCB types */ ++ OUTPUT_NONE = 4, ++ OUTPUT_ANALOG = 0, ++ OUTPUT_TMDS = 2, ++ OUTPUT_LVDS = 3, ++ OUTPUT_TV = 1, ++ OUTPUT_ANY = 5, ++}; ++ ++enum nouveau_or { ++ OUTPUT_A = (1 << 0), ++ OUTPUT_B = (1 << 1), ++ OUTPUT_C = (1 << 2) ++}; ++ ++enum LVDS_script { ++ /* Order *does* matter here */ ++ LVDS_INIT = 1, ++ LVDS_RESET, ++ LVDS_BACKLIGHT_ON, ++ LVDS_BACKLIGHT_OFF, ++ LVDS_PANEL_ON, ++ LVDS_PANEL_OFF ++}; ++ ++/* changing these requires matching changes to reg tables in nv_get_clock */ ++#define MAX_PLL_TYPES 4 ++enum pll_types { ++ NVPLL, ++ MPLL, ++ VPLL1, ++ VPLL2 ++}; ++ ++struct pll_lims { ++ struct { ++ int minfreq; ++ int maxfreq; ++ int min_inputfreq; ++ int max_inputfreq; ++ ++ uint8_t min_m; ++ uint8_t max_m; ++ uint8_t min_n; ++ uint8_t max_n; ++ } vco1, vco2; ++ ++ uint8_t max_log2p_bias; ++ uint8_t log2p_bias; ++ int refclk; ++}; ++ ++struct nouveau_bios_info { ++ struct parsed_dcb *dcb; ++ ++ uint8_t chip_version; ++ ++ uint32_t dactestval; ++ uint8_t digital_min_front_porch; ++ bool fp_no_ddc; ++}; ++ ++struct nvbios { ++ struct nouveau_bios_info pub; ++ ++ uint8_t data[NV_PROM_SIZE]; ++ unsigned int length; ++ bool execute; ++ ++ uint8_t major_version; ++ uint8_t feature_byte; ++ bool is_mobile; ++ ++ uint32_t fmaxvco, fminvco; ++ ++ bool old_style_init; ++ uint16_t init_script_tbls_ptr; ++ uint16_t extra_init_script_tbl_ptr; ++ uint16_t macro_index_tbl_ptr; ++ uint16_t macro_tbl_ptr; ++ uint16_t condition_tbl_ptr; ++ uint16_t io_condition_tbl_ptr; ++ uint16_t io_flag_condition_tbl_ptr; ++ uint16_t init_function_tbl_ptr; ++ ++ uint16_t pll_limit_tbl_ptr; ++ uint16_t ram_restrict_tbl_ptr; ++ ++ struct bios_parsed_dcb bdcb; ++ ++ struct { ++ uint16_t fptablepointer; /* also used by tmds */ ++ uint16_t fpxlatetableptr; ++ int xlatwidth; ++ uint16_t lvdsmanufacturerpointer; ++ uint16_t fpxlatemanufacturertableptr; ++ uint16_t mode_ptr; ++ uint16_t xlated_entry; ++ bool power_off_for_reset; ++ bool reset_after_pclk_change; ++ bool dual_link; ++ bool link_c_increment; ++ bool BITbit1; ++ int duallink_transition_clk; ++ uint8_t *edid; ++ ++ /* will need resetting after suspend */ ++ int last_script_invoc; ++ bool lvds_init_run; ++ } fp; ++ ++ struct { ++ uint16_t output0_script_ptr; ++ uint16_t output1_script_ptr; ++ } tmds; ++ ++ struct { ++ uint16_t mem_init_tbl_ptr; ++ uint16_t sdr_seq_tbl_ptr; ++ uint16_t ddr_seq_tbl_ptr; ++ ++ struct { ++ uint8_t crt, tv, panel; ++ } i2c_indices; ++ ++ uint16_t lvds_single_a_script_ptr; ++ } legacy; ++}; ++ ++#endif +diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c +new file mode 100644 +index 0000000..0f80857 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c +@@ -0,0 +1,415 @@ ++/* ++ * Copyright 2007 Dave Airlied ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++/* ++ * Authors: Dave Airlied ++ * Ben Skeggs ++ * Jeremy Kolb ++ */ ++ ++#include "drmP.h" ++#include "nouveau_drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++ ++static struct drm_ttm_backend * ++nouveau_bo_create_ttm_backend_entry(struct drm_device * dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ switch (dev_priv->gart_info.type) { ++ case NOUVEAU_GART_AGP: ++ return drm_agp_init_ttm(dev); ++ case NOUVEAU_GART_SGDMA: ++ return nouveau_sgdma_init_ttm(dev); ++ default: ++ NV_ERROR(dev, "Unknown GART type %d\n", dev_priv->gart_info.type); ++ break; ++ } ++ ++ return NULL; ++} ++ ++static int ++nouveau_bo_fence_type(struct drm_buffer_object *bo, ++ uint32_t *fclass, uint32_t *type) ++{ ++ /* When we get called, *fclass is set to the requested fence class */ ++ *type = 1; ++ return 0; ++ ++} ++ ++static int ++nouveau_bo_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags) ++{ ++ /* We'll do this from user space. */ ++ return 0; ++} ++ ++static int ++nouveau_bo_init_mem_type(struct drm_device *dev, uint32_t type, ++ struct drm_mem_type_manager *man) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ switch (type) { ++ case DRM_BO_MEM_LOCAL: ++ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | ++ _DRM_FLAG_MEMTYPE_CACHED; ++ man->drm_bus_maptype = 0; ++ break; ++ case DRM_BO_MEM_VRAM: ++ man->flags = _DRM_FLAG_MEMTYPE_FIXED | ++ _DRM_FLAG_MEMTYPE_MAPPABLE | ++ _DRM_FLAG_NEEDS_IOREMAP; ++ man->io_addr = NULL; ++ man->drm_bus_maptype = _DRM_FRAME_BUFFER; ++ man->io_offset = drm_get_resource_start(dev, 1); ++ man->io_size = drm_get_resource_len(dev, 1); ++ if (man->io_size > nouveau_mem_fb_amount(dev)) ++ man->io_size = nouveau_mem_fb_amount(dev); ++ man->gpu_offset = dev_priv->vm_vram_base; ++ break; ++ case DRM_BO_MEM_PRIV0: ++ /* Unmappable VRAM */ ++ man->flags = _DRM_FLAG_MEMTYPE_CMA; ++ man->drm_bus_maptype = 0; ++ break; ++ case DRM_BO_MEM_TT: ++ switch (dev_priv->gart_info.type) { ++ case NOUVEAU_GART_AGP: ++ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | ++ _DRM_FLAG_MEMTYPE_CSELECT | ++ _DRM_FLAG_NEEDS_IOREMAP; ++ man->drm_bus_maptype = _DRM_AGP; ++ break; ++ case NOUVEAU_GART_SGDMA: ++ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | ++ _DRM_FLAG_MEMTYPE_CSELECT | ++ _DRM_FLAG_MEMTYPE_CMA; ++ man->drm_bus_maptype = _DRM_SCATTER_GATHER; ++ break; ++ default: ++ NV_ERROR(dev, "Unknown GART type: %d\n", ++ dev_priv->gart_info.type); ++ return -EINVAL; ++ } ++ ++ man->io_offset = dev_priv->gart_info.aper_base; ++ man->io_size = dev_priv->gart_info.aper_size; ++ man->io_addr = NULL; ++ man->gpu_offset = dev_priv->vm_gart_base; ++ break; ++ default: ++ NV_ERROR(dev, "Unsupported memory type %u\n", (unsigned)type); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static uint64_t ++nouveau_bo_evict_flags(struct drm_buffer_object *bo) ++{ ++ switch (bo->mem.mem_type) { ++ case DRM_BO_MEM_LOCAL: ++ case DRM_BO_MEM_TT: ++ return DRM_BO_FLAG_MEM_LOCAL; ++ default: ++ return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED; ++ } ++ return 0; ++} ++ ++ ++/* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access ++ * DRM_BO_MEM_{VRAM,PRIV0,TT} directly. ++ */ ++static inline uint32_t ++nouveau_bo_mem_ctxdma(struct nouveau_channel *chan, struct drm_bo_mem_reg *mem) ++{ ++ if (mem->mem_type == DRM_BO_MEM_TT) ++ return chan->gart_handle; ++ ++ return chan->vram_handle; ++} ++ ++static int ++nouveau_bo_move_m2mf(struct drm_buffer_object *bo, int evict, int no_wait, ++ struct drm_bo_mem_reg *old_mem, ++ struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan; ++ uint64_t src_offset, dst_offset; ++ uint32_t page_count; ++ ++ chan = nouveau_fence_channel(dev, bo->new_fence_class); ++ if (!chan) { ++ NV_ERROR(dev, "channel %d non-existant, using kchan\n", ++ bo->fence_class); ++ ++ chan = dev_priv->channel; ++ if (!chan) ++ return -EINVAL; ++ } ++ ++ src_offset = old_mem->mm_node->start << PAGE_SHIFT; ++ dst_offset = new_mem->mm_node->start << PAGE_SHIFT; ++ if (dev_priv->card_type >= NV_50 && ++ !(new_mem->proposed_flags & DRM_NOUVEAU_BO_FLAG_NOVM)) { ++ /* It's quite possibly safe to use bo->offset for src */ ++ if (old_mem->mem_type == DRM_BO_MEM_TT) ++ src_offset += dev_priv->vm_gart_base; ++ else ++ src_offset += dev_priv->vm_vram_base; ++ ++ if (new_mem->mem_type == DRM_BO_MEM_TT) ++ dst_offset += dev_priv->vm_gart_base; ++ else ++ dst_offset += dev_priv->vm_vram_base; ++ } ++ ++ RING_SPACE(chan, 3); ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2); ++ OUT_RING (chan, nouveau_bo_mem_ctxdma(chan, old_mem)); ++ OUT_RING (chan, nouveau_bo_mem_ctxdma(chan, new_mem)); ++ ++ if (dev_priv->card_type >= NV_50) { ++ RING_SPACE(chan, 4); ++ BEGIN_RING(chan, NvSubM2MF, 0x0200, 1); ++ OUT_RING (chan, 1); ++ BEGIN_RING(chan, NvSubM2MF, 0x021c, 1); ++ OUT_RING (chan, 1); ++ } ++ ++ page_count = new_mem->num_pages; ++ while (page_count) { ++ int line_count = (page_count > 2047) ? 2047 : page_count; ++ ++ if (dev_priv->card_type >= NV_50) { ++ RING_SPACE(chan, 3); ++ BEGIN_RING(chan, NvSubM2MF, 0x0238, 2); ++ OUT_RING (chan, upper_32_bits(src_offset)); ++ OUT_RING (chan, upper_32_bits(dst_offset)); ++ } ++ RING_SPACE(chan, 11); ++ BEGIN_RING(chan, NvSubM2MF, ++ NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); ++ OUT_RING (chan, lower_32_bits(src_offset)); ++ OUT_RING (chan, lower_32_bits(dst_offset)); ++ OUT_RING (chan, PAGE_SIZE); /* src_pitch */ ++ OUT_RING (chan, PAGE_SIZE); /* dst_pitch */ ++ OUT_RING (chan, PAGE_SIZE); /* line_length */ ++ OUT_RING (chan, line_count); ++ OUT_RING (chan, (1<<8)|(1<<0)); ++ OUT_RING (chan, 0); ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1); ++ OUT_RING (chan, 0); ++ ++ page_count -= line_count; ++ src_offset += (PAGE_SIZE * line_count); ++ dst_offset += (PAGE_SIZE * line_count); ++ } ++ ++ return drm_bo_move_accel_cleanup(bo, evict, no_wait, chan->id, ++ DRM_FENCE_TYPE_EXE, 0, new_mem); ++} ++ ++/* Flip pages into the GART and move if we can. */ ++static int ++nouveau_bo_move_flipd(struct drm_buffer_object *bo, int evict, int no_wait, ++ struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_bo_mem_reg tmp_mem; ++ int ret; ++ ++ tmp_mem = *new_mem; ++ tmp_mem.mm_node = NULL; ++ tmp_mem.proposed_flags = (DRM_BO_FLAG_MEM_TT | ++ DRM_BO_FLAG_CACHED | ++ DRM_BO_FLAG_FORCE_CACHING); ++ ++ ret = drm_bo_mem_space(bo, &tmp_mem, no_wait); ++ if (ret) ++ return ret; ++ ++ ret = drm_ttm_bind(bo->ttm, &tmp_mem); ++ if (ret) ++ goto out_cleanup; ++ ++ ret = nouveau_bo_move_m2mf(bo, 1, no_wait, &bo->mem, &tmp_mem); ++ if (ret) ++ goto out_cleanup; ++ ++ ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem); ++ ++out_cleanup: ++ if (tmp_mem.mm_node) { ++ mutex_lock(&dev->struct_mutex); ++ if (tmp_mem.mm_node != bo->pinned_node) ++ drm_mm_put_block(tmp_mem.mm_node); ++ tmp_mem.mm_node = NULL; ++ mutex_unlock(&dev->struct_mutex); ++ } ++ ++ return ret; ++} ++ ++static int ++nouveau_bo_move_flips(struct drm_buffer_object *bo, int evict, int no_wait, ++ struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_device *dev = bo->dev; ++ struct drm_bo_mem_reg tmp_mem; ++ int ret = 0; ++ ++ tmp_mem = bo->mem; ++ tmp_mem.mm_node = NULL; ++ tmp_mem.proposed_flags = DRM_BO_FLAG_MEM_TT; ++ ret = drm_bo_mem_space(bo, &tmp_mem, no_wait); ++ if (ret) ++ return ret; ++ ++ if (!bo->ttm) { ++ ret = drm_bo_add_ttm(bo); ++ if (ret) ++ goto out_cleanup; ++ } ++ ++ ret = drm_bo_move_ttm(bo, evict, no_wait, &tmp_mem); ++ if (ret) ++ goto out_cleanup; ++ ++ ret = nouveau_bo_move_m2mf(bo, 1, no_wait, &bo->mem, new_mem); ++ if (ret) ++ goto out_cleanup; ++ ++out_cleanup: ++ if (tmp_mem.mm_node) { ++ mutex_lock(&dev->struct_mutex); ++ if (tmp_mem.mm_node != bo->pinned_node) ++ drm_mm_put_block(tmp_mem.mm_node); ++ tmp_mem.mm_node = NULL; ++ mutex_lock(&dev->struct_mutex); ++ } ++ ++ return ret; ++} ++ ++static int ++nouveau_bo_move(struct drm_buffer_object *bo, int evict, int no_wait, ++ struct drm_bo_mem_reg *new_mem) ++{ ++ struct drm_nouveau_private *dev_priv = bo->dev->dev_private; ++ struct drm_bo_mem_reg *old_mem = &bo->mem; ++ int ret; ++ ++ if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE) ++ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ ++ if (dev_priv->card_type == NV_50 && ++ (new_mem->mem_type == DRM_BO_MEM_VRAM || ++ new_mem->mem_type == DRM_BO_MEM_PRIV0) && ++ !(new_mem->proposed_flags & DRM_NOUVEAU_BO_FLAG_NOVM)) { ++ uint64_t offset = new_mem->mm_node->start << PAGE_SHIFT; ++ unsigned tile = 0; ++ ++ if (new_mem->proposed_flags & DRM_NOUVEAU_BO_FLAG_TILE) { ++ if (new_mem->proposed_flags & DRM_NOUVEAU_BO_FLAG_ZTILE) ++ tile = 0x00002800; ++ else ++ tile = 0x00007000; ++ } ++ ++ ret = nv50_mem_vm_bind_linear(bo->dev, ++ offset + dev_priv->vm_vram_base, ++ new_mem->size, tile, offset); ++ if (ret) ++ return ret; ++ } ++ ++ if (old_mem->flags & DRM_BO_FLAG_CLEAN) { ++ return drm_bo_move_accel_cleanup(bo, 1, no_wait, ++ bo->new_fence_class, ++ DRM_FENCE_TYPE_EXE, 0, ++ new_mem); ++ } ++ ++ if (dev_priv->card_type == NV_50 && ++ new_mem->proposed_flags & DRM_NOUVEAU_BO_FLAG_TILE) ++ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ ++ if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { ++ if (old_mem->mem_type == DRM_BO_MEM_LOCAL) ++ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ if (nouveau_bo_move_flipd(bo, evict, no_wait, new_mem)) ++ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ } ++ else ++ if (old_mem->mem_type == DRM_BO_MEM_LOCAL) { ++ if (nouveau_bo_move_flips(bo, evict, no_wait, new_mem)) ++ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ } ++ else { ++ if (nouveau_bo_move_m2mf(bo, evict, no_wait, old_mem, new_mem)) ++ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ } ++ ++ return 0; ++} ++ ++static void ++nouveau_bo_flush_ttm(struct drm_ttm *ttm) ++{ ++} ++ ++static uint32_t nouveau_mem_prios[] = { ++ DRM_BO_MEM_PRIV0, ++ DRM_BO_MEM_VRAM, ++ DRM_BO_MEM_TT, ++ DRM_BO_MEM_LOCAL ++}; ++static uint32_t nouveau_busy_prios[] = { ++ DRM_BO_MEM_TT, ++ DRM_BO_MEM_PRIV0, ++ DRM_BO_MEM_VRAM, ++ DRM_BO_MEM_LOCAL ++}; ++ ++struct drm_bo_driver nouveau_bo_driver = { ++ .mem_type_prio = nouveau_mem_prios, ++ .mem_busy_prio = nouveau_busy_prios, ++ .num_mem_type_prio = sizeof(nouveau_mem_prios)/sizeof(uint32_t), ++ .num_mem_busy_prio = sizeof(nouveau_busy_prios)/sizeof(uint32_t), ++ .create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry, ++ .fence_type = nouveau_bo_fence_type, ++ .invalidate_caches = nouveau_bo_invalidate_caches, ++ .init_mem_type = nouveau_bo_init_mem_type, ++ .evict_flags = nouveau_bo_evict_flags, ++ .move = nouveau_bo_move, ++ .ttm_cache_flush= nouveau_bo_flush_ttm, ++ .command_stream_barrier = NULL ++}; +diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c +new file mode 100644 +index 0000000..1f5fcd5 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_calc.c +@@ -0,0 +1,627 @@ ++/* ++ * Copyright 1993-2003 NVIDIA, Corporation ++ * Copyright 2007-2009 Stuart Bennett ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF ++ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_hw.h" ++ ++/****************************************************************************\ ++* * ++* The video arbitration routines calculate some "magic" numbers. Fixes * ++* the snow seen when accessing the framebuffer without it. * ++* It just works (I hope). * ++* * ++\****************************************************************************/ ++ ++struct nv_fifo_info { ++ int graphics_lwm; ++ int video_lwm; ++ int graphics_burst_size; ++ int video_burst_size; ++ bool valid; ++}; ++ ++struct nv_sim_state { ++ int pclk_khz; ++ int mclk_khz; ++ int nvclk_khz; ++ int pix_bpp; ++ bool enable_mp; ++ bool enable_video; ++ int mem_page_miss; ++ int mem_latency; ++ int memory_type; ++ int memory_width; ++}; ++ ++static void ++nv4CalcArbitration(struct nv_fifo_info *fifo, struct nv_sim_state *arb) ++{ ++ int pagemiss, cas, width, video_enable, bpp; ++ int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs; ++ int found, mclk_extra, mclk_loop, cbs, m1, p1; ++ int mclk_freq, pclk_freq, nvclk_freq, mp_enable; ++ int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate; ++ int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt, clwm; ++ ++ pclk_freq = arb->pclk_khz; ++ mclk_freq = arb->mclk_khz; ++ nvclk_freq = arb->nvclk_khz; ++ pagemiss = arb->mem_page_miss; ++ cas = arb->mem_latency; ++ width = arb->memory_width >> 6; ++ video_enable = arb->enable_video; ++ bpp = arb->pix_bpp; ++ mp_enable = arb->enable_mp; ++ clwm = 0; ++ vlwm = 0; ++ cbs = 128; ++ pclks = 2; ++ nvclks = 2; ++ nvclks += 2; ++ nvclks += 1; ++ mclks = 5; ++ mclks += 3; ++ mclks += 1; ++ mclks += cas; ++ mclks += 1; ++ mclks += 1; ++ mclks += 1; ++ mclks += 1; ++ mclk_extra = 3; ++ nvclks += 2; ++ nvclks += 1; ++ nvclks += 1; ++ nvclks += 1; ++ if (mp_enable) ++ mclks += 4; ++ nvclks += 0; ++ pclks += 0; ++ found = 0; ++ vbs = 0; ++ while (found != 1) { ++ fifo->valid = true; ++ found = 1; ++ mclk_loop = mclks + mclk_extra; ++ us_m = mclk_loop * 1000 * 1000 / mclk_freq; ++ us_n = nvclks * 1000 * 1000 / nvclk_freq; ++ us_p = nvclks * 1000 * 1000 / pclk_freq; ++ if (video_enable) { ++ video_drain_rate = pclk_freq * 2; ++ crtc_drain_rate = pclk_freq * bpp / 8; ++ vpagemiss = 2; ++ vpagemiss += 1; ++ crtpagemiss = 2; ++ vpm_us = vpagemiss * pagemiss * 1000 * 1000 / mclk_freq; ++ if (nvclk_freq * 2 > mclk_freq * width) ++ video_fill_us = cbs * 1000 * 1000 / 16 / nvclk_freq; ++ else ++ video_fill_us = cbs * 1000 * 1000 / (8 * width) / mclk_freq; ++ us_video = vpm_us + us_m + us_n + us_p + video_fill_us; ++ vlwm = us_video * video_drain_rate / (1000 * 1000); ++ vlwm++; ++ vbs = 128; ++ if (vlwm > 128) ++ vbs = 64; ++ if (vlwm > (256 - 64)) ++ vbs = 32; ++ if (nvclk_freq * 2 > mclk_freq * width) ++ video_fill_us = vbs * 1000 * 1000 / 16 / nvclk_freq; ++ else ++ video_fill_us = vbs * 1000 * 1000 / (8 * width) / mclk_freq; ++ cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq; ++ us_crt = us_video + video_fill_us + cpm_us + us_m + us_n + us_p; ++ clwm = us_crt * crtc_drain_rate / (1000 * 1000); ++ clwm++; ++ } else { ++ crtc_drain_rate = pclk_freq * bpp / 8; ++ crtpagemiss = 2; ++ crtpagemiss += 1; ++ cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq; ++ us_crt = cpm_us + us_m + us_n + us_p; ++ clwm = us_crt * crtc_drain_rate / (1000 * 1000); ++ clwm++; ++ } ++ m1 = clwm + cbs - 512; ++ p1 = m1 * pclk_freq / mclk_freq; ++ p1 = p1 * bpp / 8; ++ if ((p1 < m1 && m1 > 0) || ++ (video_enable && (clwm > 511 || vlwm > 255)) || ++ (!video_enable && clwm > 519)) { ++ fifo->valid = false; ++ found = !mclk_extra; ++ mclk_extra--; ++ } ++ if (clwm < 384) ++ clwm = 384; ++ if (vlwm < 128) ++ vlwm = 128; ++ fifo->graphics_lwm = clwm; ++ fifo->graphics_burst_size = 128; ++ fifo->video_lwm = vlwm + 15; ++ fifo->video_burst_size = vbs; ++ } ++} ++ ++static void ++nv10CalcArbitration(struct nv_fifo_info *fifo, struct nv_sim_state *arb) ++{ ++ int pagemiss, width, video_enable, bpp; ++ int nvclks, mclks, pclks, vpagemiss, crtpagemiss; ++ int nvclk_fill; ++ int found, mclk_extra, mclk_loop, cbs, m1; ++ int mclk_freq, pclk_freq, nvclk_freq, mp_enable; ++ int us_m, us_m_min, us_n, us_p, crtc_drain_rate; ++ int vus_m; ++ int vpm_us, us_video, cpm_us, us_crt, clwm; ++ int clwm_rnd_down; ++ int m2us, us_pipe_min, p1clk, p2; ++ int min_mclk_extra; ++ int us_min_mclk_extra; ++ ++ pclk_freq = arb->pclk_khz; /* freq in KHz */ ++ mclk_freq = arb->mclk_khz; ++ nvclk_freq = arb->nvclk_khz; ++ pagemiss = arb->mem_page_miss; ++ width = arb->memory_width / 64; ++ video_enable = arb->enable_video; ++ bpp = arb->pix_bpp; ++ mp_enable = arb->enable_mp; ++ clwm = 0; ++ cbs = 512; ++ pclks = 4; /* lwm detect. */ ++ nvclks = 3; /* lwm -> sync. */ ++ nvclks += 2; /* fbi bus cycles (1 req + 1 busy) */ ++ mclks = 1; /* 2 edge sync. may be very close to edge so just put one. */ ++ mclks += 1; /* arb_hp_req */ ++ mclks += 5; /* ap_hp_req tiling pipeline */ ++ mclks += 2; /* tc_req latency fifo */ ++ mclks += 2; /* fb_cas_n_ memory request to fbio block */ ++ mclks += 7; /* sm_d_rdv data returned from fbio block */ ++ ++ /* fb.rd.d.Put_gc need to accumulate 256 bits for read */ ++ if (arb->memory_type == 0) { ++ if (arb->memory_width == 64) /* 64 bit bus */ ++ mclks += 4; ++ else ++ mclks += 2; ++ } else if (arb->memory_width == 64) /* 64 bit bus */ ++ mclks += 2; ++ else ++ mclks += 1; ++ ++ if (!video_enable && arb->memory_width == 128) { ++ mclk_extra = (bpp == 32) ? 31 : 42; /* Margin of error */ ++ min_mclk_extra = 17; ++ } else { ++ mclk_extra = (bpp == 32) ? 8 : 4; /* Margin of error */ ++ /* mclk_extra = 4; *//* Margin of error */ ++ min_mclk_extra = 18; ++ } ++ ++ nvclks += 1; /* 2 edge sync. may be very close to edge so just put one. */ ++ nvclks += 1; /* fbi_d_rdv_n */ ++ nvclks += 1; /* Fbi_d_rdata */ ++ nvclks += 1; /* crtfifo load */ ++ ++ if (mp_enable) ++ mclks += 4; /* Mp can get in with a burst of 8. */ ++ /* Extra clocks determined by heuristics */ ++ ++ nvclks += 0; ++ pclks += 0; ++ found = 0; ++ while (found != 1) { ++ fifo->valid = true; ++ found = 1; ++ mclk_loop = mclks + mclk_extra; ++ us_m = mclk_loop * 1000 * 1000 / mclk_freq; /* Mclk latency in us */ ++ us_m_min = mclks * 1000 * 1000 / mclk_freq; /* Minimum Mclk latency in us */ ++ us_min_mclk_extra = min_mclk_extra * 1000 * 1000 / mclk_freq; ++ us_n = nvclks * 1000 * 1000 / nvclk_freq; /* nvclk latency in us */ ++ us_p = pclks * 1000 * 1000 / pclk_freq; /* nvclk latency in us */ ++ us_pipe_min = us_m_min + us_n + us_p; ++ ++ vus_m = mclk_loop * 1000 * 1000 / mclk_freq; /* Mclk latency in us */ ++ ++ if (video_enable) { ++ crtc_drain_rate = pclk_freq * bpp / 8; /* MB/s */ ++ ++ vpagemiss = 1; /* self generating page miss */ ++ vpagemiss += 1; /* One higher priority before */ ++ ++ crtpagemiss = 2; /* self generating page miss */ ++ if (mp_enable) ++ crtpagemiss += 1; /* if MA0 conflict */ ++ ++ vpm_us = vpagemiss * pagemiss * 1000 * 1000 / mclk_freq; ++ ++ us_video = vpm_us + vus_m; /* Video has separate read return path */ ++ ++ cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq; ++ us_crt = us_video /* Wait for video */ ++ + cpm_us /* CRT Page miss */ ++ + us_m + us_n + us_p; /* other latency */ ++ ++ clwm = us_crt * crtc_drain_rate / (1000 * 1000); ++ clwm++; /* fixed point <= float_point - 1. Fixes that */ ++ } else { ++ crtc_drain_rate = pclk_freq * bpp / 8; /* bpp * pclk/8 */ ++ ++ crtpagemiss = 1; /* self generating page miss */ ++ crtpagemiss += 1; /* MA0 page miss */ ++ if (mp_enable) ++ crtpagemiss += 1; /* if MA0 conflict */ ++ cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq; ++ us_crt = cpm_us + us_m + us_n + us_p; ++ clwm = us_crt * crtc_drain_rate / (1000 * 1000); ++ clwm++; /* fixed point <= float_point - 1. Fixes that */ ++ ++ /* Finally, a heuristic check when width == 64 bits */ ++ if (width == 1) { ++ nvclk_fill = nvclk_freq * 8; ++ if (crtc_drain_rate * 100 >= nvclk_fill * 102) ++ clwm = 0xfff; /* Large number to fail */ ++ else if (crtc_drain_rate * 100 >= nvclk_fill * 98) { ++ clwm = 1024; ++ cbs = 512; ++ } ++ } ++ } ++ ++ /* ++ * Overfill check: ++ */ ++ ++ clwm_rnd_down = (clwm / 8) * 8; ++ if (clwm_rnd_down < clwm) ++ clwm += 8; ++ ++ m1 = clwm + cbs - 1024; /* Amount of overfill */ ++ m2us = us_pipe_min + us_min_mclk_extra; ++ ++ /* pclk cycles to drain */ ++ p1clk = m2us * pclk_freq / (1000 * 1000); ++ p2 = p1clk * bpp / 8; /* bytes drained. */ ++ ++ if (p2 < m1 && m1 > 0) { ++ fifo->valid = false; ++ found = 0; ++ if (min_mclk_extra == 0) { ++ if (cbs <= 32) ++ found = 1; /* Can't adjust anymore! */ ++ else ++ cbs = cbs / 2; /* reduce the burst size */ ++ } else ++ min_mclk_extra--; ++ } else if (clwm > 1023) { /* Have some margin */ ++ fifo->valid = false; ++ found = 0; ++ if (min_mclk_extra == 0) ++ found = 1; /* Can't adjust anymore! */ ++ else ++ min_mclk_extra--; ++ } ++ ++ if (clwm < (1024 - cbs + 8)) ++ clwm = 1024 - cbs + 8; ++ /* printf("CRT LWM: prog: 0x%x, bs: 256\n", clwm); */ ++ fifo->graphics_lwm = clwm; ++ fifo->graphics_burst_size = cbs; ++ ++ fifo->video_lwm = 1024; ++ fifo->video_burst_size = 512; ++ } ++} ++ ++void ++nv4_10UpdateArbitrationSettings(struct drm_device *dev, int VClk, int bpp, ++ int *burst, int *lwm) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv_fifo_info fifo_data; ++ struct nv_sim_state sim_data; ++ int MClk = nouveau_hw_get_clock(dev, MPLL); ++ int NVClk = nouveau_hw_get_clock(dev, NVPLL); ++ uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1); ++ ++ sim_data.pclk_khz = VClk; ++ sim_data.mclk_khz = MClk; ++ sim_data.nvclk_khz = NVClk; ++ sim_data.pix_bpp = bpp; ++ sim_data.enable_mp = false; ++ if ((dev->pci_device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ || ++ (dev->pci_device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) { ++ uint32_t type; ++ ++ pci_read_config_dword(pci_get_bus_and_slot(0, 1), 0x7c, &type); ++ ++ sim_data.enable_video = false; ++ sim_data.memory_type = (type >> 12) & 1; ++ sim_data.memory_width = 64; ++ sim_data.mem_latency = 3; ++ sim_data.mem_page_miss = 10; ++ } else { ++ sim_data.enable_video = (dev_priv->card_type != NV_04); ++ sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1; ++ sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; ++ sim_data.mem_latency = cfg1 & 0xf; ++ sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1); ++ } ++ ++ if (dev_priv->card_type == NV_04) ++ nv4CalcArbitration(&fifo_data, &sim_data); ++ else ++ nv10CalcArbitration(&fifo_data, &sim_data); ++ ++ if (fifo_data.valid) { ++ int b = fifo_data.graphics_burst_size >> 4; ++ *burst = 0; ++ while (b >>= 1) ++ (*burst)++; ++ *lwm = fifo_data.graphics_lwm >> 3; ++ } ++} ++ ++void ++nv30UpdateArbitrationSettings(int *burst, int *lwm) ++{ ++ unsigned int fifo_size, burst_size, graphics_lwm; ++ ++ fifo_size = 2048; ++ burst_size = 512; ++ graphics_lwm = fifo_size - burst_size; ++ ++ *burst = 0; ++ burst_size >>= 5; ++ while (burst_size >>= 1) ++ (*burst)++; ++ *lwm = graphics_lwm >> 3; ++} ++ ++void ++nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->card_type < NV_30) ++ nv4_10UpdateArbitrationSettings(dev, vclk, bpp, burst, lwm); ++ else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ || ++ (dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) { ++ *burst = 128; ++ *lwm = 0x0480; ++ } else ++ nv30UpdateArbitrationSettings(burst, lwm); ++} ++ ++static int ++getMNP_single(struct drm_device *dev, struct pll_lims *pll_lim, int clk, ++ struct nouveau_pll_vals *bestpv) ++{ ++ /* Find M, N and P for a single stage PLL ++ * ++ * Note that some bioses (NV3x) have lookup tables of precomputed MNP ++ * values, but we're too lazy to use those atm ++ * ++ * "clk" parameter in kHz ++ * returns calculated clock ++ */ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int chip_version = dev_priv->vbios->chip_version; ++ int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq; ++ int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m; ++ int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n; ++ int minU = pll_lim->vco1.min_inputfreq, maxU = pll_lim->vco1.max_inputfreq; ++ int maxlog2P; ++ int crystal = pll_lim->refclk; ++ int M, N, log2P, P; ++ int clkP, calcclk; ++ int delta, bestdelta = INT_MAX; ++ int bestclk = 0; ++ ++ /* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */ ++ /* possibly correlated with introduction of 27MHz crystal */ ++ if (chip_version <= 0x16 || chip_version == 0x20) { ++ if (clk > 250000) ++ maxM = 6; ++ if (clk > 340000) ++ maxM = 2; ++ maxlog2P = 4; ++ } else if (chip_version < 0x40) { ++ if (clk > 150000) ++ maxM = 6; ++ if (clk > 200000) ++ maxM = 4; ++ if (clk > 340000) ++ maxM = 2; ++ maxlog2P = 5; ++ } else /* nv4x may be subject to the nv17+ limits, but assume not for now */ ++ maxlog2P = 6; ++ ++ if ((clk << maxlog2P) < minvco) { ++ minvco = clk << maxlog2P; ++ maxvco = minvco * 2; ++ } ++ if (clk + clk/200 > maxvco) /* +0.5% */ ++ maxvco = clk + clk/200; ++ ++ /* NV34 goes maxlog2P->0, NV20 goes 0->maxlog2P */ ++ for (log2P = 0; log2P <= maxlog2P; log2P++) { ++ P = 1 << log2P; ++ clkP = clk * P; ++ ++ if (clkP < minvco) ++ continue; ++ if (clkP > maxvco) ++ return bestclk; ++ ++ for (M = minM; M <= maxM; M++) { ++ if (crystal/M < minU) ++ return bestclk; ++ if (crystal/M > maxU) ++ continue; ++ ++ /* add crystal/2 to round better */ ++ N = (clkP * M + crystal/2) / crystal; ++ ++ if (N < minN) ++ continue; ++ if (N > maxN) ++ break; ++ ++ /* more rounding additions */ ++ calcclk = ((N * crystal + P/2) / P + M/2) / M; ++ delta = abs(calcclk - clk); ++ /* we do an exhaustive search rather than terminating ++ * on an optimality condition... ++ */ ++ if (delta < bestdelta) { ++ bestdelta = delta; ++ bestclk = calcclk; ++ bestpv->N1 = N; ++ bestpv->M1 = M; ++ bestpv->log2P = log2P; ++ if (delta == 0) /* except this one */ ++ return bestclk; ++ } ++ } ++ } ++ ++ return bestclk; ++} ++ ++static int ++getMNP_double(struct drm_device *dev, struct pll_lims *pll_lim, int clk, ++ struct nouveau_pll_vals *bestpv) ++{ ++ /* Find M, N and P for a two stage PLL ++ * ++ * Note that some bioses (NV30+) have lookup tables of precomputed MNP ++ * values, but we're too lazy to use those atm ++ * ++ * "clk" parameter in kHz ++ * returns calculated clock ++ */ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int chip_version = dev_priv->vbios->chip_version; ++ int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq; ++ int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq; ++ int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq; ++ int maxU1 = pll_lim->vco1.max_inputfreq, maxU2 = pll_lim->vco2.max_inputfreq; ++ int minM1 = pll_lim->vco1.min_m, maxM1 = pll_lim->vco1.max_m; ++ int minN1 = pll_lim->vco1.min_n, maxN1 = pll_lim->vco1.max_n; ++ int minM2 = pll_lim->vco2.min_m, maxM2 = pll_lim->vco2.max_m; ++ int minN2 = pll_lim->vco2.min_n, maxN2 = pll_lim->vco2.max_n; ++ int crystal = pll_lim->refclk; ++ bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2); ++ int M1, N1, M2, N2, log2P; ++ int clkP, calcclk1, calcclk2, calcclkout; ++ int delta, bestdelta = INT_MAX; ++ int bestclk = 0; ++ ++ int vco2 = (maxvco2 - maxvco2/200) / 2; ++ for (log2P = 0; clk && log2P < 6 && clk <= (vco2 >> log2P); log2P++) /* log2P is maximum of 6 */ ++ ; ++ clkP = clk << log2P; ++ ++ if (maxvco2 < clk + clk/200) /* +0.5% */ ++ maxvco2 = clk + clk/200; ++ ++ for (M1 = minM1; M1 <= maxM1; M1++) { ++ if (crystal/M1 < minU1) ++ return bestclk; ++ if (crystal/M1 > maxU1) ++ continue; ++ ++ for (N1 = minN1; N1 <= maxN1; N1++) { ++ calcclk1 = crystal * N1 / M1; ++ if (calcclk1 < minvco1) ++ continue; ++ if (calcclk1 > maxvco1) ++ break; ++ ++ for (M2 = minM2; M2 <= maxM2; M2++) { ++ if (calcclk1/M2 < minU2) ++ break; ++ if (calcclk1/M2 > maxU2) ++ continue; ++ ++ /* add calcclk1/2 to round better */ ++ N2 = (clkP * M2 + calcclk1/2) / calcclk1; ++ if (N2 < minN2) ++ continue; ++ if (N2 > maxN2) ++ break; ++ ++ if (!fixedgain2) { ++ if (chip_version < 0x60) ++ if (N2/M2 < 4 || N2/M2 > 10) ++ continue; ++ ++ calcclk2 = calcclk1 * N2 / M2; ++ if (calcclk2 < minvco2) ++ break; ++ if (calcclk2 > maxvco2) ++ continue; ++ } else ++ calcclk2 = calcclk1; ++ ++ calcclkout = calcclk2 >> log2P; ++ delta = abs(calcclkout - clk); ++ /* we do an exhaustive search rather than terminating ++ * on an optimality condition... ++ */ ++ if (delta < bestdelta) { ++ bestdelta = delta; ++ bestclk = calcclkout; ++ bestpv->N1 = N1; ++ bestpv->M1 = M1; ++ bestpv->N2 = N2; ++ bestpv->M2 = M2; ++ bestpv->log2P = log2P; ++ if (delta == 0) /* except this one */ ++ return bestclk; ++ } ++ } ++ } ++ } ++ ++ return bestclk; ++} ++ ++int ++nouveau_calc_pll_mnp(struct drm_device *dev, struct pll_lims *pll_lim, int clk, ++ struct nouveau_pll_vals *pv) ++{ ++ int outclk; ++ ++ if (!pll_lim->vco2.maxfreq) ++ outclk = getMNP_single(dev, pll_lim, clk, pv); ++ else ++ outclk = getMNP_double(dev, pll_lim, clk, pv); ++ ++ if (!outclk) ++ NV_ERROR(dev, "Could not find a compatible set of PLL values\n"); ++ ++ return outclk; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h +new file mode 100644 +index 0000000..9c78c88 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_connector.h +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __NOUVEAU_CONNECTOR_H__ ++#define __NOUVEAU_CONNECTOR_H__ ++ ++#include "nouveau_i2c.h" ++ ++struct nouveau_connector { ++ struct drm_connector base; ++ ++ struct drm_display_mode *native_mode; ++ bool digital; ++ ++ int bus; ++ struct nouveau_i2c_chan *i2c_chan; ++ ++ int scaling_mode; ++ ++ bool use_dithering; ++ ++ struct nouveau_encoder *(*to_encoder) (struct nouveau_connector *connector, bool digital); ++}; ++#define to_nouveau_connector(x) container_of((x), struct nouveau_connector, base) ++ ++int nv50_connector_create(struct drm_device *dev, int bus, int i2c_index, int type); ++void nv50_connector_detect_all(struct drm_device *dev); ++ ++#endif /* __NOUVEAU_CONNECTOR_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h +new file mode 100644 +index 0000000..5104431 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h +@@ -0,0 +1,74 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __NOUVEAU_CRTC_H__ ++#define __NOUVEAU_CRTC_H__ ++ ++struct nouveau_crtc { ++ struct drm_crtc base; ++ ++ int index; ++ ++ struct drm_mode_set mode_set; ++ ++ struct drm_display_mode *mode; ++ bool use_dithering; ++ ++ struct { ++ uint32_t offset; ++ } fb; ++ ++ struct { ++ struct drm_gem_object *gem; ++ bool visible; ++ uint32_t offset; ++ void (*set_offset)(struct nouveau_crtc *, uint32_t offset); ++ void (*set_pos)(struct nouveau_crtc *, int x, int y); ++ void (*hide)(struct nouveau_crtc *, bool update); ++ void (*show)(struct nouveau_crtc *, bool update); ++ } cursor; ++ ++ struct { ++ struct mem_block *mem; ++ uint16_t r[256]; ++ uint16_t g[256]; ++ uint16_t b[256]; ++ int depth; ++ } lut; ++ ++ int (*set_dither) (struct nouveau_crtc *crtc, bool update); ++ int (*set_scale) (struct nouveau_crtc *crtc, int mode, bool update); ++ int (*set_clock) (struct nouveau_crtc *crtc, struct drm_display_mode *); ++ int (*set_clock_mode) (struct nouveau_crtc *crtc); ++ int (*destroy) (struct nouveau_crtc *crtc); ++}; ++#define to_nouveau_crtc(x) container_of((x), struct nouveau_crtc, base) ++ ++int nv50_crtc_create(struct drm_device *dev, int index); ++int nv50_cursor_init(struct nouveau_crtc *); ++void nv50_cursor_fini(struct nouveau_crtc *); ++ ++#endif /* __NOUVEAU_CRTC_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c +new file mode 100644 +index 0000000..8096bb5 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_display.c +@@ -0,0 +1,114 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_fb.h" ++#include "nouveau_fbcon.h" ++ ++static void ++nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) ++{ ++ struct nouveau_framebuffer *fb = to_nouveau_framebuffer(drm_fb); ++ struct drm_device *dev = drm_fb->dev; ++ ++ if (drm_fb->fbdev) ++ nouveau_fbcon_remove(dev, drm_fb); ++ ++ if (fb->gem) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(fb->gem); ++ mutex_unlock(&dev->struct_mutex); ++ } ++ ++ drm_framebuffer_cleanup(drm_fb); ++ kfree(fb); ++} ++ ++static int ++nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, ++ struct drm_file *file_priv, ++ unsigned int *handle) ++{ ++ struct nouveau_framebuffer *fb = to_nouveau_framebuffer(drm_fb); ++ ++ return drm_gem_handle_create(file_priv, fb->gem, handle); ++} ++ ++static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { ++ .destroy = nouveau_user_framebuffer_destroy, ++ .create_handle = nouveau_user_framebuffer_create_handle, ++}; ++ ++struct drm_framebuffer * ++nouveau_framebuffer_create(struct drm_device *dev, struct drm_gem_object *gem, ++ struct drm_mode_fb_cmd *mode_cmd) ++{ ++ struct nouveau_framebuffer *fb; ++ int ret; ++ ++ fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); ++ if (!fb) ++ return NULL; ++ ++ ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs); ++ if (ret) { ++ kfree(fb); ++ return NULL; ++ } ++ ++ drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd); ++ ++ fb->gem = gem; ++ return &fb->base; ++} ++ ++static struct drm_framebuffer * ++nouveau_user_framebuffer_create(struct drm_device *dev, ++ struct drm_file *file_priv, ++ struct drm_mode_fb_cmd *mode_cmd) ++{ ++ struct drm_framebuffer *fb; ++ struct drm_gem_object *gem; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); ++ if (!gem) ++ return NULL; ++ ++ fb = nouveau_framebuffer_create(dev, gem, mode_cmd); ++ if (!fb) { ++ drm_gem_object_unreference(gem); ++ return NULL; ++ } ++ ++ return fb; ++} ++ ++const struct drm_mode_config_funcs nouveau_mode_config_funcs = { ++ .fb_create = nouveau_user_framebuffer_create, ++ .fb_changed = nouveau_fbcon_probe, ++}; ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c +new file mode 100644 +index 0000000..83b2f5e +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_dma.c +@@ -0,0 +1,209 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++ ++int ++nouveau_dma_channel_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct mem_block *pushbuf = NULL; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* On !mm_enabled, we can't map a GART push buffer into kernel ++ * space easily - so we'll just use VRAM. ++ */ ++ pushbuf = nouveau_mem_alloc(dev, 0, 0x8000, NOUVEAU_MEM_NOVM | ++ NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, ++ (struct drm_file *)-2); ++ if (!pushbuf) { ++ NV_ERROR(dev, "Failed to allocate DMA push buffer\n"); ++ return -ENOMEM; ++ } ++ ++ ret = nouveau_fifo_alloc(dev, &dev_priv->channel, (struct drm_file *)-2, ++ pushbuf, NvDmaFB, NvDmaTT); ++ if (ret) { ++ NV_ERROR(dev, "Error allocating GPU channel: %d\n", ret); ++ return ret; ++ } ++ ++ if (!dev_priv->mm_enabled) { ++ ret = nouveau_dma_channel_setup(dev_priv->channel); ++ if (ret) { ++ nouveau_fifo_free(dev_priv->channel); ++ dev_priv->channel = NULL; ++ return ret; ++ } ++ } ++ ++ NV_DEBUG(dev, "Using FIFO channel %d\n", dev_priv->channel->id); ++ return 0; ++} ++ ++void ++nouveau_dma_channel_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (dev_priv->channel) { ++ nouveau_fifo_free(dev_priv->channel); ++ dev_priv->channel = NULL; ++ } ++} ++ ++int ++nouveau_dma_channel_setup(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *m2mf = NULL; ++ int ret, i; ++ ++ /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ ++ ret = nouveau_gpuobj_gr_new(chan, dev_priv->card_type < NV_50 ? ++ 0x0039 : 0x5039, &m2mf); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_ref_add(dev, chan, NvM2MF, m2mf, NULL); ++ if (ret) ++ return ret; ++ ++ /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ ++ ret = nouveau_notifier_alloc(chan, NvNotify0, 1, &chan->m2mf_ntfy); ++ if (ret) ++ return ret; ++ ++ /* Map push buffer */ ++ if (dev_priv->mm_enabled) { ++ ret = drm_bo_kmap(chan->pushbuf_mem->bo, 0, ++ chan->pushbuf_mem->bo->mem.num_pages, ++ &chan->pushbuf_mem->kmap); ++ if (ret) ++ return ret; ++ chan->dma.pushbuf = chan->pushbuf_mem->kmap.virtual; ++ } else { ++ drm_core_ioremap(chan->pushbuf_mem->map, dev); ++ if (!chan->pushbuf_mem->map->handle) { ++ NV_ERROR(dev, "Failed to ioremap push buffer\n"); ++ return -EINVAL; ++ } ++ chan->dma.pushbuf = (void *)chan->pushbuf_mem->map->handle; ++ } ++ ++ /* Map M2MF notifier object - fbcon. */ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ ret = drm_bo_kmap(chan->notifier_block->bo, 0, ++ chan->notifier_block->bo->mem.num_pages, ++ &chan->notifier_block->kmap); ++ if (ret) ++ return ret; ++ chan->m2mf_ntfy_map = chan->notifier_block->kmap.virtual; ++ chan->m2mf_ntfy_map += chan->m2mf_ntfy; ++ } ++ ++ /* Initialise DMA vars */ ++ chan->dma.max = (chan->pushbuf_mem->size >> 2) - 2; ++ chan->dma.put = 0; ++ chan->dma.cur = chan->dma.put; ++ chan->dma.free = chan->dma.max - chan->dma.cur; ++ ++ /* Insert NOPS for NOUVEAU_DMA_SKIPS */ ++ RING_SPACE(chan, NOUVEAU_DMA_SKIPS); ++ for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) ++ OUT_RING (chan, 0); ++ ++ /* Initialise NV_MEMORY_TO_MEMORY_FORMAT */ ++ RING_SPACE(chan, 4); ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1); ++ OUT_RING (chan, NvM2MF); ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); ++ OUT_RING (chan, NvNotify0); ++ ++ /* Sit back and pray the channel works.. */ ++ FIRE_RING (chan); ++ ++ return 0; ++} ++ ++int ++nouveau_dma_wait(struct nouveau_channel *chan, int size) ++{ ++ const int us_timeout = 100000; ++ int ret = -EBUSY, i; ++ ++ for (i = 0; i < us_timeout; i++) { ++ uint32_t get = READ_GET(); ++ ++ if (chan->dma.put >= get) { ++ chan->dma.free = chan->dma.max - chan->dma.cur; ++ ++ if (chan->dma.free < size) { ++ OUT_RING(chan, 0x20000000|chan->pushbuf_base); ++ if (get <= NOUVEAU_DMA_SKIPS) { ++ /*corner case - will be idle*/ ++ if (chan->dma.put <= NOUVEAU_DMA_SKIPS) ++ WRITE_PUT(NOUVEAU_DMA_SKIPS + 1); ++ ++ for (; i < us_timeout; i++) { ++ get = READ_GET(); ++ if (get > NOUVEAU_DMA_SKIPS) ++ break; ++ ++ DRM_UDELAY(1); ++ } ++ ++ if (i >= us_timeout) ++ break; ++ } ++ ++ WRITE_PUT(NOUVEAU_DMA_SKIPS); ++ chan->dma.cur = ++ chan->dma.put = NOUVEAU_DMA_SKIPS; ++ chan->dma.free = get - (NOUVEAU_DMA_SKIPS + 1); ++ } ++ } else { ++ chan->dma.free = get - chan->dma.cur - 1; ++ } ++ ++ if (chan->dma.free >= size) { ++ ret = 0; ++ break; ++ } ++ ++ DRM_UDELAY(1); ++ } ++ ++ return ret; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h +new file mode 100644 +index 0000000..4383883 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_dma.h +@@ -0,0 +1,107 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __NOUVEAU_DMA_H__ ++#define __NOUVEAU_DMA_H__ ++ ++typedef enum { ++ NvSubM2MF = 0, ++ NvSub2D = 1 ++} nouveau_subchannel_id_t; ++ ++typedef enum { ++ NvM2MF = 0x80000001, ++ NvDmaFB = 0x80000002, ++ NvDmaTT = 0x80000003, ++ NvNotify0 = 0x80000004, ++ Nv2D = 0x80000005, ++} nouveau_object_handle_t; ++ ++#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NAME 0x00000000 ++#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF 0x00000050 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE 0x00000000 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN 0x00000001 ++#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x00000180 ++#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE 0x00000184 ++#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c ++ ++#define NV50_MEMORY_TO_MEMORY_FORMAT 0x00005039 ++#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200 0x00000200 ++#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C 0x0000021c ++#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x00000238 ++#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c ++ ++static inline int ++RING_SPACE(struct nouveau_channel *chan, int size) ++{ ++ if (chan->dma.free < size) { ++ int ret; ++ ++ ret = nouveau_dma_wait(chan, size); ++ if (ret) ++ return ret; ++ } ++ ++ chan->dma.free -= size; ++ return 0; ++} ++ ++static inline void ++OUT_RING(struct nouveau_channel *chan, int data) ++{ ++ chan->dma.pushbuf[chan->dma.cur++] = data; ++} ++ ++static inline void ++BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size) ++{ ++ OUT_RING(chan, (subc << 13) | (size << 18) | mthd); ++} ++ ++#define READ_GET() ((nvchan_rd32(0x44) - chan->pushbuf_base) >> 2) ++#define WRITE_PUT(val) nvchan_wr32(0x40, ((val) << 2) + chan->pushbuf_base) ++ ++static inline void ++FIRE_RING(struct nouveau_channel *chan) ++{ ++ if (chan->dma.cur == chan->dma.put) ++ return; ++ chan->accel_done = true; ++ ++ DRM_MEMORYBARRIER(); ++ chan->dma.put = chan->dma.cur; ++ WRITE_PUT(chan->dma.put); ++} ++ ++/* This should allow easy switching to a real fifo in the future. */ ++#define OUT_MODE(mthd, val) do { \ ++ nv50_display_command(dev, mthd, val); \ ++} while(0) ++ ++#endif +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c +new file mode 100644 +index 0000000..f497aae +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.c +@@ -0,0 +1,190 @@ ++/* ++ * Copyright 2005 Stephane Marchesin. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++#include "drm_pciids.h" ++ ++MODULE_PARM_DESC(noagp, "Disable AGP"); ++int nouveau_noagp = 0; ++module_param_named(noagp, nouveau_noagp, int, 0400); ++ ++MODULE_PARM_DESC(mm_enabled, "Enable TTM/GEM memory manager"); ++int nouveau_mm_enabled = 0; ++module_param_named(mm_enabled, nouveau_mm_enabled, int, 0400); ++ ++MODULE_PARM_DESC(modeset, "Enable kernel modesetting (>=GeForce 8)"); ++int nouveau_modeset = -1; /* kms */ ++module_param_named(modeset, nouveau_modeset, int, 0400); ++ ++MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); ++int nouveau_duallink = 0; ++module_param_named(duallink, nouveau_duallink, int, 0400); ++ ++int nouveau_fbpercrtc = 0; ++#if 0 ++module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400); ++#endif ++ ++static struct pci_device_id pciidlist[] = { ++ { ++ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), ++ .class = PCI_BASE_CLASS_DISPLAY << 16, ++ .class_mask = 0xff << 16, ++ }, ++ { ++ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID), ++ .class = PCI_BASE_CLASS_DISPLAY << 16, ++ .class_mask = 0xff << 16, ++ }, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(pci, pciidlist); ++ ++static struct drm_driver driver; ++ ++static int __devinit ++nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ++{ ++ return drm_get_dev(pdev, ent, &driver); ++} ++ ++static void ++nouveau_pci_remove(struct pci_dev *pdev) ++{ ++ struct drm_device *dev = pci_get_drvdata(pdev); ++ ++ drm_put_dev(dev); ++} ++ ++static int ++nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct drm_device *dev = pci_get_drvdata(pdev); ++ (void)dev; ++ return -ENODEV; ++} ++ ++static int ++nouveau_pci_resume(struct pci_dev *pdev) ++{ ++ struct drm_device *dev = pci_get_drvdata(pdev); ++ (void)dev; ++ return -ENODEV; ++} ++ ++extern struct drm_ioctl_desc nouveau_ioctls[]; ++extern int nouveau_max_ioctl; ++ ++static struct drm_driver driver = { ++ .driver_features = ++ DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | ++ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, ++ .load = nouveau_load, ++ .firstopen = nouveau_firstopen, ++ .lastclose = nouveau_lastclose, ++ .unload = nouveau_unload, ++ .preclose = nouveau_preclose, ++ .irq_preinstall = nouveau_irq_preinstall, ++ .irq_postinstall = nouveau_irq_postinstall, ++ .irq_uninstall = nouveau_irq_uninstall, ++ .irq_handler = nouveau_irq_handler, ++ .reclaim_buffers = drm_core_reclaim_buffers, ++ .get_map_ofs = drm_core_get_map_ofs, ++ .get_reg_ofs = drm_core_get_reg_ofs, ++ .ioctls = nouveau_ioctls, ++ .fops = { ++ .owner = THIS_MODULE, ++ .open = drm_open, ++ .release = drm_release, ++ .ioctl = drm_ioctl, ++ .mmap = drm_mmap, ++ .poll = drm_poll, ++ .fasync = drm_fasync, ++#if defined(CONFIG_COMPAT) ++ .compat_ioctl = nouveau_compat_ioctl, ++#endif ++ }, ++ .pci_driver = { ++ .name = DRIVER_NAME, ++ .id_table = pciidlist, ++ .probe = nouveau_pci_probe, ++ .remove = nouveau_pci_remove, ++ .suspend = nouveau_pci_suspend, ++ .resume = nouveau_pci_resume ++ }, ++ ++ .gem_init_object = nouveau_gem_object_new, ++ .gem_free_object = nouveau_gem_object_del, ++ .bo_driver = &nouveau_bo_driver, ++ .fence_driver = &nouveau_fence_driver, ++ ++ .name = DRIVER_NAME, ++ .desc = DRIVER_DESC, ++#ifdef GIT_REVISION ++ .date = GIT_REVISION, ++#else ++ .date = DRIVER_DATE, ++#endif ++ .major = DRIVER_MAJOR, ++ .minor = DRIVER_MINOR, ++ .patchlevel = DRIVER_PATCHLEVEL, ++}; ++ ++static int __init nouveau_init(void) ++{ ++ driver.num_ioctls = nouveau_max_ioctl; ++ ++ if (nouveau_modeset == -1) ++#if defined(CONFIG_DRM_NOUVEAU_KMS) ++ nouveau_modeset = 1; ++#else ++ nouveau_modeset = 0; ++#endif ++ ++ if (nouveau_modeset == 1) { ++ driver.driver_features |= DRIVER_MODESET; ++ nouveau_mm_enabled = 1; ++ } ++ ++ if (nouveau_mm_enabled == 1) ++ driver.driver_features |= DRIVER_GEM; ++ ++ return drm_init(&driver); ++} ++ ++static void __exit nouveau_exit(void) ++{ ++ drm_exit(&driver); ++} ++ ++module_init(nouveau_init); ++module_exit(nouveau_exit); ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE("GPL and additional rights"); +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h +new file mode 100644 +index 0000000..ae93ea1 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.h +@@ -0,0 +1,776 @@ ++/* ++ * Copyright 2005 Stephane Marchesin. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef __NOUVEAU_DRV_H__ ++#define __NOUVEAU_DRV_H__ ++ ++#define DRIVER_AUTHOR "Stephane Marchesin" ++#define DRIVER_EMAIL "dri-devel@lists.sourceforge.net" ++ ++#define DRIVER_NAME "nouveau" ++#define DRIVER_DESC "nVidia Riva/TNT/GeForce" ++#define DRIVER_DATE "20060213" ++ ++#define DRIVER_MAJOR 0 ++#define DRIVER_MINOR 0 ++#define DRIVER_PATCHLEVEL 12 ++ ++#define NOUVEAU_FAMILY 0x0000FFFF ++#define NOUVEAU_FLAGS 0xFFFF0000 ++ ++#include "nouveau_drm.h" ++#include "nouveau_reg.h" ++#include "nouveau_bios.h" ++ ++#define DRM_NOUVEAU_BO_FLAG_NOVM 0x8000000000000000ULL ++#define DRM_NOUVEAU_BO_FLAG_TILE 0x4000000000000000ULL ++#define DRM_NOUVEAU_BO_FLAG_ZTILE 0x2000000000000000ULL ++ ++#define MAX_NUM_DCB_ENTRIES 16 ++ ++struct nouveau_gem_object { ++ struct list_head entry; ++ ++ struct drm_gem_object *gem; ++ struct drm_buffer_object *bo; ++ bool mappable; ++}; ++ ++static inline struct nouveau_gem_object * ++nouveau_gem_object(struct drm_gem_object *gem) ++{ ++ return gem ? gem->driver_private : NULL; ++} ++ ++struct mem_block { ++ struct mem_block *next; ++ struct mem_block *prev; ++ uint64_t start; ++ uint64_t size; ++ struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ ++ int flags; ++ struct drm_local_map *map; ++ drm_handle_t map_handle; ++ ++ struct drm_buffer_object *bo; ++ struct drm_bo_kmap_obj kmap; ++}; ++ ++enum nouveau_flags { ++ NV_NFORCE =0x10000000, ++ NV_NFORCE2 =0x20000000 ++}; ++ ++#define NVOBJ_ENGINE_SW 0 ++#define NVOBJ_ENGINE_GR 1 ++#define NVOBJ_ENGINE_INT 0xdeadbeef ++ ++#define NVOBJ_FLAG_ALLOW_NO_REFS (1 << 0) ++#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) ++#define NVOBJ_FLAG_ZERO_FREE (1 << 2) ++#define NVOBJ_FLAG_FAKE (1 << 3) ++struct nouveau_gpuobj { ++ struct list_head list; ++ ++ int im_channel; ++ struct mem_block *im_pramin; ++ struct mem_block *im_backing; ++ int im_bound; ++ ++ uint32_t flags; ++ int refcount; ++ ++ uint32_t engine; ++ uint32_t class; ++ ++ void (*dtor)(struct drm_device *, struct nouveau_gpuobj *); ++ void *priv; ++}; ++ ++struct nouveau_gpuobj_ref { ++ struct list_head list; ++ ++ struct nouveau_gpuobj *gpuobj; ++ uint32_t instance; ++ ++ int channel; ++ int handle; ++}; ++ ++struct nouveau_channel ++{ ++ struct drm_device *dev; ++ int id; ++ ++ /* owner of this fifo */ ++ struct drm_file *file_priv; ++ /* mapping of the fifo itself */ ++ struct drm_local_map *map; ++ /* mapping of the regs controling the fifo */ ++ struct drm_local_map *user; ++ ++ /* Fencing */ ++ uint32_t next_sequence; ++ ++ /* DMA push buffer */ ++ struct nouveau_gpuobj_ref *pushbuf; ++ struct mem_block *pushbuf_mem; ++ uint32_t pushbuf_base; ++ ++ /* Notifier memory */ ++ struct mem_block *notifier_block; ++ struct mem_block *notifier_heap; ++ struct drm_local_map *notifier_map; ++ ++ /* PFIFO context */ ++ struct nouveau_gpuobj_ref *ramfc; ++ ++ /* PGRAPH context */ ++ /* XXX may be merge 2 pointers as private data ??? */ ++ struct nouveau_gpuobj_ref *ramin_grctx; ++ void *pgraph_ctx; ++ ++ /* NV50 VM */ ++ struct nouveau_gpuobj *vm_pd; ++ struct nouveau_gpuobj_ref *vm_gart_pt; ++ struct nouveau_gpuobj_ref **vm_vram_pt; ++ ++ /* Objects */ ++ struct nouveau_gpuobj_ref *ramin; /* Private instmem */ ++ struct mem_block *ramin_heap; /* Private PRAMIN heap */ ++ struct nouveau_gpuobj_ref *ramht; /* Hash table */ ++ struct list_head ramht_refs; /* Objects referenced by RAMHT */ ++ ++ /* GPU object info for stuff used in-kernel (mm_enabled) */ ++ uint32_t m2mf_ntfy; ++ volatile uint32_t *m2mf_ntfy_map; ++ uint32_t vram_handle; ++ uint32_t gart_handle; ++ bool accel_done; ++ ++ /* Push buffer state (only for drm's channel on !mm_enabled) */ ++ struct { ++ int max; ++ int free; ++ int cur; ++ int put; ++ ++ volatile uint32_t *pushbuf; ++ } dma; ++}; ++ ++struct nouveau_config { ++ struct { ++ int location; ++ int size; ++ } cmdbuf; ++}; ++ ++struct nouveau_instmem_engine { ++ void *priv; ++ ++ int (*init)(struct drm_device *dev); ++ void (*takedown)(struct drm_device *dev); ++ ++ int (*populate)(struct drm_device *, struct nouveau_gpuobj *, ++ uint32_t *size); ++ void (*clear)(struct drm_device *, struct nouveau_gpuobj *); ++ int (*bind)(struct drm_device *, struct nouveau_gpuobj *); ++ int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); ++ void (*prepare_access)(struct drm_device *, bool write); ++ void (*finish_access)(struct drm_device *); ++}; ++ ++struct nouveau_mc_engine { ++ int (*init)(struct drm_device *dev); ++ void (*takedown)(struct drm_device *dev); ++}; ++ ++struct nouveau_timer_engine { ++ int (*init)(struct drm_device *dev); ++ void (*takedown)(struct drm_device *dev); ++ uint64_t (*read)(struct drm_device *dev); ++}; ++ ++struct nouveau_fb_engine { ++ int (*init)(struct drm_device *dev); ++ void (*takedown)(struct drm_device *dev); ++}; ++ ++struct nouveau_fifo_engine { ++ void *priv; ++ ++ int channels; ++ ++ int (*init)(struct drm_device *); ++ void (*takedown)(struct drm_device *); ++ ++ int (*channel_id)(struct drm_device *); ++ ++ int (*create_context)(struct nouveau_channel *); ++ void (*destroy_context)(struct nouveau_channel *); ++ int (*load_context)(struct nouveau_channel *); ++ int (*save_context)(struct nouveau_channel *); ++}; ++ ++struct nouveau_pgraph_engine { ++ int (*init)(struct drm_device *); ++ void (*takedown)(struct drm_device *); ++ ++ void (*fifo_access)(struct drm_device *, bool); ++ ++ int (*create_context)(struct nouveau_channel *); ++ void (*destroy_context)(struct nouveau_channel *); ++ int (*load_context)(struct nouveau_channel *); ++ int (*save_context)(struct nouveau_channel *); ++}; ++ ++struct nouveau_engine { ++ struct nouveau_instmem_engine instmem; ++ struct nouveau_mc_engine mc; ++ struct nouveau_timer_engine timer; ++ struct nouveau_fb_engine fb; ++ struct nouveau_pgraph_engine graph; ++ struct nouveau_fifo_engine fifo; ++}; ++ ++#define NOUVEAU_MAX_CHANNEL_NR 128 ++struct drm_nouveau_private { ++ enum { ++ NOUVEAU_CARD_INIT_DOWN, ++ NOUVEAU_CARD_INIT_DONE, ++ NOUVEAU_CARD_INIT_FAILED ++ } init_state; ++ ++ int mm_enabled; ++ ++ /* the card type, takes NV_* as values */ ++ int card_type; ++ /* exact chipset, derived from NV_PMC_BOOT_0 */ ++ int chipset; ++ int flags; ++ ++ struct drm_local_map *mmio; ++ struct drm_local_map *fb; ++ struct drm_local_map *ramin_map; ++ struct drm_local_map *ramin; ++ ++ int fifo_alloc_count; ++ struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; ++ ++ struct nouveau_engine engine; ++ struct nouveau_channel *channel; ++ ++ /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ ++ struct nouveau_gpuobj *ramht; ++ uint32_t ramin_rsvd_vram; ++ uint32_t ramht_offset; ++ uint32_t ramht_size; ++ uint32_t ramht_bits; ++ uint32_t ramfc_offset; ++ uint32_t ramfc_size; ++ uint32_t ramro_offset; ++ uint32_t ramro_size; ++ ++ /* base physical adresses */ ++ uint64_t fb_phys; ++ uint64_t fb_available_size; ++ ++ struct { ++ enum { ++ NOUVEAU_GART_NONE = 0, ++ NOUVEAU_GART_AGP, ++ NOUVEAU_GART_SGDMA ++ } type; ++ uint64_t aper_base; ++ uint64_t aper_size; ++ ++ struct nouveau_gpuobj *sg_ctxdma; ++ struct page *sg_dummy_page; ++ dma_addr_t sg_dummy_bus; ++ ++ /* nottm hack */ ++ struct drm_ttm_backend *sg_be; ++ unsigned long sg_handle; ++ } gart_info; ++ ++ /* G8x/G9x virtual address space */ ++ uint64_t vm_gart_base; ++ uint64_t vm_gart_size; ++ uint64_t vm_vram_base; ++ uint64_t vm_vram_size; ++ uint64_t vm_end; ++ struct nouveau_gpuobj **vm_vram_pt; ++ int vm_vram_pt_nr; ++ ++ /* the mtrr covering the FB */ ++ int fb_mtrr; ++ ++ struct mem_block *agp_heap; ++ struct mem_block *fb_heap; ++ struct mem_block *fb_nomap_heap; ++ struct mem_block *ramin_heap; ++ struct mem_block *pci_heap; ++ ++ /* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */ ++ uint32_t ctx_table_size; ++ struct nouveau_gpuobj_ref *ctx_table; ++ ++ struct nouveau_config config; ++ ++ struct list_head gpuobj_list; ++ ++ bool in_modeset; ++ ++ struct nvbios VBIOS; ++ struct nouveau_bios_info *vbios; ++ ++ struct nouveau_suspend_resume { ++ uint32_t fifo_mode; ++ uint32_t graph_ctx_control; ++ uint32_t graph_state; ++ uint32_t *ramin_copy; ++ uint64_t ramin_size; ++ } susres; ++ ++ struct mutex submit_mutex; ++ ++ struct backlight_device *backlight; ++ ++ struct drm_gem_object *sfb_gem; ++ struct mem_block *sfb; ++ uint64_t sfbhack_handle; ++ uint64_t sfbhack_size; ++}; ++ ++#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \ ++ struct drm_nouveau_private *nv = dev->dev_private; \ ++ if (nv->init_state != NOUVEAU_CARD_INIT_DONE) { \ ++ NV_ERROR(dev, "called without init\n"); \ ++ return -EINVAL; \ ++ } \ ++} while(0) ++ ++#define NOUVEAU_CHECK_MM_ENABLED_WITH_RETURN do { \ ++ struct drm_nouveau_private *nv = dev->dev_private; \ ++ if (!nv->mm_enabled) { \ ++ NV_ERROR(dev, "invalid - using legacy mm\n"); \ ++ return -EINVAL; \ ++ } \ ++} while(0) ++ ++#define NOUVEAU_CHECK_MM_DISABLED_WITH_RETURN do { \ ++ struct drm_nouveau_private *nv = dev->dev_private; \ ++ if (nv->mm_enabled) { \ ++ NV_ERROR(dev, "invalid - using kernel mm\n"); \ ++ return -EINVAL; \ ++ } \ ++} while(0) ++ ++#define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id,cl,ch) do { \ ++ struct drm_nouveau_private *nv = dev->dev_private; \ ++ if (!nouveau_fifo_owner(dev, (cl), (id))) { \ ++ NV_ERROR(dev, "pid %d doesn't own channel %d\n", \ ++ DRM_CURRENTPID, (id)); \ ++ return -EPERM; \ ++ } \ ++ (ch) = nv->fifos[(id)]; \ ++} while(0) ++ ++/* nouveau_state.c */ ++extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); ++extern int nouveau_load(struct drm_device *, unsigned long flags); ++extern int nouveau_firstopen(struct drm_device *); ++extern void nouveau_lastclose(struct drm_device *); ++extern int nouveau_unload(struct drm_device *); ++extern int nouveau_ioctl_getparam(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_setparam(struct drm_device *, void *data, ++ struct drm_file *); ++extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout, ++ uint32_t reg, uint32_t mask, uint32_t val); ++extern void nouveau_wait_for_idle(struct drm_device *); ++extern int nouveau_card_init(struct drm_device *); ++extern int nouveau_ioctl_card_init(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_suspend(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_resume(struct drm_device *, void *data, ++ struct drm_file *); ++ ++/* nouveau_mem.c */ ++extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, ++ uint64_t size); ++extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, ++ uint64_t size, int align2, ++ struct drm_file *, int tail); ++extern void nouveau_mem_takedown(struct mem_block **heap); ++extern void nouveau_mem_free_block(struct mem_block *); ++extern uint64_t nouveau_mem_fb_amount(struct drm_device *); ++extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); ++extern int nouveau_ioctl_mem_alloc(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_mem_free(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_mem_tile(struct drm_device *, void *data, ++ struct drm_file *); ++extern struct mem_block* nouveau_mem_alloc(struct drm_device *, ++ int alignment, uint64_t size, ++ int flags, struct drm_file *); ++extern void nouveau_mem_free(struct drm_device *dev, struct mem_block*); ++extern int nouveau_mem_init(struct drm_device *); ++extern int nouveau_mem_init_ttm(struct drm_device *); ++extern void nouveau_mem_close(struct drm_device *); ++extern int nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt, ++ uint32_t size, uint32_t flags, ++ uint64_t phys); ++extern void nv50_mem_vm_unbind(struct drm_device *, uint64_t virt, ++ uint32_t size); ++ ++/* nouveau_notifier.c */ ++extern int nouveau_notifier_init_channel(struct nouveau_channel *); ++extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); ++extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, ++ int cout, uint32_t *offset); ++extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data, ++ struct drm_file *); ++ ++/* nouveau_fifo.c */ ++extern int nouveau_fifo_init(struct drm_device *); ++extern int nouveau_fifo_ctx_size(struct drm_device *); ++extern void nouveau_fifo_cleanup(struct drm_device *, struct drm_file *); ++extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *, ++ int channel); ++extern int nouveau_fifo_alloc(struct drm_device *dev, ++ struct nouveau_channel **chan, ++ struct drm_file *file_priv, ++ struct mem_block *pushbuf, ++ uint32_t fb_ctxdma, uint32_t tt_ctxdma); ++extern void nouveau_fifo_free(struct nouveau_channel *); ++extern int nouveau_channel_idle(struct nouveau_channel *chan); ++ ++/* nouveau_object.c */ ++extern int nouveau_gpuobj_early_init(struct drm_device *); ++extern int nouveau_gpuobj_init(struct drm_device *); ++extern void nouveau_gpuobj_takedown(struct drm_device *); ++extern void nouveau_gpuobj_late_takedown(struct drm_device *); ++extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, ++ uint32_t vram_h, uint32_t tt_h); ++extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *); ++extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *, ++ int size, int align, uint32_t flags, ++ struct nouveau_gpuobj **); ++extern int nouveau_gpuobj_del(struct drm_device *, struct nouveau_gpuobj **); ++extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *, ++ uint32_t handle, struct nouveau_gpuobj *, ++ struct nouveau_gpuobj_ref **); ++extern int nouveau_gpuobj_ref_del(struct drm_device *, ++ struct nouveau_gpuobj_ref **); ++extern int nouveau_gpuobj_ref_find(struct nouveau_channel *, uint32_t handle, ++ struct nouveau_gpuobj_ref **ref_ret); ++extern int nouveau_gpuobj_new_ref(struct drm_device *, ++ struct nouveau_channel *alloc_chan, ++ struct nouveau_channel *ref_chan, ++ uint32_t handle, int size, int align, ++ uint32_t flags, struct nouveau_gpuobj_ref **); ++extern int nouveau_gpuobj_new_fake(struct drm_device *, ++ uint32_t p_offset, uint32_t b_offset, ++ uint32_t size, uint32_t flags, ++ struct nouveau_gpuobj **, ++ struct nouveau_gpuobj_ref**); ++extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, ++ uint64_t offset, uint64_t size, int access, ++ int target, struct nouveau_gpuobj **); ++extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *, ++ uint64_t offset, uint64_t size, ++ int access, struct nouveau_gpuobj **, ++ uint32_t *o_ret); ++extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, ++ struct nouveau_gpuobj **); ++extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, ++ struct drm_file *); ++ ++/* nouveau_irq.c */ ++extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); ++extern void nouveau_irq_preinstall(struct drm_device *); ++extern int nouveau_irq_postinstall(struct drm_device *); ++extern void nouveau_irq_uninstall(struct drm_device *); ++ ++/* nouveau_sgdma.c */ ++extern int nouveau_sgdma_init(struct drm_device *); ++extern void nouveau_sgdma_takedown(struct drm_device *); ++extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset, ++ uint32_t *page); ++extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *); ++extern int nouveau_sgdma_nottm_hack_init(struct drm_device *); ++extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *); ++ ++/* nouveau_dma.c */ ++extern int nouveau_dma_channel_init(struct drm_device *); ++extern void nouveau_dma_channel_takedown(struct drm_device *); ++extern int nouveau_dma_channel_setup(struct nouveau_channel *); ++extern int nouveau_dma_wait(struct nouveau_channel *, int size); ++ ++/* nouveau_backlight.c */ ++extern int nouveau_backlight_init(struct drm_device *); ++extern void nouveau_backlight_exit(struct drm_device *); ++ ++/* nouveau_bios.c */ ++extern int nouveau_parse_bios(struct drm_device *); ++extern int get_pll_limits(struct drm_device *, uint32_t limit_match, ++ struct pll_lims *); ++ ++/* nv04_fb.c */ ++extern int nv04_fb_init(struct drm_device *); ++extern void nv04_fb_takedown(struct drm_device *); ++ ++/* nv10_fb.c */ ++extern int nv10_fb_init(struct drm_device *); ++extern void nv10_fb_takedown(struct drm_device *); ++ ++/* nv40_fb.c */ ++extern int nv40_fb_init(struct drm_device *); ++extern void nv40_fb_takedown(struct drm_device *); ++ ++/* nv04_fifo.c */ ++extern int nv04_fifo_channel_id(struct drm_device *); ++extern int nv04_fifo_create_context(struct nouveau_channel *); ++extern void nv04_fifo_destroy_context(struct nouveau_channel *); ++extern int nv04_fifo_load_context(struct nouveau_channel *); ++extern int nv04_fifo_save_context(struct nouveau_channel *); ++ ++/* nv10_fifo.c */ ++extern int nv10_fifo_channel_id(struct drm_device *); ++extern int nv10_fifo_create_context(struct nouveau_channel *); ++extern void nv10_fifo_destroy_context(struct nouveau_channel *); ++extern int nv10_fifo_load_context(struct nouveau_channel *); ++extern int nv10_fifo_save_context(struct nouveau_channel *); ++ ++/* nv40_fifo.c */ ++extern int nv40_fifo_init(struct drm_device *); ++extern int nv40_fifo_create_context(struct nouveau_channel *); ++extern void nv40_fifo_destroy_context(struct nouveau_channel *); ++extern int nv40_fifo_load_context(struct nouveau_channel *); ++extern int nv40_fifo_save_context(struct nouveau_channel *); ++ ++/* nv50_fifo.c */ ++extern int nv50_fifo_init(struct drm_device *); ++extern void nv50_fifo_takedown(struct drm_device *); ++extern int nv50_fifo_channel_id(struct drm_device *); ++extern int nv50_fifo_create_context(struct nouveau_channel *); ++extern void nv50_fifo_destroy_context(struct nouveau_channel *); ++extern int nv50_fifo_load_context(struct nouveau_channel *); ++extern int nv50_fifo_save_context(struct nouveau_channel *); ++ ++/* nv04_graph.c */ ++extern void nouveau_nv04_context_switch(struct drm_device *); ++extern int nv04_graph_init(struct drm_device *); ++extern void nv04_graph_takedown(struct drm_device *); ++extern void nv04_graph_fifo_access(struct drm_device *, bool); ++extern int nv04_graph_create_context(struct nouveau_channel *); ++extern void nv04_graph_destroy_context(struct nouveau_channel *); ++extern int nv04_graph_load_context(struct nouveau_channel *); ++extern int nv04_graph_save_context(struct nouveau_channel *); ++ ++/* nv10_graph.c */ ++extern void nouveau_nv10_context_switch(struct drm_device *); ++extern int nv10_graph_init(struct drm_device *); ++extern void nv10_graph_takedown(struct drm_device *); ++extern int nv10_graph_create_context(struct nouveau_channel *); ++extern void nv10_graph_destroy_context(struct nouveau_channel *); ++extern int nv10_graph_load_context(struct nouveau_channel *); ++extern int nv10_graph_save_context(struct nouveau_channel *); ++ ++/* nv20_graph.c */ ++extern int nv20_graph_create_context(struct nouveau_channel *); ++extern void nv20_graph_destroy_context(struct nouveau_channel *); ++extern int nv20_graph_load_context(struct nouveau_channel *); ++extern int nv20_graph_save_context(struct nouveau_channel *); ++extern int nv20_graph_init(struct drm_device *); ++extern void nv20_graph_takedown(struct drm_device *); ++extern int nv30_graph_init(struct drm_device *); ++ ++/* nv40_graph.c */ ++extern int nv40_graph_init(struct drm_device *); ++extern void nv40_graph_takedown(struct drm_device *); ++extern int nv40_graph_create_context(struct nouveau_channel *); ++extern void nv40_graph_destroy_context(struct nouveau_channel *); ++extern int nv40_graph_load_context(struct nouveau_channel *); ++extern int nv40_graph_save_context(struct nouveau_channel *); ++ ++/* nv50_graph.c */ ++extern int nv50_graph_init(struct drm_device *); ++extern void nv50_graph_takedown(struct drm_device *); ++extern void nv50_graph_fifo_access(struct drm_device *, bool); ++extern int nv50_graph_create_context(struct nouveau_channel *); ++extern void nv50_graph_destroy_context(struct nouveau_channel *); ++extern int nv50_graph_load_context(struct nouveau_channel *); ++extern int nv50_graph_save_context(struct nouveau_channel *); ++ ++/* nv04_instmem.c */ ++extern int nv04_instmem_init(struct drm_device *); ++extern void nv04_instmem_takedown(struct drm_device *); ++extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, ++ uint32_t *size); ++extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); ++extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); ++extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); ++extern void nv04_instmem_prepare_access(struct drm_device *, bool write); ++extern void nv04_instmem_finish_access(struct drm_device *); ++ ++/* nv50_instmem.c */ ++extern int nv50_instmem_init(struct drm_device *); ++extern void nv50_instmem_takedown(struct drm_device *); ++extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, ++ uint32_t *size); ++extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); ++extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); ++extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); ++extern void nv50_instmem_prepare_access(struct drm_device *, bool write); ++extern void nv50_instmem_finish_access(struct drm_device *); ++ ++/* nv04_mc.c */ ++extern int nv04_mc_init(struct drm_device *); ++extern void nv04_mc_takedown(struct drm_device *); ++ ++/* nv40_mc.c */ ++extern int nv40_mc_init(struct drm_device *); ++extern void nv40_mc_takedown(struct drm_device *); ++ ++/* nv50_mc.c */ ++extern int nv50_mc_init(struct drm_device *); ++extern void nv50_mc_takedown(struct drm_device *); ++ ++/* nv04_timer.c */ ++extern int nv04_timer_init(struct drm_device *); ++extern uint64_t nv04_timer_read(struct drm_device *); ++extern void nv04_timer_takedown(struct drm_device *); ++ ++extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg); ++ ++/* nouveau_buffer.c */ ++extern struct drm_bo_driver nouveau_bo_driver; ++ ++/* nouveau_fence.c */ ++extern struct drm_fence_driver nouveau_fence_driver; ++extern void nouveau_fence_handler(struct drm_device *dev, int channel); ++extern struct nouveau_channel * ++nouveau_fence_channel(struct drm_device *dev, uint32_t fence_class); ++ ++/* nouveau_gem.c */ ++extern int nouveau_gem_object_new(struct drm_gem_object *); ++extern void nouveau_gem_object_del(struct drm_gem_object *); ++extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, ++ int size, int align, uint32_t domain, ++ struct drm_gem_object **); ++extern int nouveau_gem_pin(struct drm_gem_object *, uint32_t domain); ++extern int nouveau_gem_unpin(struct drm_gem_object *); ++extern int nouveau_gem_ioctl_new(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_pushbuf_call(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_pin(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_unpin(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_tile(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_mmap(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *, ++ struct drm_file *); ++ ++#define NVDEV ((struct drm_nouveau_private *)dev->dev_private) ++#if defined(__powerpc__) ++#define nv_out32(map,reg,val) out_be32((void __iomem *)NVDEV->map->handle + (reg), (val)) ++#define nv_out16(map,reg,val) out_be16((void __iomem *)NVDEV->map->handle + (reg), (val)) ++#define nv_in32(map,reg) in_be32((void __iomem *)NVDEV->map->handle + (reg)) ++#define nv_in16(map,reg) in_be16((void __iomem *)NVDEV->map->handle + (reg)) ++#else ++#define nv_out32(map,reg,val) DRM_WRITE32(NVDEV->map, (reg), (val)) ++#define nv_out16(map,reg,val) DRM_WRITE16(NVDEV->map, (reg), (val)) ++#define nv_in32(map,reg) DRM_READ32(NVDEV->map, (reg)) ++#define nv_in16(map,reg) DRM_READ16(NVDEV->map, (reg)) ++#endif ++#define nv_out08(map,reg,val) DRM_WRITE8(NVDEV->map, (reg), (val)) ++#define nv_in08(map,reg) DRM_READ8(NVDEV->map, (reg)) ++ ++/* channel control reg access */ ++#if defined(__powerpc__) ++#define nvchan_wr32(reg,val) out_be32((void __iomem *)chan->user->handle + (reg), (val)) ++#define nvchan_rd32(reg) in_be32((void __iomem *)chan->user->handle + (reg)) ++#else ++#define nvchan_wr32(reg,val) DRM_WRITE32(chan->user, (reg), (val)) ++#define nvchan_rd32(reg) DRM_READ32(chan->user, (reg)) ++#endif ++ ++ ++/* register access */ ++#define nv_rd32(reg) nv_in32(mmio, (reg)) ++#define nv_wr32(reg,val) nv_out32(mmio, (reg), (val)) ++#define nv_rd16(reg) nv_in16(mmio, (reg)) ++#define nv_wr16(reg,val) nv_out16(mmio, (reg), (val)) ++#define nv_rd08(reg) nv_in08(mmio, (reg)) ++#define nv_wr08(reg,val) nv_out08(mmio, (reg), (val)) ++#define nv_wait(reg,mask,val) nouveau_wait_until(dev, 1000000000ULL, (reg), \ ++ (mask), (val)) ++ ++/* VRAM access */ ++#define nv_rv32(reg) 0 /* vram */ ++#define nv_wv32(reg,val) ++#define nv_rf32(reg) 0 /* fb bar, *not* same as vram in all cases.. */ ++#define nv_wf32(reg,val) ++ ++/* PRAMIN access */ ++#define nv_ri32(reg) nv_in32(ramin_map, (reg)) ++#define nv_wi32(reg,val) nv_out32(ramin_map, (reg), (val)) ++/* object access */ ++#define INSTANCE_RD(o,i) nv_ri32((o)->im_pramin->start + ((i)<<2)) ++#define INSTANCE_WR(o,i,v) nv_wi32((o)->im_pramin->start + ((i)<<2), (v)) ++ ++/* logging */ ++#define NV_PRINTK(level, d, fmt, arg...) \ ++ printk(level "nouveau %s: " fmt, pci_name(d->pdev), ##arg) ++#define NV_DEBUG(d, fmt, arg...) do { \ ++ if (drm_debug) { \ ++ NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \ ++ __LINE__, ##arg); \ ++ } \ ++} while(0) ++#define NV_ERROR(d, fmt, arg...) NV_PRINTK(KERN_ERR, d, fmt, ##arg) ++#define NV_INFO(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg) ++#define NV_TRACEWARN(d, fmt, arg...) NV_PRINTK(KERN_NOTICE, d, fmt, ##arg) ++#define NV_TRACE(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg) ++#define NV_WARN(d, fmt, arg...) NV_PRINTK(KERN_WARNING, d, fmt, ##arg) ++ ++#endif /* __NOUVEAU_DRV_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h +new file mode 100644 +index 0000000..ea2b9dd +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __NOUVEAU_OUTPUT_H__ ++#define __NOUVEAU_OUTPUT_H__ ++ ++struct nouveau_encoder { ++ struct drm_encoder base; ++ ++ struct dcb_entry *dcb_entry; ++ int or; ++ ++ bool dual_link; ++ ++ int (*set_clock_mode) (struct nouveau_encoder *encoder, ++ struct drm_display_mode *mode); ++}; ++#define to_nouveau_encoder(x) container_of((x), struct nouveau_encoder, base) ++ ++int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry); ++int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry); ++ ++#endif /* __NOUVEAU_OUTPUT_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h +new file mode 100644 +index 0000000..88ffdc0 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_fb.h +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __NOUVEAU_FB_H__ ++#define __NOUVEAU_FB_H__ ++ ++struct nouveau_framebuffer { ++ struct drm_framebuffer base; ++ struct drm_gem_object *gem; ++ struct drm_bo_kmap_obj kmap; ++}; ++ ++#define to_nouveau_framebuffer(x) container_of((x), struct nouveau_framebuffer, base) ++ ++extern const struct drm_mode_config_funcs nouveau_mode_config_funcs; ++ ++struct drm_framebuffer * ++nouveau_framebuffer_create(struct drm_device *, struct drm_gem_object *, ++ struct drm_mode_fb_cmd *); ++ ++#endif /* __NOUVEAU_FB_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +new file mode 100644 +index 0000000..38d929d +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +@@ -0,0 +1,946 @@ ++/* ++ * Copyright © 2007 David Airlie ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * David Airlie ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_crtc.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nouveau_crtc.h" ++#include "nouveau_fb.h" ++#include "nouveau_fbcon.h" ++ ++extern int nouveau_fbpercrtc; ++ ++static int nouveau_fbcon_setcolreg(unsigned regno, unsigned red, unsigned green, ++ unsigned blue, unsigned transp, ++ struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_crtc *crtc; ++ int i; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_crtc *nouveau_crtc = to_nouveau_crtc(crtc); ++ struct drm_mode_set *modeset = &nouveau_crtc->mode_set; ++ struct drm_framebuffer *fb = modeset->fb; ++ ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ if (i == par->crtc_count) ++ continue; ++ ++ ++ if (regno > 255) ++ return 1; ++ ++ if (fb->depth == 8) { ++ /* TODO */ ++ } ++ ++ if (regno < 16) { ++ switch (fb->depth) { ++ case 15: ++ fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | ++ ((green & 0xf800) >> 6) | ++ ((blue & 0xf800) >> 11); ++ break; ++ case 16: ++ fb->pseudo_palette[regno] = (red & 0xf800) | ++ ((green & 0xfc00) >> 5) | ++ ((blue & 0xf800) >> 11); ++ break; ++ case 24: ++ case 32: ++ fb->pseudo_palette[regno] = ((red & 0xff00) << 8) | ++ (green & 0xff00) | ++ ((blue & 0xff00) >> 8); ++ break; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int nouveau_fbcon_check_var(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct nouveau_framebuffer *nouveau_fb = par->nouveau_fb; ++ struct drm_device *dev = par->dev; ++ struct drm_framebuffer *fb = &nouveau_fb->base; ++ int depth; ++ ++ if (var->pixclock == -1 || !var->pixclock) ++ return -EINVAL; ++ ++ /* Need to resize the fb object !!! */ ++ if (var->xres > fb->width || var->yres > fb->height) { ++ NV_ERROR(dev, "Requested width/height is greater than current fb object %dx%d > %dx%d\n",var->xres,var->yres,fb->width,fb->height); ++ NV_ERROR(dev, "Need resizing code.\n"); ++ return -EINVAL; ++ } ++ ++ switch (var->bits_per_pixel) { ++ case 16: ++ depth = (var->green.length == 6) ? 16 : 15; ++ break; ++ case 32: ++ depth = (var->transp.length > 0) ? 32 : 24; ++ break; ++ default: ++ depth = var->bits_per_pixel; ++ break; ++ } ++ ++ switch (depth) { ++ case 8: ++ var->red.offset = 0; ++ var->green.offset = 0; ++ var->blue.offset = 0; ++ var->red.length = 8; ++ var->green.length = 8; ++ var->blue.length = 8; ++ var->transp.length = 0; ++ var->transp.offset = 0; ++ break; ++ case 15: ++ var->red.offset = 10; ++ var->green.offset = 5; ++ var->blue.offset = 0; ++ var->red.length = 5; ++ var->green.length = 5; ++ var->blue.length = 5; ++ var->transp.length = 1; ++ var->transp.offset = 15; ++ break; ++ case 16: ++ var->red.offset = 11; ++ var->green.offset = 5; ++ var->blue.offset = 0; ++ var->red.length = 5; ++ var->green.length = 6; ++ var->blue.length = 5; ++ var->transp.length = 0; ++ var->transp.offset = 0; ++ break; ++ case 24: ++ var->red.offset = 16; ++ var->green.offset = 8; ++ var->blue.offset = 0; ++ var->red.length = 8; ++ var->green.length = 8; ++ var->blue.length = 8; ++ var->transp.length = 0; ++ var->transp.offset = 0; ++ break; ++ case 32: ++ var->red.offset = 16; ++ var->green.offset = 8; ++ var->blue.offset = 0; ++ var->red.length = 8; ++ var->green.length = 8; ++ var->blue.length = 8; ++ var->transp.length = 8; ++ var->transp.offset = 24; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* this will let fbcon do the mode init */ ++/* FIXME: take mode config lock? */ ++static int nouveau_fbcon_set_par(struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct fb_var_screeninfo *var = &info->var; ++ int i; ++ ++ NV_DEBUG(dev, "%d %d\n", var->xres, var->pixclock); ++ ++ if (var->pixclock != -1) { ++ ++ NV_ERROR(dev, "PIXEL CLCOK SET\n"); ++ return -EINVAL; ++ } else { ++ struct drm_crtc *crtc; ++ int ret; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_crtc *nouveau_crtc = to_nouveau_crtc(crtc); ++ ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ if (i == par->crtc_count) ++ continue; ++ ++ if (crtc->fb == nouveau_crtc->mode_set.fb) { ++ mutex_lock(&dev->mode_config.mutex); ++ ret = crtc->funcs->set_config(&nouveau_crtc->mode_set); ++ mutex_unlock(&dev->mode_config.mutex); ++ if (ret) ++ return ret; ++ } ++ } ++ return 0; ++ } ++} ++ ++static int nouveau_fbcon_pan_display(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_mode_set *modeset; ++ struct drm_crtc *crtc; ++ struct nouveau_crtc *nouveau_crtc; ++ int ret = 0; ++ int i; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ if (i == par->crtc_count) ++ continue; ++ ++ nouveau_crtc = to_nouveau_crtc(crtc); ++ modeset = &nouveau_crtc->mode_set; ++ ++ modeset->x = var->xoffset; ++ modeset->y = var->yoffset; ++ ++ if (modeset->num_connectors) { ++ mutex_lock(&dev->mode_config.mutex); ++ ret = crtc->funcs->set_config(modeset); ++ mutex_unlock(&dev->mode_config.mutex); ++ if (!ret) { ++ info->var.xoffset = var->xoffset; ++ info->var.yoffset = var->yoffset; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++static void nouveau_fbcon_on(struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_crtc *crtc; ++ struct drm_encoder *encoder; ++ int i; ++ ++ /* ++ * For each CRTC in this fb, find all associated encoders ++ * and turn them off, then turn off the CRTC. ++ */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; ++ ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); ++ ++ /* Found a CRTC on this fb, now find encoders */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ if (encoder->crtc == crtc) { ++ struct drm_encoder_helper_funcs *encoder_funcs; ++ encoder_funcs = encoder->helper_private; ++ encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); ++ } ++ } ++ } ++} ++ ++static void nouveau_fbcon_off(struct fb_info *info, int dpms_mode) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_crtc *crtc; ++ struct drm_encoder *encoder; ++ int i; ++ ++ /* ++ * For each CRTC in this fb, find all associated encoders ++ * and turn them off, then turn off the CRTC. ++ */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; ++ ++ for (i = 0; i < par->crtc_count; i++) ++ if (crtc->base.id == par->crtc_ids[i]) ++ break; ++ ++ /* Found a CRTC on this fb, now find encoders */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ if (encoder->crtc == crtc) { ++ struct drm_encoder_helper_funcs *encoder_funcs; ++ encoder_funcs = encoder->helper_private; ++ encoder_funcs->dpms(encoder, dpms_mode); ++ } ++ } ++ if (dpms_mode == DRM_MODE_DPMS_OFF) ++ crtc_funcs->dpms(crtc, dpms_mode); ++ } ++} ++ ++static int nouveau_fbcon_blank(int blank, struct fb_info *info) ++{ ++ switch (blank) { ++ case FB_BLANK_UNBLANK: ++ nouveau_fbcon_on(info); ++ break; ++ case FB_BLANK_NORMAL: ++ nouveau_fbcon_off(info, DRM_MODE_DPMS_STANDBY); ++ break; ++ case FB_BLANK_HSYNC_SUSPEND: ++ nouveau_fbcon_off(info, DRM_MODE_DPMS_STANDBY); ++ break; ++ case FB_BLANK_VSYNC_SUSPEND: ++ nouveau_fbcon_off(info, DRM_MODE_DPMS_SUSPEND); ++ break; ++ case FB_BLANK_POWERDOWN: ++ nouveau_fbcon_off(info, DRM_MODE_DPMS_OFF); ++ break; ++ } ++ return 0; ++} ++ ++static struct fb_ops nouveau_fbcon_ops = { ++ .owner = THIS_MODULE, ++ .fb_check_var = nouveau_fbcon_check_var, ++ .fb_set_par = nouveau_fbcon_set_par, ++ .fb_setcolreg = nouveau_fbcon_setcolreg, ++ .fb_fillrect = cfb_fillrect, ++ .fb_copyarea = cfb_copyarea, ++ .fb_imageblit = cfb_imageblit, ++ .fb_pan_display = nouveau_fbcon_pan_display, ++ .fb_blank = nouveau_fbcon_blank, ++}; ++ ++/** ++ * Curretly it is assumed that the old framebuffer is reused. ++ * ++ * LOCKING ++ * caller should hold the mode config lock. ++ * ++ */ ++int nouveau_fbcon_resize(struct drm_device *dev, struct drm_crtc *crtc) ++{ ++ struct fb_info *info; ++ struct drm_framebuffer *fb; ++ struct drm_display_mode *mode = crtc->desired_mode; ++ ++ fb = crtc->fb; ++ if (!fb) ++ return 1; ++ ++ info = fb->fbdev; ++ if (!info) ++ return 1; ++ ++ if (!mode) ++ return 1; ++ ++ info->var.xres = mode->hdisplay; ++ info->var.right_margin = mode->hsync_start - mode->hdisplay; ++ info->var.hsync_len = mode->hsync_end - mode->hsync_start; ++ info->var.left_margin = mode->htotal - mode->hsync_end; ++ info->var.yres = mode->vdisplay; ++ info->var.lower_margin = mode->vsync_start - mode->vdisplay; ++ info->var.vsync_len = mode->vsync_end - mode->vsync_start; ++ info->var.upper_margin = mode->vtotal - mode->vsync_end; ++ info->var.pixclock = 10000000 / mode->htotal * 1000 / mode->vtotal * 100; ++ /* avoid overflow */ ++ info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh; ++ ++ return 0; ++} ++EXPORT_SYMBOL(nouveau_fbcon_resize); ++ ++static struct drm_mode_set kernelfb_mode; ++ ++static int nouveau_fbcon_panic(struct notifier_block *n, unsigned long ununsed, ++ void *panic_str) ++{ ++ printk("panic occurred, switching back to text console\n"); ++ ++ nouveau_fbcon_restore(); ++ return 0; ++} ++ ++static struct notifier_block paniced = { ++ .notifier_call = nouveau_fbcon_panic, ++}; ++ ++static int nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, ++ uint32_t fb_height, uint32_t surface_width, ++ uint32_t surface_height, ++ struct nouveau_framebuffer **nouveau_fb_p) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct fb_info *info; ++ struct nouveau_fbcon_par *par; ++ struct drm_framebuffer *fb; ++ struct nouveau_framebuffer *nouveau_fb; ++ struct drm_mode_fb_cmd mode_cmd; ++ struct drm_gem_object *gem = NULL; ++ struct nouveau_gem_object *ngem; ++ struct device *device = &dev->pdev->dev; ++ struct fb_fillrect rect; ++ int size, ret; ++ ++ mode_cmd.width = surface_width; ++ mode_cmd.height = surface_height; ++ ++ mode_cmd.bpp = 32; ++ mode_cmd.pitch = ALIGN(mode_cmd.width, 64) * ((mode_cmd.bpp + 1) / 8); ++ mode_cmd.depth = 24; ++ ++ size = mode_cmd.pitch * mode_cmd.height; ++ size = ALIGN(size, PAGE_SIZE); ++ ++ ret = nouveau_gem_new(dev, NULL, size, 0, NOUVEAU_GEM_DOMAIN_VRAM, &gem); ++ if (ret) { ++ printk(KERN_ERR "failed to allocate framebuffer\n"); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ngem = gem->driver_private; ++ ++ ret = nouveau_gem_pin(gem, NOUVEAU_GEM_DOMAIN_VRAM); ++ mutex_lock(&dev->struct_mutex); ++ if (ret) { ++ NV_ERROR(dev, "failed to pin fb: %d\n", ret); ++ goto out_unref; ++ } ++ ++ fb = nouveau_framebuffer_create(dev, gem, &mode_cmd); ++ if (!fb) { ++ ret = -ENOMEM; ++ NV_ERROR(dev, "failed to allocate fb.\n"); ++ goto out_unref; ++ } ++ ++ list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list); ++ ++ nouveau_fb = to_nouveau_framebuffer(fb); ++ *nouveau_fb_p = nouveau_fb; ++ ++ ret = drm_bo_kmap(ngem->bo, 0, ngem->bo->mem.num_pages, ++ &nouveau_fb->kmap); ++ if (ret) { ++ NV_ERROR(dev, "failed to kmap fb: %d\n", ret); ++ goto out_unref; ++ } ++ ++ info = framebuffer_alloc(sizeof(struct nouveau_fbcon_par), device); ++ if (!info) { ++ ret = -ENOMEM; ++ goto out_unref; ++ } ++ ++ par = info->par; ++ ++ strcpy(info->fix.id, "nouveaudrmfb"); ++ info->fix.type = FB_TYPE_PACKED_PIXELS; ++ info->fix.visual = FB_VISUAL_TRUECOLOR; ++ info->fix.type_aux = 0; ++ info->fix.xpanstep = 1; /* doing it in hw */ ++ info->fix.ypanstep = 1; /* doing it in hw */ ++ info->fix.ywrapstep = 0; ++ info->fix.accel = FB_ACCEL_I830; ++ info->fix.type_aux = 0; ++ ++ info->flags = FBINFO_DEFAULT; ++ ++ info->fbops = &nouveau_fbcon_ops; ++ ++ info->fix.line_length = fb->pitch; ++ info->fix.smem_start = dev->mode_config.fb_base + ngem->bo->offset - ++ dev_priv->vm_vram_base; ++ info->fix.smem_len = size; ++ ++ info->flags = FBINFO_DEFAULT; ++ ++ info->screen_base = nouveau_fb->kmap.virtual; ++ info->screen_size = size; ++ ++// memset(info->screen_base, 0, size); ++ ++ info->pseudo_palette = fb->pseudo_palette; ++ info->var.xres_virtual = fb->width; ++ info->var.yres_virtual = fb->height; ++ info->var.bits_per_pixel = fb->bits_per_pixel; ++ info->var.xoffset = 0; ++ info->var.yoffset = 0; ++ info->var.activate = FB_ACTIVATE_NOW; ++ info->var.height = -1; ++ info->var.width = -1; ++ ++ info->var.xres = fb_width; ++ info->var.yres = fb_height; ++ ++ /* FIXME: we really shouldn't expose mmio space at all */ ++ info->fix.mmio_start = pci_resource_start(dev->pdev, 1); ++ info->fix.mmio_len = pci_resource_len(dev->pdev, 1); ++ ++ info->pixmap.size = 64*1024; ++ info->pixmap.buf_align = 8; ++ info->pixmap.access_align = 32; ++ info->pixmap.flags = FB_PIXMAP_SYSTEM; ++ info->pixmap.scan_align = 1; ++ ++ switch(fb->depth) { ++ case 8: ++ info->var.red.offset = 0; ++ info->var.green.offset = 0; ++ info->var.blue.offset = 0; ++ info->var.red.length = 8; /* 8bit DAC */ ++ info->var.green.length = 8; ++ info->var.blue.length = 8; ++ info->var.transp.offset = 0; ++ info->var.transp.length = 0; ++ break; ++ case 15: ++ info->var.red.offset = 10; ++ info->var.green.offset = 5; ++ info->var.blue.offset = 0; ++ info->var.red.length = 5; ++ info->var.green.length = 5; ++ info->var.blue.length = 5; ++ info->var.transp.offset = 15; ++ info->var.transp.length = 1; ++ break; ++ case 16: ++ info->var.red.offset = 11; ++ info->var.green.offset = 5; ++ info->var.blue.offset = 0; ++ info->var.red.length = 5; ++ info->var.green.length = 6; ++ info->var.blue.length = 5; ++ info->var.transp.offset = 0; ++ break; ++ case 24: ++ info->var.red.offset = 16; ++ info->var.green.offset = 8; ++ info->var.blue.offset = 0; ++ info->var.red.length = 8; ++ info->var.green.length = 8; ++ info->var.blue.length = 8; ++ info->var.transp.offset = 0; ++ info->var.transp.length = 0; ++ break; ++ case 32: ++ info->var.red.offset = 16; ++ info->var.green.offset = 8; ++ info->var.blue.offset = 0; ++ info->var.red.length = 8; ++ info->var.green.length = 8; ++ info->var.blue.length = 8; ++ info->var.transp.offset = 24; ++ info->var.transp.length = 8; ++ break; ++ default: ++ break; ++ } ++ ++ fb->fbdev = info; ++ ++ par->nouveau_fb = nouveau_fb; ++ par->dev = dev; ++ ++ switch (dev_priv->card_type) { ++ case NV_50: ++ nv50_fbcon_accel_init(info); ++ break; ++ default: ++ break; ++ }; ++ ++ /* Clear the entire fbcon. The drm will program every connector ++ * with it's preferred mode. If the sizes differ, one display will ++ * quite likely have garbage around the console. ++ */ ++ rect.dx = rect.dy = 0; ++ rect.width = surface_width; ++ rect.height = surface_height; ++ rect.color = 0; ++ rect.rop = ROP_COPY; ++ info->fbops->fb_fillrect(info, &rect); ++ ++ /* To allow resizeing without swapping buffers */ ++ printk("allocated %dx%d fb: 0x%lx, bo %p\n", nouveau_fb->base.width, ++ nouveau_fb->base.height, ngem->bo->offset, gem); ++ ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++ ++out_unref: ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++out: ++ return ret; ++} ++ ++static int nouveau_fbcon_multi_fb_probe_crtc(struct drm_device *dev, ++ struct drm_crtc *crtc) ++{ ++ struct nouveau_crtc *nouveau_crtc = to_nouveau_crtc(crtc); ++ struct nouveau_framebuffer *nouveau_fb; ++ struct drm_framebuffer *fb; ++ struct drm_connector *connector; ++ struct fb_info *info; ++ struct nouveau_fbcon_par *par; ++ struct drm_mode_set *modeset; ++ unsigned int width, height; ++ int new_fb = 0; ++ int ret, i, conn_count; ++ ++ if (!drm_helper_crtc_in_use(crtc)) ++ return 0; ++ ++ if (!crtc->desired_mode) ++ return 0; ++ ++ width = crtc->desired_mode->hdisplay; ++ height = crtc->desired_mode->vdisplay; ++ ++ /* is there an fb bound to this crtc already */ ++ if (!nouveau_crtc->mode_set.fb) { ++ ret = nouveau_fbcon_create(dev, width, height, width, height, &nouveau_fb); ++ if (ret) ++ return -EINVAL; ++ new_fb = 1; ++ } else { ++ fb = nouveau_crtc->mode_set.fb; ++ nouveau_fb = to_nouveau_framebuffer(fb); ++ if ((nouveau_fb->base.width < width) || (nouveau_fb->base.height < height)) ++ return -EINVAL; ++ } ++ ++ info = nouveau_fb->base.fbdev; ++ par = info->par; ++ ++ modeset = &nouveau_crtc->mode_set; ++ modeset->fb = &nouveau_fb->base; ++ conn_count = 0; ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { ++ if (connector->encoder) { ++ if (connector->encoder->crtc == modeset->crtc) { ++ modeset->connectors[conn_count] = connector; ++ conn_count++; ++ if (conn_count > NOUVEAUFB_CONN_LIMIT) ++ BUG(); ++ } ++ } ++ } ++ ++ for (i = conn_count; i < NOUVEAUFB_CONN_LIMIT; i++) ++ modeset->connectors[i] = NULL; ++ ++ par->crtc_ids[0] = crtc->base.id; ++ ++ modeset->num_connectors = conn_count; ++ if (modeset->mode != modeset->crtc->desired_mode) ++ modeset->mode = modeset->crtc->desired_mode; ++ ++ par->crtc_count = 1; ++ ++ if (new_fb) { ++ info->var.pixclock = -1; ++ if (register_framebuffer(info) < 0) ++ return -EINVAL; ++ } else ++ nouveau_fbcon_set_par(info); ++ ++ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, ++ info->fix.id); ++ ++ /* Switch back to kernel console on panic */ ++ kernelfb_mode = *modeset; ++ atomic_notifier_chain_register(&panic_notifier_list, &paniced); ++ printk(KERN_INFO "registered panic notifier\n"); ++ ++ return 0; ++} ++ ++static int nouveau_fbcon_multi_fb_probe(struct drm_device *dev) ++{ ++ ++ struct drm_crtc *crtc; ++ int ret = 0; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ ret = nouveau_fbcon_multi_fb_probe_crtc(dev, crtc); ++ if (ret) ++ return ret; ++ } ++ return ret; ++} ++ ++static int nouveau_fbcon_single_fb_probe(struct drm_device *dev) ++{ ++ struct drm_crtc *crtc; ++ struct drm_connector *connector; ++ unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1; ++ unsigned int surface_width = 0, surface_height = 0; ++ int new_fb = 0; ++ int crtc_count = 0; ++ int ret, i, conn_count = 0; ++ struct nouveau_framebuffer *nouveau_fb; ++ struct fb_info *info; ++ struct nouveau_fbcon_par *par; ++ struct drm_mode_set *modeset = NULL; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* Get a count of crtcs now in use and new min/maxes width/heights */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ if (!drm_helper_crtc_in_use(crtc)) ++ continue; ++ ++ crtc_count++; ++ if (!crtc->desired_mode) ++ continue; ++ ++ /* Smallest mode determines console size... */ ++ if (crtc->desired_mode->hdisplay < fb_width) ++ fb_width = crtc->desired_mode->hdisplay; ++ ++ if (crtc->desired_mode->vdisplay < fb_height) ++ fb_height = crtc->desired_mode->vdisplay; ++ ++ /* ... but largest for memory allocation dimensions */ ++ if (crtc->desired_mode->hdisplay > surface_width) ++ surface_width = crtc->desired_mode->hdisplay; ++ ++ if (crtc->desired_mode->vdisplay > surface_height) ++ surface_height = crtc->desired_mode->vdisplay; ++ } ++ ++ if (crtc_count == 0 || fb_width == -1 || fb_height == -1) { ++ /* hmm everyone went away - assume VGA cable just fell out ++ and will come back later. */ ++ NV_DEBUG(dev, "no CRTCs available?\n"); ++ return 0; ++ } ++ ++//fail ++ /* Find the fb for our new config */ ++ if (list_empty(&dev->mode_config.fb_kernel_list)) { ++ NV_DEBUG(dev, "creating new fb (console size %dx%d, " ++ "buffer size %dx%d)\n", fb_width, fb_height, ++ surface_width, surface_height); ++ ret = nouveau_fbcon_create(dev, fb_width, fb_height, surface_width, ++ surface_height, &nouveau_fb); ++ if (ret) ++ return -EINVAL; ++ new_fb = 1; ++ } else { ++ struct drm_framebuffer *fb; ++ ++ fb = list_first_entry(&dev->mode_config.fb_kernel_list, ++ struct drm_framebuffer, filp_head); ++ nouveau_fb = to_nouveau_framebuffer(fb); ++ ++ /* if someone hotplugs something bigger than we have already ++ * allocated, we are pwned. As really we can't resize an ++ * fbdev that is in the wild currently due to fbdev not really ++ * being designed for the lower layers moving stuff around ++ * under it. ++ * - so in the grand style of things - punt. ++ */ ++ if ((fb->width < surface_width) || ++ (fb->height < surface_height)) { ++ NV_ERROR(dev, "fb not large enough for console\n"); ++ return -EINVAL; ++ } ++ } ++// fail ++ ++ info = nouveau_fb->base.fbdev; ++ par = info->par; ++ ++ crtc_count = 0; ++ /* ++ * For each CRTC, set up the connector list for the CRTC's mode ++ * set configuration. ++ */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_crtc *nouveau_crtc = to_nouveau_crtc(crtc); ++ ++ modeset = &nouveau_crtc->mode_set; ++ modeset->fb = &nouveau_fb->base; ++ conn_count = 0; ++ list_for_each_entry(connector, &dev->mode_config.connector_list, ++ head) { ++ if (!connector->encoder) ++ continue; ++ ++ if(connector->encoder->crtc == modeset->crtc) { ++ modeset->connectors[conn_count++] = connector; ++ if (conn_count > NOUVEAUFB_CONN_LIMIT) ++ BUG(); ++ } ++ } ++ ++ /* Zero out remaining connector pointers */ ++ for (i = conn_count; i < NOUVEAUFB_CONN_LIMIT; i++) ++ modeset->connectors[i] = NULL; ++ ++ par->crtc_ids[crtc_count++] = crtc->base.id; ++ ++ modeset->num_connectors = conn_count; ++ if (modeset->mode != modeset->crtc->desired_mode) ++ modeset->mode = modeset->crtc->desired_mode; ++ } ++ par->crtc_count = crtc_count; ++ ++ if (new_fb) { ++ info->var.pixclock = -1; ++ if (register_framebuffer(info) < 0) ++ return -EINVAL; ++ } else ++ nouveau_fbcon_set_par(info); ++ ++ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, ++ info->fix.id); ++ ++ /* Switch back to kernel console on panic */ ++ kernelfb_mode = *modeset; ++ atomic_notifier_chain_register(&panic_notifier_list, &paniced); ++ printk(KERN_INFO "registered panic notifier\n"); ++ ++ return 0; ++} ++ ++/** ++ * nouveau_fbcon_restore - restore the framebuffer console (kernel) config ++ * ++ * Restore's the kernel's fbcon mode, used for lastclose & panic paths. ++ */ ++void nouveau_fbcon_restore(void) ++{ ++ drm_crtc_helper_set_config(&kernelfb_mode); ++} ++ ++static void nouveau_fbcon_sysrq(int dummy1, struct tty_struct *dummy3) ++{ ++ nouveau_fbcon_restore(); ++} ++ ++static struct sysrq_key_op sysrq_nouveau_fbcon_restore_op = { ++ .handler = nouveau_fbcon_sysrq, ++ .help_msg = "force fb", ++ .action_msg = "force restore of fb console", ++}; ++ ++int nouveau_fbcon_probe(struct drm_device *dev) ++{ ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* something has changed in the lower levels of hell - deal with it ++ here */ ++ ++ /* two modes : a) 1 fb to rule all crtcs. ++ b) one fb per crtc. ++ two actions 1) new connected device ++ 2) device removed. ++ case a/1 : if the fb surface isn't big enough - resize the surface fb. ++ if the fb size isn't big enough - resize fb into surface. ++ if everything big enough configure the new crtc/etc. ++ case a/2 : undo the configuration ++ possibly resize down the fb to fit the new configuration. ++ case b/1 : see if it is on a new crtc - setup a new fb and add it. ++ case b/2 : teardown the new fb. ++ */ ++ ++ /* mode a first */ ++ /* search for an fb */ ++ if (nouveau_fbpercrtc) { ++ ret = nouveau_fbcon_multi_fb_probe(dev); ++ } else { ++ ret = nouveau_fbcon_single_fb_probe(dev); ++ } ++ ++ register_sysrq_key('g', &sysrq_nouveau_fbcon_restore_op); ++ ++ return ret; ++} ++EXPORT_SYMBOL(nouveau_fbcon_probe); ++ ++int nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb) ++{ ++ struct nouveau_framebuffer *nouveau_fb = to_nouveau_framebuffer(fb); ++ struct fb_info *info; ++ ++ if (!fb) ++ return -EINVAL; ++ ++ info = fb->fbdev; ++ ++ if (info) { ++ unregister_framebuffer(info); ++ drm_bo_kunmap(&nouveau_fb->kmap); ++ framebuffer_release(info); ++ } ++ ++ atomic_notifier_chain_unregister(&panic_notifier_list, &paniced); ++ memset(&kernelfb_mode, 0, sizeof(struct drm_mode_set)); ++ return 0; ++} ++EXPORT_SYMBOL(nouveau_fbcon_remove); ++MODULE_LICENSE("GPL and additional rights"); +diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h +new file mode 100644 +index 0000000..471d2e8 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __NOUVEAU_FBCON_H__ ++#define __NOUVEAU_FBCON_H__ ++ ++#define NOUVEAUFB_CONN_LIMIT 4 ++ ++struct nouveau_fbcon_par { ++ struct drm_device *dev; ++ struct drm_display_mode *our_mode; ++ struct nouveau_framebuffer *nouveau_fb; ++ int crtc_count; ++ /* crtc currently bound to this */ ++ uint32_t crtc_ids[2]; ++}; ++ ++int nouveau_fbcon_probe(struct drm_device *dev); ++int nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb); ++void nouveau_fbcon_restore(void); ++ ++int nv50_fbcon_accel_init(struct fb_info *info); ++ ++#endif /* __NV50_FBCON_H__ */ ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c +new file mode 100644 +index 0000000..a24c137 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_fence.c +@@ -0,0 +1,126 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++ ++struct nouveau_channel * ++nouveau_fence_channel(struct drm_device *dev, uint32_t class) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (class == 0) ++ class = dev_priv->channel->id; ++ ++ return dev_priv->fifos[class]; ++} ++ ++static int ++nouveau_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags) ++{ ++ NV_DEBUG(dev, "class=%d, flags=0x%08x\n", class, flags); ++ ++ return 0; ++} ++ ++static int ++nouveau_fence_emit(struct drm_device *dev, uint32_t class, uint32_t flags, ++ uint32_t *breadcrumb, uint32_t *native_type) ++{ ++ struct nouveau_channel *chan = nouveau_fence_channel(dev, class); ++ int ret; ++ ++ NV_DEBUG(dev, "class=%d, flags=0x%08x\n", class, flags); ++ ++ ret = RING_SPACE(chan, 2); ++ if (ret) ++ return ret; ++ ++ *breadcrumb = ++chan->next_sequence; ++ *native_type = DRM_FENCE_TYPE_EXE; ++ ++ NV_DEBUG(dev, "emit 0x%08x\n", *breadcrumb); ++ ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_SET_REF, 1); ++ OUT_RING (chan, *breadcrumb); ++ FIRE_RING (chan); ++ ++ return 0; ++} ++ ++static void ++nouveau_fence_poll(struct drm_device *dev, uint32_t class, uint32_t waiting_types) ++{ ++ struct drm_fence_class_manager *fc = &dev->fm.fence_class[class]; ++ struct nouveau_channel *chan = nouveau_fence_channel(dev, class); ++ ++ NV_DEBUG(dev, "class=%d\n", class); ++ NV_DEBUG(dev, "pending: 0x%08x 0x%08x\n", waiting_types, fc->waiting_types); ++ ++ if (!chan) { ++ static int warn_once = 0; ++ if (!warn_once) { ++ NV_ERROR(dev, "AIII channel %d inactive\n", class); ++ warn_once = 1; ++ } ++ return; ++ } ++ ++ if (1) { ++ uint32_t sequence = nvchan_rd32(0x48); ++ ++ NV_DEBUG(dev, "got 0x%08x\n", sequence); ++ drm_fence_handler(dev, class, sequence, waiting_types, 0); ++ } ++} ++ ++void ++nouveau_fence_handler(struct drm_device *dev, int channel) ++{ ++ struct drm_fence_manager *fm = &dev->fm; ++ struct drm_fence_class_manager *fc = &fm->fence_class[channel]; ++ ++ NV_DEBUG(dev, "class=%d\n", channel); ++ ++ write_lock(&fm->lock); ++ nouveau_fence_poll(dev, channel, fc->waiting_types); ++ write_unlock(&fm->lock); ++} ++ ++struct drm_fence_driver nouveau_fence_driver = { ++ .num_classes = 8, ++ .wrap_diff = (1 << 30), ++ .flush_diff = (1 << 29), ++ .sequence_mask = 0xffffffffU, ++ .has_irq = nouveau_fence_has_irq, ++ .emit = nouveau_fence_emit, ++ .flush = NULL, ++ .poll = nouveau_fence_poll, ++ .needed_flush = NULL, ++ .wait = NULL ++}; +diff --git a/drivers/gpu/drm/nouveau/nouveau_fifo.c b/drivers/gpu/drm/nouveau/nouveau_fifo.c +new file mode 100644 +index 0000000..670ee1f +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_fifo.c +@@ -0,0 +1,692 @@ ++/* ++ * Copyright 2005-2006 Stephane Marchesin ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nouveau_dma.h" ++ ++ ++/* returns the size of fifo context */ ++int nouveau_fifo_ctx_size(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv=dev->dev_private; ++ ++ if (dev_priv->card_type >= NV_40) ++ return 128; ++ else if (dev_priv->card_type >= NV_17) ++ return 64; ++ else ++ return 32; ++} ++ ++/*********************************** ++ * functions doing the actual work ++ ***********************************/ ++ ++static int nouveau_fifo_instmem_configure(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ nv_wr32(NV03_PFIFO_RAMHT, ++ (0x03 << 24) /* search 128 */ | ++ ((dev_priv->ramht_bits - 9) << 16) | ++ (dev_priv->ramht_offset >> 8) ++ ); ++ ++ nv_wr32(NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); ++ ++ switch(dev_priv->card_type) ++ { ++ case NV_40: ++ switch (dev_priv->chipset) { ++ case 0x47: ++ case 0x49: ++ case 0x4b: ++ nv_wr32(0x2230, 1); ++ break; ++ default: ++ break; ++ } ++ nv_wr32(NV40_PFIFO_RAMFC, 0x30002); ++ break; ++ case NV_44: ++ nv_wr32(NV40_PFIFO_RAMFC, ((nouveau_mem_fb_amount(dev)-512*1024+dev_priv->ramfc_offset)>>16) | ++ (2 << 16)); ++ break; ++ case NV_30: ++ case NV_20: ++ case NV_17: ++ nv_wr32(NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset>>8) | ++ (1 << 16) /* 64 Bytes entry*/); ++ /* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */ ++ break; ++ case NV_11: ++ case NV_10: ++ case NV_04: ++ nv_wr32(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); ++ break; ++ } ++ ++ return 0; ++} ++ ++int nouveau_fifo_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) & ++ ~NV_PMC_ENABLE_PFIFO); ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PFIFO); ++ ++ /* Enable PFIFO error reporting */ ++ nv_wr32(NV03_PFIFO_INTR_0, 0xFFFFFFFF); ++ nv_wr32(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); ++ ++ nv_wr32(NV03_PFIFO_CACHES, 0x00000000); ++ ++ ret = nouveau_fifo_instmem_configure(dev); ++ if (ret) { ++ NV_ERROR(dev, "Failed to configure instance memory\n"); ++ return ret; ++ } ++ ++ /* FIXME remove all the stuff that's done in nouveau_fifo_alloc */ ++ ++ NV_DEBUG(dev, "Setting defaults for remaining PFIFO regs\n"); ++ ++ /* All channels into PIO mode */ ++ nv_wr32(NV04_PFIFO_MODE, 0x00000000); ++ ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000000); ++ /* Channel 0 active, PIO mode */ ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH1, 0x00000000); ++ /* PUT and GET to 0 */ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUT, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_GET, 0x00000000); ++ /* No cmdbuf object */ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_INSTANCE, 0x00000000); ++ nv_wr32(NV03_PFIFO_CACHE0_PUSH0, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE0_PULL0, 0x00000000); ++ nv_wr32(NV04_PFIFO_SIZE, 0x0000FFFF); ++ nv_wr32(NV04_PFIFO_CACHE1_HASH, 0x0000FFFF); ++ nv_wr32(NV04_PFIFO_CACHE0_PULL1, 0x00000001); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_CTL, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_ENGINE, 0x00000000); ++ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 | ++#ifdef __BIG_ENDIAN ++ NV_PFIFO_CACHE1_BIG_ENDIAN | ++#endif ++ 0x00000000); ++ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001); ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000001); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000001); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL1, 0x00000001); ++ ++ /* FIXME on NV04 */ ++ if (dev_priv->card_type >= NV_10) { ++ nv_wr32(NV10_PGRAPH_CTX_USER, 0x0); ++ nv_wr32(NV04_PFIFO_DELAY_0, 0xff /* retrycount*/ ); ++ if (dev_priv->card_type >= NV_40) ++ nv_wr32(NV10_PGRAPH_CTX_CONTROL, 0x00002001); ++ else ++ nv_wr32(NV10_PGRAPH_CTX_CONTROL, 0x10110000); ++ } else { ++ nv_wr32(NV04_PGRAPH_CTX_USER, 0x0); ++ nv_wr32(NV04_PFIFO_DELAY_0, 0xff /* retrycount*/ ); ++ nv_wr32(NV04_PGRAPH_CTX_CONTROL, 0x10110000); ++ } ++ ++ nv_wr32(NV04_PFIFO_DMA_TIMESLICE, 0x001fffff); ++ nv_wr32(NV03_PFIFO_CACHES, 0x00000001); ++ return 0; ++} ++ ++static int ++nouveau_fifo_pushbuf_ctxdma_init(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct mem_block *pb = chan->pushbuf_mem; ++ struct nouveau_gpuobj *pushbuf = NULL; ++ int ret; ++ ++ if (pb->flags & NOUVEAU_MEM_AGP) { ++ ret = nouveau_gpuobj_gart_dma_new(chan, pb->start, pb->size, ++ NV_DMA_ACCESS_RO, ++ &pushbuf, ++ &chan->pushbuf_base); ++ } else ++ if (pb->flags & NOUVEAU_MEM_PCI) { ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ pb->start, pb->size, ++ NV_DMA_ACCESS_RO, ++ NV_DMA_TARGET_PCI_NONLINEAR, ++ &pushbuf); ++ chan->pushbuf_base = 0; ++ } else if (dev_priv->card_type != NV_04) { ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ pb->start, pb->size, ++ NV_DMA_ACCESS_RO, ++ NV_DMA_TARGET_VIDMEM, &pushbuf); ++ chan->pushbuf_base = 0; ++ } else { ++ /* NV04 cmdbuf hack, from original ddx.. not sure of it's ++ * exact reason for existing :) PCI access to cmdbuf in ++ * VRAM. ++ */ ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ pb->start + ++ drm_get_resource_start(dev, 1), ++ pb->size, NV_DMA_ACCESS_RO, ++ NV_DMA_TARGET_PCI, &pushbuf); ++ chan->pushbuf_base = 0; ++ } ++ ++ if ((ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, ++ &chan->pushbuf))) { ++ NV_ERROR(dev, "Error referencing push buffer ctxdma: %d\n", ret); ++ if (pushbuf != dev_priv->gart_info.sg_ctxdma) ++ nouveau_gpuobj_del(dev, &pushbuf); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static struct mem_block * ++nouveau_fifo_user_pushbuf_alloc(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_config *config = &dev_priv->config; ++ struct mem_block *pb; ++ int pb_min_size = max(NV03_FIFO_SIZE, PAGE_SIZE); ++ ++ /* Defaults for unconfigured values */ ++ if (!dev_priv->mm_enabled) { ++ if (!config->cmdbuf.location) ++ config->cmdbuf.location = NOUVEAU_MEM_FB; ++ if (!config->cmdbuf.size || config->cmdbuf.size < pb_min_size) ++ config->cmdbuf.size = pb_min_size; ++ } else { ++ config->cmdbuf.location = NOUVEAU_MEM_AGP; ++ config->cmdbuf.size = 0x10000; ++ } ++ ++ pb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, ++ config->cmdbuf.location | NOUVEAU_MEM_MAPPED | ++ NOUVEAU_MEM_NOVM, (struct drm_file *)-2); ++ if (!pb) { ++ NV_ERROR(dev, "Couldn't allocate DMA push buffer\n"); ++ return NULL; ++ } ++ ++ return pb; ++} ++ ++/* allocates and initializes a fifo for user space consumption */ ++int ++nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, ++ struct drm_file *file_priv, struct mem_block *pushbuf, ++ uint32_t vram_handle, uint32_t tt_handle) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ struct nouveau_channel *chan; ++ int channel, user; ++ int ret; ++ ++ /* ++ * Alright, here is the full story ++ * Nvidia cards have multiple hw fifo contexts (praise them for that, ++ * no complicated crash-prone context switches) ++ * We allocate a new context for each app and let it write to it directly ++ * (woo, full userspace command submission !) ++ * When there are no more contexts, you lost ++ */ ++ for (channel = 0; channel < engine->fifo.channels; channel++) { ++ if (dev_priv->fifos[channel] == NULL) ++ break; ++ } ++ ++ /* no more fifos. you lost. */ ++ if (channel == engine->fifo.channels) ++ return -EINVAL; ++ ++ dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel), ++ DRM_MEM_DRIVER); ++ if (!dev_priv->fifos[channel]) ++ return -ENOMEM; ++ dev_priv->fifo_alloc_count++; ++ chan = dev_priv->fifos[channel]; ++ chan->dev = dev; ++ chan->id = channel; ++ chan->file_priv = file_priv; ++ chan->pushbuf_mem = pushbuf; ++ chan->vram_handle = vram_handle; ++ chan->gart_handle = tt_handle; ++ ++ NV_INFO(dev, "Allocating FIFO number %d\n", channel); ++ ++ /* Locate channel's user control regs */ ++ if (dev_priv->card_type < NV_40) ++ user = NV03_USER(channel); ++ else ++ if (dev_priv->card_type < NV_50) ++ user = NV40_USER(channel); ++ else ++ user = NV50_USER(channel); ++ ++ ret = drm_addmap(dev, drm_get_resource_start(dev, 0) + user, ++ PAGE_SIZE, _DRM_REGISTERS, _DRM_DRIVER | ++ (dev_priv->mm_enabled ? _DRM_READ_ONLY : 0), ++ &chan->user); ++ ++ /* Allocate space for per-channel fixed notifier memory */ ++ ret = nouveau_notifier_init_channel(chan); ++ if (ret) { ++ NV_ERROR(dev, "ntfy %d\n", ret); ++ nouveau_fifo_free(chan); ++ return ret; ++ } ++ ++ /* Setup channel's default objects */ ++ ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); ++ if (ret) { ++ NV_ERROR(dev, "gpuobj %d\n", ret); ++ nouveau_fifo_free(chan); ++ return ret; ++ } ++ ++ /* Create a dma object for the push buffer */ ++ ret = nouveau_fifo_pushbuf_ctxdma_init(chan); ++ if (ret) { ++ NV_ERROR(dev, "pbctxdma %d\n", ret); ++ nouveau_fifo_free(chan); ++ return ret; ++ } ++ ++ engine->graph.fifo_access(dev, false); ++ nouveau_wait_for_idle(dev); ++ ++ /* disable the fifo caches */ ++ nv_wr32(NV03_PFIFO_CACHES, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH, nv_rd32(NV04_PFIFO_CACHE1_DMA_PUSH)&(~0x1)); ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000000); ++ ++ /* Create a graphics context for new channel */ ++ ret = engine->graph.create_context(chan); ++ if (ret) { ++ nouveau_fifo_free(chan); ++ return ret; ++ } ++ ++ /* Construct inital RAMFC for new channel */ ++ ret = engine->fifo.create_context(chan); ++ if (ret) { ++ nouveau_fifo_free(chan); ++ return ret; ++ } ++ ++ /* setup channel's default get/put values ++ * XXX: quite possibly extremely pointless.. ++ */ ++ nvchan_wr32(0x44, chan->pushbuf_base); ++ nvchan_wr32(0x40, chan->pushbuf_base); ++ ++ /* If this is the first channel, setup PFIFO ourselves. For any ++ * other case, the GPU will handle this when it switches contexts. ++ */ ++ if (dev_priv->card_type < NV_50 && ++ dev_priv->fifo_alloc_count == 1) { ++ ret = engine->fifo.load_context(chan); ++ if (ret) { ++ nouveau_fifo_free(chan); ++ return ret; ++ } ++ ++ ret = engine->graph.load_context(chan); ++ if (ret) { ++ nouveau_fifo_free(chan); ++ return ret; ++ } ++ } ++ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH, ++ nv_rd32(NV04_PFIFO_CACHE1_DMA_PUSH) | 1); ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000001); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000001); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL1, 0x00000001); ++ ++ /* reenable the fifo caches */ ++ nv_wr32(NV03_PFIFO_CACHES, 1); ++ ++ engine->graph.fifo_access(dev, true); ++ ++ if (dev_priv->mm_enabled) { ++ ret = nouveau_dma_channel_setup(chan); ++ if (ret) { ++ nouveau_fifo_free(chan); ++ return ret; ++ } ++ } ++ ++ NV_INFO(dev, "%s: initialised FIFO %d\n", __func__, channel); ++ *chan_ret = chan; ++ return 0; ++} ++ ++int ++nouveau_channel_idle(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ uint32_t caches; ++ int idle; ++ ++ if (!chan) { ++ NV_ERROR(dev, "no channel...\n"); ++ return 1; ++ } ++ ++ caches = nv_rd32(NV03_PFIFO_CACHES); ++ nv_wr32(NV03_PFIFO_CACHES, caches & ~1); ++ ++ if (engine->fifo.channel_id(dev) != chan->id) { ++ struct nouveau_gpuobj *ramfc = ++ chan->ramfc ? chan->ramfc->gpuobj : NULL; ++ ++ if (!ramfc) { ++ NV_ERROR(dev, "No RAMFC for channel %d\n", chan->id); ++ return 1; ++ } ++ ++ engine->instmem.prepare_access(dev, false); ++ if (INSTANCE_RD(ramfc, 0) != INSTANCE_RD(ramfc, 1)) ++ idle = 0; ++ else ++ idle = 1; ++ engine->instmem.finish_access(dev); ++ } else { ++ idle = (nv_rd32(NV04_PFIFO_CACHE1_DMA_GET) == ++ nv_rd32(NV04_PFIFO_CACHE1_DMA_PUT)); ++ } ++ ++ nv_wr32(NV03_PFIFO_CACHES, caches); ++ return idle; ++} ++ ++/* stops a fifo */ ++void nouveau_fifo_free(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ uint64_t t_start; ++ bool timeout = false; ++ int ret; ++ ++ NV_INFO(dev, "%s: freeing fifo %d\n", __func__, chan->id); ++ ++ /* Give the channel a chance to idle, wait 2s (hopefully) */ ++ t_start = engine->timer.read(dev); ++ while (!nouveau_channel_idle(chan)) { ++ if (engine->timer.read(dev) - t_start > 2000000000ULL) { ++ NV_ERROR(dev, "Failed to idle channel %d. " ++ "Prepare for strangeness..\n", chan->id); ++ timeout = true; ++ break; ++ } ++ } ++ ++ /* Wait on a fence until channel goes idle, this ensures the engine ++ * has finished with the last push buffer completely before we destroy ++ * the channel. ++ */ ++ if (!timeout && dev_priv->mm_enabled) { ++ struct drm_fence_object *fence = NULL; ++ ++ ret = drm_fence_object_create(dev, chan->id, DRM_FENCE_TYPE_EXE, ++ DRM_FENCE_FLAG_EMIT, &fence); ++ if (ret == 0) ++ ret = drm_fence_object_wait(fence, 0, 1, ++ DRM_FENCE_TYPE_EXE); ++ ++ if (ret) { ++ NV_ERROR(dev, "Failed to fence channel %d. " ++ "Prepare for strangeness..\n", chan->id); ++ timeout = true; ++ } ++ } ++ ++ /* Ensure all outstanding fences are signaled. They should be if the ++ * above attempts at idling were OK, but if we failed this'll tell TTM ++ * we're done with the buffers. ++ */ ++ if (dev_priv->mm_enabled) { ++ drm_fence_handler(dev, chan->id, chan->next_sequence, ++ DRM_FENCE_TYPE_EXE, 0); ++ } ++ ++ /*XXX: Maybe should wait for PGRAPH to finish with the stuff it fetched ++ * from CACHE1 too? ++ *25/3/2009: handled in the mm_enabled case ++ */ ++ ++ /* disable the fifo caches */ ++ nv_wr32(NV03_PFIFO_CACHES, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH, nv_rd32(NV04_PFIFO_CACHE1_DMA_PUSH)&(~0x1)); ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000000); ++ ++ // FIXME XXX needs more code ++ ++ engine->fifo.destroy_context(chan); ++ ++ /* Cleanup PGRAPH state */ ++ engine->graph.destroy_context(chan); ++ ++ /* reenable the fifo caches */ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH, ++ nv_rd32(NV04_PFIFO_CACHE1_DMA_PUSH) | 1); ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000001); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000001); ++ nv_wr32(NV03_PFIFO_CACHES, 0x00000001); ++ ++ /* Deallocate push buffer */ ++ nouveau_gpuobj_ref_del(dev, &chan->pushbuf); ++ if (chan->pushbuf_mem) { ++ nouveau_mem_free(dev, chan->pushbuf_mem); ++ chan->pushbuf_mem = NULL; ++ } ++ ++ /* Destroy objects belonging to the channel */ ++ nouveau_gpuobj_channel_takedown(chan); ++ ++ nouveau_notifier_takedown_channel(chan); ++ ++ if (chan->user) ++ drm_rmmap(dev, chan->user); ++ ++ dev_priv->fifos[chan->id] = NULL; ++ dev_priv->fifo_alloc_count--; ++ drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); ++} ++ ++/* cleanups all the fifos from file_priv */ ++void nouveau_fifo_cleanup(struct drm_device *dev, struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ int i; ++ ++ NV_DEBUG(dev, "clearing FIFO enables from file_priv\n"); ++ for(i = 0; i < engine->fifo.channels; i++) { ++ struct nouveau_channel *chan = dev_priv->fifos[i]; ++ ++ if (chan && chan->file_priv == file_priv) ++ nouveau_fifo_free(chan); ++ } ++} ++ ++int ++nouveau_fifo_owner(struct drm_device *dev, struct drm_file *file_priv, ++ int channel) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ ++ if (channel >= engine->fifo.channels) ++ return 0; ++ if (dev_priv->fifos[channel] == NULL) ++ return 0; ++ return (dev_priv->fifos[channel]->file_priv == file_priv); ++} ++ ++/*********************************** ++ * ioctls wrapping the functions ++ ***********************************/ ++ ++static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_channel_alloc *init = data; ++ struct drm_map_list *entry; ++ struct nouveau_channel *chan; ++ struct mem_block *pushbuf = NULL; ++ int res; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) ++ return -EINVAL; ++ ++ pushbuf = nouveau_fifo_user_pushbuf_alloc(dev); ++ if (!pushbuf) ++ return -ENOMEM; ++ ++ res = nouveau_fifo_alloc(dev, &chan, file_priv, pushbuf, ++ init->fb_ctxdma_handle, ++ init->tt_ctxdma_handle); ++ if (res) ++ return res; ++ init->channel = chan->id; ++ ++ if (!dev_priv->mm_enabled) { ++ init->put_base = chan->pushbuf_base; ++ ++ /* make the fifo available to user space */ ++ /* first, the fifo control regs */ ++ entry = drm_find_matching_map(dev, chan->user); ++ if (!entry) ++ return -EINVAL; ++ init->ctrl = entry->user_token; ++ init->ctrl_size = chan->user->size; ++ ++ /* pass back FIFO map info to the caller */ ++ init->cmdbuf = chan->pushbuf_mem->map_handle; ++ init->cmdbuf_size = chan->pushbuf_mem->size; ++ ++ init->nr_subchan = 0; ++ } else { ++ init->subchan[0].handle = NvM2MF; ++ if (dev_priv->card_type < NV_50) ++ init->subchan[0].grclass = 0x5039; ++ else ++ init->subchan[0].grclass = 0x0039; ++ init->nr_subchan = 1; ++ } ++ ++ /* and the notifier block */ ++ if (!dev_priv->mm_enabled) { ++ init->notifier = chan->notifier_block->map_handle; ++ } else { ++ entry = drm_find_matching_map(dev, chan->notifier_map); ++ if (!entry) { ++ nouveau_fifo_free(chan); ++ return -EFAULT; ++ } ++ ++ init->notifier = entry->user_token; ++ } ++ init->notifier_size = chan->notifier_block->size; ++ ++ return 0; ++} ++ ++static int nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_channel_free *cfree = data; ++ struct nouveau_channel *chan; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); ++ ++ nouveau_fifo_free(chan); ++ return 0; ++} ++ ++/*********************************** ++ * finally, the ioctl table ++ ***********************************/ ++ ++struct drm_ioctl_desc nouveau_ioctls[] = { ++ DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_ALLOC, nouveau_ioctl_mem_alloc, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_FREE, nouveau_ioctl_mem_free, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_TILE, nouveau_ioctl_mem_tile, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_SUSPEND, nouveau_ioctl_suspend, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_RESUME, nouveau_ioctl_resume, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL, nouveau_gem_ioctl_pushbuf_call, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PIN, nouveau_gem_ioctl_pin, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_UNPIN, nouveau_gem_ioctl_unpin, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_MMAP, nouveau_gem_ioctl_mmap, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_TILE, nouveau_gem_ioctl_tile, DRM_AUTH), ++}; ++ ++int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); +diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c +new file mode 100644 +index 0000000..66e35dc +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c +@@ -0,0 +1,729 @@ ++/* ++ * Copyright (C) 2008 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++#include "drmP.h" ++#include "drm.h" ++ ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nouveau_dma.h" ++ ++#define nouveau_gem_pushbuf_sync(chan) 0 ++ ++int ++nouveau_gem_object_new(struct drm_gem_object *gem) ++{ ++ struct nouveau_gem_object *ngem; ++ ++ ngem = drm_calloc(1, sizeof(*ngem), DRM_MEM_DRIVER); ++ if (!ngem) ++ return -ENOMEM; ++ ngem->gem = gem; ++ ++ INIT_LIST_HEAD(&ngem->entry); ++ ++ gem->driver_private = ngem; ++ return 0; ++} ++ ++void ++nouveau_gem_object_del(struct drm_gem_object *gem) ++{ ++ struct nouveau_gem_object *ngem = gem->driver_private; ++ ++ if (ngem->bo) { ++ drm_bo_takedown_vm_locked(ngem->bo); ++ drm_bo_usage_deref_locked(&ngem->bo); ++ } ++ ++ drm_free(ngem, sizeof(*ngem), DRM_MEM_DRIVER); ++} ++ ++int ++nouveau_gem_new(struct drm_device *dev, struct nouveau_channel *chan, ++ int size, int align, uint32_t domain, ++ struct drm_gem_object **pgem) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gem_object *ngem; ++ struct drm_gem_object *gem; ++ uint64_t flags; ++ int ret; ++ ++ flags = DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; ++ flags |= DRM_BO_FLAG_MAPPABLE; ++ flags |= DRM_BO_FLAG_MEM_LOCAL; ++ if (dev_priv->gart_info.type != NOUVEAU_GART_AGP) ++ flags |= DRM_BO_FLAG_CACHED; ++ ++ size = (size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); ++ if (dev_priv->card_type == NV_50) { ++ size = (size + 65535) & ~65535; ++ if (align < (65536 / PAGE_SIZE)) ++ align = (65536 / PAGE_SIZE); ++ ++ if (domain & NOUVEAU_GEM_DOMAIN_TILE) { ++ flags |= DRM_NOUVEAU_BO_FLAG_TILE; ++ if (domain & NOUVEAU_GEM_DOMAIN_TILE_ZETA) ++ flags |= DRM_NOUVEAU_BO_FLAG_ZTILE; ++ } ++ } ++ ++ gem = drm_gem_object_alloc(dev, size); ++ if (!gem) ++ return -ENOMEM; ++ ngem = gem->driver_private; ++ ngem->mappable = true; ++ ++ ret = drm_buffer_object_create(dev, size, drm_bo_type_device, flags, ++ 0, align, 0, &ngem->bo); ++ if (ret) ++ goto out; ++ ++ if (domain & (NOUVEAU_GEM_DOMAIN_VRAM | NOUVEAU_GEM_DOMAIN_GART)) { ++ int class = chan ? chan->id : 0; ++ ++ flags = 0; ++ if (domain & NOUVEAU_GEM_DOMAIN_VRAM) { ++ flags |= DRM_BO_FLAG_MEM_VRAM; ++ if (flags & NOUVEAU_GEM_DOMAIN_NOMAP) { ++ flags |= DRM_BO_FLAG_MEM_PRIV0; ++ ngem->mappable = false; ++ } ++ } ++ if (domain & NOUVEAU_GEM_DOMAIN_GART) ++ flags |= DRM_BO_FLAG_MEM_TT; ++ ++ ret = drm_bo_do_validate(ngem->bo, flags, DRM_BO_MASK_MEMTYPE, ++ DRM_BO_HINT_DONT_FENCE, class); ++ } ++ ++out: ++ if (ret) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++ } ++ ++ *pgem = gem; ++ return 0; ++} ++ ++int ++nouveau_gem_pin(struct drm_gem_object *gem, uint32_t domain) ++{ ++ struct nouveau_gem_object *ngem = gem->driver_private; ++ uint64_t flags, mask; ++ int ret; ++ ++ flags = mask = DRM_BO_FLAG_NO_EVICT; ++ if (domain) { ++ mask |= DRM_BO_MASK_MEM; ++ if (domain & NOUVEAU_GEM_DOMAIN_VRAM) ++ flags |= DRM_BO_FLAG_MEM_VRAM; ++ if (domain & NOUVEAU_GEM_DOMAIN_GART) ++ flags |= DRM_BO_FLAG_MEM_TT; ++ } ++ ++ ret = drm_bo_do_validate(ngem->bo, flags, mask, ++ DRM_BO_HINT_DONT_FENCE, 0); ++ return ret; ++} ++ ++int ++nouveau_gem_unpin(struct drm_gem_object *gem) ++{ ++ struct nouveau_gem_object *ngem = gem->driver_private; ++ int ret; ++ ++ ret = drm_bo_do_validate(ngem->bo, 0, DRM_BO_FLAG_NO_EVICT, ++ DRM_BO_HINT_DONT_FENCE, 0); ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_new(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_new *req = data; ++ struct nouveau_gem_object *ngem = NULL; ++ struct drm_gem_object *gem; ++ struct nouveau_channel *chan = NULL; ++ int ret = 0; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_ENABLED_WITH_RETURN; ++ ++ if (req->channel_hint) { ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel_hint, ++ file_priv, chan); ++ } ++ ++ req->size = roundup(req->size, PAGE_SIZE); ++ ++ ret = nouveau_gem_new(dev, chan, req->size, req->align, req->domain, ++ &gem); ++ if (ret) ++ return ret; ++ ngem = gem->driver_private; ++ ++ req->offset = ngem->bo->offset; ++ if (ngem->bo->mem.mem_type == DRM_BO_MEM_VRAM || ++ ngem->bo->mem.mem_type == DRM_BO_MEM_PRIV0) ++ req->domain = NOUVEAU_GEM_DOMAIN_VRAM; ++ else ++ if (ngem->bo->mem.mem_type == DRM_BO_MEM_TT) ++ req->domain = NOUVEAU_GEM_DOMAIN_GART; ++ else ++ req->domain = 0; ++ ++ ret = drm_gem_handle_create(file_priv, ngem->gem, &req->handle); ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_handle_unreference(ngem->gem); ++ mutex_unlock(&dev->struct_mutex); ++ ++ if (ret) ++ drm_gem_object_unreference(ngem->gem); ++ return ret; ++} ++ ++static int ++nouveau_gem_set_domain(struct nouveau_channel *chan, struct drm_gem_object *gem, ++ uint32_t read_domains, uint32_t write_domains, ++ uint32_t valid_domains) ++{ ++ struct nouveau_gem_object *ngem = gem->driver_private; ++ struct drm_buffer_object *bo = ngem->bo; ++ uint64_t mask = DRM_BO_MASK_MEM | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; ++ uint64_t flags; ++ int ret; ++ ++ if (!valid_domains || (!read_domains && !write_domains)) ++ return -EINVAL; ++ ++ if (write_domains) { ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && ++ (write_domains & NOUVEAU_GEM_DOMAIN_VRAM)) ++ flags = DRM_BO_FLAG_MEM_VRAM; ++ else ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && ++ (write_domains & NOUVEAU_GEM_DOMAIN_GART)) ++ flags = DRM_BO_FLAG_MEM_TT; ++ else ++ return -EINVAL; ++ } else { ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && ++ (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) && ++ (bo->mem.mem_type == DRM_BO_MEM_VRAM || ++ bo->mem.mem_type == DRM_BO_MEM_PRIV0)) ++ flags = DRM_BO_FLAG_MEM_VRAM; ++ else ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && ++ (read_domains & NOUVEAU_GEM_DOMAIN_GART) && ++ bo->mem.mem_type == DRM_BO_MEM_TT) ++ flags = DRM_BO_FLAG_MEM_TT; ++ else ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && ++ (read_domains & NOUVEAU_GEM_DOMAIN_VRAM)) ++ flags = DRM_BO_FLAG_MEM_VRAM; ++ else ++ flags = DRM_BO_FLAG_MEM_TT; ++ } ++ ++ if ((flags & (DRM_BO_FLAG_MEM_VRAM)) && !ngem->mappable) ++ flags |= DRM_BO_FLAG_MEM_PRIV0; ++ ++ if (read_domains) ++ flags |= DRM_BO_FLAG_READ; ++ ++ if (write_domains) ++ flags |= DRM_BO_FLAG_WRITE; ++ ++ ret = drm_bo_do_validate(ngem->bo, flags, mask, 0, chan->id); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int ++nouveau_gem_pushbuf_bo_validate(struct nouveau_channel *chan, ++ struct drm_file *file_priv, ++ struct drm_nouveau_gem_pushbuf_bo *b, ++ uint64_t user_bo, int nr_buffers, ++ struct drm_fence_object **fence, ++ int *apply_relocs) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gem_object *ngem; ++ struct list_head validated, *entry, *tmp; ++ int ret, i; ++ ++ INIT_LIST_HEAD(&validated); ++ ++ ret = drm_fence_object_create(dev, chan->id, DRM_FENCE_TYPE_EXE, ++ 0, fence); ++ if (ret) ++ return ret; ++ ++ if (nr_buffers == 0) ++ return 0; ++ ++ if (apply_relocs) ++ *apply_relocs = 0; ++ ++ mutex_lock(&dev_priv->submit_mutex); ++ ++ for (i = 0; i < nr_buffers; i++, b++) { ++ struct nouveau_gem_object *ngem; ++ struct drm_gem_object *gem; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, b->handle); ++ if (!gem) { ++ NV_ERROR(dev, "Unknown handle 0x%08x\n", b->handle); ++ ret = -EINVAL; ++ break; ++ } ++ ngem = gem->driver_private; ++ ++ ret = nouveau_gem_set_domain(chan, gem, b->read_domains, ++ b->write_domains, ++ b->valid_domains); ++ if (ret) ++ break; ++ ++ list_add_tail(&ngem->entry, &validated); ++ ++ if (ngem->bo->offset == b->presumed_offset && ++ (((ngem->bo->mem.mem_type == DRM_BO_MEM_VRAM || ++ ngem->bo->mem.mem_type == DRM_BO_MEM_PRIV0) && ++ b->presumed_domain & NOUVEAU_GEM_DOMAIN_VRAM) || ++ (ngem->bo->mem.mem_type == DRM_BO_MEM_TT && ++ b->presumed_domain & NOUVEAU_GEM_DOMAIN_GART))) ++ continue; ++ ++ if (ngem->bo->mem.mem_type == DRM_BO_MEM_TT) ++ b->presumed_domain = NOUVEAU_GEM_DOMAIN_GART; ++ else ++ b->presumed_domain = NOUVEAU_GEM_DOMAIN_VRAM; ++ b->presumed_offset = ngem->bo->offset; ++ b->presumed_ok = 0; ++ if (apply_relocs) ++ (*apply_relocs)++; ++ ++ if (DRM_COPY_TO_USER((void __user *)user_bo + (i * sizeof(*b)), ++ b, sizeof(*b))) { ++ ret = -EFAULT; ++ break; ++ } ++ } ++ ++ mutex_lock(&dev->struct_mutex); ++ list_for_each_safe(entry, tmp, &validated) { ++ ngem = list_entry(entry, struct nouveau_gem_object, entry); ++ drm_gem_object_unreference(ngem->gem); ++ list_del(&ngem->entry); ++ } ++ mutex_unlock(&dev->struct_mutex); ++ ++ if (!ret) ++ ret = drm_fence_buffer_objects(dev, NULL, 0, *fence, fence); ++ ++ if (ret) { ++ drm_putback_buffer_objects(dev); ++ drm_fence_usage_deref_unlocked(fence); ++ } ++ ++ mutex_unlock(&dev_priv->submit_mutex); ++ return ret; ++} ++ ++static int ++nouveau_gem_pushbuf_reloc_apply(struct nouveau_channel *chan, ++ struct drm_nouveau_gem_pushbuf_reloc *reloc, ++ struct drm_nouveau_gem_pushbuf_bo *bo, ++ uint32_t *pushbuf, int nr_relocs, ++ int nr_buffers, int nr_dwords) ++{ ++ struct drm_device *dev = chan->dev; ++ int i; ++ ++ for (i = 0; i < nr_relocs; i++) { ++ struct drm_nouveau_gem_pushbuf_reloc *r = &reloc[i]; ++ struct drm_nouveau_gem_pushbuf_bo *b; ++ uint32_t data; ++ ++ if (r->bo_index >= nr_buffers || r->reloc_index >= nr_dwords) { ++ NV_ERROR(dev, "Bad relocation %d\n", i); ++ NV_ERROR(dev, " bo: %d max %d\n", r->bo_index, nr_buffers); ++ NV_ERROR(dev, " id: %d max %d\n", r->reloc_index, nr_dwords); ++ return -EINVAL; ++ } ++ ++ b = &bo[r->bo_index]; ++ if (b->presumed_ok) ++ continue; ++ ++ if (r->flags & NOUVEAU_GEM_RELOC_LOW) ++ data = b->presumed_offset + r->data; ++ else ++ if (r->flags & NOUVEAU_GEM_RELOC_HIGH) ++ data = (b->presumed_offset + r->data) >> 32; ++ else ++ data = r->data; ++ ++ if (r->flags & NOUVEAU_GEM_RELOC_OR) { ++ if (b->presumed_domain == NOUVEAU_GEM_DOMAIN_GART) ++ data |= r->tor; ++ else ++ data |= r->vor; ++ } ++ ++ pushbuf[r->reloc_index] = data; ++ } ++ ++ return 0; ++} ++ ++static inline void * ++u_memcpya(uint64_t user, unsigned nmemb, unsigned size) ++{ ++ void *mem; ++ ++ mem = drm_alloc(nmemb * size, DRM_MEM_DRIVER); ++ if (!mem) ++ return (void *)-ENOMEM; ++ ++ if (DRM_COPY_FROM_USER(mem, (void __user *)user, nmemb * size)) { ++ drm_free(mem, nmemb * size, DRM_MEM_DRIVER); ++ return (void *)-EFAULT; ++ } ++ ++ return mem; ++} ++ ++int ++nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_pushbuf *req = data; ++ struct drm_nouveau_gem_pushbuf_bo *bo = NULL; ++ struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL; ++ struct drm_fence_object *fence = NULL; ++ struct nouveau_channel *chan; ++ uint32_t *pushbuf = NULL; ++ int ret = 0, i; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_ENABLED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); ++ ++ if (req->nr_dwords >= chan->dma.max || ++ req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS || ++ req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) { ++ NV_ERROR(dev, "Pushbuf config exceeds limits:\n"); ++ NV_ERROR(dev, " dwords : %d max %d\n", req->nr_dwords, ++ chan->dma.max - 1); ++ NV_ERROR(dev, " buffers: %d max %d\n", req->nr_buffers, ++ NOUVEAU_GEM_MAX_BUFFERS); ++ NV_ERROR(dev, " relocs : %d max %d\n", req->nr_relocs, ++ NOUVEAU_GEM_MAX_RELOCS); ++ return -EINVAL; ++ } ++ ++ pushbuf = u_memcpya(req->dwords, req->nr_dwords, sizeof(uint32_t)); ++ if (IS_ERR(pushbuf)) ++ return (unsigned long)pushbuf; ++ ++ bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo)); ++ if (IS_ERR(bo)) { ++ drm_free(pushbuf, req->nr_dwords * sizeof(uint32_t), ++ DRM_MEM_DRIVER); ++ return (unsigned long)bo; ++ } ++ ++ reloc = u_memcpya(req->relocs, req->nr_relocs, sizeof(*reloc)); ++ if (IS_ERR(reloc)) { ++ drm_free(bo, req->nr_buffers * sizeof(*bo), DRM_MEM_DRIVER); ++ drm_free(pushbuf, req->nr_dwords * sizeof(uint32_t), ++ DRM_MEM_DRIVER); ++ return (unsigned long)reloc; ++ } ++ ++ /* Validate buffer list */ ++ ret = nouveau_gem_pushbuf_bo_validate(chan, file_priv, bo, ++ req->buffers, req->nr_buffers, ++ &fence, NULL); ++ if (ret) ++ goto out; ++ ++ /* Apply any relocations that are required */ ++ ret = nouveau_gem_pushbuf_reloc_apply(chan, reloc, bo, pushbuf, ++ req->nr_relocs, req->nr_buffers, ++ req->nr_dwords); ++ if (ret) ++ goto out; ++ ++ /* Emit push buffer to the hw ++ *XXX: OMG ALSO YUCK!!! ++ */ ++ ret = RING_SPACE(chan, req->nr_dwords); ++ if (ret) ++ goto out; ++ ++ for (i = 0; i < req->nr_dwords; i++) ++ OUT_RING (chan, pushbuf[i]); ++ ++ ret = drm_fence_object_emit(fence, 0, chan->id, ++ DRM_FENCE_TYPE_EXE); ++ if (ret) { ++ /*XXX*/ ++ } ++ ++ if (nouveau_gem_pushbuf_sync(chan)) { ++ ret = drm_fence_object_wait(fence, 0, 1, 1); ++ if (ret) { ++ for (i = 0; i < req->nr_dwords; i++) ++ NV_ERROR(dev, "0x%08x\n", pushbuf[i]); ++ NV_ERROR(dev, "^^ above push buffer is fail :(\n"); ++ } ++ } ++ ++ FIRE_RING(chan); ++ ++out: ++ if (fence) ++ drm_fence_usage_deref_unlocked(&fence); ++ ++ drm_free(pushbuf, req->nr_dwords * sizeof(uint32_t), DRM_MEM_DRIVER); ++ drm_free(bo, req->nr_buffers * sizeof(uint32_t), DRM_MEM_DRIVER); ++ drm_free(reloc, req->nr_relocs * sizeof(uint32_t), DRM_MEM_DRIVER); ++ ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENODEV; ++} ++ ++int ++nouveau_gem_ioctl_pin(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_pin *req = data; ++ struct nouveau_gem_object *ngem; ++ struct drm_gem_object *gem; ++ int ret = 0; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_ENABLED_WITH_RETURN; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return -EINVAL; ++ ngem = gem->driver_private; ++ ++ ret = nouveau_gem_pin(gem, req->domain); ++ if (ret) ++ goto out; ++ ++ req->offset = ngem->bo->offset; ++ req->domain = 0; ++ if (ngem->bo->mem.mem_type == DRM_BO_MEM_VRAM || ++ ngem->bo->mem.mem_type == DRM_BO_MEM_PRIV0) ++ req->domain |= NOUVEAU_GEM_DOMAIN_VRAM; ++ else ++ if (ngem->bo->mem.mem_type == DRM_BO_MEM_TT) ++ req->domain |= NOUVEAU_GEM_DOMAIN_GART; ++ ++out: ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_unpin(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_pin *req = data; ++ struct nouveau_gem_object *ngem; ++ struct drm_gem_object *gem; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_ENABLED_WITH_RETURN; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return -EINVAL; ++ ngem = gem->driver_private; ++ ++ ret = drm_bo_do_validate(ngem->bo, 0, DRM_BO_FLAG_NO_EVICT, ++ DRM_BO_HINT_DONT_FENCE, 0); ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_mmap(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_mmap *req = data; ++ struct nouveau_gem_object *ngem; ++ struct drm_gem_object *gem; ++ unsigned long addr; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_ENABLED_WITH_RETURN; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return -EINVAL; ++ ngem = gem->driver_private; ++ ++ if (!ngem->mappable) ++ return -EINVAL; ++ ++ if (ngem->bo->mem.mem_type == DRM_BO_MEM_LOCAL) { ++ ret = drm_bo_do_validate(ngem->bo, DRM_BO_FLAG_MEM_TT, ++ DRM_BO_MASK_MEMTYPE, ++ DRM_BO_HINT_DONT_FENCE, 0); ++ if (ret) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++ } ++ } ++ ++ down_write(¤t->mm->mmap_sem); ++ addr = do_mmap_pgoff(file_priv->filp, 0, ngem->bo->mem.size, ++ PROT_READ | PROT_WRITE, MAP_SHARED, ++ ngem->bo->map_list.hash.key); ++ up_write(¤t->mm->mmap_sem); ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ ++ if (IS_ERR((void *)addr)) ++ return addr; ++ req->vaddr = (uint64_t)addr; ++ ++ return 0; ++} ++ ++int ++nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_mmap *req = data; ++ struct nouveau_gem_object *ngem; ++ struct drm_gem_object *gem; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_ENABLED_WITH_RETURN; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return -EINVAL; ++ ngem = gem->driver_private; ++ ++ mutex_lock(&ngem->bo->mutex); ++ ret = drm_bo_wait(ngem->bo, 0, 0, 0, 0); ++ mutex_unlock(&ngem->bo->mutex); ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_ENABLED_WITH_RETURN; ++ ++ return 0; ++} ++ ++int ++nouveau_gem_ioctl_tile(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_gem_tile *req = data; ++ struct nouveau_gem_object *ngem; ++ struct drm_gem_object *gem; ++ unsigned offset, tile = 0; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_ENABLED_WITH_RETURN; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return -EINVAL; ++ ngem = gem->driver_private; ++ ++ offset = ngem->bo->offset + req->delta; ++ offset -= dev_priv->vm_vram_base; ++ ++ if (req->flags & NOUVEAU_MEM_TILE) { ++ if (req->flags & NOUVEAU_MEM_TILE_ZETA) ++ tile = 0x00002800; ++ else ++ tile = 0x00007000; ++ } ++ ++ ret = nv50_mem_vm_bind_linear(dev, ngem->bo->offset + req->delta, ++ req->size, tile, offset); ++ if (ret) ++ return ret; ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c +new file mode 100644 +index 0000000..bd11b69 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_hw.c +@@ -0,0 +1,1041 @@ ++/* ++ * Copyright 2006 Dave Airlie ++ * Copyright 2007 Maarten Maathuis ++ * Copyright 2007-2009 Stuart Bennett ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF ++ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_hw.h" ++ ++#define CHIPSET_NFORCE 0x01a0 ++#define CHIPSET_NFORCE2 0x01f0 ++ ++/* ++ * misc hw access wrappers/control functions ++ */ ++ ++void ++NVWriteVgaSeq(struct drm_device *dev, int head, uint8_t index, uint8_t value) ++{ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index); ++ NVWritePRMVIO(dev, head, NV_PRMVIO_SR, value); ++} ++ ++uint8_t ++NVReadVgaSeq(struct drm_device *dev, int head, uint8_t index) ++{ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index); ++ return NVReadPRMVIO(dev, head, NV_PRMVIO_SR); ++} ++ ++void ++NVWriteVgaGr(struct drm_device *dev, int head, uint8_t index, uint8_t value) ++{ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index); ++ NVWritePRMVIO(dev, head, NV_PRMVIO_GX, value); ++} ++ ++uint8_t ++NVReadVgaGr(struct drm_device *dev, int head, uint8_t index) ++{ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index); ++ return NVReadPRMVIO(dev, head, NV_PRMVIO_GX); ++} ++ ++/* CR44 takes values 0 (head A), 3 (head B) and 4 (heads tied) ++ * it affects only the 8 bit vga io regs, which we access using mmio at ++ * 0xc{0,2}3c*, 0x60{1,3}3*, and 0x68{1,3}3d* ++ * in general, the set value of cr44 does not matter: reg access works as ++ * expected and values can be set for the appropriate head by using a 0x2000 ++ * offset as required ++ * however: ++ * a) pre nv40, the head B range of PRMVIO regs at 0xc23c* was not exposed and ++ * cr44 must be set to 0 or 3 for accessing values on the correct head ++ * through the common 0xc03c* addresses ++ * b) in tied mode (4) head B is programmed to the values set on head A, and ++ * access using the head B addresses can have strange results, ergo we leave ++ * tied mode in init once we know to what cr44 should be restored on exit ++ * ++ * the owner parameter is slightly abused: ++ * 0 and 1 are treated as head values and so the set value is (owner * 3) ++ * other values are treated as literal values to set ++ */ ++void ++NVSetOwner(struct drm_device *dev, int owner) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (owner == 1) ++ owner *= 3; ++ ++ /* CR44 is always changed on CRTC0 */ ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_44, owner); ++ if (dev_priv->chipset == 0x11) { /* set me harder */ ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner); ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner); ++ } ++} ++ ++void ++NVBlankScreen(struct drm_device *dev, int head, bool blank) ++{ ++ unsigned char seq1; ++ ++ NV_ERROR(dev, "FIXME\n"); ++ if (1) //dev_priv->twoHeads) ++ NVSetOwner(dev, head); ++ ++ seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX); ++ ++ NVVgaSeqReset(dev, head, true); ++ if (blank) ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); ++ else ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); ++ NVVgaSeqReset(dev, head, false); ++} ++ ++/* ++ * PLL setting ++ */ ++ ++static int ++powerctrl_1_shift(int chip_version, int reg) ++{ ++ int shift = -4; ++ ++ if (chip_version < 0x17 || chip_version == 0x20) ++ return shift; ++ ++ switch (reg) { ++ case NV_RAMDAC_VPLL2: ++ shift += 4; ++ case NV_PRAMDAC_VPLL_COEFF: ++ shift += 4; ++ case NV_PRAMDAC_MPLL_COEFF: ++ shift += 4; ++ case NV_PRAMDAC_NVPLL_COEFF: ++ shift += 4; ++ } ++ ++ /* ++ * the shift for vpll regs is only used for nv3x chips with a single ++ * stage pll ++ */ ++ if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 || ++ chip_version == 0x36 || chip_version >= 0x40)) ++ shift = -4; ++ ++ return shift; ++} ++ ++static void ++setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int chip_version = dev_priv->vbios->chip_version; ++ uint32_t oldpll = NVReadRAMDAC(dev, 0, reg); ++ int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff; ++ uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1; ++ uint32_t saved_powerctrl_1 = 0; ++ int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg); ++ ++ if (oldpll == pll) ++ return; /* already set */ ++ ++ if (shift_powerctrl_1 >= 0) { ++ saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1); ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_1, ++ (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) | ++ 1 << shift_powerctrl_1); ++ } ++ ++ if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1)) ++ /* upclock -- write new post divider first */ ++ NVWriteRAMDAC(dev, 0, reg, pv->log2P << 16 | (oldpll & 0xffff)); ++ else ++ /* downclock -- write new NM first */ ++ NVWriteRAMDAC(dev, 0, reg, (oldpll & 0xffff0000) | pv->NM1); ++ ++ if (chip_version < 0x17 && chip_version != 0x11) ++ /* wait a bit on older chips */ ++ msleep(64); ++ NVReadRAMDAC(dev, 0, reg); ++ ++ /* then write the other half as well */ ++ NVWriteRAMDAC(dev, 0, reg, pll); ++ ++ if (shift_powerctrl_1 >= 0) ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1); ++} ++ ++static uint32_t ++new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580) ++{ ++ bool head_a = (reg1 == NV_PRAMDAC_VPLL_COEFF); ++ ++ if (ss) /* single stage pll mode */ ++ ramdac580 |= head_a ? NV_RAMDAC_580_VPLL1_ACTIVE : ++ NV_RAMDAC_580_VPLL2_ACTIVE; ++ else ++ ramdac580 &= head_a ? ~NV_RAMDAC_580_VPLL1_ACTIVE : ++ ~NV_RAMDAC_580_VPLL2_ACTIVE; ++ ++ return ramdac580; ++} ++ ++static void ++setPLL_double_highregs(struct drm_device *dev, uint32_t reg1, ++ struct nouveau_pll_vals *pv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int chip_version = dev_priv->vbios->chip_version; ++ bool nv3035 = chip_version == 0x30 || chip_version == 0x35; ++ uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70); ++ uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1); ++ uint32_t oldpll2 = !nv3035 ? NVReadRAMDAC(dev, 0, reg2) : 0; ++ uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1; ++ uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2; ++ uint32_t oldramdac580 = 0, ramdac580 = 0; ++ bool single_stage = !pv->NM2 || pv->N2 == pv->M2; /* nv41+ only */ ++ uint32_t saved_powerctrl_1 = 0, savedc040 = 0; ++ int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1); ++ ++ /* model specific additions to generic pll1 and pll2 set up above */ ++ if (nv3035) { ++ pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 | ++ (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4; ++ pll2 = 0; ++ } ++ if (chip_version > 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) { /* !nv40 */ ++ oldramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580); ++ ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580); ++ if (oldramdac580 != ramdac580) ++ oldpll1 = ~0; /* force mismatch */ ++ if (single_stage) ++ /* magic value used by nvidia in single stage mode */ ++ pll2 |= 0x011f; ++ } ++ if (chip_version > 0x70) ++ /* magic bits set by the blob (but not the bios) on g71-73 */ ++ pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28; ++ ++ if (oldpll1 == pll1 && oldpll2 == pll2) ++ return; /* already set */ ++ ++ if (shift_powerctrl_1 >= 0) { ++ saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1); ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_1, ++ (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) | ++ 1 << shift_powerctrl_1); ++ } ++ ++ if (chip_version >= 0x40) { ++ int shift_c040 = 14; ++ ++ switch (reg1) { ++ case NV_PRAMDAC_MPLL_COEFF: ++ shift_c040 += 2; ++ case NV_PRAMDAC_NVPLL_COEFF: ++ shift_c040 += 2; ++ case NV_RAMDAC_VPLL2: ++ shift_c040 += 2; ++ case NV_PRAMDAC_VPLL_COEFF: ++ shift_c040 += 2; ++ } ++ ++ savedc040 = nvReadMC(dev, 0xc040); ++ if (shift_c040 != 14) ++ nvWriteMC(dev, 0xc040, savedc040 & ~(3 << shift_c040)); ++ } ++ ++ if (oldramdac580 != ramdac580) ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_580, ramdac580); ++ ++ if (!nv3035) ++ NVWriteRAMDAC(dev, 0, reg2, pll2); ++ NVWriteRAMDAC(dev, 0, reg1, pll1); ++ ++ if (shift_powerctrl_1 >= 0) ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1); ++ if (chip_version >= 0x40) ++ nvWriteMC(dev, 0xc040, savedc040); ++} ++ ++static void ++setPLL_double_lowregs(struct drm_device *dev, uint32_t NMNMreg, ++ struct nouveau_pll_vals *pv) ++{ ++ /* When setting PLLs, there is a merry game of disabling and enabling ++ * various bits of hardware during the process. This function is a ++ * synthesis of six nv4x traces, nearly each card doing a subtly ++ * different thing. With luck all the necessary bits for each card are ++ * combined herein. Without luck it deviates from each card's formula ++ * so as to not work on any :) ++ */ ++ ++ uint32_t Preg = NMNMreg - 4; ++ bool mpll = Preg == 0x4020; ++ uint32_t oldPval = nvReadMC(dev, Preg); ++ uint32_t NMNM = pv->NM2 << 16 | pv->NM1; ++ uint32_t Pval = (oldPval & (mpll ? ~(0x11 << 16) : ~(1 << 16))) | ++ 0xc << 28 | pv->log2P << 16; ++ uint32_t saved4600 = 0; ++ /* some cards have different maskc040s */ ++ uint32_t maskc040 = ~(3 << 14), savedc040; ++ bool single_stage = !pv->NM2 || pv->N2 == pv->M2; ++ ++ if (nvReadMC(dev, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval) ++ return; ++ ++ if (Preg == 0x4000) ++ maskc040 = ~0x333; ++ if (Preg == 0x4058) ++ maskc040 = ~(0xc << 24); ++ ++ if (mpll) { ++ struct pll_lims pll_lim; ++ uint8_t Pval2; ++ ++ if (get_pll_limits(dev, Preg, &pll_lim)) ++ return; ++ ++ Pval2 = pv->log2P + pll_lim.log2p_bias; ++ if (Pval2 > pll_lim.max_log2p_bias) ++ Pval2 = pll_lim.max_log2p_bias; ++ Pval |= 1 << 28 | Pval2 << 20; ++ ++ saved4600 = nvReadMC(dev, 0x4600); ++ nvWriteMC(dev, 0x4600, saved4600 | 8 << 28); ++ } ++ if (single_stage) ++ Pval |= mpll ? 1 << 12 : 1 << 8; ++ ++ nvWriteMC(dev, Preg, oldPval | 1 << 28); ++ nvWriteMC(dev, Preg, Pval & ~(4 << 28)); ++ if (mpll) { ++ Pval |= 8 << 20; ++ nvWriteMC(dev, 0x4020, Pval & ~(0xc << 28)); ++ nvWriteMC(dev, 0x4038, Pval & ~(0xc << 28)); ++ } ++ ++ savedc040 = nvReadMC(dev, 0xc040); ++ nvWriteMC(dev, 0xc040, savedc040 & maskc040); ++ ++ nvWriteMC(dev, NMNMreg, NMNM); ++ if (NMNMreg == 0x4024) ++ nvWriteMC(dev, 0x403c, NMNM); ++ ++ nvWriteMC(dev, Preg, Pval); ++ if (mpll) { ++ Pval &= ~(8 << 20); ++ nvWriteMC(dev, 0x4020, Pval); ++ nvWriteMC(dev, 0x4038, Pval); ++ nvWriteMC(dev, 0x4600, saved4600); ++ } ++ ++ nvWriteMC(dev, 0xc040, savedc040); ++ ++ if (mpll) { ++ nvWriteMC(dev, 0x4020, Pval & ~(1 << 28)); ++ nvWriteMC(dev, 0x4038, Pval & ~(1 << 28)); ++ } ++} ++ ++void ++nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1, ++ struct nouveau_pll_vals *pv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int cv = dev_priv->vbios->chip_version; ++ ++ if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 || ++ cv >= 0x40) { ++ if (reg1 > 0x405c) ++ setPLL_double_highregs(dev, reg1, pv); ++ else ++ setPLL_double_lowregs(dev, reg1, pv); ++ } else ++ setPLL_single(dev, reg1, pv); ++} ++ ++/* ++ * PLL getting ++ */ ++ ++static void ++nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1, ++ uint32_t pll2, struct nouveau_pll_vals *pllvals) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_ERROR(dev, "FIXME two_reg_pll\n"); ++ ++ /* to force parsing as single stage (i.e. nv40 vplls) pass pll2 as 0 */ ++ ++ /* log2P is & 0x7 as never more than 6, and nv30/35 only uses 3 bits */ ++ pllvals->log2P = (pll1 >> 16) & 0x7; ++ pllvals->N2 = pllvals->M2 = 1; ++ ++ if (reg1 <= 0x405c) { ++ pllvals->NM1 = pll2 & 0xffff; ++ /* single stage NVPLL and VPLLs use 1 << 8, MPLL uses 1 << 12 */ ++ if (!(pll1 & 0x1100)) ++ pllvals->NM2 = pll2 >> 16; ++ } else { ++ pllvals->NM1 = pll1 & 0xffff; ++ if (1/*dev_priv->two_reg_pll*/ && pll2 & NV31_RAMDAC_ENABLE_VCO2) ++ pllvals->NM2 = pll2 & 0xffff; ++ else if (dev_priv->chipset == 0x30 || dev_priv->chipset == 0x35) { ++ pllvals->M1 &= 0xf; /* only 4 bits */ ++ if (pll1 & NV30_RAMDAC_ENABLE_VCO2) { ++ pllvals->M2 = (pll1 >> 4) & 0x7; ++ pllvals->N2 = ((pll1 >> 21) & 0x18) | ++ ((pll1 >> 19) & 0x7); ++ } ++ } ++ } ++} ++ ++int ++nouveau_hw_get_pllvals(struct drm_device *dev, enum pll_types plltype, ++ struct nouveau_pll_vals *pllvals) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ const uint32_t nv04_regs[MAX_PLL_TYPES] = { NV_PRAMDAC_NVPLL_COEFF, ++ NV_PRAMDAC_MPLL_COEFF, ++ NV_PRAMDAC_VPLL_COEFF, ++ NV_RAMDAC_VPLL2 }; ++ const uint32_t nv40_regs[MAX_PLL_TYPES] = { 0x4000, ++ 0x4020, ++ NV_PRAMDAC_VPLL_COEFF, ++ NV_RAMDAC_VPLL2 }; ++ uint32_t reg1, pll1, pll2 = 0; ++ struct pll_lims pll_lim; ++ int ret; ++ ++ NV_ERROR(dev, "two_reg_pll\n"); ++ ++ if (dev_priv->card_type < NV_40) ++ reg1 = nv04_regs[plltype]; ++ else ++ reg1 = nv40_regs[plltype]; ++ ++ pll1 = nvReadMC(dev, reg1); ++ ++ if (reg1 <= 0x405c) ++ pll2 = nvReadMC(dev, reg1 + 4); ++ else if (1) { //dev_priv->two_reg_pll) { ++ uint32_t reg2 = reg1 + (reg1 == NV_RAMDAC_VPLL2 ? 0x5c : 0x70); ++ ++ pll2 = nvReadMC(dev, reg2); ++ } ++ ++ if (dev_priv->card_type == 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) { ++ uint32_t ramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580); ++ ++ /* check whether vpll has been forced into single stage mode */ ++ if (reg1 == NV_PRAMDAC_VPLL_COEFF) { ++ if (ramdac580 & NV_RAMDAC_580_VPLL1_ACTIVE) ++ pll2 = 0; ++ } else ++ if (ramdac580 & NV_RAMDAC_580_VPLL2_ACTIVE) ++ pll2 = 0; ++ } ++ ++ nouveau_hw_decode_pll(dev, reg1, pll1, pll2, pllvals); ++ ++ if ((ret = get_pll_limits(dev, plltype, &pll_lim))) ++ return ret; ++ ++ pllvals->refclk = pll_lim.refclk; ++ ++ return 0; ++} ++ ++int ++nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pv) ++{ ++ /* Avoid divide by zero if called at an inappropriate time */ ++ if (!pv->M1 || !pv->M2) ++ return 0; ++ ++ return (pv->N1 * pv->N2 * pv->refclk / (pv->M1 * pv->M2) >> pv->log2P); ++} ++ ++int ++nouveau_hw_get_clock(struct drm_device *dev, enum pll_types plltype) ++{ ++ struct nouveau_pll_vals pllvals; ++ ++ if (plltype == MPLL && (dev->pci_device & 0x0ff0) == CHIPSET_NFORCE) { ++ uint32_t mpllP; ++ ++ pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP); ++ if (!mpllP) ++ mpllP = 4; ++ ++ return 400000 / mpllP; ++ } else ++ if (plltype == MPLL && (dev->pci_device & 0xff0) == CHIPSET_NFORCE2) { ++ uint32_t clock; ++ ++ pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock); ++ return clock; ++ } ++ ++ nouveau_hw_get_pllvals(dev, plltype, &pllvals); ++ ++ return nouveau_hw_pllvals_to_clk(&pllvals); ++} ++ ++static void ++nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head) ++{ ++ /* the vpll on an unused head can come up with a random value, way ++ * beyond the pll limits. for some reason this causes the chip to ++ * lock up when reading the dac palette regs, so set a valid pll here ++ * when such a condition detected. only seen on nv11 to date ++ */ ++ ++ struct pll_lims pll_lim; ++ struct nouveau_pll_vals pv; ++ uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF; ++ ++ if (get_pll_limits(dev, head ? VPLL2 : VPLL1, &pll_lim)) ++ return; ++ nouveau_hw_get_pllvals(dev, head ? VPLL2 : VPLL1, &pv); ++ ++ if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m && ++ pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n && ++ pv.log2P <= 4) /* log2P limit for NV11 */ ++ return; ++ ++ NV_WARN(dev, "VPLL %d outwith limits, attempting to fix\n", head + 1); ++ ++ /* set lowest clock within static limits */ ++ pv.M1 = pll_lim.vco1.max_m; ++ pv.N1 = pll_lim.vco1.min_n; ++ pv.log2P = 4; ++ nouveau_hw_setpll(dev, pllreg, &pv); ++} ++ ++/* ++ * vga font save/restore ++ */ ++ ++void ++nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save) ++{ ++ bool graphicsmode; ++ uint8_t misc, gr4, gr5, gr6, seq2, seq4; ++ int i; ++ ++ NV_ERROR(dev, "FIXME twoHeads, saved_vga_font\n"); ++ if (1) //dev_priv->twoHeads) ++ NVSetOwner(dev, 0); ++ ++ NVSetEnablePalette(dev, 0, true); ++ graphicsmode = NVReadVgaAttr(dev, 0, NV_CIO_AR_MODE_INDEX) & 1; ++ NVSetEnablePalette(dev, 0, false); ++ ++ if (graphicsmode) /* graphics mode => framebuffer => no need to save */ ++ return; ++ ++ NV_INFO(dev, "%sing VGA fonts\n", save ? "Sav" : "Restor"); ++ if (1) //dev_priv->twoHeads) ++ NVBlankScreen(dev, 1, true); ++ NVBlankScreen(dev, 0, true); ++ ++ /* save control regs */ ++ misc = NVReadPRMVIO(dev, 0, NV_PRMVIO_MISC__READ); ++ seq2 = NVReadVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX); ++ seq4 = NVReadVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX); ++ gr4 = NVReadVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX); ++ gr5 = NVReadVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX); ++ gr6 = NVReadVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX); ++ ++ NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, 0x67); ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, 0x6); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, 0x0); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, 0x5); ++ ++ /* store font in plane 0 */ ++#if 0 ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x1); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, 0x0); ++ for (i = 0; i < 16384; i++) ++ if (save) ++ dev_priv->saved_vga_font[0][i] = nv_rf32(i * 4); ++ else ++ nv_wf32(i * 4, dev_priv->saved_vga_font[0][i]); ++ ++ /* store font in plane 1 */ ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x2); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, 0x1); ++ for (i = 0; i < 16384; i++) ++ if (save) ++ dev_priv->saved_vga_font[1][i] = nv_rf32(i * 4); ++ else ++ nv_wf32(i * 4, dev_priv->saved_vga_font[1][i]); ++ ++ /* store font in plane 2 */ ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x4); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, 0x2); ++ for (i = 0; i < 16384; i++) ++ if (save) ++ dev_priv->saved_vga_font[2][i] = nv_rf32(i * 4); ++ else ++ nv_wf32(i * 4, dev_priv->saved_vga_font[2][i]); ++ ++ /* store font in plane 3 */ ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x8); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, 0x3); ++ for (i = 0; i < 16384; i++) ++ if (save) ++ dev_priv->saved_vga_font[3][i] = nv_rf32(i * 4); ++ else ++ nv_wf32(i * 4, dev_priv->saved_vga_font[3][i]); ++#endif ++ ++ /* restore control regs */ ++ NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, misc); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, gr4); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, gr5); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, gr6); ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, seq2); ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, seq4); ++ ++ if (1) //dev_priv->twoHeads) ++ NVBlankScreen(dev, 1, false); ++ NVBlankScreen(dev, 0, false); ++} ++ ++/* ++ * mode state save/load ++ */ ++ ++static void ++rd_cio_state(struct drm_device *dev, int head, ++ struct nv04_crtc_reg *crtcstate, int index) ++{ ++ crtcstate->CRTC[index] = NVReadVgaCrtc(dev, head, index); ++} ++ ++static void ++wr_cio_state(struct drm_device *dev, int head, ++ struct nv04_crtc_reg *crtcstate, int index) ++{ ++ NVWriteVgaCrtc(dev, head, index, crtcstate->CRTC[index]); ++} ++ ++static void ++nv_save_state_ramdac(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg * regp = &state->crtc_reg[head]; ++ int i; ++ ++ NV_ERROR(dev, "FIXME twoHeads\n"); ++ ++ nouveau_hw_get_pllvals(dev, head ? VPLL2 : VPLL1, ®p->pllvals); ++ if (1) //dev_priv->twoHeads) ++ state->sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK); ++ state->pllsel = NVReadRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT); ++ ++ regp->ramdac_gen_ctrl = NVReadRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL); ++ ++ if (1) { //dev_priv->twoHeads) { ++ if (dev_priv->chipset >= 0x17) ++ regp->ramdac_630 = NVReadRAMDAC(dev, head, NV_PRAMDAC_630); ++ if (dev_priv->chipset >= 0x30) ++ regp->ramdac_634 = NVReadRAMDAC(dev, head, NV_PRAMDAC_634); ++ ++ regp->fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); ++ regp->fp_debug_0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0); ++ regp->fp_debug_1 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1); ++ regp->fp_debug_2 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2); ++ ++ regp->ramdac_a20 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A20); ++ regp->ramdac_a24 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A24); ++ regp->ramdac_a34 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A34); ++ } ++ ++ if (dev_priv->chipset == 0x11) { ++ regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11); ++ } else if (1) { //dev_priv->twoHeads) { ++ regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_FP_DITHER); ++ for (i = 0; i < 3; i++) { ++ regp->dither_regs[i] = NVReadRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4); ++ regp->dither_regs[i + 3] = NVReadRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4); ++ } ++ } ++ if (dev_priv->card_type >= NV_10) ++ regp->nv10_cursync = NVReadRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC); ++ ++ /* The regs below are 0 for non-flatpanels, so you can load and save them */ ++ ++ for (i = 0; i < 7; i++) { ++ uint32_t ramdac_reg = NV_PRAMDAC_FP_HDISPLAY_END + (i * 4); ++ regp->fp_horiz_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg); ++ } ++ ++ for (i = 0; i < 7; i++) { ++ uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4); ++ regp->fp_vert_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg); ++ } ++} ++ ++static void ++nv_load_state_ramdac(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg * regp = &state->crtc_reg[head]; ++ uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF; ++ int i; ++ ++ NV_ERROR(dev, "FIXME twoHeads\n"); ++ ++ /* This sequence is important, the NV28 is very sensitive in this area. */ ++ /* Keep pllsel last and sel_clk first. */ ++ if (1) //dev_priv->twoHeads) ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, state->sel_clk); ++ nouveau_hw_setpll(dev, pllreg, ®p->pllvals); ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); ++ ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL, regp->ramdac_gen_ctrl); ++ ++ if (1) { //dev_priv->twoHeads) { ++ if (dev_priv->chipset >= 0x17) ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_630, regp->ramdac_630); ++ if (dev_priv->chipset >= 0x30) ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_634, regp->ramdac_634); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, regp->fp_control); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regp->fp_debug_1); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2, regp->fp_debug_2); ++ if (dev_priv->chipset == 0x30) { /* For unknown purposes. */ ++ uint32_t reg890 = NVReadRAMDAC(dev, head, NV_PRAMDAC_890); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_89C, reg890); ++ } ++ ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_A20, regp->ramdac_a20); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_A24, regp->ramdac_a24); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_A34, regp->ramdac_a34); ++ } ++ ++ if (dev_priv->chipset == 0x11) ++ NVWriteRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11, regp->dither); ++ else if (1) { //dev_priv->twoHeads) { ++ NVWriteRAMDAC(dev, head, NV_RAMDAC_FP_DITHER, regp->dither); ++ for (i = 0; i < 3; i++) { ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4, regp->dither_regs[i]); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4, regp->dither_regs[i + 3]); ++ } ++ } ++ if (dev_priv->card_type >= NV_10) ++ NVWriteRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync); ++ ++ /* The regs below are 0 for non-flatpanels, so you can load and save them */ ++ ++ for (i = 0; i < 7; i++) { ++ uint32_t ramdac_reg = NV_PRAMDAC_FP_HDISPLAY_END + (i * 4); ++ NVWriteRAMDAC(dev, head, ramdac_reg, regp->fp_horiz_regs[i]); ++ } ++ ++ for (i = 0; i < 7; i++) { ++ uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4); ++ NVWriteRAMDAC(dev, head, ramdac_reg, regp->fp_vert_regs[i]); ++ } ++} ++ ++static void ++nv_save_state_vga(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct nv04_crtc_reg * regp = &state->crtc_reg[head]; ++ int i; ++ ++ regp->MiscOutReg = NVReadPRMVIO(dev, head, NV_PRMVIO_MISC__READ); ++ ++ for (i = 0; i < 25; i++) ++ rd_cio_state(dev, head, regp, i); ++ ++ NVSetEnablePalette(dev, head, true); ++ for (i = 0; i < 21; i++) ++ regp->Attribute[i] = NVReadVgaAttr(dev, head, i); ++ NVSetEnablePalette(dev, head, false); ++ ++ for (i = 0; i < 9; i++) ++ regp->Graphics[i] = NVReadVgaGr(dev, head, i); ++ ++ for (i = 0; i < 5; i++) ++ regp->Sequencer[i] = NVReadVgaSeq(dev, head, i); ++} ++ ++static void ++nv_load_state_vga(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct nv04_crtc_reg * regp = &state->crtc_reg[head]; ++ int i; ++ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_MISC__WRITE, regp->MiscOutReg); ++ ++ for (i = 0; i < 5; i++) ++ NVWriteVgaSeq(dev, head, i, regp->Sequencer[i]); ++ ++ nv_lock_vga_crtc_base(dev, head, false); ++ for (i = 0; i < 25; i++) ++ wr_cio_state(dev, head, regp, i); ++ nv_lock_vga_crtc_base(dev, head, true); ++ ++ for (i = 0; i < 9; i++) ++ NVWriteVgaGr(dev, head, i, regp->Graphics[i]); ++ ++ NVSetEnablePalette(dev, head, true); ++ for (i = 0; i < 21; i++) ++ NVWriteVgaAttr(dev, head, i, regp->Attribute[i]); ++ NVSetEnablePalette(dev, head, false); ++} ++ ++static void ++nv_save_state_ext(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg * regp = &state->crtc_reg[head]; ++ int i; ++ ++ NV_ERROR(dev, "FIXME twoHeads\n"); ++ ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); ++ ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_21); ++ if (dev_priv->card_type >= NV_30) ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_47); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX); ++ ++ if (dev_priv->card_type >= NV_10) { ++ regp->crtc_830 = NVReadCRTC(dev, head, NV_PCRTC_830); ++ regp->crtc_834 = NVReadCRTC(dev, head, NV_PCRTC_834); ++ if (dev_priv->card_type == NV_40) { ++ regp->crtc_850 = NVReadCRTC(dev, head, NV_PCRTC_850); ++ regp->gpio_ext = NVReadCRTC(dev, head, NV_PCRTC_GPIO_EXT); ++ } ++ if (1) //dev_priv->twoHeads) ++ regp->crtc_eng_ctrl = NVReadCRTC(dev, head, NV_PCRTC_ENGINE_CTRL); ++ regp->cursor_cfg = NVReadCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG); ++ } ++ ++ regp->crtc_cfg = NVReadCRTC(dev, head, NV_PCRTC_CONFIG); ++ ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX); ++ if (dev_priv->card_type >= NV_10) { ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_CSB); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_4B); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY); ++ } ++ /* NV11 and NV20 don't have this, they stop at 0x52. */ ++ if (dev_priv->chipset >= 0x17 && 1) { //dev_priv->twoHeads) { ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_53); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_54); ++ ++ for (i = 0; i < 0x10; i++) ++ regp->CR58[i] = NVReadVgaCrtc5758(dev, head, i); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_59); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_5B); ++ ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_85); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_86); ++ } ++ ++ regp->fb_start = NVReadCRTC(dev, head, NV_PCRTC_START); ++} ++ ++static void ++nv_load_state_ext(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg * regp = &state->crtc_reg[head]; ++ int i; ++ ++ NV_ERROR(dev, "FIXME twoHeads\n"); ++ ++ if (dev_priv->card_type >= NV_10) { ++ if (1) //dev_priv->twoHeads) ++ /* setting ENGINE_CTRL (EC) *must* come before ++ * CIO_CRE_LCD, as writing CRE_LCD sets bits 16 & 17 in ++ * EC that should not be overwritten by writing stale EC ++ */ ++ NVWriteCRTC(dev, head, NV_PCRTC_ENGINE_CTRL, regp->crtc_eng_ctrl); ++ ++ nvWriteVIDEO(dev, NV_PVIDEO_STOP, 1); ++ nvWriteVIDEO(dev, NV_PVIDEO_INTR_EN, 0); ++ nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(0), 0); ++ nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(1), 0); ++ nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(0), dev_priv->fb_available_size - 1); ++ nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(1), dev_priv->fb_available_size - 1); ++ nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(0), dev_priv->fb_available_size - 1); ++ nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(1), dev_priv->fb_available_size - 1); ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0); ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_21); ++ NVWriteCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg); ++ NVWriteCRTC(dev, head, NV_PCRTC_830, regp->crtc_830); ++ NVWriteCRTC(dev, head, NV_PCRTC_834, regp->crtc_834); ++ if (dev_priv->card_type == NV_40) { ++ NVWriteCRTC(dev, head, NV_PCRTC_850, regp->crtc_850); ++ NVWriteCRTC(dev, head, NV_PCRTC_GPIO_EXT, regp->gpio_ext); ++ } ++ ++ if (dev_priv->card_type == NV_40) { ++ uint32_t reg900 = NVReadRAMDAC(dev, head, NV_PRAMDAC_900); ++ if (regp->crtc_cfg == NV_PCRTC_CONFIG_START_ADDRESS_HSYNC) ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 | 0x10000); ++ else ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 & ~0x10000); ++ } ++ } ++ ++ NVWriteCRTC(dev, head, NV_PCRTC_CONFIG, regp->crtc_cfg); ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); ++ if (dev_priv->card_type >= NV_30) ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_47); ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX); ++ if (dev_priv->card_type == NV_40) ++ nv_fix_nv40_hw_cursor(dev, head); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX); ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX); ++ if (dev_priv->card_type >= NV_10) { ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_CSB); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_4B); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY); ++ } ++ /* NV11 and NV20 stop at 0x52. */ ++ if (dev_priv->chipset >= 0x17 && 1) { //dev_priv->twoHeads) { ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_53); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_54); ++ ++ for (i = 0; i < 0x10; i++) ++ NVWriteVgaCrtc5758(dev, head, i, regp->CR58[i]); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_59); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_5B); ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_85); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_86); ++ } ++ ++ NVWriteCRTC(dev, head, NV_PCRTC_START, regp->fb_start); ++ ++ /* Setting 1 on this value gives you interrupts for every vblank period. */ ++ NVWriteCRTC(dev, head, NV_PCRTC_INTR_EN_0, 0); ++ NVWriteCRTC(dev, head, NV_PCRTC_INTR_0, NV_PCRTC_INTR_0_VBLANK); ++} ++ ++static void ++nv_save_state_palette(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ int head_offset = head * NV_PRMDIO_SIZE, i; ++ ++ nv_wr08(NV_PRMDIO_PIXEL_MASK + head_offset, NV_PRMDIO_PIXEL_MASK_MASK); ++ nv_wr08(NV_PRMDIO_READ_MODE_ADDRESS + head_offset, 0x0); ++ ++ for (i = 0; i < 768; i++) { ++ state->crtc_reg[head].DAC[i] = nv_rd08(NV_PRMDIO_PALETTE_DATA + head_offset); ++ } ++ ++ NVSetEnablePalette(dev, head, false); ++} ++ ++void ++nouveau_hw_load_state_palette(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ int head_offset = head * NV_PRMDIO_SIZE, i; ++ ++ nv_wr08(NV_PRMDIO_PIXEL_MASK + head_offset, NV_PRMDIO_PIXEL_MASK_MASK); ++ nv_wr08(NV_PRMDIO_WRITE_MODE_ADDRESS + head_offset, 0x0); ++ ++ for (i = 0; i < 768; i++) { ++ nv_wr08(NV_PRMDIO_PALETTE_DATA + head_offset, state->crtc_reg[head].DAC[i]); ++ } ++ ++ NVSetEnablePalette(dev, head, false); ++} ++ ++void nouveau_hw_save_state(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->chipset == 0x11) ++ /* NB: no attempt is made to restore the bad pll later on */ ++ nouveau_hw_fix_bad_vpll(dev, head); ++ nv_save_state_ramdac(dev, head, state); ++ nv_save_state_vga(dev, head, state); ++ nv_save_state_palette(dev, head, state); ++ nv_save_state_ext(dev, head, state); ++} ++ ++void nouveau_hw_load_state(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ NVVgaProtect(dev, head, true); ++ nv_load_state_ramdac(dev, head, state); ++ nv_load_state_ext(dev, head, state); ++ nouveau_hw_load_state_palette(dev, head, state); ++ nv_load_state_vga(dev, head, state); ++ NVVgaProtect(dev, head, false); ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/nouveau_hw.h +new file mode 100644 +index 0000000..74f5913 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_hw.h +@@ -0,0 +1,508 @@ ++/* ++ * Copyright 2008 Stuart Bennett ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF ++ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#ifndef __NOUVEAU_HW_H__ ++#define __NOUVEAU_HW_H__ ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++ ++#define MASK(field) ((0xffffffff >> (31 - ((1?field) - (0?field)))) << (0?field)) ++#define XLATE(src, srclowbit, outfield) ((((src) >> (srclowbit)) << (0?outfield)) & MASK(outfield)) ++ ++struct nouveau_pll_vals { ++ union { ++ struct { ++#ifdef __BIG_ENDIAN ++ uint8_t N1, M1, N2, M2; ++#else ++ uint8_t M1, N1, M2, N2; ++#endif ++ }; ++ struct { ++ uint16_t NM1, NM2; ++ } __attribute__((packed)); ++ }; ++ int log2P; ++ ++ int refclk; ++}; ++ ++struct nv04_crtc_reg { ++ unsigned char MiscOutReg; /* */ ++ uint8_t CRTC[0x9f]; ++ uint8_t CR58[0x10]; ++ uint8_t Sequencer[5]; ++ uint8_t Graphics[9]; ++ uint8_t Attribute[21]; ++ unsigned char DAC[768]; /* Internal Colorlookuptable */ ++ ++ /* PCRTC regs */ ++ uint32_t fb_start; ++ uint32_t crtc_cfg; ++ uint32_t cursor_cfg; ++ uint32_t gpio_ext; ++ uint32_t crtc_830; ++ uint32_t crtc_834; ++ uint32_t crtc_850; ++ uint32_t crtc_eng_ctrl; ++ ++ /* PRAMDAC regs */ ++ uint32_t nv10_cursync; ++ struct nouveau_pll_vals pllvals; ++ uint32_t ramdac_gen_ctrl; ++ uint32_t ramdac_630; ++ uint32_t ramdac_634; ++ uint32_t fp_horiz_regs[7]; ++ uint32_t fp_vert_regs[7]; ++ uint32_t dither; ++ uint32_t fp_control; ++ uint32_t dither_regs[6]; ++ uint32_t fp_debug_0; ++ uint32_t fp_debug_1; ++ uint32_t fp_debug_2; ++ uint32_t ramdac_a20; ++ uint32_t ramdac_a24; ++ uint32_t ramdac_a34; ++}; ++ ++struct nv04_output_reg { ++ uint32_t output; ++ int head; ++}; ++ ++struct nv04_mode_state { ++ uint32_t bpp; ++ uint32_t width; ++ uint32_t height; ++ uint32_t interlace; ++ uint32_t repaint0; ++ uint32_t repaint1; ++ uint32_t screen; ++ uint32_t scale; ++ uint32_t dither; ++ uint32_t extra; ++ uint32_t fifo; ++ uint32_t pixel; ++ uint32_t horiz; ++ int arbitration0; ++ int arbitration1; ++ uint32_t pll; ++ uint32_t pllB; ++ uint32_t vpll; ++ uint32_t vpll2; ++ uint32_t vpllB; ++ uint32_t vpll2B; ++ uint32_t pllsel; ++ uint32_t sel_clk; ++ uint32_t general; ++ uint32_t crtcOwner; ++ uint32_t head; ++ uint32_t head2; ++ uint32_t cursorConfig; ++ uint32_t cursor0; ++ uint32_t cursor1; ++ uint32_t cursor2; ++ uint32_t timingH; ++ uint32_t timingV; ++ uint32_t displayV; ++ uint32_t crtcSync; ++ ++ struct nv04_crtc_reg crtc_reg[2]; ++}; ++ ++void NVWriteVgaSeq(struct drm_device *, int head, uint8_t index, uint8_t value); ++uint8_t NVReadVgaSeq(struct drm_device *, int head, uint8_t index); ++void NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value); ++uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index); ++void NVSetOwner(struct drm_device *, int owner); ++void NVBlankScreen(struct drm_device *, int head, bool blank); ++void nouveau_hw_setpll(struct drm_device *, uint32_t reg1, ++ struct nouveau_pll_vals *pv); ++int nouveau_hw_get_pllvals(struct drm_device *, enum pll_types plltype, ++ struct nouveau_pll_vals *pllvals); ++int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals); ++int nouveau_hw_get_clock(struct drm_device *, enum pll_types plltype); ++void nouveau_hw_save_vga_fonts(struct drm_device *, bool save); ++void nouveau_hw_save_state(struct drm_device *, int head, ++ struct nv04_mode_state *state); ++void nouveau_hw_load_state(struct drm_device *, int head, ++ struct nv04_mode_state *state); ++void nouveau_hw_load_state_palette(struct drm_device *, int head, ++ struct nv04_mode_state *state); ++ ++/* nouveau_calc.c */ ++extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp, ++ int *burst, int *lwm); ++extern int nouveau_calc_pll_mnp(struct drm_device *, struct pll_lims *pll_lim, ++ int clk, struct nouveau_pll_vals *pv); ++ ++static inline uint32_t ++nvReadMC(struct drm_device *dev, uint32_t reg) ++{ ++ uint32_t val = nv_rd32(reg); ++ NV_DEBUG(dev, "nvReadMC: reg %08x val %08x\n", reg, val); ++ return val; ++} ++ ++static inline void ++nvWriteMC(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ NV_DEBUG(dev, "nvWriteMC: reg %08x val %08x\n", reg, val); ++ nv_wr32(reg, val); ++} ++ ++static inline uint32_t ++nvReadVIDEO(struct drm_device *dev, uint32_t reg) ++{ ++ uint32_t val = nv_rd32(reg); ++ NV_DEBUG(dev, "nvReadVIDEO: reg %08x val %08x\n", reg, val); ++ return val; ++} ++ ++static inline void ++nvWriteVIDEO(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ NV_DEBUG(dev, "nvWriteVIDEO: reg %08x val %08x\n", reg, val); ++ nv_wr32(reg, val); ++} ++ ++static inline uint32_t ++nvReadFB(struct drm_device *dev, uint32_t reg) ++{ ++ uint32_t val = nv_rd32(reg); ++ NV_DEBUG(dev, "nvReadFB: reg %08x val %08x\n", reg, val); ++ return val; ++} ++ ++static inline void ++nvWriteFB(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ NV_DEBUG(dev, "nvWriteFB: reg %08x val %08x\n", reg, val); ++ nv_wr32(reg, val); ++} ++ ++static inline uint32_t ++nvReadEXTDEV(struct drm_device *dev, uint32_t reg) ++{ ++ uint32_t val = nv_rd32(reg); ++ NV_DEBUG(dev, "nvReadEXTDEV: reg %08x val %08x\n", reg, val); ++ return val; ++} ++ ++static inline void ++nvWriteEXTDEV(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ NV_DEBUG(dev, "nvWriteEXTDEV: reg %08x val %08x\n", reg, val); ++ nv_wr32(reg, val); ++} ++ ++static inline uint32_t NVRead(struct drm_device *dev, uint32_t reg) ++{ ++ NV_DEBUG(dev, "NVRead: reg %08x val %08x\n", reg, (uint32_t)nv_rd32(reg)); ++ return nv_rd32(reg); ++} ++ ++static inline void NVWrite(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ NV_DEBUG(dev, "NVWrite: reg %08x val %08x\n", reg, val); ++ nv_wr32(reg, val); ++} ++ ++static inline uint32_t NVReadCRTC(struct drm_device *dev, int head, uint32_t reg) ++{ ++ if (head) ++ reg += NV_PCRTC0_SIZE; ++ NV_DEBUG(dev, "NVReadCRTC: head %d reg %08x val %08x\n", head, reg, nv_rd32(reg)); ++ return nv_rd32(reg); ++} ++ ++static inline void NVWriteCRTC(struct drm_device *dev, int head, uint32_t reg, uint32_t val) ++{ ++ if (head) ++ reg += NV_PCRTC0_SIZE; ++ NV_DEBUG(dev, "NVWriteCRTC: head %d reg %08x val %08x\n", head, reg, val); ++ nv_wr32(reg, val); ++} ++ ++static inline uint32_t NVReadRAMDAC(struct drm_device *dev, int head, uint32_t reg) ++{ ++ if (head) ++ reg += NV_PRAMDAC0_SIZE; ++ NV_DEBUG(dev, "NVReadRamdac: head %d reg %08x val %08x\n", head, reg, nv_rd32(reg)); ++ return nv_rd32(reg); ++} ++ ++static inline void ++NVWriteRAMDAC(struct drm_device *dev, int head, uint32_t reg, uint32_t val) ++{ ++ if (head) ++ reg += NV_PRAMDAC0_SIZE; ++ NV_DEBUG(dev, "NVWriteRamdac: head %d reg %08x val %08x\n", head, reg, val); ++ nv_wr32(reg, val); ++} ++ ++static inline uint8_t nv_read_tmds(struct drm_device *dev, int or, int dl, uint8_t address) ++{ ++ int ramdac = (or & OUTPUT_C) >> 2; ++ ++ NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, ++ NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address); ++ return NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8); ++} ++ ++static inline void ++nv_write_tmds(struct drm_device *dev, int or, int dl, uint8_t address, uint8_t data) ++{ ++ int ramdac = (or & OUTPUT_C) >> 2; ++ ++ NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data); ++ NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address); ++} ++ ++static inline void ++NVWriteVgaCrtc(struct drm_device *dev, int head, uint8_t index, uint8_t value) ++{ ++ NV_DEBUG(dev, "NVWriteVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, value); ++ nv_wr08(NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); ++ nv_wr08(NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value); ++} ++ ++static inline uint8_t NVReadVgaCrtc(struct drm_device *dev, int head, uint8_t index) ++{ ++ nv_wr08(NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); ++ NV_DEBUG(dev, "NVReadVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, nv_rd08(NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE)); ++ return nv_rd08(NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE); ++} ++ ++/* CR57 and CR58 are a fun pair of regs. CR57 provides an index (0-0xf) for CR58 ++ * I suspect they in fact do nothing, but are merely a way to carry useful ++ * per-head variables around ++ * ++ * Known uses: ++ * CR57 CR58 ++ * 0x00 index to the appropriate dcb entry (or 7f for inactive) ++ * 0x02 dcb entry's "or" value (or 00 for inactive) ++ * 0x03 bit0 set for dual link (LVDS, possibly elsewhere too) ++ * 0x08 or 0x09 pxclk in MHz ++ * 0x0f laptop panel info - low nibble for PEXTDEV_BOOT_0 strap ++ * high nibble for xlat strap value ++ */ ++ ++static inline void ++NVWriteVgaCrtc5758(struct drm_device *dev, int head, uint8_t index, uint8_t value) ++{ ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_58, value); ++} ++ ++static inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_t index) ++{ ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); ++ return NVReadVgaCrtc(dev, head, NV_CIO_CRE_58); ++} ++ ++static inline uint8_t NVReadPRMVIO(struct drm_device *dev, int head, uint32_t reg) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* Only NV4x have two pvio ranges; other twoHeads cards MUST call ++ * NVSetOwner for the relevant head to be programmed */ ++ if (head && dev_priv->card_type == NV_40) ++ reg += NV_PRMVIO_SIZE; ++ ++ NV_DEBUG(dev, "NVReadPRMVIO: head %d reg %08x val %02x\n", head, reg, nv_rd08(reg)); ++ return nv_rd08(reg); ++} ++ ++static inline void ++NVWritePRMVIO(struct drm_device *dev, int head, uint32_t reg, uint8_t value) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* Only NV4x have two pvio ranges; other twoHeads cards MUST call ++ * NVSetOwner for the relevant head to be programmed */ ++ if (head && dev_priv->card_type == NV_40) ++ reg += NV_PRMVIO_SIZE; ++ ++ NV_DEBUG(dev, "NVWritePRMVIO: head %d reg %08x val %02x\n", head, reg, value); ++ nv_wr08(reg, value); ++} ++ ++static inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable) ++{ ++ nv_rd08(NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); ++ nv_wr08(NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20); ++} ++ ++static inline bool NVGetEnablePalette(struct drm_device *dev, int head) ++{ ++ nv_rd08(NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); ++ return !(nv_rd08(NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20); ++} ++ ++static inline void NVWriteVgaAttr(struct drm_device *dev, int head, uint8_t index, uint8_t value) ++{ ++ if (NVGetEnablePalette(dev, head)) ++ index &= ~0x20; ++ else ++ index |= 0x20; ++ ++ nv_rd08(NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); ++ NV_DEBUG(dev, "NVWriteVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, value); ++ nv_wr08(NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); ++ nv_wr08(NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value); ++} ++ ++static inline uint8_t NVReadVgaAttr(struct drm_device *dev, int head, uint8_t index) ++{ ++ if (NVGetEnablePalette(dev, head)) ++ index &= ~0x20; ++ else ++ index |= 0x20; ++ ++ nv_rd08(NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); ++ nv_wr08(NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); ++ NV_DEBUG(dev, "NVReadVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, nv_rd08(NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE)); ++ return nv_rd08(NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE); ++} ++ ++static inline void NVVgaSeqReset(struct drm_device *dev, int head, bool start) ++{ ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3); ++} ++ ++static inline void NVVgaProtect(struct drm_device *dev, int head, bool protect) ++{ ++ uint8_t seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX); ++ ++ if (protect) { ++ NVVgaSeqReset(dev, head, true); ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); ++ } else { ++ /* Reenable sequencer, then turn on screen */ ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); /* reenable display */ ++ NVVgaSeqReset(dev, head, false); ++ } ++ NVSetEnablePalette(dev, head, protect); ++} ++ ++static inline bool ++nv_heads_tied(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->chipset == 0x11) ++ return !!(nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28)); ++ ++ return (NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44) & 0x4); ++} ++ ++/* makes cr0-7 on the specified head read-only */ ++static inline bool ++nv_lock_vga_crtc_base(struct drm_device *dev, int head, bool lock) ++{ ++ uint8_t cr11 = NVReadVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX); ++ bool waslocked = cr11 & 0x80; ++ ++ if (lock) ++ cr11 |= 0x80; ++ else ++ cr11 &= ~0x80; ++ NVWriteVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX, cr11); ++ ++ return waslocked; ++} ++ ++/* renders the extended crtc regs (cr19+) on all crtcs impervious: ++ * immutable and unreadable ++ */ ++static inline bool ++NVLockVgaCrtcs(struct drm_device *dev, bool lock) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ bool waslocked = !NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX); ++ ++ NVWriteVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX, ++ lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE); ++ /* NV11 has independently lockable extended crtcs, except when tied */ ++ if (dev_priv->chipset == 0x11 && !nv_heads_tied(dev)) ++ NVWriteVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX, ++ lock ? NV_CIO_SR_LOCK_VALUE : ++ NV_CIO_SR_UNLOCK_RW_VALUE); ++ ++ return waslocked; ++} ++ ++static inline void ++nv_fix_nv40_hw_cursor(struct drm_device *dev, int head) ++{ ++ /* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense) nv40, ++ * the gf6800gt) a hardware bug requires a write to PRAMDAC_CURSOR_POS ++ * for changes to the CRTC CURCTL regs to take effect, whether changing ++ * the pixmap location, or just showing/hiding the cursor ++ */ ++ volatile uint32_t curpos = NVReadRAMDAC(dev, head, ++ NV_PRAMDAC_CU_START_POS); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos); ++} ++ ++static inline void ++nv_show_cursor(struct drm_device *dev, int head, bool show) ++{ ++ NV_ERROR(dev, "FIXME ModeReg\n"); ++#if 0 ++ uint8_t *curctl1 = ++ &pNv->ModeReg.crtc_reg[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX]; ++ ++ if (show) ++ *curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE); ++ else ++ *curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE); ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1); ++ ++ if (dev_priv->card_type == NV_40) ++ nv_fix_nv40_hw_cursor(dev, head); ++#endif ++} ++ ++static inline uint32_t ++nv_pitch_align(struct drm_device *dev, uint32_t width, int bpp) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int mask; ++ ++ if (bpp == 15) ++ bpp = 16; ++ if (bpp == 24) ++ bpp = 8; ++ ++ /* Alignment requirements taken from the Haiku driver */ ++ if (dev_priv->card_type == NV_04) ++ mask = 128 / bpp - 1; ++ else ++ mask = 512 / bpp - 1; ++ ++ return (width + mask) & ~mask; ++} ++ ++#endif /* __NOUVEAU_HW_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c +new file mode 100644 +index 0000000..5cd2fbf +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c +@@ -0,0 +1,225 @@ ++/* ++ * Copyright 2009 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Ben Skeggs ++ */ ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_i2c.h" ++#include "nouveau_hw.h" ++ ++static void ++nv04_i2c_setscl(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ uint8_t val; ++ ++ val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xd0) | (state ? 0x20 : 0); ++ NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01); ++} ++ ++static void ++nv04_i2c_setsda(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ uint8_t val; ++ ++ val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xe0) | (state ? 0x10 : 0); ++ NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01); ++} ++ ++static int ++nv04_i2c_getscl(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 4); ++} ++ ++static int ++nv04_i2c_getsda(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 8); ++} ++ ++static int ++nv50_i2c_getscl(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!(nv_rd32(i2c->rd) & 1); ++} ++ ++ ++static int ++nv50_i2c_getsda(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!(nv_rd32(i2c->rd) & 2); ++} ++ ++static void ++nv50_i2c_setscl(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ nv_wr32(i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0)); ++} ++ ++static void ++nv50_i2c_setsda(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ nv_wr32(i2c->wr, (nv_rd32(i2c->rd) & 1) | 4 | (state ? 2 : 0)); ++ i2c->data = state; ++} ++ ++int ++nouveau_i2c_new(struct drm_device *dev, const char *name, unsigned index, ++ struct nouveau_i2c_chan **pi2c) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct dcb_i2c_entry *dcbi2c = &dev_priv->vbios->dcb->i2c[index]; ++ struct nouveau_i2c_chan *i2c; ++ int ret; ++ ++ if (dcbi2c->chan) { ++ *pi2c = dcbi2c->chan; ++ return 0; ++ } ++ ++ i2c = drm_calloc(1, sizeof(*i2c), DRM_MEM_DRIVER); ++ if (i2c == NULL) ++ return -ENOMEM; ++ ++ snprintf(i2c->adapter.name, I2C_NAME_SIZE, "nouveau %s", name); ++ i2c->adapter.owner = THIS_MODULE; ++ i2c->adapter.algo_data = &i2c->algo; ++ i2c->dev = dev; ++ ++ switch (dcbi2c->port_type) { ++ case 0: ++ case 4: ++ i2c->algo.setsda = nv04_i2c_setsda; ++ i2c->algo.setscl = nv04_i2c_setscl; ++ i2c->algo.getsda = nv04_i2c_getsda; ++ i2c->algo.getscl = nv04_i2c_getscl; ++ i2c->rd = dcbi2c->read; ++ i2c->wr = dcbi2c->write; ++ break; ++ case 5: ++ i2c->algo.setsda = nv50_i2c_setsda; ++ i2c->algo.setscl = nv50_i2c_setscl; ++ i2c->algo.getsda = nv50_i2c_getsda; ++ i2c->algo.getscl = nv50_i2c_getscl; ++ /* not 100% convinced this is correct everywhere, but ++ * the best guess so far.. ++ */ ++ if (dcbi2c->read <= 3) ++ i2c->rd = 0xe138 + (dcbi2c->read * 24); ++ else ++ if (dev_priv->chipset < 0x90) ++ i2c->rd = 0xe1e0 + (dcbi2c->read * 24); ++ else ++ i2c->rd = 0xe1d4 + (dcbi2c->read * 32); ++ i2c->wr = i2c->rd; ++ break; ++ default: ++ NV_ERROR(dev, "DCB I2C port type %d unknown\n", ++ dcbi2c->port_type); ++ drm_free(i2c, sizeof(*i2c), DRM_MEM_DRIVER); ++ return -EINVAL; ++ } ++ i2c->algo.udelay = 20; ++ i2c->algo.timeout = usecs_to_jiffies(2200); ++ i2c->algo.data = i2c; ++ ++ i2c_set_adapdata(&i2c->adapter, i2c); ++ ++ ret = i2c_bit_add_bus(&i2c->adapter); ++ if (ret) { ++ NV_ERROR(dev, "Failed to register i2c %s\n", name); ++ drm_free(i2c, sizeof(*i2c), DRM_MEM_DRIVER); ++ return ret; ++ } ++ ++ *pi2c = dcbi2c->chan = i2c; ++ return 0; ++ ++} ++ ++void ++nouveau_i2c_del(struct nouveau_i2c_chan **pi2c) ++{ ++ struct nouveau_i2c_chan *i2c = *pi2c; ++ ++ if (!i2c) ++ return; ++ ++ *pi2c = NULL; ++ i2c_del_adapter(&i2c->adapter); ++ drm_free(i2c, sizeof(*i2c), DRM_MEM_DRIVER); ++} ++ ++bool ++nouveau_i2c_detect(struct nouveau_connector *connector) ++{ ++ struct drm_device *dev = connector->base.dev; ++ /* kindly borrrowed from the intel driver, hope it works. */ ++ uint8_t out_buf[] = { 0x0, 0x0}; ++ uint8_t buf[2]; ++ bool ret; ++ struct i2c_msg msgs[] = { ++ { ++ .addr = 0x50, ++ .flags = 0, ++ .len = 1, ++ .buf = out_buf, ++ }, ++ { ++ .addr = 0x50, ++ .flags = I2C_M_RD, ++ .len = 1, ++ .buf = buf, ++ } ++ }; ++ ++ if (!connector->i2c_chan) ++ return false; ++ ++ ret = (i2c_transfer(&connector->i2c_chan->adapter, msgs, 2) == 2); ++ ++ NV_DEBUG(dev, "i2c_detect: bus=%d present=%d\n", connector->bus, ret); ++ return ret; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h +new file mode 100644 +index 0000000..70b1a54 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h +@@ -0,0 +1,46 @@ ++/* ++ * Copyright 2009 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef __NOUVEAU_I2C_H__ ++#define __NOUVEAU_I2C_H__ ++ ++#include ++#include ++#include ++ ++#include "nouveau_connector.h" ++ ++struct nouveau_i2c_chan { ++ struct drm_device *dev; ++ struct i2c_adapter adapter; ++ struct i2c_algo_bit_data algo; ++ unsigned rd; ++ unsigned wr; ++ unsigned data; ++}; ++ ++int nouveau_i2c_new(struct drm_device *, const char *, unsigned, ++ struct nouveau_i2c_chan **); ++void nouveau_i2c_del(struct nouveau_i2c_chan **); ++bool nouveau_i2c_detect(struct nouveau_connector *connector); ++ ++#endif /* __NOUVEAU_I2C_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_ioc32.c b/drivers/gpu/drm/nouveau/nouveau_ioc32.c +new file mode 100644 +index 0000000..f55ae7a +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_ioc32.c +@@ -0,0 +1,72 @@ ++/** ++ * \file mga_ioc32.c ++ * ++ * 32-bit ioctl compatibility routines for the MGA DRM. ++ * ++ * \author Dave Airlie with code from patches by Egbert Eich ++ * ++ * ++ * Copyright (C) Paul Mackerras 2005 ++ * Copyright (C) Egbert Eich 2003,2004 ++ * Copyright (C) Dave Airlie 2005 ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ ++ ++#include ++ ++#include "drmP.h" ++#include "drm.h" ++ ++#include "nouveau_drm.h" ++ ++/** ++ * Called whenever a 32-bit process running under a 64-bit kernel ++ * performs an ioctl on /dev/dri/card. ++ * ++ * \param filp file pointer. ++ * \param cmd command. ++ * \param arg user argument. ++ * \return zero on success or negative number on failure. ++ */ ++long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ unsigned int nr = DRM_IOCTL_NR(cmd); ++ drm_ioctl_compat_t *fn = NULL; ++ int ret; ++ ++ if (nr < DRM_COMMAND_BASE) ++ return drm_compat_ioctl(filp, cmd, arg); ++ ++#if 0 ++ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) ++ fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE]; ++#endif ++ lock_kernel(); /* XXX for now */ ++ if (fn != NULL) ++ ret = (*fn)(filp, cmd, arg); ++ else ++ ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); ++ unlock_kernel(); ++ ++ return ret; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c +new file mode 100644 +index 0000000..c3ad906 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_irq.c +@@ -0,0 +1,592 @@ ++/* ++ * Copyright (C) 2006 Ben Skeggs. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++/* ++ * Authors: ++ * Ben Skeggs ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_reg.h" ++#include "nouveau_swmthd.h" ++ ++/* needed for hotplug irq */ ++#include "nouveau_connector.h" ++ ++void ++nouveau_irq_preinstall(struct drm_device *dev) ++{ ++ /* Master disable */ ++ nv_wr32(NV03_PMC_INTR_EN_0, 0); ++} ++ ++int ++nouveau_irq_postinstall(struct drm_device *dev) ++{ ++ /* Master enable */ ++ nv_wr32(NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE); ++ return 0; ++} ++ ++void ++nouveau_irq_uninstall(struct drm_device *dev) ++{ ++ /* Master disable */ ++ nv_wr32(NV03_PMC_INTR_EN_0, 0); ++} ++ ++static void ++nouveau_fifo_irq_handler(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ uint32_t status, reassign; ++ ++ reassign = nv_rd32(NV03_PFIFO_CACHES) & 1; ++ while ((status = nv_rd32(NV03_PFIFO_INTR_0))) { ++ uint32_t chid, get; ++ ++ nv_wr32(NV03_PFIFO_CACHES, 0); ++ ++ chid = engine->fifo.channel_id(dev); ++ get = nv_rd32(NV03_PFIFO_CACHE1_GET); ++ ++ if (status & NV_PFIFO_INTR_CACHE_ERROR) { ++ uint32_t mthd, data; ++ int ptr; ++ ++ ptr = get >> 2; ++ if (dev_priv->card_type < NV_40) { ++ mthd = nv_rd32(NV04_PFIFO_CACHE1_METHOD(ptr)); ++ data = nv_rd32(NV04_PFIFO_CACHE1_DATA(ptr)); ++ } else { ++ mthd = nv_rd32(NV40_PFIFO_CACHE1_METHOD(ptr)); ++ data = nv_rd32(NV40_PFIFO_CACHE1_DATA(ptr)); ++ } ++ ++ NV_INFO(dev, "PFIFO_CACHE_ERROR - " ++ "Ch %d/%d Mthd 0x%04x Data 0x%08x\n", ++ chid, (mthd >> 13) & 7, mthd & 0x1ffc, data); ++ ++ nv_wr32(NV03_PFIFO_CACHE1_GET, get + 4); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 1); ++ ++ status &= ~NV_PFIFO_INTR_CACHE_ERROR; ++ nv_wr32(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR); ++ } ++ ++ if (status & NV_PFIFO_INTR_DMA_PUSHER) { ++ NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d\n", chid); ++ ++ status &= ~NV_PFIFO_INTR_DMA_PUSHER; ++ nv_wr32(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_DMA_PUSHER); ++ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000); ++ if (nv_rd32(NV04_PFIFO_CACHE1_DMA_PUT) != get) ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_GET, get + 4); ++ } ++ ++ if (status) { ++ NV_INFO(dev, "Unhandled PFIFO_INTR - 0x%08x\n", status); ++ nv_wr32(NV03_PFIFO_INTR_0, status); ++ nv_wr32(NV03_PMC_INTR_EN_0, 0); ++ } ++ ++ nv_wr32(NV03_PFIFO_CACHES, reassign); ++ } ++ ++ nv_wr32(NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING); ++} ++ ++struct nouveau_bitfield_names { ++ uint32_t mask; ++ const char * name; ++}; ++ ++static struct nouveau_bitfield_names nouveau_nstatus_names[] = ++{ ++ { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, ++ { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, ++ { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, ++ { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } ++}; ++ ++static struct nouveau_bitfield_names nouveau_nstatus_names_nv10[] = ++{ ++ { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, ++ { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, ++ { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, ++ { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } ++}; ++ ++static struct nouveau_bitfield_names nouveau_nsource_names[] = ++{ ++ { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, ++ { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, ++ { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, ++ { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" }, ++ { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" }, ++ { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" }, ++ { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" }, ++ { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" }, ++ { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" }, ++ { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" }, ++ { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" }, ++ { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" }, ++ { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" }, ++ { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" }, ++ { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" }, ++ { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" }, ++ { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, ++ { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, ++ { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, ++}; ++ ++static void ++nouveau_print_bitfield_names(uint32_t value, ++ const struct nouveau_bitfield_names *namelist, ++ const int namelist_len) ++{ ++ int i; ++ for(i=0; idev_private; ++ uint32_t inst, tmp; ++ int i; ++ ++ if (dev_priv->card_type < NV_40) ++ return dev_priv->engine.fifo.channels; ++ else ++ if (dev_priv->card_type < NV_50) ++ inst = (nv_rd32(0x40032c) & 0xfffff) << 4; ++ else ++ inst = nv_rd32(0x40032c) & 0xfffff; ++ ++ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { ++ struct nouveau_channel *chan = dev_priv->fifos[i]; ++ ++ if (!chan || !chan->ramin_grctx) ++ continue; ++ ++ if (dev_priv->card_type < NV_50) { ++ if (inst == chan->ramin_grctx->instance) ++ break; ++ } else { ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ tmp = INSTANCE_RD(chan->ramin_grctx->gpuobj, 0); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ if (inst == tmp) ++ break; ++ } ++ } ++ ++ return i; ++} ++ ++static int ++nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ int channel; ++ ++ if (dev_priv->card_type < NV_10) ++ channel = (nv_rd32(NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf; ++ else ++ if (dev_priv->card_type < NV_40) ++ channel = (nv_rd32(NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; ++ else ++ channel = nouveau_graph_chid_from_grctx(dev); ++ ++ if (channel >= engine->fifo.channels || !dev_priv->fifos[channel]) { ++ NV_ERROR(dev, "AIII, invalid/inactive channel id %d\n", channel); ++ return -EINVAL; ++ } ++ ++ *channel_ret = channel; ++ return 0; ++} ++ ++struct nouveau_pgraph_trap { ++ int channel; ++ int class; ++ int subc, mthd, size; ++ uint32_t data, data2; ++ uint32_t nsource, nstatus; ++}; ++ ++static void ++nouveau_graph_trap_info(struct drm_device *dev, ++ struct nouveau_pgraph_trap *trap) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t address; ++ ++ trap->nsource = trap->nstatus = 0; ++ if (dev_priv->card_type < NV_50) { ++ trap->nsource = nv_rd32(NV03_PGRAPH_NSOURCE); ++ trap->nstatus = nv_rd32(NV03_PGRAPH_NSTATUS); ++ } ++ ++ if (nouveau_graph_trapped_channel(dev, &trap->channel)) ++ trap->channel = -1; ++ address = nv_rd32(NV04_PGRAPH_TRAPPED_ADDR); ++ ++ trap->mthd = address & 0x1FFC; ++ trap->data = nv_rd32(NV04_PGRAPH_TRAPPED_DATA); ++ if (dev_priv->card_type < NV_10) { ++ trap->subc = (address >> 13) & 0x7; ++ } else { ++ trap->subc = (address >> 16) & 0x7; ++ trap->data2 = nv_rd32(NV10_PGRAPH_TRAPPED_DATA_HIGH); ++ } ++ ++ if (dev_priv->card_type < NV_10) { ++ trap->class = nv_rd32(0x400180 + trap->subc*4) & 0xFF; ++ } else if (dev_priv->card_type < NV_40) { ++ trap->class = nv_rd32(0x400160 + trap->subc*4) & 0xFFF; ++ } else if (dev_priv->card_type < NV_50) { ++ trap->class = nv_rd32(0x400160 + trap->subc*4) & 0xFFFF; ++ } else { ++ trap->class = nv_rd32(0x400814); ++ } ++} ++ ++static void ++nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id, ++ struct nouveau_pgraph_trap *trap) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t nsource = trap->nsource, nstatus = trap->nstatus; ++ ++ NV_INFO(dev, "%s - nSource:", id); ++ nouveau_print_bitfield_names(nsource, nouveau_nsource_names, ++ ARRAY_SIZE(nouveau_nsource_names)); ++ printk(", nStatus:"); ++ if (dev_priv->card_type < NV_10) ++ nouveau_print_bitfield_names(nstatus, nouveau_nstatus_names, ++ ARRAY_SIZE(nouveau_nstatus_names)); ++ else ++ nouveau_print_bitfield_names(nstatus, nouveau_nstatus_names_nv10, ++ ARRAY_SIZE(nouveau_nstatus_names_nv10)); ++ printk("\n"); ++ ++ NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x Data 0x%08x:0x%08x\n", ++ id, trap->channel, trap->subc, trap->class, trap->mthd, ++ trap->data2, trap->data); ++} ++ ++static inline void ++nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) ++{ ++ struct nouveau_pgraph_trap trap; ++ int unhandled = 0; ++ ++ nouveau_graph_trap_info(dev, &trap); ++ ++ if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { ++ /* NV4 (nvidia TNT 1) reports software methods with ++ * PGRAPH NOTIFY ILLEGAL_MTHD ++ */ ++ NV_DEBUG(dev, "Got NV04 software method method %x for class %#x\n", ++ trap.mthd, trap.class); ++ ++ if (nouveau_sw_method_execute(dev, trap.class, trap.mthd)) { ++ NV_ERROR(dev, "Unable to execute NV04 software method " ++ "%x for class %x. Please report.\n", ++ trap.mthd, trap.class); ++ unhandled = 1; ++ } ++ } else { ++ unhandled = 1; ++ } ++ ++ if (unhandled) ++ nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap); ++} ++ ++static inline void ++nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource) ++{ ++ struct nouveau_pgraph_trap trap; ++ int unhandled = 0; ++ ++ nouveau_graph_trap_info(dev, &trap); ++ trap.nsource = nsource; ++ ++ if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { ++ if (trap.channel >= 0 && trap.mthd == 0x0150) { ++ nouveau_fence_handler(dev, trap.channel); ++ } else ++ if (nouveau_sw_method_execute(dev, trap.class, trap.mthd)) { ++ unhandled = 1; ++ } ++ } else { ++ unhandled = 1; ++ } ++ ++ if (unhandled) ++ nouveau_graph_dump_trap_info(dev, "PGRAPH_ERROR", &trap); ++} ++ ++static inline void ++nouveau_pgraph_intr_context_switch(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ uint32_t chid; ++ ++ chid = engine->fifo.channel_id(dev); ++ NV_DEBUG(dev, "PGRAPH context switch interrupt channel %x\n", chid); ++ ++ switch(dev_priv->card_type) { ++ case NV_04: ++ case NV_05: ++ nouveau_nv04_context_switch(dev); ++ break; ++ case NV_10: ++ case NV_11: ++ case NV_17: ++ nouveau_nv10_context_switch(dev); ++ break; ++ default: ++ NV_ERROR(dev, "Context switch not implemented\n"); ++ break; ++ } ++} ++ ++static void ++nouveau_pgraph_irq_handler(struct drm_device *dev) ++{ ++ uint32_t status; ++ ++ while ((status = nv_rd32(NV03_PGRAPH_INTR))) { ++ uint32_t nsource = nv_rd32(NV03_PGRAPH_NSOURCE); ++ ++ if (status & NV_PGRAPH_INTR_NOTIFY) { ++ nouveau_pgraph_intr_notify(dev, nsource); ++ ++ status &= ~NV_PGRAPH_INTR_NOTIFY; ++ nv_wr32(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY); ++ } ++ ++ if (status & NV_PGRAPH_INTR_ERROR) { ++ nouveau_pgraph_intr_error(dev, nsource); ++ ++ status &= ~NV_PGRAPH_INTR_ERROR; ++ nv_wr32(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_ERROR); ++ } ++ ++ if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { ++ nouveau_pgraph_intr_context_switch(dev); ++ ++ status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; ++ nv_wr32(NV03_PGRAPH_INTR, ++ NV_PGRAPH_INTR_CONTEXT_SWITCH); ++ } ++ ++ if (status) { ++ NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status); ++ nv_wr32(NV03_PGRAPH_INTR, status); ++ } ++ ++ if ((nv_rd32(NV04_PGRAPH_FIFO) & (1 << 0)) == 0) ++ nv_wr32(NV04_PGRAPH_FIFO, 1); ++ } ++ ++ nv_wr32(NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); ++} ++ ++static void ++nv50_pgraph_irq_handler(struct drm_device *dev) ++{ ++ uint32_t status, nsource; ++ ++ status = nv_rd32(NV03_PGRAPH_INTR); ++ nsource = nv_rd32(NV03_PGRAPH_NSOURCE); ++ ++ if (status & 0x00000020) { ++ nouveau_pgraph_intr_error(dev, ++ NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD); ++ ++ status &= ~0x00000020; ++ nv_wr32(NV03_PGRAPH_INTR, 0x00000020); ++ } ++ ++ if (status & 0x00100000) { ++ nouveau_pgraph_intr_error(dev, ++ NV03_PGRAPH_NSOURCE_DATA_ERROR); ++ ++ status &= ~0x00100000; ++ nv_wr32(NV03_PGRAPH_INTR, 0x00100000); ++ } ++ ++ if (status & 0x00200000) { ++ int r; ++ ++ nouveau_pgraph_intr_error(dev, nsource | ++ NV03_PGRAPH_NSOURCE_PROTECTION_ERROR); ++ ++ NV_ERROR(dev, "magic set 1:\n"); ++ for (r = 0x408900; r <= 0x408910; r += 4) ++ NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(r)); ++ nv_wr32(0x408900, nv_rd32(0x408904) | 0xc0000000); ++ for (r = 0x408e08; r <= 0x408e24; r += 4) ++ NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(r)); ++ nv_wr32(0x408e08, nv_rd32(0x408e08) | 0xc0000000); ++ ++ NV_ERROR(dev, "magic set 2:\n"); ++ for (r = 0x409900; r <= 0x409910; r += 4) ++ NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(r)); ++ nv_wr32(0x409900, nv_rd32(0x409904) | 0xc0000000); ++ for (r = 0x409e08; r <= 0x409e24; r += 4) ++ NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(r)); ++ nv_wr32(0x409e08, nv_rd32(0x409e08) | 0xc0000000); ++ ++ status &= ~0x00200000; ++ nv_wr32(NV03_PGRAPH_NSOURCE, nsource); ++ nv_wr32(NV03_PGRAPH_INTR, 0x00200000); ++ } ++ ++ if (status) { ++ NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status); ++ nv_wr32(NV03_PGRAPH_INTR, status); ++ } ++ ++ { ++ const int isb = (1 << 16) | (1 << 0); ++ ++ if ((nv_rd32(0x400500) & isb) != isb) ++ nv_wr32(0x400500, nv_rd32(0x400500) | isb); ++ } ++ ++ nv_wr32(NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); ++} ++ ++static void ++nouveau_crtc_irq_handler(struct drm_device *dev, int crtc) ++{ ++ if (crtc & 1) ++ nv_wr32(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); ++ ++ if (crtc & 2) ++ nv_wr32(NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK); ++} ++ ++static void ++nouveau_nv50_display_irq_handler(struct drm_device *dev) ++{ ++ uint32_t val = nv_rd32(NV50_PDISPLAY_SUPERVISOR); ++ ++ NV_DEBUG(dev, "NV50_PDISPLAY_SUPERVISOR - 0x%08X\n", val); ++ ++ /* vblank interrupts */ ++ if (val & NV50_PDISPLAY_SUPERVISOR_CRTCn) { ++ nv_wr32(NV50_PDISPLAY_SUPERVISOR, val & NV50_PDISPLAY_SUPERVISOR_CRTCn); ++ val &= ~NV50_PDISPLAY_SUPERVISOR_CRTCn; ++ } ++ ++ if (val) ++ NV_ERROR(dev, "unsupported NV50_DISPLAY_INTR - 0x%08X\n", val); ++ ++ nv_wr32(NV50_PDISPLAY_SUPERVISOR, val); ++} ++ ++static void ++nouveau_nv50_i2c_irq_handler(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "NV50_PCONNECTOR_HOTPLUG_CTRL - 0x%08X\n", ++ nv_rd32(NV50_PCONNECTOR_HOTPLUG_CTRL)); ++ ++ /* This seems to be the way to acknowledge an interrupt. */ ++ nv_wr32(NV50_PCONNECTOR_HOTPLUG_CTRL, 0x7FFF7FFF); ++ ++ /* Do a "dumb" detect all */ ++ nv50_connector_detect_all(dev); ++} ++ ++irqreturn_t ++nouveau_irq_handler(DRM_IRQ_ARGS) ++{ ++ struct drm_device *dev = (struct drm_device*)arg; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t status; ++ ++ status = nv_rd32(NV03_PMC_INTR_0); ++ if (!status) ++ return IRQ_NONE; ++ ++ if (status & NV_PMC_INTR_0_PFIFO_PENDING) { ++ nouveau_fifo_irq_handler(dev); ++ status &= ~NV_PMC_INTR_0_PFIFO_PENDING; ++ } ++ ++ if (status & NV_PMC_INTR_0_PGRAPH_PENDING) { ++ if (dev_priv->card_type >= NV_50) ++ nv50_pgraph_irq_handler(dev); ++ else ++ nouveau_pgraph_irq_handler(dev); ++ ++ status &= ~NV_PMC_INTR_0_PGRAPH_PENDING; ++ } ++ ++ if (status & NV_PMC_INTR_0_CRTCn_PENDING) { ++ nouveau_crtc_irq_handler(dev, (status>>24)&3); ++ status &= ~NV_PMC_INTR_0_CRTCn_PENDING; ++ } ++ ++ if (status & NV_PMC_INTR_0_NV50_DISPLAY_PENDING) { ++ nouveau_nv50_display_irq_handler(dev); ++ status &= ~NV_PMC_INTR_0_NV50_DISPLAY_PENDING; ++ } ++ ++ if (status & NV_PMC_INTR_0_NV50_I2C_PENDING) { ++ nouveau_nv50_i2c_irq_handler(dev); ++ status &= ~NV_PMC_INTR_0_NV50_I2C_PENDING; ++ } ++ ++ if (status) ++ NV_ERROR(dev, "Unhandled PMC INTR status bits 0x%08x\n", status); ++ ++ return IRQ_HANDLED; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c +new file mode 100644 +index 0000000..44b3b34 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_mem.c +@@ -0,0 +1,1073 @@ ++/* ++ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. ++ * Copyright 2005 Stephane Marchesin ++ * ++ * The Weather Channel (TM) funded Tungsten Graphics to develop the ++ * initial release of the Radeon 8500 driver under the XFree86 license. ++ * This notice must be preserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * Keith Whitwell ++ */ ++ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_sarea.h" ++#include "nouveau_drv.h" ++ ++extern int nouveau_noagp; ++ ++static struct mem_block * ++split_block(struct mem_block *p, uint64_t start, uint64_t size, ++ struct drm_file *file_priv) ++{ ++ /* Maybe cut off the start of an existing block */ ++ if (start > p->start) { ++ struct mem_block *newblock = ++ drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); ++ if (!newblock) ++ goto out; ++ newblock->start = start; ++ newblock->size = p->size - (start - p->start); ++ newblock->file_priv = NULL; ++ newblock->next = p->next; ++ newblock->prev = p; ++ p->next->prev = newblock; ++ p->next = newblock; ++ p->size -= newblock->size; ++ p = newblock; ++ } ++ ++ /* Maybe cut off the end of an existing block */ ++ if (size < p->size) { ++ struct mem_block *newblock = ++ drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); ++ if (!newblock) ++ goto out; ++ newblock->start = start + size; ++ newblock->size = p->size - size; ++ newblock->file_priv = NULL; ++ newblock->next = p->next; ++ newblock->prev = p; ++ p->next->prev = newblock; ++ p->next = newblock; ++ p->size = size; ++ } ++ ++out: ++ /* Our block is in the middle */ ++ p->file_priv = file_priv; ++ return p; ++} ++ ++struct mem_block * ++nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, ++ int align2, struct drm_file *file_priv, int tail) ++{ ++ struct mem_block *p; ++ uint64_t mask = (1 << align2) - 1; ++ ++ if (!heap) ++ return NULL; ++ ++ if (tail) { ++ list_for_each_prev(p, heap) { ++ uint64_t start = ((p->start + p->size) - size) & ~mask; ++ ++ if (p->file_priv == 0 && start >= p->start && ++ start + size <= p->start + p->size) ++ return split_block(p, start, size, file_priv); ++ } ++ } else { ++ list_for_each(p, heap) { ++ uint64_t start = (p->start + mask) & ~mask; ++ ++ if (p->file_priv == 0 && ++ start + size <= p->start + p->size) ++ return split_block(p, start, size, file_priv); ++ } ++ } ++ ++ return NULL; ++} ++ ++static struct mem_block *find_block(struct mem_block *heap, uint64_t start) ++{ ++ struct mem_block *p; ++ ++ list_for_each(p, heap) ++ if (p->start == start) ++ return p; ++ ++ return NULL; ++} ++ ++void nouveau_mem_free_block(struct mem_block *p) ++{ ++ p->file_priv = NULL; ++ ++ /* Assumes a single contiguous range. Needs a special file_priv in ++ * 'heap' to stop it being subsumed. ++ */ ++ if (p->next->file_priv == 0) { ++ struct mem_block *q = p->next; ++ p->size += q->size; ++ p->next = q->next; ++ p->next->prev = p; ++ drm_free(q, sizeof(*q), DRM_MEM_BUFS); ++ } ++ ++ if (p->prev->file_priv == 0) { ++ struct mem_block *q = p->prev; ++ q->size += p->size; ++ q->next = p->next; ++ q->next->prev = q; ++ drm_free(p, sizeof(*q), DRM_MEM_BUFS); ++ } ++} ++ ++/* Initialize. How to check for an uninitialized heap? ++ */ ++int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start, ++ uint64_t size) ++{ ++ struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS); ++ ++ if (!blocks) ++ return -ENOMEM; ++ ++ *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS); ++ if (!*heap) { ++ drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS); ++ return -ENOMEM; ++ } ++ ++ blocks->start = start; ++ blocks->size = size; ++ blocks->file_priv = NULL; ++ blocks->next = blocks->prev = *heap; ++ ++ memset(*heap, 0, sizeof(**heap)); ++ (*heap)->file_priv = (struct drm_file *) - 1; ++ (*heap)->next = (*heap)->prev = blocks; ++ return 0; ++} ++ ++/* ++ * Free all blocks associated with the releasing file_priv ++ */ ++void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap) ++{ ++ struct mem_block *p; ++ ++ if (!heap || !heap->next) ++ return; ++ ++ list_for_each(p, heap) { ++ if (p->file_priv == file_priv) ++ p->file_priv = NULL; ++ } ++ ++ /* Assumes a single contiguous range. Needs a special file_priv in ++ * 'heap' to stop it being subsumed. ++ */ ++ list_for_each(p, heap) { ++ while ((p->file_priv == 0) && (p->next->file_priv == 0) && ++ (p->next!=heap)) { ++ struct mem_block *q = p->next; ++ p->size += q->size; ++ p->next = q->next; ++ p->next->prev = p; ++ drm_free(q, sizeof(*q), DRM_MEM_DRIVER); ++ } ++ } ++} ++ ++/* ++ * NV50 VM helpers ++ */ ++#define VMBLOCK (512*1024*1024) ++static int ++nv50_mem_vm_preinit(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ dev_priv->vm_gart_base = roundup(VMBLOCK, VMBLOCK); ++ dev_priv->vm_gart_size = VMBLOCK; ++ ++ dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size; ++ dev_priv->vm_vram_size = roundup(nouveau_mem_fb_amount(dev), VMBLOCK); ++ dev_priv->vm_end = dev_priv->vm_vram_base + dev_priv->vm_vram_size; ++ ++ NV_DEBUG(dev, "NV50VM: GART 0x%016llx-0x%016llx\n", ++ dev_priv->vm_gart_base, ++ dev_priv->vm_gart_base + dev_priv->vm_gart_size - 1); ++ NV_DEBUG(dev, "NV50VM: VRAM 0x%016llx-0x%016llx\n", ++ dev_priv->vm_vram_base, ++ dev_priv->vm_vram_base + dev_priv->vm_vram_size - 1); ++ return 0; ++} ++ ++static void ++nv50_mem_vm_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int i; ++ ++ if (!dev_priv->vm_vram_pt) ++ return; ++ ++ for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { ++ if (!dev_priv->vm_vram_pt[i]) ++ break; ++ ++ nouveau_gpuobj_del(dev, &dev_priv->vm_vram_pt[i]); ++ } ++ ++ drm_free(dev_priv->vm_vram_pt, ++ dev_priv->vm_vram_pt_nr * sizeof(struct nouveau_gpuobj *), ++ DRM_MEM_DRIVER); ++ dev_priv->vm_vram_pt = NULL; ++ dev_priv->vm_vram_pt_nr = 0; ++} ++ ++static int ++nv50_mem_vm_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ const int nr = dev_priv->vm_vram_size / VMBLOCK; ++ int i, ret; ++ ++ dev_priv->vm_vram_pt_nr = nr; ++ dev_priv->vm_vram_pt = drm_calloc(nr, sizeof(struct nouveau_gpuobj *), ++ DRM_MEM_DRIVER); ++ if (!dev_priv->vm_vram_pt) ++ return -ENOMEM; ++ ++ for (i = 0; i < nr; i++) { ++ ret = nouveau_gpuobj_new(dev, NULL, VMBLOCK/65536*8, 0, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ALLOW_NO_REFS, ++ &dev_priv->vm_vram_pt[i]); ++ if (ret) { ++ NV_ERROR(dev, "Error creating VRAM page tables: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++int ++nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, ++ uint32_t flags, uint64_t phys) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj **pgt; ++ unsigned psz, pfl, pages; ++ ++ if (virt >= dev_priv->vm_gart_base && ++ (virt + size) < (dev_priv->vm_gart_base + dev_priv->vm_gart_size)) { ++ psz = 12; ++ pgt = &dev_priv->gart_info.sg_ctxdma; ++ pfl = 0x21; ++ virt -= dev_priv->vm_gart_base; ++ } else ++ if (virt >= dev_priv->vm_vram_base && ++ (virt + size) < (dev_priv->vm_vram_base + dev_priv->vm_vram_size)) { ++ psz = 16; ++ pgt = dev_priv->vm_vram_pt; ++ pfl = 0x01; ++ virt -= dev_priv->vm_vram_base; ++ } else { ++ NV_ERROR(dev, "Invalid address: 0x%16llx-0x%16llx\n", ++ virt, virt + size - 1); ++ return -EINVAL; ++ } ++ ++ pages = size >> psz; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ if (flags & 0x80000000) { ++ while (pages--) { ++ struct nouveau_gpuobj *pt = pgt[virt >> 29]; ++ unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; ++ ++ INSTANCE_WR(pt, pte++, 0x00000000); ++ INSTANCE_WR(pt, pte++, 0x00000000); ++ ++ virt += (1 << psz); ++ } ++ } else { ++ while (pages--) { ++ struct nouveau_gpuobj *pt = pgt[virt >> 29]; ++ unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; ++ ++ INSTANCE_WR(pt, pte++, phys | pfl); ++ INSTANCE_WR(pt, pte++, flags); ++ ++ phys += (1 << psz); ++ virt += (1 << psz); ++ } ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ return 0; ++} ++ ++void ++nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) ++{ ++ nv50_mem_vm_bind_linear(dev, virt, size, 0x80000000, 0); ++} ++ ++/* ++ * Cleanup everything ++ */ ++void nouveau_mem_takedown(struct mem_block **heap) ++{ ++ struct mem_block *p; ++ ++ if (!*heap) ++ return; ++ ++ for (p = (*heap)->next; p != *heap;) { ++ struct mem_block *q = p; ++ p = p->next; ++ drm_free(q, sizeof(*q), DRM_MEM_DRIVER); ++ } ++ ++ drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER); ++ *heap = NULL; ++} ++ ++void nouveau_mem_close(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->card_type >= NV_50) ++ nv50_mem_vm_takedown(dev); ++ ++ if (!dev_priv->mm_enabled) { ++ nouveau_mem_takedown(&dev_priv->agp_heap); ++ nouveau_mem_takedown(&dev_priv->fb_heap); ++ if (dev_priv->pci_heap) ++ nouveau_mem_takedown(&dev_priv->pci_heap); ++ } else { ++ drm_bo_driver_finish(dev); ++ } ++ ++ if (dev_priv->fb_mtrr) { ++ drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1), ++ drm_get_resource_len(dev, 1), DRM_MTRR_WC); ++ dev_priv->fb_mtrr = 0; ++ } ++} ++ ++/*XXX won't work on BSD because of pci_read_config_dword */ ++static uint32_t ++nouveau_mem_fb_amount_igp(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct pci_dev *bridge; ++ uint32_t mem; ++ ++ bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0,1)); ++ if (!bridge) { ++ NV_ERROR(dev, "no bridge device\n"); ++ return 0; ++ } ++ ++ if (dev_priv->flags&NV_NFORCE) { ++ pci_read_config_dword(bridge, 0x7C, &mem); ++ return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; ++ } else ++ if(dev_priv->flags&NV_NFORCE2) { ++ pci_read_config_dword(bridge, 0x84, &mem); ++ return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; ++ } ++ ++ NV_ERROR(dev, "impossible!\n"); ++ return 0; ++} ++ ++/* returns the amount of FB ram in bytes */ ++uint64_t nouveau_mem_fb_amount(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv=dev->dev_private; ++ switch(dev_priv->card_type) ++ { ++ case NV_04: ++ case NV_05: ++ if (nv_rd32(NV03_BOOT_0) & 0x00000100) { ++ return (((nv_rd32(NV03_BOOT_0) >> 12) & 0xf)*2+2)*1024*1024; ++ } else ++ switch(nv_rd32(NV03_BOOT_0)&NV03_BOOT_0_RAM_AMOUNT) ++ { ++ case NV04_BOOT_0_RAM_AMOUNT_32MB: ++ return 32*1024*1024; ++ case NV04_BOOT_0_RAM_AMOUNT_16MB: ++ return 16*1024*1024; ++ case NV04_BOOT_0_RAM_AMOUNT_8MB: ++ return 8*1024*1024; ++ case NV04_BOOT_0_RAM_AMOUNT_4MB: ++ return 4*1024*1024; ++ } ++ break; ++ case NV_10: ++ case NV_11: ++ case NV_17: ++ case NV_20: ++ case NV_30: ++ case NV_40: ++ case NV_44: ++ case NV_50: ++ default: ++ if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { ++ return nouveau_mem_fb_amount_igp(dev); ++ } else { ++ uint64_t mem; ++ ++ mem = (nv_rd32(NV04_FIFO_DATA) & ++ NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> ++ NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT; ++ return mem*1024*1024; ++ } ++ break; ++ } ++ ++ NV_ERROR(dev, "Unable to detect video ram size. Please report your setup to " DRIVER_EMAIL "\n"); ++ return 0; ++} ++ ++static void nouveau_mem_reset_agp(struct drm_device *dev) ++{ ++ uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable; ++ ++ saved_pci_nv_1 = nv_rd32(NV04_PBUS_PCI_NV_1); ++ saved_pci_nv_19 = nv_rd32(NV04_PBUS_PCI_NV_19); ++ ++ /* clear busmaster bit */ ++ nv_wr32(NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4); ++ /* clear SBA and AGP bits */ ++ nv_wr32(NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff); ++ ++ /* power cycle pgraph, if enabled */ ++ pmc_enable = nv_rd32(NV03_PMC_ENABLE); ++ if (pmc_enable & NV_PMC_ENABLE_PGRAPH) { ++ nv_wr32(NV03_PMC_ENABLE, pmc_enable & ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ } ++ ++ /* and restore (gives effect of resetting AGP) */ ++ nv_wr32(NV04_PBUS_PCI_NV_19, saved_pci_nv_19); ++ nv_wr32(NV04_PBUS_PCI_NV_1, saved_pci_nv_1); ++} ++ ++static int ++nouveau_mem_init_agp(struct drm_device *dev, int ttm) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_agp_info info; ++ struct drm_agp_mode mode; ++ int ret; ++ ++ if (nouveau_noagp) ++ return 0; ++ ++ nouveau_mem_reset_agp(dev); ++ ++ ret = drm_agp_acquire(dev); ++ if (ret) { ++ NV_ERROR(dev, "Unable to acquire AGP: %d\n", ret); ++ return ret; ++ } ++ ++ ret = drm_agp_info(dev, &info); ++ if (ret) { ++ NV_ERROR(dev, "Unable to get AGP info: %d\n", ret); ++ return ret; ++ } ++ ++ /* see agp.h for the AGPSTAT_* modes available */ ++ mode.mode = info.mode; ++ ret = drm_agp_enable(dev, mode); ++ if (ret) { ++ NV_ERROR(dev, "Unable to enable AGP: %d\n", ret); ++ return ret; ++ } ++ ++ if (!ttm) { ++ struct drm_agp_buffer agp_req; ++ struct drm_agp_binding bind_req; ++ ++ agp_req.size = info.aperture_size; ++ agp_req.type = 0; ++ ret = drm_agp_alloc(dev, &agp_req); ++ if (ret) { ++ NV_ERROR(dev, "Unable to alloc AGP: %d\n", ret); ++ return ret; ++ } ++ ++ bind_req.handle = agp_req.handle; ++ bind_req.offset = 0; ++ ret = drm_agp_bind(dev, &bind_req); ++ if (ret) { ++ NV_ERROR(dev, "Unable to bind AGP: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ dev_priv->gart_info.type = NOUVEAU_GART_AGP; ++ dev_priv->gart_info.aper_base = info.aperture_base; ++ dev_priv->gart_info.aper_size = info.aperture_size; ++ return 0; ++} ++ ++int ++nouveau_mem_init_ttm(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t vram_size, bar1_size, text_size; ++ int ret; ++ ++ dev_priv->fb_phys = drm_get_resource_start(dev, 1); ++ dev_priv->gart_info.type = NOUVEAU_GART_NONE; ++ ++ if (dev_priv->card_type >= NV_50) { ++ ret = nv50_mem_vm_preinit(dev); ++ if (ret) ++ return ret; ++ } ++ ++ drm_bo_driver_init(dev); ++ ++ /* non-mappable vram */ ++ dev_priv->fb_available_size = nouveau_mem_fb_amount(dev); ++ dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram; ++ vram_size = dev_priv->fb_available_size >> PAGE_SHIFT; ++ bar1_size = drm_get_resource_len(dev, 1) >> PAGE_SHIFT; ++ text_size = (256 * 1024) >> PAGE_SHIFT; ++ if (bar1_size < vram_size) { ++ if (dev_priv->card_type < NV_50 && ++ (ret = drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, bar1_size, ++ vram_size - bar1_size, 1))) { ++ NV_ERROR(dev, "Failed PRIV0 mm init: %d\n", ret); ++ return ret; ++ } ++ vram_size = bar1_size; ++ } ++ ++ /* mappable vram */ ++ if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, text_size, ++ vram_size - text_size, 1))) { ++ NV_ERROR(dev, "Failed VRAM mm init: %d\n", ret); ++ return ret; ++ } ++ ++ /* GART */ ++#if !defined(__powerpc__) && !defined(__ia64__) ++ if (drm_device_is_agp(dev) && dev->agp) { ++ if ((ret = nouveau_mem_init_agp(dev, 1))) ++ NV_ERROR(dev, "Error initialising AGP: %d\n", ret); ++ } ++#endif ++ ++ if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) { ++ if ((ret = nouveau_sgdma_init(dev))) ++ NV_ERROR(dev, "Error initialising PCI SGDMA: %d\n", ret); ++ } ++ ++ if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0, ++ dev_priv->gart_info.aper_size >> PAGE_SHIFT, ++ 1))) { ++ NV_ERROR(dev, "Failed TT mm init: %d\n", ret); ++ return ret; ++ } ++ ++ dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1), ++ drm_get_resource_len(dev, 1), ++ DRM_MTRR_WC); ++ ++ if (dev_priv->card_type >= NV_50) { ++ ret = nv50_mem_vm_init(dev); ++ if (ret) { ++ NV_ERROR(dev, "Error creating VM page tables: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++int nouveau_mem_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t fb_size, vram_base, gart_base; ++ int ret = 0; ++ ++ dev_priv->agp_heap = dev_priv->pci_heap = dev_priv->fb_heap = NULL; ++ dev_priv->fb_phys = 0; ++ dev_priv->gart_info.type = NOUVEAU_GART_NONE; ++ ++ /* setup a mtrr over the FB */ ++ dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1), ++ nouveau_mem_fb_amount(dev), ++ DRM_MTRR_WC); ++ ++ if (dev_priv->card_type >= NV_50) { ++ ret = nv50_mem_vm_preinit(dev); ++ if (ret) ++ return ret; ++ } ++ gart_base = dev_priv->vm_gart_base; ++ vram_base = dev_priv->vm_vram_base; ++ ++ /* Init FB */ ++ dev_priv->fb_phys=drm_get_resource_start(dev,1); ++ fb_size = nouveau_mem_fb_amount(dev); ++ fb_size -= dev_priv->ramin_rsvd_vram; ++ dev_priv->fb_available_size = fb_size; ++ NV_DEBUG(dev, "Available VRAM: %dKiB\n", fb_size>>10); ++ ++ if (fb_size>256*1024*1024) { ++ /* On cards with > 256Mb, you can't map everything. ++ * So we create a second FB heap for that type of memory */ ++ if (nouveau_mem_init_heap(&dev_priv->fb_heap, ++ vram_base, 256*1024*1024)) ++ return -ENOMEM; ++ if (nouveau_mem_init_heap(&dev_priv->fb_nomap_heap, ++ vram_base + 256*1024*1024, ++ fb_size - 256*1024*1024)) ++ return -ENOMEM; ++ } else { ++ if (nouveau_mem_init_heap(&dev_priv->fb_heap, vram_base, fb_size)) ++ return -ENOMEM; ++ dev_priv->fb_nomap_heap=NULL; ++ } ++ ++#if !defined(__powerpc__) && !defined(__ia64__) ++ /* Init AGP / NV50 PCIEGART */ ++ if (drm_device_is_agp(dev) && dev->agp) { ++ if ((ret = nouveau_mem_init_agp(dev, 0))) ++ NV_ERROR(dev, "Error initialising AGP: %d\n", ret); ++ } ++#endif ++ ++ /*Note: this is *not* just NV50 code, but only used on NV50 for now */ ++ if (dev_priv->gart_info.type == NOUVEAU_GART_NONE && ++ dev_priv->card_type >= NV_50) { ++ ret = nouveau_sgdma_init(dev); ++ if (!ret) { ++ ret = nouveau_sgdma_nottm_hack_init(dev); ++ if (ret) ++ nouveau_sgdma_takedown(dev); ++ } ++ ++ if (ret) ++ NV_ERROR(dev, "Error initialising SG DMA: %d\n", ret); ++ } ++ ++ if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { ++ if (nouveau_mem_init_heap(&dev_priv->agp_heap, gart_base, ++ dev_priv->gart_info.aper_size)) { ++ if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { ++ nouveau_sgdma_nottm_hack_takedown(dev); ++ nouveau_sgdma_takedown(dev); ++ } ++ } ++ } ++ ++ /* NV04-NV40 PCIEGART */ ++ if (!dev_priv->agp_heap && dev_priv->card_type < NV_50) { ++ struct drm_scatter_gather sgreq; ++ ++ NV_DEBUG(dev, "Allocating sg memory for PCI DMA\n"); ++ sgreq.size = 16 << 20; //16MB of PCI scatter-gather zone ++ ++ if (drm_sg_alloc(dev, &sgreq)) { ++ NV_ERROR(dev, ++ "Unable to allocate %ldMB of scatter-gather" ++ " pages for PCI DMA!",sgreq.size>>20); ++ } else { ++ if (nouveau_mem_init_heap(&dev_priv->pci_heap, 0, ++ dev->sg->pages * PAGE_SIZE)) { ++ NV_ERROR(dev, "Unable to initialize pci_heap!"); ++ } ++ } ++ } ++ ++ if (dev_priv->card_type >= NV_50) { ++ ret = nv50_mem_vm_init(dev); ++ if (ret) { ++ NV_ERROR(dev, "Error creating VM page tables: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++struct mem_block * ++nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, ++ int flags, struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct mem_block *block; ++ int type, tail = !(flags & NOUVEAU_MEM_USER); ++ int ret; ++ ++ /* ++ * Make things easier on ourselves: all allocations are page-aligned. ++ * We need that to map allocated regions into the user space ++ */ ++ if (alignment < PAGE_SIZE) ++ alignment = PAGE_SIZE; ++ ++ /* Align allocation sizes to 64KiB blocks on G8x. We use a 64KiB ++ * page size in the GPU VM. ++ */ ++ if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) { ++ size = (size + 65535) & ~65535; ++ if (alignment < 65536) ++ alignment = 65536; ++ } ++ ++ /* Further down wants alignment in pages, not bytes */ ++ alignment >>= PAGE_SHIFT; ++ ++ /* This case will only ever be hit through in-kernel use */ ++ if (dev_priv->mm_enabled) { ++ uint64_t memtype = 0; ++ ++ size = (size + 65535) & ~65535; ++ if (alignment < (65536 / PAGE_SIZE)) ++ alignment = (65536 / PAGE_SIZE); ++ ++ block = drm_calloc(1, sizeof(*block), DRM_MEM_DRIVER); ++ if (!block) ++ return NULL; ++ ++ if (flags & (NOUVEAU_MEM_FB | NOUVEAU_MEM_FB_ACCEPTABLE)) { ++ memtype |= DRM_BO_FLAG_MEM_VRAM; ++ if (!(flags & NOUVEAU_MEM_MAPPED)) ++ memtype |= DRM_BO_FLAG_MEM_PRIV0; ++ } ++ if (flags & NOUVEAU_MEM_AGP) ++ memtype |= DRM_BO_FLAG_MEM_TT; ++ if (flags & NOUVEAU_MEM_NOVM) ++ memtype |= DRM_NOUVEAU_BO_FLAG_NOVM; ++ ++ ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, ++ DRM_BO_FLAG_READ | ++ DRM_BO_FLAG_WRITE | ++ DRM_BO_FLAG_NO_EVICT | ++ memtype, DRM_BO_HINT_DONT_FENCE, ++ alignment, 0, &block->bo); ++ if (ret) { ++ drm_free(block, sizeof(*block), DRM_MEM_DRIVER); ++ return NULL; ++ } ++ ++ block->start = block->bo->offset; ++ block->size = block->bo->mem.size; ++ ++ if (block->bo->mem.mem_type == DRM_BO_MEM_VRAM) { ++ block->flags = NOUVEAU_MEM_FB; ++ if (flags & NOUVEAU_MEM_NOVM) { ++ block->flags |= NOUVEAU_MEM_NOVM; ++ block->start -= dev_priv->vm_vram_base; ++ } ++ } else ++ if (block->bo->mem.mem_type == DRM_BO_MEM_TT) { ++ block->flags = NOUVEAU_MEM_AGP; ++ } ++ ++ return block; ++ } ++ ++ /* ++ * Warn about 0 sized allocations, but let it go through. It'll return 1 page ++ */ ++ if (size == 0) ++ NV_WARN(dev, "warning : 0 byte allocation\n"); ++ ++ /* ++ * Keep alloc size a multiple of the page size to keep drm_addmap() happy ++ */ ++ if (size & (~PAGE_MASK)) ++ size = ((size/PAGE_SIZE) + 1) * PAGE_SIZE; ++ ++ ++#define NOUVEAU_MEM_ALLOC_AGP {\ ++ type=NOUVEAU_MEM_AGP;\ ++ block = nouveau_mem_alloc_block(dev_priv->agp_heap, size,\ ++ alignment, file_priv, tail); \ ++ if (block) goto alloc_ok;\ ++ } ++ ++#define NOUVEAU_MEM_ALLOC_PCI {\ ++ type = NOUVEAU_MEM_PCI;\ ++ block = nouveau_mem_alloc_block(dev_priv->pci_heap, size, \ ++ alignment, file_priv, tail); \ ++ if ( block ) goto alloc_ok;\ ++ } ++ ++#define NOUVEAU_MEM_ALLOC_FB {\ ++ type=NOUVEAU_MEM_FB;\ ++ if (!(flags&NOUVEAU_MEM_MAPPED)) {\ ++ block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap,\ ++ size, alignment, \ ++ file_priv, tail); \ ++ if (block) goto alloc_ok;\ ++ }\ ++ block = nouveau_mem_alloc_block(dev_priv->fb_heap, size,\ ++ alignment, file_priv, tail);\ ++ if (block) goto alloc_ok;\ ++ } ++ ++ ++ if (flags&NOUVEAU_MEM_FB) NOUVEAU_MEM_ALLOC_FB ++ if (flags&NOUVEAU_MEM_AGP) NOUVEAU_MEM_ALLOC_AGP ++ if (flags&NOUVEAU_MEM_PCI) NOUVEAU_MEM_ALLOC_PCI ++ if (flags&NOUVEAU_MEM_FB_ACCEPTABLE) NOUVEAU_MEM_ALLOC_FB ++ if (flags&NOUVEAU_MEM_AGP_ACCEPTABLE) NOUVEAU_MEM_ALLOC_AGP ++ if (flags&NOUVEAU_MEM_PCI_ACCEPTABLE) NOUVEAU_MEM_ALLOC_PCI ++ ++ ++ return NULL; ++ ++alloc_ok: ++ block->flags=type; ++ ++ /* On G8x, map memory into VM */ ++ if (block->flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50 && ++ !(flags & NOUVEAU_MEM_NOVM)) { ++ unsigned offset = block->start - dev_priv->vm_vram_base; ++ unsigned tile = 0; ++ ++ /* The tiling stuff is *not* what NVIDIA does - but both the ++ * 2D and 3D engines seem happy with this simpler method. ++ * Should look into why NVIDIA do what they do at some point. ++ */ ++ if (flags & NOUVEAU_MEM_TILE) { ++ if (flags & NOUVEAU_MEM_TILE_ZETA) ++ tile = 0x00002800; ++ else ++ tile = 0x00007000; ++ } ++ ++ ret = nv50_mem_vm_bind_linear(dev, block->start, block->size, ++ tile, offset); ++ if (ret) { ++ NV_ERROR(dev, "error binding into vm: %d\n", ret); ++ nouveau_mem_free_block(block); ++ return NULL; ++ } ++ } else ++ if (block->flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) { ++ block->start -= dev_priv->vm_vram_base; ++ block->flags |= NOUVEAU_MEM_NOVM; ++ } ++ ++ if (flags & NOUVEAU_MEM_MAPPED) ++ { ++ struct drm_map_list *entry; ++ uint64_t map_offset; ++ int ret = 0; ++ ++ block->flags |= NOUVEAU_MEM_MAPPED; ++ ++ map_offset = block->start; ++ if (!(block->flags & NOUVEAU_MEM_NOVM)) { ++ if (block->flags & NOUVEAU_MEM_FB) ++ map_offset -= dev_priv->vm_vram_base; ++ else ++ if (block->flags & NOUVEAU_MEM_AGP) ++ map_offset -= dev_priv->vm_gart_base; ++ } ++ ++ if (type == NOUVEAU_MEM_AGP) { ++ if (dev_priv->gart_info.type != NOUVEAU_GART_SGDMA) ++ ret = drm_addmap(dev, map_offset, block->size, ++ _DRM_AGP, 0, &block->map); ++ else ++ ret = drm_addmap(dev, map_offset, block->size, ++ _DRM_SCATTER_GATHER, 0, &block->map); ++ } ++ else if (type == NOUVEAU_MEM_FB) ++ ret = drm_addmap(dev, map_offset + dev_priv->fb_phys, ++ block->size, _DRM_FRAME_BUFFER, ++ 0, &block->map); ++ else if (type == NOUVEAU_MEM_PCI) ++ ret = drm_addmap(dev, map_offset, block->size, ++ _DRM_SCATTER_GATHER, 0, &block->map); ++ ++ if (ret) { ++ nouveau_mem_free_block(block); ++ return NULL; ++ } ++ ++ entry = drm_find_matching_map(dev, block->map); ++ if (!entry) { ++ nouveau_mem_free_block(block); ++ return NULL; ++ } ++ block->map_handle = entry->user_token; ++ } ++ ++ NV_DEBUG(dev, "allocated %lld bytes at 0x%llx type=0x%08x\n", ++ block->size, block->start, block->flags); ++ return block; ++} ++ ++void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_DEBUG(dev, "freeing 0x%llx type=0x%08x\n", ++ block->start, block->flags); ++ ++ if (dev_priv->mm_enabled) { ++ if (block->kmap.virtual) ++ drm_bo_kunmap(&block->kmap); ++ drm_bo_usage_deref_unlocked(&block->bo); ++ drm_free(block, sizeof(*block), DRM_MEM_DRIVER); ++ return; ++ } ++ ++ if (block->flags&NOUVEAU_MEM_MAPPED) ++ drm_rmmap(dev, block->map); ++ ++ /* G8x: Remove pages from vm */ ++ if (block->flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50 && ++ !(block->flags & NOUVEAU_MEM_NOVM)) { ++ nv50_mem_vm_unbind(dev, block->start, block->size); ++ } ++ ++ nouveau_mem_free_block(block); ++} ++ ++/* ++ * Ioctls ++ */ ++ ++int ++nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_mem_alloc *alloc = data; ++ struct mem_block *block; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_DISABLED_WITH_RETURN; ++ ++ if (alloc->flags & NOUVEAU_MEM_INTERNAL) ++ return -EINVAL; ++ ++ block = nouveau_mem_alloc(dev, alloc->alignment, alloc->size, ++ alloc->flags | NOUVEAU_MEM_USER, file_priv); ++ if (!block) ++ return -ENOMEM; ++ alloc->map_handle=block->map_handle; ++ alloc->offset=block->start; ++ alloc->flags=block->flags; ++ ++ return 0; ++} ++ ++int ++nouveau_ioctl_mem_free(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_mem_free *memfree = data; ++ struct mem_block *block; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_DISABLED_WITH_RETURN; ++ ++ block=NULL; ++ if (dev_priv->fb_heap && memfree->flags & NOUVEAU_MEM_FB) ++ block = find_block(dev_priv->fb_heap, memfree->offset); ++ else ++ if (dev_priv->agp_heap && memfree->flags & NOUVEAU_MEM_AGP) ++ block = find_block(dev_priv->agp_heap, memfree->offset); ++ else ++ if (dev_priv->pci_heap && memfree->flags & NOUVEAU_MEM_PCI) ++ block = find_block(dev_priv->pci_heap, memfree->offset); ++ ++ if (!block) ++ return -EFAULT; ++ ++ if (block->file_priv != file_priv) ++ return -EPERM; ++ ++ nouveau_mem_free(dev, block); ++ return 0; ++} ++ ++int ++nouveau_ioctl_mem_tile(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_mem_tile *memtile = data; ++ struct mem_block *block = NULL; ++ unsigned offset, tile = 0; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_CHECK_MM_DISABLED_WITH_RETURN; ++ ++ if (dev_priv->card_type < NV_50) ++ return -EINVAL; ++ ++ if (memtile->flags & NOUVEAU_MEM_FB) ++ block = find_block(dev_priv->fb_heap, memtile->offset); ++ ++ if (!block || (memtile->delta + memtile->size > block->size)) ++ return -EINVAL; ++ ++ if (block->file_priv != file_priv) ++ return -EPERM; ++ ++ offset = block->start + memtile->delta; ++ offset -= dev_priv->vm_vram_base; ++ ++ if (memtile->flags & NOUVEAU_MEM_TILE) { ++ if (memtile->flags & NOUVEAU_MEM_TILE_ZETA) ++ tile = 0x00002800; ++ else ++ tile = 0x00007000; ++ } ++ ++ ret = nv50_mem_vm_bind_linear(dev, block->start + memtile->delta, ++ memtile->size, tile, offset); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c +new file mode 100644 +index 0000000..bc5cb41 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c +@@ -0,0 +1,176 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++int ++nouveau_notifier_init_channel(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int flags, ret; ++ ++ flags = NOUVEAU_MEM_FB | NOUVEAU_MEM_NOVM | NOUVEAU_MEM_MAPPED; ++ ++ chan->notifier_block = nouveau_mem_alloc(dev, 0, PAGE_SIZE, flags, ++ (struct drm_file *)-2); ++ if (!chan->notifier_block) ++ return -ENOMEM; ++ NV_DEBUG(dev, "Allocated notifier block in 0x%08x\n", ++ chan->notifier_block->flags); ++ ++ if (dev_priv->mm_enabled) { ++ ret = drm_addmap(dev, chan->notifier_block->start + ++ dev_priv->fb_phys, chan->notifier_block->size, ++ _DRM_FRAME_BUFFER, 0, &chan->notifier_map); ++ if (ret) { ++ nouveau_mem_free(dev, chan->notifier_block); ++ chan->notifier_block = NULL; ++ return ret; ++ } ++ } ++ ++ ret = nouveau_mem_init_heap(&chan->notifier_heap, ++ 0, chan->notifier_block->size); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void ++nouveau_notifier_takedown_channel(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ if (chan->notifier_block) { ++ nouveau_mem_free(dev, chan->notifier_block); ++ chan->notifier_block = NULL; ++ } ++ ++ nouveau_mem_takedown(&chan->notifier_heap); ++} ++ ++static void ++nouveau_notifier_gpuobj_dtor(struct drm_device *dev, ++ struct nouveau_gpuobj *gpuobj) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ if (gpuobj->priv) ++ nouveau_mem_free_block(gpuobj->priv); ++} ++ ++int ++nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, ++ int count, uint32_t *b_offset) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *nobj = NULL; ++ struct mem_block *mem; ++ uint32_t offset; ++ int target, ret; ++ ++ if (!chan->notifier_heap) { ++ NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n", ++ chan->id); ++ return -EINVAL; ++ } ++ ++ mem = nouveau_mem_alloc_block(chan->notifier_heap, count*32, 0, ++ (struct drm_file *)-2, 0); ++ if (!mem) { ++ NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); ++ return -ENOMEM; ++ } ++ mem->flags = NOUVEAU_MEM_NOTIFIER; ++ ++ offset = chan->notifier_block->start; ++ if (chan->notifier_block->flags & NOUVEAU_MEM_FB) { ++ target = NV_DMA_TARGET_VIDMEM; ++ } else ++ if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) { ++ if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA && ++ dev_priv->card_type < NV_50) { ++ ret = nouveau_sgdma_get_page(dev, offset, &offset); ++ if (ret) ++ return ret; ++ target = NV_DMA_TARGET_PCI; ++ } else { ++ target = NV_DMA_TARGET_AGP; ++ } ++ } else ++ if (chan->notifier_block->flags & NOUVEAU_MEM_PCI) { ++ target = NV_DMA_TARGET_PCI_NONLINEAR; ++ } else { ++ NV_ERROR(dev, "Bad DMA target, flags 0x%08x!\n", ++ chan->notifier_block->flags); ++ return -EINVAL; ++ } ++ offset += mem->start; ++ ++ if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ offset, mem->size, ++ NV_DMA_ACCESS_RW, target, &nobj))) { ++ nouveau_mem_free_block(mem); ++ NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret); ++ return ret; ++ } ++ nobj->dtor = nouveau_notifier_gpuobj_dtor; ++ nobj->priv = mem; ++ ++ if ((ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL))) { ++ nouveau_gpuobj_del(dev, &nobj); ++ nouveau_mem_free_block(mem); ++ NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret); ++ return ret; ++ } ++ ++ *b_offset = mem->start; ++ return 0; ++} ++ ++int ++nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_notifierobj_alloc *na = data; ++ struct nouveau_channel *chan; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); ++ ++ ret = nouveau_notifier_alloc(chan, na->handle, na->count, &na->offset); ++ if (ret) ++ return ret; ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c +new file mode 100644 +index 0000000..5fed5cb +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_object.c +@@ -0,0 +1,1236 @@ ++/* ++ * Copyright (C) 2006 Ben Skeggs. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++/* ++ * Authors: ++ * Ben Skeggs ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++/* NVidia uses context objects to drive drawing operations. ++ ++ Context objects can be selected into 8 subchannels in the FIFO, ++ and then used via DMA command buffers. ++ ++ A context object is referenced by a user defined handle (CARD32). The HW ++ looks up graphics objects in a hash table in the instance RAM. ++ ++ An entry in the hash table consists of 2 CARD32. The first CARD32 contains ++ the handle, the second one a bitfield, that contains the address of the ++ object in instance RAM. ++ ++ The format of the second CARD32 seems to be: ++ ++ NV4 to NV30: ++ ++ 15: 0 instance_addr >> 4 ++ 17:16 engine (here uses 1 = graphics) ++ 28:24 channel id (here uses 0) ++ 31 valid (use 1) ++ ++ NV40: ++ ++ 15: 0 instance_addr >> 4 (maybe 19-0) ++ 21:20 engine (here uses 1 = graphics) ++ I'm unsure about the other bits, but using 0 seems to work. ++ ++ The key into the hash table depends on the object handle and channel id and ++ is given as: ++*/ ++static uint32_t ++nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle) ++{ ++ struct drm_nouveau_private *dev_priv=dev->dev_private; ++ uint32_t hash = 0; ++ int i; ++ ++ NV_DEBUG(dev, "ch%d handle=0x%08x\n", channel, handle); ++ ++ for (i=32;i>0;i-=dev_priv->ramht_bits) { ++ hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1)); ++ handle >>= dev_priv->ramht_bits; ++ } ++ if (dev_priv->card_type < NV_50) ++ hash ^= channel << (dev_priv->ramht_bits - 4); ++ hash <<= 3; ++ ++ NV_DEBUG(dev, "hash=0x%08x\n", hash); ++ return hash; ++} ++ ++static int ++nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht, ++ uint32_t offset) ++{ ++ struct drm_nouveau_private *dev_priv=dev->dev_private; ++ uint32_t ctx = INSTANCE_RD(ramht, (offset + 4)/4); ++ ++ if (dev_priv->card_type < NV_40) ++ return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0); ++ return (ctx != 0); ++} ++ ++static int ++nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) ++{ ++ struct drm_nouveau_private *dev_priv=dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ struct nouveau_channel *chan = dev_priv->fifos[ref->channel]; ++ struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; ++ struct nouveau_gpuobj *gpuobj = ref->gpuobj; ++ uint32_t ctx, co, ho; ++ ++ if (!ramht) { ++ NV_ERROR(dev, "No hash table!\n"); ++ return -EINVAL; ++ } ++ ++ if (dev_priv->card_type < NV_40) { ++ ctx = NV_RAMHT_CONTEXT_VALID | (ref->instance >> 4) | ++ (ref->channel << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | ++ (gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT); ++ } else ++ if (dev_priv->card_type < NV_50) { ++ ctx = (ref->instance >> 4) | ++ (ref->channel << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | ++ (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); ++ } else { ++ ctx = (ref->instance >> 4) | ++ (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); ++ } ++ ++ instmem->prepare_access(dev, true); ++ co = ho = nouveau_ramht_hash_handle(dev, ref->channel, ref->handle); ++ do { ++ if (!nouveau_ramht_entry_valid(dev, ramht, co)) { ++ NV_DEBUG(dev, "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n", ++ ref->channel, co, ref->handle, ctx); ++ INSTANCE_WR(ramht, (co + 0)/4, ref->handle); ++ INSTANCE_WR(ramht, (co + 4)/4, ctx); ++ ++ list_add_tail(&ref->list, &chan->ramht_refs); ++ instmem->finish_access(dev); ++ return 0; ++ } ++ NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n", ++ ref->channel, co, INSTANCE_RD(ramht, co/4)); ++ ++ co += 8; ++ if (co >= dev_priv->ramht_size) ++ co = 0; ++ } while (co != ho); ++ instmem->finish_access(dev); ++ ++ NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", ref->channel); ++ return -ENOMEM; ++} ++ ++static void ++nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ struct nouveau_channel *chan = dev_priv->fifos[ref->channel]; ++ struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; ++ uint32_t co, ho; ++ ++ if (!ramht) { ++ NV_ERROR(dev, "No hash table!\n"); ++ return; ++ } ++ ++ instmem->prepare_access(dev, true); ++ co = ho = nouveau_ramht_hash_handle(dev, ref->channel, ref->handle); ++ do { ++ if (nouveau_ramht_entry_valid(dev, ramht, co) && ++ (ref->handle == INSTANCE_RD(ramht, (co/4)))) { ++ NV_DEBUG(dev, "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n", ++ ref->channel, co, ref->handle, ++ INSTANCE_RD(ramht, (co + 4))); ++ INSTANCE_WR(ramht, (co + 0)/4, 0x00000000); ++ INSTANCE_WR(ramht, (co + 4)/4, 0x00000000); ++ ++ list_del(&ref->list); ++ instmem->finish_access(dev); ++ return; ++ } ++ ++ co += 8; ++ if (co >= dev_priv->ramht_size) ++ co = 0; ++ } while (co != ho); ++ list_del(&ref->list); ++ instmem->finish_access(dev); ++ ++ NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", ++ ref->channel, ref->handle); ++} ++ ++int ++nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, ++ int size, int align, uint32_t flags, ++ struct nouveau_gpuobj **gpuobj_ret) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ struct nouveau_gpuobj *gpuobj; ++ struct mem_block *pramin = NULL; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d size=%d align=%d flags=0x%08x\n", ++ chan ? chan->id : -1, size, align, flags); ++ ++ if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL) ++ return -EINVAL; ++ ++ gpuobj = drm_calloc(1, sizeof(*gpuobj), DRM_MEM_DRIVER); ++ if (!gpuobj) ++ return -ENOMEM; ++ NV_DEBUG(dev, "gpuobj %p\n", gpuobj); ++ gpuobj->flags = flags; ++ gpuobj->im_channel = chan ? chan->id : -1; ++ ++ list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); ++ ++ /* Choose between global instmem heap, and per-channel private ++ * instmem heap. On ramin_heap) { ++ NV_DEBUG(dev, "private heap\n"); ++ pramin = chan->ramin_heap; ++ } else ++ if (dev_priv->card_type < NV_50) { ++ NV_DEBUG(dev, "global heap fallback\n"); ++ pramin = dev_priv->ramin_heap; ++ } ++ } else { ++ NV_DEBUG(dev, "global heap\n"); ++ pramin = dev_priv->ramin_heap; ++ } ++ ++ if (!pramin) { ++ NV_ERROR(dev, "No PRAMIN heap!\n"); ++ return -EINVAL; ++ } ++ ++ if (!chan && (ret = engine->instmem.populate(dev, gpuobj, &size))) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return ret; ++ } ++ ++ /* Allocate a chunk of the PRAMIN aperture */ ++ gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, ++ drm_order(align), ++ (struct drm_file *)-2, 0); ++ if (!gpuobj->im_pramin) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return -ENOMEM; ++ } ++ gpuobj->im_pramin->flags = NOUVEAU_MEM_INSTANCE; ++ ++ if (!chan && (ret = engine->instmem.bind(dev, gpuobj))) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return ret; ++ } ++ ++ if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { ++ int i; ++ ++ engine->instmem.prepare_access(dev, true); ++ for (i = 0; i < gpuobj->im_pramin->size; i += 4) ++ INSTANCE_WR(gpuobj, i/4, 0); ++ engine->instmem.finish_access(dev); ++ } ++ ++ *gpuobj_ret = gpuobj; ++ return 0; ++} ++ ++int ++nouveau_gpuobj_early_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ INIT_LIST_HEAD(&dev_priv->gpuobj_list); ++ ++ return 0; ++} ++ ++int ++nouveau_gpuobj_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (dev_priv->card_type < NV_50) { ++ if ((ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramht_offset, ++ ~0, dev_priv->ramht_size, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ALLOW_NO_REFS, ++ &dev_priv->ramht, NULL))) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void ++nouveau_gpuobj_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nouveau_gpuobj_del(dev, &dev_priv->ramht); ++} ++ ++void ++nouveau_gpuobj_late_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = NULL; ++ struct list_head *entry, *tmp; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) { ++ gpuobj = list_entry(entry, struct nouveau_gpuobj, list); ++ ++ NV_ERROR(dev, "gpuobj %p still exists at takedown, refs=%d\n", ++ gpuobj, gpuobj->refcount); ++ gpuobj->refcount = 0; ++ nouveau_gpuobj_del(dev, &gpuobj); ++ } ++} ++ ++int ++nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ struct nouveau_gpuobj *gpuobj; ++ int i; ++ ++ NV_DEBUG(dev, "gpuobj %p\n", pgpuobj ? *pgpuobj : NULL); ++ ++ if (!dev_priv || !pgpuobj || !(*pgpuobj)) ++ return -EINVAL; ++ gpuobj = *pgpuobj; ++ ++ if (gpuobj->refcount != 0) { ++ NV_ERROR(dev, "gpuobj refcount is %d\n", gpuobj->refcount); ++ return -EINVAL; ++ } ++ ++ if (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE) { ++ engine->instmem.prepare_access(dev, true); ++ for (i = 0; i < gpuobj->im_pramin->size; i += 4) ++ INSTANCE_WR(gpuobj, i/4, 0); ++ engine->instmem.finish_access(dev); ++ } ++ ++ if (gpuobj->dtor) ++ gpuobj->dtor(dev, gpuobj); ++ ++ if (gpuobj->im_backing) { ++ if (gpuobj->flags & NVOBJ_FLAG_FAKE) ++ drm_free(gpuobj->im_backing, ++ sizeof(*gpuobj->im_backing), DRM_MEM_DRIVER); ++ else ++ engine->instmem.clear(dev, gpuobj); ++ } ++ ++ if (gpuobj->im_pramin) { ++ if (gpuobj->flags & NVOBJ_FLAG_FAKE) ++ drm_free(gpuobj->im_pramin, sizeof(*gpuobj->im_pramin), ++ DRM_MEM_DRIVER); ++ else ++ nouveau_mem_free_block(gpuobj->im_pramin); ++ } ++ ++ list_del(&gpuobj->list); ++ ++ *pgpuobj = NULL; ++ drm_free(gpuobj, sizeof(*gpuobj), DRM_MEM_DRIVER); ++ return 0; ++} ++ ++static int ++nouveau_gpuobj_instance_get(struct drm_device *dev, ++ struct nouveau_channel *chan, ++ struct nouveau_gpuobj *gpuobj, uint32_t *inst) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *cpramin; ++ ++ /* card_type < NV_50) { ++ *inst = gpuobj->im_pramin->start; ++ return 0; ++ } ++ ++ if (chan && gpuobj->im_channel != chan->id) { ++ NV_ERROR(dev, "Channel mismatch: obj %d, ref %d\n", ++ gpuobj->im_channel, chan->id); ++ return -EINVAL; ++ } ++ ++ /* NV50 channel-local instance */ ++ if (chan > 0) { ++ cpramin = chan->ramin->gpuobj; ++ *inst = gpuobj->im_pramin->start - cpramin->im_pramin->start; ++ return 0; ++ } ++ ++ /* NV50 global (VRAM) instance */ ++ if (gpuobj->im_channel < 0) { ++ /* ...from global heap */ ++ if (!gpuobj->im_backing) { ++ NV_ERROR(dev, "AII, no VRAM backing gpuobj\n"); ++ return -EINVAL; ++ } ++ *inst = gpuobj->im_backing->start; ++ return 0; ++ } else { ++ /* ...from local heap */ ++ cpramin = dev_priv->fifos[gpuobj->im_channel]->ramin->gpuobj; ++ *inst = cpramin->im_backing->start + ++ (gpuobj->im_pramin->start - cpramin->im_pramin->start); ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++int ++nouveau_gpuobj_ref_add(struct drm_device *dev, struct nouveau_channel *chan, ++ uint32_t handle, struct nouveau_gpuobj *gpuobj, ++ struct nouveau_gpuobj_ref **ref_ret) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj_ref *ref; ++ uint32_t instance; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d h=0x%08x gpuobj=%p\n", ++ chan ? chan->id : -1, handle, gpuobj); ++ ++ if (!dev_priv || !gpuobj || (ref_ret && *ref_ret != NULL)) ++ return -EINVAL; ++ ++ if (!chan && !ref_ret) ++ return -EINVAL; ++ ++ ret = nouveau_gpuobj_instance_get(dev, chan, gpuobj, &instance); ++ if (ret) ++ return ret; ++ ++ ref = drm_calloc(1, sizeof(*ref), DRM_MEM_DRIVER); ++ if (!ref) ++ return -ENOMEM; ++ ref->gpuobj = gpuobj; ++ ref->channel = chan ? chan->id : -1; ++ ref->instance = instance; ++ ++ if (!ref_ret) { ++ ref->handle = handle; ++ ++ ret = nouveau_ramht_insert(dev, ref); ++ if (ret) { ++ drm_free(ref, sizeof(*ref), DRM_MEM_DRIVER); ++ return ret; ++ } ++ } else { ++ ref->handle = ~0; ++ *ref_ret = ref; ++ } ++ ++ ref->gpuobj->refcount++; ++ return 0; ++} ++ ++int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **pref) ++{ ++ struct nouveau_gpuobj_ref *ref; ++ ++ NV_DEBUG(dev, "ref %p\n", pref ? *pref : NULL); ++ ++ if (!dev || !pref || *pref == NULL) ++ return -EINVAL; ++ ref = *pref; ++ ++ if (ref->handle != ~0) ++ nouveau_ramht_remove(dev, ref); ++ ++ if (ref->gpuobj) { ++ ref->gpuobj->refcount--; ++ ++ if (ref->gpuobj->refcount == 0) { ++ if (!(ref->gpuobj->flags & NVOBJ_FLAG_ALLOW_NO_REFS)) ++ nouveau_gpuobj_del(dev, &ref->gpuobj); ++ } ++ } ++ ++ *pref = NULL; ++ drm_free(ref, sizeof(ref), DRM_MEM_DRIVER); ++ return 0; ++} ++ ++int ++nouveau_gpuobj_new_ref(struct drm_device *dev, ++ struct nouveau_channel *oc, struct nouveau_channel *rc, ++ uint32_t handle, int size, int align, uint32_t flags, ++ struct nouveau_gpuobj_ref **ref) ++{ ++ struct nouveau_gpuobj *gpuobj = NULL; ++ int ret; ++ ++ if ((ret = nouveau_gpuobj_new(dev, oc, size, align, flags, &gpuobj))) ++ return ret; ++ ++ if ((ret = nouveau_gpuobj_ref_add(dev, rc, handle, gpuobj, ref))) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int ++nouveau_gpuobj_ref_find(struct nouveau_channel *chan, uint32_t handle, ++ struct nouveau_gpuobj_ref **ref_ret) ++{ ++ struct nouveau_gpuobj_ref *ref; ++ struct list_head *entry, *tmp; ++ ++ list_for_each_safe(entry, tmp, &chan->ramht_refs) { ++ ref = list_entry(entry, struct nouveau_gpuobj_ref, list); ++ ++ if (ref->handle == handle) { ++ if (ref_ret) ++ *ref_ret = ref; ++ return 0; ++ } ++ } ++ ++ return -EINVAL; ++} ++ ++int ++nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset, ++ uint32_t b_offset, uint32_t size, ++ uint32_t flags, struct nouveau_gpuobj **pgpuobj, ++ struct nouveau_gpuobj_ref **pref) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = NULL; ++ int i; ++ ++ NV_DEBUG(dev, ++ "p_offset=0x%08x b_offset=0x%08x size=0x%08x flags=0x%08x\n", ++ p_offset, b_offset, size, flags); ++ ++ gpuobj = drm_calloc(1, sizeof(*gpuobj), DRM_MEM_DRIVER); ++ if (!gpuobj) ++ return -ENOMEM; ++ NV_DEBUG(dev, "gpuobj %p\n", gpuobj); ++ gpuobj->im_channel = -1; ++ gpuobj->flags = flags | NVOBJ_FLAG_FAKE; ++ ++ list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); ++ ++ if (p_offset != ~0) { ++ gpuobj->im_pramin = drm_calloc(1, sizeof(struct mem_block), ++ DRM_MEM_DRIVER); ++ if (!gpuobj->im_pramin) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return -ENOMEM; ++ } ++ gpuobj->im_pramin->start = p_offset; ++ gpuobj->im_pramin->size = size; ++ } ++ ++ if (b_offset != ~0) { ++ gpuobj->im_backing = drm_calloc(1, sizeof(*gpuobj->im_backing), ++ DRM_MEM_DRIVER); ++ if (!gpuobj->im_backing) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return -ENOMEM; ++ } ++ gpuobj->im_backing->start = b_offset; ++ gpuobj->im_backing->size = size; ++ } ++ ++ if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i = 0; i < gpuobj->im_pramin->size; i += 4) ++ INSTANCE_WR(gpuobj, i/4, 0); ++ dev_priv->engine.instmem.finish_access(dev); ++ } ++ ++ if (pref) { ++ if ((i = nouveau_gpuobj_ref_add(dev, NULL, 0, gpuobj, pref))) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return i; ++ } ++ } ++ ++ if (pgpuobj) ++ *pgpuobj = gpuobj; ++ return 0; ++} ++ ++ ++static int ++nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /*XXX: dodgy hack for now */ ++ if (dev_priv->card_type >= NV_50) ++ return 24; ++ if (dev_priv->card_type >= NV_40) ++ return 32; ++ return 16; ++} ++ ++/* ++ DMA objects are used to reference a piece of memory in the ++ framebuffer, PCI or AGP address space. Each object is 16 bytes big ++ and looks as follows: ++ ++ entry[0] ++ 11:0 class (seems like I can always use 0 here) ++ 12 page table present? ++ 13 page entry linear? ++ 15:14 access: 0 rw, 1 ro, 2 wo ++ 17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP ++ 31:20 dma adjust (bits 0-11 of the address) ++ entry[1] ++ dma limit (size of transfer) ++ entry[X] ++ 1 0 readonly, 1 readwrite ++ 31:12 dma frame address of the page (bits 12-31 of the address) ++ entry[N] ++ page table terminator, same value as the first pte, as does nvidia ++ rivatv uses 0xffffffff ++ ++ Non linear page tables need a list of frame addresses afterwards, ++ the rivatv project has some info on this. ++ ++ The method below creates a DMA object in instance RAM and returns a handle ++ to it that can be used to set up context objects. ++*/ ++int ++nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, ++ uint64_t offset, uint64_t size, int access, ++ int target, struct nouveau_gpuobj **gpuobj) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ int ret; ++ uint32_t is_scatter_gather = 0; ++ ++ /* Total number of pages covered by the request. ++ */ ++ const unsigned int page_count = (size + PAGE_SIZE - 1) / PAGE_SIZE; ++ ++ ++ NV_DEBUG(dev, "ch%d class=0x%04x offset=0x%llx size=0x%llx\n", ++ chan->id, class, offset, size); ++ NV_DEBUG(dev, "access=%d target=%d\n", access, target); ++ ++ switch (target) { ++ case NV_DMA_TARGET_AGP: ++ offset += dev_priv->gart_info.aper_base; ++ break; ++ case NV_DMA_TARGET_PCI_NONLINEAR: ++ /*assume the "offset" is a virtual memory address*/ ++ is_scatter_gather = 1; ++ /*put back the right value*/ ++ target = NV_DMA_TARGET_PCI; ++ break; ++ default: ++ break; ++ } ++ ++ ret = nouveau_gpuobj_new(dev, chan, ++ is_scatter_gather ? ((page_count << 2) + 12) : nouveau_gpuobj_class_instmem_size(dev, class), ++ 16, ++ NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, ++ gpuobj); ++ if (ret) { ++ NV_ERROR(dev, "Error creating gpuobj: %d\n", ret); ++ return ret; ++ } ++ ++ instmem->prepare_access(dev, true); ++ ++ if (dev_priv->card_type < NV_50) { ++ uint32_t frame, adjust, pte_flags = 0; ++ adjust = offset & 0x00000fff; ++ if (access != NV_DMA_ACCESS_RO) ++ pte_flags |= (1<<1); ++ ++ if ( ! is_scatter_gather ) ++ { ++ frame = offset & ~0x00000fff; ++ ++ INSTANCE_WR(*gpuobj, 0, ((1<<12) | (1<<13) | ++ (adjust << 20) | ++ (access << 14) | ++ (target << 16) | ++ class)); ++ INSTANCE_WR(*gpuobj, 1, size - 1); ++ INSTANCE_WR(*gpuobj, 2, frame | pte_flags); ++ INSTANCE_WR(*gpuobj, 3, frame | pte_flags); ++ } ++ else ++ { ++ /* Intial page entry in the scatter-gather area that ++ * corresponds to the base offset ++ */ ++ unsigned int idx = offset / PAGE_SIZE; ++ ++ uint32_t instance_offset; ++ unsigned int i; ++ ++ if ((idx + page_count) > dev->sg->pages) { ++ NV_ERROR(dev, "Requested page range exceedes " ++ "allocated scatter-gather range!"); ++ return -E2BIG; ++ } ++ ++ NV_DEBUG(dev, "Creating PCI DMA object using virtual zone starting at %#llx, size %d\n", offset, (uint32_t)size); ++ INSTANCE_WR(*gpuobj, 0, ((1<<12) | (0<<13) | ++ (adjust << 20) | ++ (access << 14) | ++ (target << 16) | ++ class)); ++ INSTANCE_WR(*gpuobj, 1, (uint32_t) size-1); ++ ++ ++ /*write starting at the third dword*/ ++ instance_offset = 2; ++ ++ /*for each PAGE, get its bus address, fill in the page table entry, and advance*/ ++ for (i = 0; i < page_count; i++) { ++ if (dev->sg->busaddr[idx] == 0) { ++ dev->sg->busaddr[idx] = ++ pci_map_page(dev->pdev, ++ dev->sg->pagelist[idx], ++ 0, ++ PAGE_SIZE, ++ DMA_BIDIRECTIONAL); ++ ++ /* Not a 100% sure this is the right kdev in all cases. */ ++ if (dma_mapping_error(&dev->primary->kdev, dev->sg->busaddr[idx])) { ++ instmem->finish_access(dev); ++ return -ENOMEM; ++ } ++ } ++ ++ frame = (uint32_t) dev->sg->busaddr[idx]; ++ INSTANCE_WR(*gpuobj, instance_offset, ++ frame | pte_flags); ++ ++ idx++; ++ instance_offset ++; ++ } ++ } ++ } else { ++ uint32_t flags0, flags5; ++ ++ if (target == NV_DMA_TARGET_VIDMEM) { ++ flags0 = 0x00190000; ++ flags5 = 0x00010000; ++ } else { ++ flags0 = 0x7fc00000; ++ flags5 = 0x00080000; ++ } ++ ++ INSTANCE_WR(*gpuobj, 0, flags0 | class); ++ INSTANCE_WR(*gpuobj, 1, offset + size - 1); ++ INSTANCE_WR(*gpuobj, 2, offset); ++ INSTANCE_WR(*gpuobj, 5, flags5); ++ } ++ ++ instmem->finish_access(dev); ++ ++ (*gpuobj)->engine = NVOBJ_ENGINE_SW; ++ (*gpuobj)->class = class; ++ return 0; ++} ++ ++int ++nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan, ++ uint64_t offset, uint64_t size, int access, ++ struct nouveau_gpuobj **gpuobj, ++ uint32_t *o_ret) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ if (dev_priv->gart_info.type == NOUVEAU_GART_AGP || ++ (dev_priv->card_type >= NV_50 && ++ dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) { ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ offset, size, access, ++ NV_DMA_TARGET_AGP, gpuobj); ++ if (o_ret) ++ *o_ret = 0; ++ } else ++ if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { ++ *gpuobj = dev_priv->gart_info.sg_ctxdma; ++ if (offset & ~0xffffffffULL) { ++ NV_ERROR(dev, "obj offset exceeds 32-bits\n"); ++ return -EINVAL; ++ } ++ if (o_ret) ++ *o_ret = (uint32_t)offset; ++ ret = (*gpuobj != NULL) ? 0 : -EINVAL; ++ } else { ++ NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type); ++ return -EINVAL; ++ } ++ ++ return ret; ++} ++ ++/* Context objects in the instance RAM have the following structure. ++ * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes. ++ ++ NV4 - NV30: ++ ++ entry[0] ++ 11:0 class ++ 12 chroma key enable ++ 13 user clip enable ++ 14 swizzle enable ++ 17:15 patch config: ++ scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre ++ 18 synchronize enable ++ 19 endian: 1 big, 0 little ++ 21:20 dither mode ++ 23 single step enable ++ 24 patch status: 0 invalid, 1 valid ++ 25 context_surface 0: 1 valid ++ 26 context surface 1: 1 valid ++ 27 context pattern: 1 valid ++ 28 context rop: 1 valid ++ 29,30 context beta, beta4 ++ entry[1] ++ 7:0 mono format ++ 15:8 color format ++ 31:16 notify instance address ++ entry[2] ++ 15:0 dma 0 instance address ++ 31:16 dma 1 instance address ++ entry[3] ++ dma method traps ++ ++ NV40: ++ No idea what the exact format is. Here's what can be deducted: ++ ++ entry[0]: ++ 11:0 class (maybe uses more bits here?) ++ 17 user clip enable ++ 21:19 patch config ++ 25 patch status valid ? ++ entry[1]: ++ 15:0 DMA notifier (maybe 20:0) ++ entry[2]: ++ 15:0 DMA 0 instance (maybe 20:0) ++ 24 big endian ++ entry[3]: ++ 15:0 DMA 1 instance (maybe 20:0) ++ entry[4]: ++ entry[5]: ++ set to 0? ++*/ ++int ++nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, ++ struct nouveau_gpuobj **gpuobj) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); ++ ++ ret = nouveau_gpuobj_new(dev, chan, ++ nouveau_gpuobj_class_instmem_size(dev, class), ++ 16, ++ NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, ++ gpuobj); ++ if (ret) { ++ NV_ERROR(dev, "Error creating gpuobj: %d\n", ret); ++ return ret; ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ if (dev_priv->card_type >= NV_50) { ++ INSTANCE_WR(*gpuobj, 0, class); ++ INSTANCE_WR(*gpuobj, 5, 0x00010000); ++ } else { ++ switch (class) { ++ case NV_CLASS_NULL: ++ INSTANCE_WR(*gpuobj, 0, 0x00001030); ++ INSTANCE_WR(*gpuobj, 1, 0xFFFFFFFF); ++ break; ++ default: ++ if (dev_priv->card_type >= NV_40) { ++ INSTANCE_WR(*gpuobj, 0, class); ++#ifdef __BIG_ENDIAN ++ INSTANCE_WR(*gpuobj, 2, 0x01000000); ++#endif ++ } else { ++#ifdef __BIG_ENDIAN ++ INSTANCE_WR(*gpuobj, 0, class | 0x00080000); ++#else ++ INSTANCE_WR(*gpuobj, 0, class); ++#endif ++ } ++ } ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ (*gpuobj)->engine = NVOBJ_ENGINE_GR; ++ (*gpuobj)->class = class; ++ return 0; ++} ++ ++static int ++nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *pramin = NULL; ++ int size, base, ret; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ /* Base amount for object storage (4KiB enough?) */ ++ size = 0x1000; ++ base = 0; ++ ++ /* PGRAPH context */ ++ ++ if (dev_priv->card_type == NV_50) { ++ /* Various fixed table thingos */ ++ size += 0x1400; /* mostly unknown stuff */ ++ size += 0x4000; /* vm pd */ ++ base = 0x6000; ++ /* RAMHT, not sure about setting size yet, 32KiB to be safe */ ++ size += 0x8000; ++ /* RAMFC */ ++ size += 0x1000; ++ /* PGRAPH context */ ++ size += 0x70000; ++ } ++ ++ NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n", ++ chan->id, size, base); ++ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0, ++ &chan->ramin); ++ if (ret) { ++ NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret); ++ return ret; ++ } ++ pramin = chan->ramin->gpuobj; ++ ++ ret = nouveau_mem_init_heap(&chan->ramin_heap, ++ pramin->im_pramin->start + base, size); ++ if (ret) { ++ NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); ++ nouveau_gpuobj_ref_del(dev, &chan->ramin); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int ++nouveau_gpuobj_channel_init(struct nouveau_channel *chan, ++ uint32_t vram_h, uint32_t tt_h) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ struct nouveau_gpuobj *vram = NULL, *tt = NULL; ++ int ret, i; ++ ++ INIT_LIST_HEAD(&chan->ramht_refs); ++ ++ NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); ++ ++ /* Reserve a block of PRAMIN for the channel ++ *XXX: maybe on card_type == NV_50) { ++ ret = nouveau_gpuobj_channel_init_pramin(chan); ++ if (ret) { ++ NV_ERROR(dev, "init pramin\n"); ++ return ret; ++ } ++ } ++ ++ /* NV50 VM ++ * - Allocate per-channel page-directory ++ * - Map GART and VRAM into the channel's address space at the ++ * locations determined during init. ++ */ ++ if (dev_priv->card_type >= NV_50) { ++ uint32_t vm_offset, pde; ++ ++ instmem->prepare_access(dev, true); ++ ++ vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200; ++ vm_offset += chan->ramin->gpuobj->im_pramin->start; ++ if ((ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000, ++ 0, &chan->vm_pd, NULL))) ++ return ret; ++ for (i=0; i<0x4000; i+=8) { ++ INSTANCE_WR(chan->vm_pd, (i+0)/4, 0x00000000); ++ INSTANCE_WR(chan->vm_pd, (i+4)/4, 0xdeadcafe); ++ } ++ ++ pde = (dev_priv->vm_gart_base / (512*1024*1024)) * 2; ++ ret = nouveau_gpuobj_ref_add(dev, NULL, 0, ++ dev_priv->gart_info.sg_ctxdma, ++ &chan->vm_gart_pt); ++ if (ret) { ++ instmem->finish_access(dev); ++ return ret; ++ } ++ INSTANCE_WR(chan->vm_pd, pde++, ++ chan->vm_gart_pt->instance | 0x03); ++ INSTANCE_WR(chan->vm_pd, pde++, 0x00000000); ++ ++ chan->vm_vram_pt = ++ drm_calloc(dev_priv->vm_vram_pt_nr, ++ sizeof(struct nouveau_gpuobj_ref *), ++ DRM_MEM_DRIVER); ++ if (!chan->vm_vram_pt) { ++ instmem->finish_access(dev); ++ return -ENOMEM; ++ } ++ ++ pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 2; ++ for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { ++ ret = nouveau_gpuobj_ref_add(dev, NULL, 0, ++ dev_priv->vm_vram_pt[i], ++ &chan->vm_vram_pt[i]); ++ if (ret) { ++ instmem->finish_access(dev); ++ return ret; ++ } ++ ++ INSTANCE_WR(chan->vm_pd, pde++, ++ chan->vm_vram_pt[i]->instance | 0x61); ++ INSTANCE_WR(chan->vm_pd, pde++, 0x00000000); ++ } ++ ++ instmem->finish_access(dev); ++ } ++ ++ /* RAMHT */ ++ if (dev_priv->card_type < NV_50) { ++ ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->ramht, ++ &chan->ramht); ++ if (ret) ++ return ret; ++ } else { ++ ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, ++ 0x8000, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &chan->ramht); ++ if (ret) ++ return ret; ++ } ++ ++ /* VRAM ctxdma */ ++ if (dev_priv->card_type >= NV_50) { ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ 0, dev_priv->vm_end, ++ NV_DMA_ACCESS_RW, ++ NV_DMA_TARGET_AGP, &vram); ++ if (ret) { ++ NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); ++ return ret; ++ } ++ } else ++ if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ 0, dev_priv->fb_available_size, ++ NV_DMA_ACCESS_RW, ++ NV_DMA_TARGET_VIDMEM, &vram))) { ++ NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); ++ return ret; ++ } ++ ++ if ((ret = nouveau_gpuobj_ref_add(dev, chan, vram_h, vram, NULL))) { ++ NV_ERROR(dev, "Error referencing VRAM ctxdma: %d\n", ret); ++ return ret; ++ } ++ ++ /* TT memory ctxdma */ ++ if (dev_priv->card_type >= NV_50) { ++ tt = vram; ++ } else ++ if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { ++ ret = nouveau_gpuobj_gart_dma_new(chan, 0, ++ dev_priv->gart_info.aper_size, ++ NV_DMA_ACCESS_RW, &tt, NULL); ++ } else ++ if (dev_priv->pci_heap) { ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ 0, dev->sg->pages * PAGE_SIZE, ++ NV_DMA_ACCESS_RW, ++ NV_DMA_TARGET_PCI_NONLINEAR, &tt); ++ } else { ++ NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type); ++ ret = -EINVAL; ++ } ++ ++ if (ret) { ++ NV_ERROR(dev, "Error creating TT ctxdma: %d\n", ret); ++ return ret; ++ } ++ ++ ret = nouveau_gpuobj_ref_add(dev, chan, tt_h, tt, NULL); ++ if (ret) { ++ NV_ERROR(dev, "Error referencing TT ctxdma: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void ++nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ struct drm_device *dev = chan->dev; ++ struct list_head *entry, *tmp; ++ struct nouveau_gpuobj_ref *ref; ++ int i; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ if (!chan->ramht_refs.next) ++ return; ++ ++ list_for_each_safe(entry, tmp, &chan->ramht_refs) { ++ ref = list_entry(entry, struct nouveau_gpuobj_ref, list); ++ ++ nouveau_gpuobj_ref_del(dev, &ref); ++ } ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramht); ++ ++ nouveau_gpuobj_del(dev, &chan->vm_pd); ++ nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt); ++ if (chan->vm_vram_pt) { ++ for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) ++ nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]); ++ drm_free(chan->vm_vram_pt, dev_priv->vm_vram_pt_nr * ++ sizeof(struct nouveau_gpuobj_ref *), DRM_MEM_DRIVER); ++ } ++ ++ if (chan->ramin_heap) ++ nouveau_mem_takedown(&chan->ramin_heap); ++ if (chan->ramin) ++ nouveau_gpuobj_ref_del(dev, &chan->ramin); ++ ++} ++ ++int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct nouveau_channel *chan; ++ struct drm_nouveau_grobj_alloc *init = data; ++ struct nouveau_gpuobj *gr = NULL; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan); ++ ++ //FIXME: check args, only allow trusted objects to be created ++ ++ if (init->handle == ~0) ++ return -EINVAL; ++ ++ if (nouveau_gpuobj_ref_find(chan, init->handle, NULL) == 0) ++ return -EEXIST; ++ ++ ret = nouveau_gpuobj_gr_new(chan, init->class, &gr); ++ if (ret) { ++ NV_ERROR(dev, "Error creating gr object: %d (%d/0x%08x)\n", ++ ret, init->channel, init->handle); ++ return ret; ++ } ++ ++ if ((ret = nouveau_gpuobj_ref_add(dev, chan, init->handle, gr, NULL))) { ++ NV_ERROR(dev, "Error referencing gr object: %d (%d/0x%08x\n)", ++ ret, init->channel, init->handle); ++ nouveau_gpuobj_del(dev, &gr); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gpuobj_free *objfree = data; ++ struct nouveau_gpuobj_ref *ref; ++ struct nouveau_channel *chan; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan); ++ ++ if ((ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref))) ++ return ret; ++ nouveau_gpuobj_ref_del(dev, &ref); ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h +new file mode 100644 +index 0000000..44337e6 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_reg.h +@@ -0,0 +1,835 @@ ++ ++ ++#define NV03_BOOT_0 0x00100000 ++# define NV03_BOOT_0_RAM_AMOUNT 0x00000003 ++# define NV03_BOOT_0_RAM_AMOUNT_8MB 0x00000000 ++# define NV03_BOOT_0_RAM_AMOUNT_2MB 0x00000001 ++# define NV03_BOOT_0_RAM_AMOUNT_4MB 0x00000002 ++# define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM 0x00000003 ++# define NV04_BOOT_0_RAM_AMOUNT_32MB 0x00000000 ++# define NV04_BOOT_0_RAM_AMOUNT_4MB 0x00000001 ++# define NV04_BOOT_0_RAM_AMOUNT_8MB 0x00000002 ++# define NV04_BOOT_0_RAM_AMOUNT_16MB 0x00000003 ++ ++#define NV04_FIFO_DATA 0x0010020c ++# define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 ++# define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 ++ ++#define NV_RAMIN 0x00700000 ++ ++#define NV_RAMHT_HANDLE_OFFSET 0 ++#define NV_RAMHT_CONTEXT_OFFSET 4 ++# define NV_RAMHT_CONTEXT_VALID (1<<31) ++# define NV_RAMHT_CONTEXT_CHANNEL_SHIFT 24 ++# define NV_RAMHT_CONTEXT_ENGINE_SHIFT 16 ++# define NV_RAMHT_CONTEXT_ENGINE_SOFTWARE 0 ++# define NV_RAMHT_CONTEXT_ENGINE_GRAPHICS 1 ++# define NV_RAMHT_CONTEXT_INSTANCE_SHIFT 0 ++# define NV40_RAMHT_CONTEXT_CHANNEL_SHIFT 23 ++# define NV40_RAMHT_CONTEXT_ENGINE_SHIFT 20 ++# define NV40_RAMHT_CONTEXT_INSTANCE_SHIFT 0 ++ ++/* DMA object defines */ ++#define NV_DMA_ACCESS_RW 0 ++#define NV_DMA_ACCESS_RO 1 ++#define NV_DMA_ACCESS_WO 2 ++#define NV_DMA_TARGET_VIDMEM 0 ++#define NV_DMA_TARGET_PCI 2 ++#define NV_DMA_TARGET_AGP 3 ++/* The following is not a real value used by the card, it's changed by ++ * nouveau_object_dma_create */ ++#define NV_DMA_TARGET_PCI_NONLINEAR 8 ++ ++/* Some object classes we care about in the drm */ ++#define NV_CLASS_DMA_FROM_MEMORY 0x00000002 ++#define NV_CLASS_DMA_TO_MEMORY 0x00000003 ++#define NV_CLASS_NULL 0x00000030 ++#define NV_CLASS_DMA_IN_MEMORY 0x0000003D ++ ++#define NV03_USER(i) (0x00800000+(i*NV03_USER_SIZE)) ++#define NV03_USER__SIZE 16 ++#define NV10_USER__SIZE 32 ++#define NV03_USER_SIZE 0x00010000 ++#define NV03_USER_DMA_PUT(i) (0x00800040+(i*NV03_USER_SIZE)) ++#define NV03_USER_DMA_PUT__SIZE 16 ++#define NV10_USER_DMA_PUT__SIZE 32 ++#define NV03_USER_DMA_GET(i) (0x00800044+(i*NV03_USER_SIZE)) ++#define NV03_USER_DMA_GET__SIZE 16 ++#define NV10_USER_DMA_GET__SIZE 32 ++#define NV03_USER_REF_CNT(i) (0x00800048+(i*NV03_USER_SIZE)) ++#define NV03_USER_REF_CNT__SIZE 16 ++#define NV10_USER_REF_CNT__SIZE 32 ++ ++#define NV40_USER(i) (0x00c00000+(i*NV40_USER_SIZE)) ++#define NV40_USER_SIZE 0x00001000 ++#define NV40_USER_DMA_PUT(i) (0x00c00040+(i*NV40_USER_SIZE)) ++#define NV40_USER_DMA_PUT__SIZE 32 ++#define NV40_USER_DMA_GET(i) (0x00c00044+(i*NV40_USER_SIZE)) ++#define NV40_USER_DMA_GET__SIZE 32 ++#define NV40_USER_REF_CNT(i) (0x00c00048+(i*NV40_USER_SIZE)) ++#define NV40_USER_REF_CNT__SIZE 32 ++ ++#define NV50_USER(i) (0x00c00000+(i*NV50_USER_SIZE)) ++#define NV50_USER_SIZE 0x00002000 ++#define NV50_USER_DMA_PUT(i) (0x00c00040+(i*NV50_USER_SIZE)) ++#define NV50_USER_DMA_PUT__SIZE 128 ++#define NV50_USER_DMA_GET(i) (0x00c00044+(i*NV50_USER_SIZE)) ++#define NV50_USER_DMA_GET__SIZE 128 ++/*XXX: I don't think this actually exists.. */ ++#define NV50_USER_REF_CNT(i) (0x00c00048+(i*NV50_USER_SIZE)) ++#define NV50_USER_REF_CNT__SIZE 128 ++ ++#define NV03_FIFO_SIZE 0x8000UL ++ ++#define NV03_PMC_BOOT_0 0x00000000 ++#define NV03_PMC_BOOT_1 0x00000004 ++#define NV03_PMC_INTR_0 0x00000100 ++# define NV_PMC_INTR_0_PFIFO_PENDING (1<< 8) ++# define NV_PMC_INTR_0_PGRAPH_PENDING (1<<12) ++# define NV_PMC_INTR_0_NV50_I2C_PENDING (1<<21) ++# define NV_PMC_INTR_0_CRTC0_PENDING (1<<24) ++# define NV_PMC_INTR_0_CRTC1_PENDING (1<<25) ++# define NV_PMC_INTR_0_NV50_DISPLAY_PENDING (1<<26) ++# define NV_PMC_INTR_0_CRTCn_PENDING (3<<24) ++#define NV03_PMC_INTR_EN_0 0x00000140 ++# define NV_PMC_INTR_EN_0_MASTER_ENABLE (1<< 0) ++#define NV03_PMC_ENABLE 0x00000200 ++# define NV_PMC_ENABLE_PFIFO (1<< 8) ++# define NV_PMC_ENABLE_PGRAPH (1<<12) ++/* Disabling the below bit breaks newer (G7X only?) mobile chipsets, ++ * the card will hang early on in the X init process. ++ */ ++# define NV_PMC_ENABLE_UNK13 (1<<13) ++#define NV40_PMC_BACKLIGHT 0x000015f0 ++# define NV40_PMC_BACKLIGHT_MASK 0x001f0000 ++#define NV40_PMC_1700 0x00001700 ++#define NV40_PMC_1704 0x00001704 ++#define NV40_PMC_1708 0x00001708 ++#define NV40_PMC_170C 0x0000170C ++ ++/* probably PMC ? */ ++#define NV50_PUNK_BAR0_PRAMIN 0x00001700 ++#define NV50_PUNK_BAR_CFG_BASE 0x00001704 ++#define NV50_PUNK_BAR_CFG_BASE_VALID (1<<30) ++#define NV50_PUNK_BAR1_CTXDMA 0x00001708 ++#define NV50_PUNK_BAR1_CTXDMA_VALID (1<<31) ++#define NV50_PUNK_BAR3_CTXDMA 0x0000170C ++#define NV50_PUNK_BAR3_CTXDMA_VALID (1<<31) ++#define NV50_PUNK_UNK1710 0x00001710 ++ ++#define NV04_PBUS_PCI_NV_1 0x00001804 ++#define NV04_PBUS_PCI_NV_19 0x0000184C ++#define NV04_PBUS_PCI_NV_20 0x00001850 ++# define NV04_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED (0 << 0) ++# define NV04_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED (1 << 0) ++ ++#define NV04_PTIMER_INTR_0 0x00009100 ++#define NV04_PTIMER_INTR_EN_0 0x00009140 ++#define NV04_PTIMER_NUMERATOR 0x00009200 ++#define NV04_PTIMER_DENOMINATOR 0x00009210 ++#define NV04_PTIMER_TIME_0 0x00009400 ++#define NV04_PTIMER_TIME_1 0x00009410 ++#define NV04_PTIMER_ALARM_0 0x00009420 ++ ++#define NV04_PFB_CFG0 0x00100200 ++#define NV04_PFB_CFG1 0x00100204 ++#define NV40_PFB_020C 0x0010020C ++#define NV10_PFB_TILE(i) (0x00100240 + (i*16)) ++#define NV10_PFB_TILE__SIZE 8 ++#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) ++#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) ++#define NV10_PFB_TSTATUS(i) (0x0010024C + (i*16)) ++#define NV10_PFB_CLOSE_PAGE2 0x0010033C ++#define NV40_PFB_TILE(i) (0x00100600 + (i*16)) ++#define NV40_PFB_TILE__SIZE_0 12 ++#define NV40_PFB_TILE__SIZE_1 15 ++#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) ++#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) ++#define NV40_PFB_TSTATUS(i) (0x0010060C + (i*16)) ++#define NV40_PFB_UNK_800 0x00100800 ++ ++#define NV04_PGRAPH_DEBUG_0 0x00400080 ++#define NV04_PGRAPH_DEBUG_1 0x00400084 ++#define NV04_PGRAPH_DEBUG_2 0x00400088 ++#define NV04_PGRAPH_DEBUG_3 0x0040008c ++#define NV10_PGRAPH_DEBUG_4 0x00400090 ++#define NV03_PGRAPH_INTR 0x00400100 ++#define NV03_PGRAPH_NSTATUS 0x00400104 ++# define NV04_PGRAPH_NSTATUS_STATE_IN_USE (1<<11) ++# define NV04_PGRAPH_NSTATUS_INVALID_STATE (1<<12) ++# define NV04_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<13) ++# define NV04_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<14) ++# define NV10_PGRAPH_NSTATUS_STATE_IN_USE (1<<23) ++# define NV10_PGRAPH_NSTATUS_INVALID_STATE (1<<24) ++# define NV10_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<25) ++# define NV10_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<26) ++#define NV03_PGRAPH_NSOURCE 0x00400108 ++# define NV03_PGRAPH_NSOURCE_NOTIFICATION (1<< 0) ++# define NV03_PGRAPH_NSOURCE_DATA_ERROR (1<< 1) ++# define NV03_PGRAPH_NSOURCE_PROTECTION_ERROR (1<< 2) ++# define NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION (1<< 3) ++# define NV03_PGRAPH_NSOURCE_LIMIT_COLOR (1<< 4) ++# define NV03_PGRAPH_NSOURCE_LIMIT_ZETA (1<< 5) ++# define NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD (1<< 6) ++# define NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION (1<< 7) ++# define NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION (1<< 8) ++# define NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION (1<< 9) ++# define NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION (1<<10) ++# define NV03_PGRAPH_NSOURCE_STATE_INVALID (1<<11) ++# define NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY (1<<12) ++# define NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE (1<<13) ++# define NV03_PGRAPH_NSOURCE_METHOD_CNT (1<<14) ++# define NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION (1<<15) ++# define NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION (1<<16) ++# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_A (1<<17) ++# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_B (1<<18) ++#define NV03_PGRAPH_INTR_EN 0x00400140 ++#define NV40_PGRAPH_INTR_EN 0x0040013C ++# define NV_PGRAPH_INTR_NOTIFY (1<< 0) ++# define NV_PGRAPH_INTR_MISSING_HW (1<< 4) ++# define NV_PGRAPH_INTR_CONTEXT_SWITCH (1<<12) ++# define NV_PGRAPH_INTR_BUFFER_NOTIFY (1<<16) ++# define NV_PGRAPH_INTR_ERROR (1<<20) ++#define NV10_PGRAPH_CTX_CONTROL 0x00400144 ++#define NV10_PGRAPH_CTX_USER 0x00400148 ++#define NV10_PGRAPH_CTX_SWITCH1 0x0040014C ++#define NV10_PGRAPH_CTX_SWITCH2 0x00400150 ++#define NV10_PGRAPH_CTX_SWITCH3 0x00400154 ++#define NV10_PGRAPH_CTX_SWITCH4 0x00400158 ++#define NV10_PGRAPH_CTX_SWITCH5 0x0040015C ++#define NV04_PGRAPH_CTX_SWITCH1 0x00400160 ++#define NV10_PGRAPH_CTX_CACHE1 0x00400160 ++#define NV04_PGRAPH_CTX_SWITCH2 0x00400164 ++#define NV04_PGRAPH_CTX_SWITCH3 0x00400168 ++#define NV04_PGRAPH_CTX_SWITCH4 0x0040016C ++#define NV04_PGRAPH_CTX_CONTROL 0x00400170 ++#define NV04_PGRAPH_CTX_USER 0x00400174 ++#define NV04_PGRAPH_CTX_CACHE1 0x00400180 ++#define NV10_PGRAPH_CTX_CACHE2 0x00400180 ++#define NV03_PGRAPH_CTX_CONTROL 0x00400190 ++#define NV03_PGRAPH_CTX_USER 0x00400194 ++#define NV04_PGRAPH_CTX_CACHE2 0x004001A0 ++#define NV10_PGRAPH_CTX_CACHE3 0x004001A0 ++#define NV04_PGRAPH_CTX_CACHE3 0x004001C0 ++#define NV10_PGRAPH_CTX_CACHE4 0x004001C0 ++#define NV04_PGRAPH_CTX_CACHE4 0x004001E0 ++#define NV10_PGRAPH_CTX_CACHE5 0x004001E0 ++#define NV40_PGRAPH_CTXCTL_0304 0x00400304 ++#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001 ++#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308 ++#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_MASK 0xff000000 ++#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT 24 ++#define NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK 0x00ffffff ++#define NV40_PGRAPH_CTXCTL_0310 0x00400310 ++#define NV40_PGRAPH_CTXCTL_0310_XFER_SAVE 0x00000020 ++#define NV40_PGRAPH_CTXCTL_0310_XFER_LOAD 0x00000040 ++#define NV40_PGRAPH_CTXCTL_030C 0x0040030c ++#define NV40_PGRAPH_CTXCTL_UCODE_INDEX 0x00400324 ++#define NV40_PGRAPH_CTXCTL_UCODE_DATA 0x00400328 ++#define NV40_PGRAPH_CTXCTL_CUR 0x0040032c ++#define NV40_PGRAPH_CTXCTL_CUR_LOADED 0x01000000 ++#define NV40_PGRAPH_CTXCTL_CUR_INST_MASK 0x000FFFFF ++#define NV03_PGRAPH_ABS_X_RAM 0x00400400 ++#define NV03_PGRAPH_ABS_Y_RAM 0x00400480 ++#define NV03_PGRAPH_X_MISC 0x00400500 ++#define NV03_PGRAPH_Y_MISC 0x00400504 ++#define NV04_PGRAPH_VALID1 0x00400508 ++#define NV04_PGRAPH_SOURCE_COLOR 0x0040050C ++#define NV04_PGRAPH_MISC24_0 0x00400510 ++#define NV03_PGRAPH_XY_LOGIC_MISC0 0x00400514 ++#define NV03_PGRAPH_XY_LOGIC_MISC1 0x00400518 ++#define NV03_PGRAPH_XY_LOGIC_MISC2 0x0040051C ++#define NV03_PGRAPH_XY_LOGIC_MISC3 0x00400520 ++#define NV03_PGRAPH_CLIPX_0 0x00400524 ++#define NV03_PGRAPH_CLIPX_1 0x00400528 ++#define NV03_PGRAPH_CLIPY_0 0x0040052C ++#define NV03_PGRAPH_CLIPY_1 0x00400530 ++#define NV03_PGRAPH_ABS_ICLIP_XMAX 0x00400534 ++#define NV03_PGRAPH_ABS_ICLIP_YMAX 0x00400538 ++#define NV03_PGRAPH_ABS_UCLIP_XMIN 0x0040053C ++#define NV03_PGRAPH_ABS_UCLIP_YMIN 0x00400540 ++#define NV03_PGRAPH_ABS_UCLIP_XMAX 0x00400544 ++#define NV03_PGRAPH_ABS_UCLIP_YMAX 0x00400548 ++#define NV03_PGRAPH_ABS_UCLIPA_XMIN 0x00400560 ++#define NV03_PGRAPH_ABS_UCLIPA_YMIN 0x00400564 ++#define NV03_PGRAPH_ABS_UCLIPA_XMAX 0x00400568 ++#define NV03_PGRAPH_ABS_UCLIPA_YMAX 0x0040056C ++#define NV04_PGRAPH_MISC24_1 0x00400570 ++#define NV04_PGRAPH_MISC24_2 0x00400574 ++#define NV04_PGRAPH_VALID2 0x00400578 ++#define NV04_PGRAPH_PASSTHRU_0 0x0040057C ++#define NV04_PGRAPH_PASSTHRU_1 0x00400580 ++#define NV04_PGRAPH_PASSTHRU_2 0x00400584 ++#define NV10_PGRAPH_DIMX_TEXTURE 0x00400588 ++#define NV10_PGRAPH_WDIMX_TEXTURE 0x0040058C ++#define NV04_PGRAPH_COMBINE_0_ALPHA 0x00400590 ++#define NV04_PGRAPH_COMBINE_0_COLOR 0x00400594 ++#define NV04_PGRAPH_COMBINE_1_ALPHA 0x00400598 ++#define NV04_PGRAPH_COMBINE_1_COLOR 0x0040059C ++#define NV04_PGRAPH_FORMAT_0 0x004005A8 ++#define NV04_PGRAPH_FORMAT_1 0x004005AC ++#define NV04_PGRAPH_FILTER_0 0x004005B0 ++#define NV04_PGRAPH_FILTER_1 0x004005B4 ++#define NV03_PGRAPH_MONO_COLOR0 0x00400600 ++#define NV04_PGRAPH_ROP3 0x00400604 ++#define NV04_PGRAPH_BETA_AND 0x00400608 ++#define NV04_PGRAPH_BETA_PREMULT 0x0040060C ++#define NV04_PGRAPH_LIMIT_VIOL_PIX 0x00400610 ++#define NV04_PGRAPH_FORMATS 0x00400618 ++#define NV10_PGRAPH_DEBUG_2 0x00400620 ++#define NV04_PGRAPH_BOFFSET0 0x00400640 ++#define NV04_PGRAPH_BOFFSET1 0x00400644 ++#define NV04_PGRAPH_BOFFSET2 0x00400648 ++#define NV04_PGRAPH_BOFFSET3 0x0040064C ++#define NV04_PGRAPH_BOFFSET4 0x00400650 ++#define NV04_PGRAPH_BOFFSET5 0x00400654 ++#define NV04_PGRAPH_BBASE0 0x00400658 ++#define NV04_PGRAPH_BBASE1 0x0040065C ++#define NV04_PGRAPH_BBASE2 0x00400660 ++#define NV04_PGRAPH_BBASE3 0x00400664 ++#define NV04_PGRAPH_BBASE4 0x00400668 ++#define NV04_PGRAPH_BBASE5 0x0040066C ++#define NV04_PGRAPH_BPITCH0 0x00400670 ++#define NV04_PGRAPH_BPITCH1 0x00400674 ++#define NV04_PGRAPH_BPITCH2 0x00400678 ++#define NV04_PGRAPH_BPITCH3 0x0040067C ++#define NV04_PGRAPH_BPITCH4 0x00400680 ++#define NV04_PGRAPH_BLIMIT0 0x00400684 ++#define NV04_PGRAPH_BLIMIT1 0x00400688 ++#define NV04_PGRAPH_BLIMIT2 0x0040068C ++#define NV04_PGRAPH_BLIMIT3 0x00400690 ++#define NV04_PGRAPH_BLIMIT4 0x00400694 ++#define NV04_PGRAPH_BLIMIT5 0x00400698 ++#define NV04_PGRAPH_BSWIZZLE2 0x0040069C ++#define NV04_PGRAPH_BSWIZZLE5 0x004006A0 ++#define NV03_PGRAPH_STATUS 0x004006B0 ++#define NV04_PGRAPH_STATUS 0x00400700 ++#define NV04_PGRAPH_TRAPPED_ADDR 0x00400704 ++#define NV04_PGRAPH_TRAPPED_DATA 0x00400708 ++#define NV04_PGRAPH_SURFACE 0x0040070C ++#define NV10_PGRAPH_TRAPPED_DATA_HIGH 0x0040070C ++#define NV04_PGRAPH_STATE 0x00400710 ++#define NV10_PGRAPH_SURFACE 0x00400710 ++#define NV04_PGRAPH_NOTIFY 0x00400714 ++#define NV10_PGRAPH_STATE 0x00400714 ++#define NV10_PGRAPH_NOTIFY 0x00400718 ++ ++#define NV04_PGRAPH_FIFO 0x00400720 ++ ++#define NV04_PGRAPH_BPIXEL 0x00400724 ++#define NV10_PGRAPH_RDI_INDEX 0x00400750 ++#define NV04_PGRAPH_FFINTFC_ST2 0x00400754 ++#define NV10_PGRAPH_RDI_DATA 0x00400754 ++#define NV04_PGRAPH_DMA_PITCH 0x00400760 ++#define NV10_PGRAPH_FFINTFC_ST2 0x00400764 ++#define NV04_PGRAPH_DVD_COLORFMT 0x00400764 ++#define NV04_PGRAPH_SCALED_FORMAT 0x00400768 ++#define NV10_PGRAPH_DMA_PITCH 0x00400770 ++#define NV10_PGRAPH_DVD_COLORFMT 0x00400774 ++#define NV10_PGRAPH_SCALED_FORMAT 0x00400778 ++#define NV20_PGRAPH_CHANNEL_CTX_TABLE 0x00400780 ++#define NV20_PGRAPH_CHANNEL_CTX_POINTER 0x00400784 ++#define NV20_PGRAPH_CHANNEL_CTX_XFER 0x00400788 ++#define NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD 0x00000001 ++#define NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE 0x00000002 ++#define NV04_PGRAPH_PATT_COLOR0 0x00400800 ++#define NV04_PGRAPH_PATT_COLOR1 0x00400804 ++#define NV04_PGRAPH_PATTERN 0x00400808 ++#define NV04_PGRAPH_PATTERN_SHAPE 0x00400810 ++#define NV04_PGRAPH_CHROMA 0x00400814 ++#define NV04_PGRAPH_CONTROL0 0x00400818 ++#define NV04_PGRAPH_CONTROL1 0x0040081C ++#define NV04_PGRAPH_CONTROL2 0x00400820 ++#define NV04_PGRAPH_BLEND 0x00400824 ++#define NV04_PGRAPH_STORED_FMT 0x00400830 ++#define NV04_PGRAPH_PATT_COLORRAM 0x00400900 ++#define NV40_PGRAPH_TILE0(i) (0x00400900 + (i*16)) ++#define NV40_PGRAPH_TLIMIT0(i) (0x00400904 + (i*16)) ++#define NV40_PGRAPH_TSIZE0(i) (0x00400908 + (i*16)) ++#define NV40_PGRAPH_TSTATUS0(i) (0x0040090C + (i*16)) ++#define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) ++#define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) ++#define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) ++#define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16)) ++#define NV04_PGRAPH_U_RAM 0x00400D00 ++#define NV47_PGRAPH_TILE0(i) (0x00400D00 + (i*16)) ++#define NV47_PGRAPH_TLIMIT0(i) (0x00400D04 + (i*16)) ++#define NV47_PGRAPH_TSIZE0(i) (0x00400D08 + (i*16)) ++#define NV47_PGRAPH_TSTATUS0(i) (0x00400D0C + (i*16)) ++#define NV04_PGRAPH_V_RAM 0x00400D40 ++#define NV04_PGRAPH_W_RAM 0x00400D80 ++#define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 ++#define NV10_PGRAPH_COMBINER1_IN_ALPHA 0x00400E44 ++#define NV10_PGRAPH_COMBINER0_IN_RGB 0x00400E48 ++#define NV10_PGRAPH_COMBINER1_IN_RGB 0x00400E4C ++#define NV10_PGRAPH_COMBINER_COLOR0 0x00400E50 ++#define NV10_PGRAPH_COMBINER_COLOR1 0x00400E54 ++#define NV10_PGRAPH_COMBINER0_OUT_ALPHA 0x00400E58 ++#define NV10_PGRAPH_COMBINER1_OUT_ALPHA 0x00400E5C ++#define NV10_PGRAPH_COMBINER0_OUT_RGB 0x00400E60 ++#define NV10_PGRAPH_COMBINER1_OUT_RGB 0x00400E64 ++#define NV10_PGRAPH_COMBINER_FINAL0 0x00400E68 ++#define NV10_PGRAPH_COMBINER_FINAL1 0x00400E6C ++#define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL 0x00400F00 ++#define NV10_PGRAPH_WINDOWCLIP_VERTICAL 0x00400F20 ++#define NV10_PGRAPH_XFMODE0 0x00400F40 ++#define NV10_PGRAPH_XFMODE1 0x00400F44 ++#define NV10_PGRAPH_GLOBALSTATE0 0x00400F48 ++#define NV10_PGRAPH_GLOBALSTATE1 0x00400F4C ++#define NV10_PGRAPH_PIPE_ADDRESS 0x00400F50 ++#define NV10_PGRAPH_PIPE_DATA 0x00400F54 ++#define NV04_PGRAPH_DMA_START_0 0x00401000 ++#define NV04_PGRAPH_DMA_START_1 0x00401004 ++#define NV04_PGRAPH_DMA_LENGTH 0x00401008 ++#define NV04_PGRAPH_DMA_MISC 0x0040100C ++#define NV04_PGRAPH_DMA_DATA_0 0x00401020 ++#define NV04_PGRAPH_DMA_DATA_1 0x00401024 ++#define NV04_PGRAPH_DMA_RM 0x00401030 ++#define NV04_PGRAPH_DMA_A_XLATE_INST 0x00401040 ++#define NV04_PGRAPH_DMA_A_CONTROL 0x00401044 ++#define NV04_PGRAPH_DMA_A_LIMIT 0x00401048 ++#define NV04_PGRAPH_DMA_A_TLB_PTE 0x0040104C ++#define NV04_PGRAPH_DMA_A_TLB_TAG 0x00401050 ++#define NV04_PGRAPH_DMA_A_ADJ_OFFSET 0x00401054 ++#define NV04_PGRAPH_DMA_A_OFFSET 0x00401058 ++#define NV04_PGRAPH_DMA_A_SIZE 0x0040105C ++#define NV04_PGRAPH_DMA_A_Y_SIZE 0x00401060 ++#define NV04_PGRAPH_DMA_B_XLATE_INST 0x00401080 ++#define NV04_PGRAPH_DMA_B_CONTROL 0x00401084 ++#define NV04_PGRAPH_DMA_B_LIMIT 0x00401088 ++#define NV04_PGRAPH_DMA_B_TLB_PTE 0x0040108C ++#define NV04_PGRAPH_DMA_B_TLB_TAG 0x00401090 ++#define NV04_PGRAPH_DMA_B_ADJ_OFFSET 0x00401094 ++#define NV04_PGRAPH_DMA_B_OFFSET 0x00401098 ++#define NV04_PGRAPH_DMA_B_SIZE 0x0040109C ++#define NV04_PGRAPH_DMA_B_Y_SIZE 0x004010A0 ++#define NV40_PGRAPH_TILE1(i) (0x00406900 + (i*16)) ++#define NV40_PGRAPH_TLIMIT1(i) (0x00406904 + (i*16)) ++#define NV40_PGRAPH_TSIZE1(i) (0x00406908 + (i*16)) ++#define NV40_PGRAPH_TSTATUS1(i) (0x0040690C + (i*16)) ++ ++ ++/* It's a guess that this works on NV03. Confirmed on NV04, though */ ++#define NV04_PFIFO_DELAY_0 0x00002040 ++#define NV04_PFIFO_DMA_TIMESLICE 0x00002044 ++#define NV04_PFIFO_NEXT_CHANNEL 0x00002050 ++#define NV03_PFIFO_INTR_0 0x00002100 ++#define NV03_PFIFO_INTR_EN_0 0x00002140 ++# define NV_PFIFO_INTR_CACHE_ERROR (1<< 0) ++# define NV_PFIFO_INTR_RUNOUT (1<< 4) ++# define NV_PFIFO_INTR_RUNOUT_OVERFLOW (1<< 8) ++# define NV_PFIFO_INTR_DMA_PUSHER (1<<12) ++# define NV_PFIFO_INTR_DMA_PT (1<<16) ++# define NV_PFIFO_INTR_SEMAPHORE (1<<20) ++# define NV_PFIFO_INTR_ACQUIRE_TIMEOUT (1<<24) ++#define NV03_PFIFO_RAMHT 0x00002210 ++#define NV03_PFIFO_RAMFC 0x00002214 ++#define NV03_PFIFO_RAMRO 0x00002218 ++#define NV40_PFIFO_RAMFC 0x00002220 ++#define NV03_PFIFO_CACHES 0x00002500 ++#define NV04_PFIFO_MODE 0x00002504 ++#define NV04_PFIFO_DMA 0x00002508 ++#define NV04_PFIFO_SIZE 0x0000250c ++#define NV50_PFIFO_CTX_TABLE(c) (0x2600+(c)*4) ++#define NV50_PFIFO_CTX_TABLE__SIZE 128 ++#define NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED (1<<31) ++#define NV50_PFIFO_CTX_TABLE_UNK30_BAD (1<<30) ++#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80 0x0FFFFFFF ++#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84 0x00FFFFFF ++#define NV03_PFIFO_CACHE0_PUSH0 0x00003000 ++#define NV03_PFIFO_CACHE0_PULL0 0x00003040 ++#define NV04_PFIFO_CACHE0_PULL0 0x00003050 ++#define NV04_PFIFO_CACHE0_PULL1 0x00003054 ++#define NV03_PFIFO_CACHE1_PUSH0 0x00003200 ++#define NV03_PFIFO_CACHE1_PUSH1 0x00003204 ++#define NV03_PFIFO_CACHE1_PUSH1_DMA (1<<8) ++#define NV40_PFIFO_CACHE1_PUSH1_DMA (1<<16) ++#define NV03_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000000f ++#define NV10_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000001f ++#define NV50_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000007f ++#define NV03_PFIFO_CACHE1_PUT 0x00003210 ++#define NV04_PFIFO_CACHE1_DMA_PUSH 0x00003220 ++#define NV04_PFIFO_CACHE1_DMA_FETCH 0x00003224 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000008 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000010 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000018 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000020 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000028 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000030 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000038 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000040 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000048 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x00000050 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x00000058 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x00000060 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x00000068 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x00000070 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x00000078 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000080 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000088 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000090 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000098 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x000000A0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x000000A8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x000000B0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x000000B8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x000000C0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x000000C8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x000000D0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x000000D8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x000000E0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x000000E8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x000000F0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x000000F8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 0x0000E000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00002000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00004000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00006000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00008000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x0000A000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x0000C000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x0000E000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 0x001F0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00010000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00020000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00030000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00040000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00050000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00060000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00070000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00080000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00090000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x000A0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x000B0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x000C0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x000D0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x000E0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x000F0000 ++# define NV_PFIFO_CACHE1_ENDIAN 0x80000000 ++# define NV_PFIFO_CACHE1_LITTLE_ENDIAN 0x7FFFFFFF ++# define NV_PFIFO_CACHE1_BIG_ENDIAN 0x80000000 ++#define NV04_PFIFO_CACHE1_DMA_STATE 0x00003228 ++#define NV04_PFIFO_CACHE1_DMA_INSTANCE 0x0000322c ++#define NV04_PFIFO_CACHE1_DMA_CTL 0x00003230 ++#define NV04_PFIFO_CACHE1_DMA_PUT 0x00003240 ++#define NV04_PFIFO_CACHE1_DMA_GET 0x00003244 ++#define NV10_PFIFO_CACHE1_REF_CNT 0x00003248 ++#define NV10_PFIFO_CACHE1_DMA_SUBROUTINE 0x0000324C ++#define NV03_PFIFO_CACHE1_PULL0 0x00003240 ++#define NV04_PFIFO_CACHE1_PULL0 0x00003250 ++#define NV03_PFIFO_CACHE1_PULL1 0x00003250 ++#define NV04_PFIFO_CACHE1_PULL1 0x00003254 ++#define NV04_PFIFO_CACHE1_HASH 0x00003258 ++#define NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT 0x00003260 ++#define NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP 0x00003264 ++#define NV10_PFIFO_CACHE1_ACQUIRE_VALUE 0x00003268 ++#define NV10_PFIFO_CACHE1_SEMAPHORE 0x0000326C ++#define NV03_PFIFO_CACHE1_GET 0x00003270 ++#define NV04_PFIFO_CACHE1_ENGINE 0x00003280 ++#define NV04_PFIFO_CACHE1_DMA_DCOUNT 0x000032A0 ++#define NV40_PFIFO_GRCTX_INSTANCE 0x000032E0 ++#define NV40_PFIFO_UNK32E4 0x000032E4 ++#define NV04_PFIFO_CACHE1_METHOD(i) (0x00003800+(i*8)) ++#define NV04_PFIFO_CACHE1_DATA(i) (0x00003804+(i*8)) ++#define NV40_PFIFO_CACHE1_METHOD(i) (0x00090000+(i*8)) ++#define NV40_PFIFO_CACHE1_DATA(i) (0x00090004+(i*8)) ++ ++#define NV_CRTC0_INTSTAT 0x00600100 ++#define NV_CRTC0_INTEN 0x00600140 ++#define NV_CRTC1_INTSTAT 0x00602100 ++#define NV_CRTC1_INTEN 0x00602140 ++# define NV_CRTC_INTR_VBLANK (1<<0) ++ ++/* This name is a partial guess. */ ++#define NV50_DISPLAY_SUPERVISOR 0x00610024 ++ ++#define NV50_PDISPLAY_BACKLIGHT 0x0061c084 ++# define NV50_PDISPLAY_BACKLIGHT_ENABLE 0x80000000 ++ ++#define NV04_PRAMIN 0x00700000 ++ ++/* Fifo commands. These are not regs, neither masks */ ++#define NV03_FIFO_CMD_JUMP 0x20000000 ++#define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc ++#define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) ++ ++/* RAMFC offsets */ ++#define NV04_RAMFC_DMA_PUT 0x00 ++#define NV04_RAMFC_DMA_GET 0x04 ++#define NV04_RAMFC_DMA_INSTANCE 0x08 ++#define NV04_RAMFC_DMA_STATE 0x0C ++#define NV04_RAMFC_DMA_FETCH 0x10 ++#define NV04_RAMFC_ENGINE 0x14 ++#define NV04_RAMFC_PULL1_ENGINE 0x18 ++ ++#define NV10_RAMFC_DMA_PUT 0x00 ++#define NV10_RAMFC_DMA_GET 0x04 ++#define NV10_RAMFC_REF_CNT 0x08 ++#define NV10_RAMFC_DMA_INSTANCE 0x0C ++#define NV10_RAMFC_DMA_STATE 0x10 ++#define NV10_RAMFC_DMA_FETCH 0x14 ++#define NV10_RAMFC_ENGINE 0x18 ++#define NV10_RAMFC_PULL1_ENGINE 0x1C ++#define NV10_RAMFC_ACQUIRE_VALUE 0x20 ++#define NV10_RAMFC_ACQUIRE_TIMESTAMP 0x24 ++#define NV10_RAMFC_ACQUIRE_TIMEOUT 0x28 ++#define NV10_RAMFC_SEMAPHORE 0x2C ++#define NV10_RAMFC_DMA_SUBROUTINE 0x30 ++ ++#define NV40_RAMFC_DMA_PUT 0x00 ++#define NV40_RAMFC_DMA_GET 0x04 ++#define NV40_RAMFC_REF_CNT 0x08 ++#define NV40_RAMFC_DMA_INSTANCE 0x0C ++#define NV40_RAMFC_DMA_DCOUNT /* ? */ 0x10 ++#define NV40_RAMFC_DMA_STATE 0x14 ++#define NV40_RAMFC_DMA_FETCH 0x18 ++#define NV40_RAMFC_ENGINE 0x1C ++#define NV40_RAMFC_PULL1_ENGINE 0x20 ++#define NV40_RAMFC_ACQUIRE_VALUE 0x24 ++#define NV40_RAMFC_ACQUIRE_TIMESTAMP 0x28 ++#define NV40_RAMFC_ACQUIRE_TIMEOUT 0x2C ++#define NV40_RAMFC_SEMAPHORE 0x30 ++#define NV40_RAMFC_DMA_SUBROUTINE 0x34 ++#define NV40_RAMFC_GRCTX_INSTANCE /* guess */ 0x38 ++#define NV40_RAMFC_DMA_TIMESLICE 0x3C ++#define NV40_RAMFC_UNK_40 0x40 ++#define NV40_RAMFC_UNK_44 0x44 ++#define NV40_RAMFC_UNK_48 0x48 ++#define NV40_RAMFC_UNK_4C 0x4C ++#define NV40_RAMFC_UNK_50 0x50 ++ ++/* This is a partial import from rules-ng, a few things may be duplicated. ++ * Eventually we should completely import everything from rules-ng. ++ * For the moment check rules-ng for docs. ++ */ ++ ++#define NV50_PMC 0x00000000 ++#define NV50_PMC__LEN 0x1 ++#define NV50_PMC__ESIZE 0x2000 ++# define NV50_PMC_BOOT_0 0x00000000 ++# define NV50_PMC_BOOT_0_REVISION 0x000000ff ++# define NV50_PMC_BOOT_0_REVISION__SHIFT 0 ++# define NV50_PMC_BOOT_0_ARCH 0x0ff00000 ++# define NV50_PMC_BOOT_0_ARCH__SHIFT 20 ++# define NV50_PMC_INTR_0 0x00000100 ++# define NV50_PMC_INTR_0_PFIFO (1<<8) ++# define NV50_PMC_INTR_0_PGRAPH (1<<12) ++# define NV50_PMC_INTR_0_PTIMER (1<<20) ++# define NV50_PMC_INTR_0_HOTPLUG (1<<21) ++# define NV50_PMC_INTR_0_DISPLAY (1<<26) ++# define NV50_PMC_INTR_EN_0 0x00000140 ++# define NV50_PMC_INTR_EN_0_MASTER (1<<0) ++# define NV50_PMC_INTR_EN_0_MASTER_DISABLED (0<<0) ++# define NV50_PMC_INTR_EN_0_MASTER_ENABLED (1<<0) ++# define NV50_PMC_ENABLE 0x00000200 ++# define NV50_PMC_ENABLE_PFIFO (1<<8) ++# define NV50_PMC_ENABLE_PGRAPH (1<<12) ++ ++#define NV50_PCONNECTOR 0x0000e000 ++#define NV50_PCONNECTOR__LEN 0x1 ++#define NV50_PCONNECTOR__ESIZE 0x1000 ++# define NV50_PCONNECTOR_HOTPLUG_INTR 0x0000e050 ++# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C0 (1<<0) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C1 (1<<1) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C2 (1<<2) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C3 (1<<3) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C0 (1<<16) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C1 (1<<17) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C2 (1<<18) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C3 (1<<19) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL 0x0000e054 ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C0 (1<<0) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C1 (1<<1) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C2 (1<<2) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C3 (1<<3) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C0 (1<<16) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C1 (1<<17) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C2 (1<<18) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C3 (1<<19) ++# define NV50_PCONNECTOR_HOTPLUG_STATE 0x0000e104 ++# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C0 (1<<2) ++# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C1 (1<<6) ++# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C2 (1<<10) ++# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C3 (1<<14) ++# define NV50_PCONNECTOR_I2C_PORT_0 0x0000e138 ++# define NV50_PCONNECTOR_I2C_PORT_1 0x0000e150 ++# define NV50_PCONNECTOR_I2C_PORT_2 0x0000e168 ++# define NV50_PCONNECTOR_I2C_PORT_3 0x0000e180 ++# define NV50_PCONNECTOR_I2C_PORT_4 0x0000e240 ++# define NV50_PCONNECTOR_I2C_PORT_5 0x0000e258 ++ ++#define NV50_PBUS 0x00088000 ++#define NV50_PBUS__LEN 0x1 ++#define NV50_PBUS__ESIZE 0x1000 ++# define NV50_PBUS_PCI_ID 0x00088000 ++# define NV50_PBUS_PCI_ID_VENDOR_ID 0x0000ffff ++# define NV50_PBUS_PCI_ID_VENDOR_ID__SHIFT 0 ++# define NV50_PBUS_PCI_ID_DEVICE_ID 0xffff0000 ++# define NV50_PBUS_PCI_ID_DEVICE_ID__SHIFT 16 ++ ++#define NV50_PFB 0x00100000 ++#define NV50_PFB__LEN 0x1 ++#define NV50_PFB__ESIZE 0x1000 ++ ++#define NV50_PEXTDEV 0x00101000 ++#define NV50_PEXTDEV__LEN 0x1 ++#define NV50_PEXTDEV__ESIZE 0x1000 ++ ++#define NV50_PROM 0x00300000 ++#define NV50_PROM__LEN 0x1 ++#define NV50_PROM__ESIZE 0x10000 ++ ++#define NV50_PGRAPH 0x00400000 ++#define NV50_PGRAPH__LEN 0x1 ++#define NV50_PGRAPH__ESIZE 0x10000 ++ ++#define NV50_PDISPLAY 0x00610000 ++#define NV50_PDISPLAY__LEN 0x1 ++#define NV50_PDISPLAY__ESIZE 0x10000 ++# define NV50_PDISPLAY_SUPERVISOR 0x00610024 ++# define NV50_PDISPLAY_SUPERVISOR_CRTCn 0x0000000c ++# define NV50_PDISPLAY_SUPERVISOR_CRTCn__SHIFT 2 ++# define NV50_PDISPLAY_SUPERVISOR_CRTC0 (1<<2) ++# define NV50_PDISPLAY_SUPERVISOR_CRTC1 (1<<3) ++# define NV50_PDISPLAY_SUPERVISOR_CLK_MASK 0x00000070 ++# define NV50_PDISPLAY_SUPERVISOR_CLK_MASK__SHIFT 4 ++# define NV50_PDISPLAY_SUPERVISOR_CLK_UPDATE (1<<5) ++# define NV50_PDISPLAY_SUPERVISOR_INTR 0x0061002c ++# define NV50_PDISPLAY_SUPERVISOR_INTR_VBLANK_CRTC0 (1<<2) ++# define NV50_PDISPLAY_SUPERVISOR_INTR_VBLANK_CRTC1 (1<<3) ++# define NV50_PDISPLAY_SUPERVISOR_INTR_UNK1 (1<<4) ++# define NV50_PDISPLAY_SUPERVISOR_INTR_CLK_UPDATE (1<<5) ++# define NV50_PDISPLAY_SUPERVISOR_INTR_UNK4 (1<<6) ++# define NV50_PDISPLAY_UNK30_CTRL 0x00610030 ++# define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0 (1<<9) ++# define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 (1<<10) ++# define NV50_PDISPLAY_UNK30_CTRL_PENDING (1<<31) ++# define NV50_PDISPLAY_UNK50_CTRL 0x00610050 ++# define NV50_PDISPLAY_UNK50_CTRL_CRTC0_ACTIVE (1<<1) ++# define NV50_PDISPLAY_UNK50_CTRL_CRTC0_ACTIVE_MASK 0x00000003 ++# define NV50_PDISPLAY_UNK50_CTRL_CRTC0_ACTIVE_MASK__SHIFT 0 ++# define NV50_PDISPLAY_UNK50_CTRL_CRTC1_ACTIVE (1<<9) ++# define NV50_PDISPLAY_UNK50_CTRL_CRTC1_ACTIVE_MASK 0x00000300 ++# define NV50_PDISPLAY_UNK50_CTRL_CRTC1_ACTIVE_MASK__SHIFT 8 ++# define NV50_PDISPLAY_UNK200_CTRL 0x00610200 ++# define NV50_PDISPLAY_CURSOR 0x00610270 ++# define NV50_PDISPLAY_CURSOR__LEN 0x2 ++# define NV50_PDISPLAY_CURSOR__ESIZE 0x10 ++# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i) (0x00610270+(i)*0x10) ++# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON (1<<0) ++# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK 0x00030000 ++# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK__SHIFT 16 ++# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE (1<<16) ++ ++# define NV50_PDISPLAY_CTRL_STATE 0x00610300 ++# define NV50_PDISPLAY_CTRL_STATE_ENABLE (1<<0) ++# define NV50_PDISPLAY_CTRL_STATE_PENDING (1<<31) ++# define NV50_PDISPLAY_CTRL_VAL 0x00610304 ++# define NV50_PDISPLAY_UNK_380 0x00610380 ++# define NV50_PDISPLAY_RAM_AMOUNT 0x00610384 ++# define NV50_PDISPLAY_UNK_388 0x00610388 ++# define NV50_PDISPLAY_UNK_38C 0x0061038c ++# define NV50_PDISPLAY_CRTC_VAL 0x00610a00 ++# define NV50_PDISPLAY_CRTC_VAL__LEN 0x2 ++# define NV50_PDISPLAY_CRTC_VAL_UNK_900(i,j) (0x00610a18+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_CLUT_MODE(i,j) (0x00610a24+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_INTERLACE(i,j) (0x00610a48+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_SCALE_CTRL(i,j) (0x00610a50+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_CURSOR_CTRL(i,j) (0x00610a58+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_UNK_904(i,j) (0x00610ab8+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_DEPTH(i,j) (0x00610ac8+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_CLOCK(i,j) (0x00610ad0+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_COLOR_CTRL(i,j) (0x00610ae0+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_SYNC_START_TO_BLANK_END(i,j) (0x00610ae8+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_MODE_UNK1(i,j) (0x00610af0+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_DISPLAY_TOTAL(i,j) (0x00610af8+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_SYNC_DURATION(i,j) (0x00610b00+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_MODE_UNK2(i,j) (0x00610b08+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_UNK_828(i,j) (0x00610b10+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_FB_SIZE(i,j) (0x00610b18+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_FB_PITCH(i,j) (0x00610b20+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_FB_PITCH_LINEAR_FB (1<<20) ++# define NV50_PDISPLAY_CRTC_VAL_FB_POS(i,j) (0x00610b28+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_SCALE_CENTER_OFFSET(i,j) (0x00610b38+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_REAL_RES(i,j) (0x00610b40+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_SCALE_RES1(i,j) (0x00610b48+(i)*0x540+(j)*0x4) ++# define NV50_PDISPLAY_CRTC_VAL_SCALE_RES2(i,j) (0x00610b50+(i)*0x540+(j)*0x4) ++ ++ ++# define NV50_PDISPLAY_DAC_VAL_MODE_CTRL(i,j) (0x00610b58+(i)*0x8+(j)*0x4) ++ ++ ++# define NV50_PDISPLAY_SOR_VAL_MODE_CTRL(i,j) (0x00610b70+(i)*0x8+(j)*0x4) ++ ++ ++# define NV50_PDISPLAY_DAC_VAL_MODE_CTRL2(i,j) (0x00610bdc+(i)*0x8+(j)*0x4) ++ ++ ++# define NV50_PDISPLAY_CRTC_CLK 0x00614000 ++# define NV50_PDISPLAY_CRTC_CLK__LEN 0x2 ++# define NV50_PDISPLAY_CRTC_CLK_CLK_CTRL1(i) (0x00614100+(i)*0x800) ++# define NV50_PDISPLAY_CRTC_CLK_CLK_CTRL1_CONNECTED 0x00000600 ++# define NV50_PDISPLAY_CRTC_CLK_CLK_CTRL1_CONNECTED__SHIFT 9 ++# define NV50_PDISPLAY_CRTC_CLK_VPLL_A(i) (0x00614104+(i)*0x800) ++# define NV50_PDISPLAY_CRTC_CLK_VPLL_B(i) (0x00614108+(i)*0x800) ++# define NV50_PDISPLAY_CRTC_CLK_CLK_CTRL2(i) (0x00614200+(i)*0x800) ++ ++# define NV50_PDISPLAY_DAC_CLK 0x00614000 ++# define NV50_PDISPLAY_DAC_CLK__LEN 0x3 ++# define NV50_PDISPLAY_DAC_CLK_CLK_CTRL2(i) (0x00614280+(i)*0x800) ++ ++# define NV50_PDISPLAY_SOR_CLK 0x00614000 ++# define NV50_PDISPLAY_SOR_CLK__LEN 0x3 ++# define NV50_PDISPLAY_SOR_CLK_CLK_CTRL2(i) (0x00614300+(i)*0x800) ++ ++# define NV50_PDISPLAY_DAC_REGS 0x0061a000 ++# define NV50_PDISPLAY_DAC_REGS__LEN 0x3 ++# define NV50_PDISPLAY_DAC_REGS__ESIZE 0x800 ++# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(i) (0x0061a004+(i)*0x800) ++# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_HSYNC_OFF (1<<0) ++# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_VSYNC_OFF (1<<2) ++# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_BLANKED (1<<4) ++# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_OFF (1<<6) ++# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING (1<<31) ++# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL(i) (0x0061a00c+(i)*0x800) ++# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_ACTIVE (1<<20) ++# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_PRESENT 0x38000000 ++# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_PRESENT__SHIFT 29 ++# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_DONE (1<<31) ++# define NV50_PDISPLAY_DAC_REGS_CLK_CTRL1(i) (0x0061a010+(i)*0x800) ++# define NV50_PDISPLAY_DAC_REGS_CLK_CTRL1_CONNECTED 0x00000600 ++# define NV50_PDISPLAY_DAC_REGS_CLK_CTRL1_CONNECTED__SHIFT 9 ++ ++# define NV50_PDISPLAY_SOR_REGS 0x0061c000 ++# define NV50_PDISPLAY_SOR_REGS__LEN 0x3 ++# define NV50_PDISPLAY_SOR_REGS__ESIZE 0x800 ++# define NV50_PDISPLAY_SOR_REGS_DPMS_CTRL(i) (0x0061c004+(i)*0x800) ++# define NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_ON (1<<0) ++# define NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_PENDING (1<<31) ++# define NV50_PDISPLAY_SOR_REGS_CLK_CTRL1(i) (0x0061c008+(i)*0x800) ++# define NV50_PDISPLAY_SOR_REGS_CLK_CTRL1_CONNECTED 0x00000600 ++# define NV50_PDISPLAY_SOR_REGS_CLK_CTRL1_CONNECTED__SHIFT 9 ++# define NV50_PDISPLAY_SOR_REGS_UNK_00C(i) (0x0061c00c+(i)*0x800) ++# define NV50_PDISPLAY_SOR_REGS_UNK_010(i) (0x0061c010+(i)*0x800) ++# define NV50_PDISPLAY_SOR_REGS_UNK_014(i) (0x0061c014+(i)*0x800) ++# define NV50_PDISPLAY_SOR_REGS_UNK_018(i) (0x0061c018+(i)*0x800) ++# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE(i) (0x0061c030+(i)*0x800) ++# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE_ACTIVE 0x00030000 ++# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE_ACTIVE__SHIFT 16 ++# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE_BLANKED (1<<19) ++# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE_WAIT (1<<28) ++ ++ ++#define NV50_UNK640000 0x00640000 ++#define NV50_UNK640000__LEN 0x6 ++#define NV50_UNK640000__ESIZE 0x1000 ++# define NV50_UNK640000_UNK_000(i) (0x00640000+(i)*0x1000) ++ ++#define NV50_HW_CURSOR 0x00647000 ++#define NV50_HW_CURSOR__LEN 0x2 ++#define NV50_HW_CURSOR__ESIZE 0x1000 ++# define NV50_HW_CURSOR_POS_CTRL(i) (0x00647080+(i)*0x1000) ++# define NV50_HW_CURSOR_POS(i) (0x00647084+(i)*0x1000) +diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c +new file mode 100644 +index 0000000..08b2171 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c +@@ -0,0 +1,340 @@ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include ++ ++#define NV_CTXDMA_PAGE_SHIFT 12 ++#define NV_CTXDMA_PAGE_SIZE (1 << NV_CTXDMA_PAGE_SHIFT) ++#define NV_CTXDMA_PAGE_MASK (NV_CTXDMA_PAGE_SIZE - 1) ++ ++struct nouveau_sgdma_be { ++ struct drm_ttm_backend backend; ++ struct drm_device *dev; ++ ++ struct page **pages; ++ unsigned nr_pages; ++ ++ unsigned pte_start; ++ bool bound; ++}; ++ ++static int ++nouveau_sgdma_needs_ub_cache_adjust(struct drm_ttm_backend *be) ++{ ++ return ((be->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1); ++} ++ ++static int ++nouveau_sgdma_populate(struct drm_ttm_backend *be, unsigned long num_pages, ++ struct page **pages, struct page *dummy_read_page) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ ++ NV_DEBUG(nvbe->dev, "num_pages = %ld\n", num_pages); ++ ++ if (nvbe->pages) ++ return -EINVAL; ++ ++ nvbe->pages = pages; ++ nvbe->nr_pages = num_pages; ++ return 0; ++} ++ ++static void ++nouveau_sgdma_clear(struct drm_ttm_backend *be) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ ++ NV_DEBUG(nvbe->dev, "\n"); ++ ++ if (nvbe && nvbe->pages) { ++ if (nvbe->bound) ++ be->func->unbind(be); ++ nvbe->pages = NULL; ++ } ++} ++ ++static inline unsigned ++nouveau_sgdma_pte(struct drm_device *dev, uint64_t offset) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ unsigned pte = (offset >> NV_CTXDMA_PAGE_SHIFT); ++ ++ if (dev_priv->card_type < NV_50) ++ return pte + 2; ++ ++ return pte << 1; ++} ++ ++static int ++nouveau_sgdma_bind(struct drm_ttm_backend *be, struct drm_bo_mem_reg *mem) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ struct drm_device *dev = nvbe->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; ++ unsigned i, j, pte, tile = 0; ++ ++ NV_DEBUG(dev, "pg=0x%lx cached=%d\n", mem->mm_node->start, ++ (mem->flags & DRM_BO_FLAG_CACHED) == 1); ++ ++ if (mem->proposed_flags & DRM_NOUVEAU_BO_FLAG_TILE && ++ mem->proposed_flags & DRM_NOUVEAU_BO_FLAG_ZTILE) ++ tile = 0x2800; ++ else ++ if (mem->proposed_flags & DRM_NOUVEAU_BO_FLAG_TILE) ++ tile = 0x7000; ++ ++ dev_priv->engine.instmem.prepare_access(nvbe->dev, true); ++ pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT); ++ nvbe->pte_start = pte; ++ for (i = 0; i < nvbe->nr_pages; i++) { ++ dma_addr_t dma_offset = page_to_phys(nvbe->pages[i]); ++ ++ for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) { ++ if (dev_priv->card_type < NV_50) ++ INSTANCE_WR(gpuobj, pte++, dma_offset | 3); ++ else { ++ INSTANCE_WR(gpuobj, pte++, dma_offset | 0x21); ++ INSTANCE_WR(gpuobj, pte++, tile); ++ } ++ ++ dma_offset += NV_CTXDMA_PAGE_SIZE; ++ } ++ } ++ dev_priv->engine.instmem.finish_access(nvbe->dev); ++ ++ nvbe->bound = true; ++ return 0; ++} ++ ++static int ++nouveau_sgdma_unbind(struct drm_ttm_backend *be) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ struct drm_device *dev = nvbe->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; ++ unsigned i, j, pte; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!nvbe->bound) ++ return 0; ++ ++ dev_priv->engine.instmem.prepare_access(nvbe->dev, true); ++ pte = nvbe->pte_start; ++ for (i = 0; i < nvbe->nr_pages; i++) { ++ dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus; ++ ++ for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) { ++ if (dev_priv->card_type < NV_50) ++ INSTANCE_WR(gpuobj, pte++, dma_offset | 3); ++ else { ++ INSTANCE_WR(gpuobj, pte++, dma_offset | 0x21); ++ INSTANCE_WR(gpuobj, pte++, 0x00000000); ++ } ++ ++ dma_offset += NV_CTXDMA_PAGE_SIZE; ++ } ++ } ++ dev_priv->engine.instmem.finish_access(nvbe->dev); ++ ++ nvbe->bound = false; ++ return 0; ++} ++ ++static void ++nouveau_sgdma_destroy(struct drm_ttm_backend *be) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ ++ if (be) { ++ NV_DEBUG(nvbe->dev, "\n"); ++ ++ if (nvbe) { ++ if (nvbe->pages) ++ be->func->clear(be); ++ drm_ctl_free(nvbe, sizeof(*nvbe), DRM_MEM_TTM); ++ } ++ } ++} ++ ++static struct drm_ttm_backend_func nouveau_sgdma_backend = { ++ .needs_ub_cache_adjust = nouveau_sgdma_needs_ub_cache_adjust, ++ .populate = nouveau_sgdma_populate, ++ .clear = nouveau_sgdma_clear, ++ .bind = nouveau_sgdma_bind, ++ .unbind = nouveau_sgdma_unbind, ++ .destroy = nouveau_sgdma_destroy ++}; ++ ++struct drm_ttm_backend * ++nouveau_sgdma_init_ttm(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_sgdma_be *nvbe; ++ ++ if (!dev_priv->gart_info.sg_ctxdma) ++ return NULL; ++ ++ nvbe = drm_ctl_calloc(1, sizeof(*nvbe), DRM_MEM_TTM); ++ if (!nvbe) ++ return NULL; ++ ++ nvbe->dev = dev; ++ ++ nvbe->backend.func = &nouveau_sgdma_backend; ++ ++ return &nvbe->backend; ++} ++ ++int ++nouveau_sgdma_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = NULL; ++ uint32_t aper_size, obj_size; ++ int i, ret; ++ ++ if (dev_priv->card_type < NV_50) { ++ aper_size = (64 * 1024 * 1024); ++ obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4; ++ obj_size += 8; /* ctxdma header */ ++ } else { ++ /* 1 entire VM page table */ ++ aper_size = (512 * 1024 * 1024); ++ obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 8; ++ } ++ ++ if ((ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16, ++ NVOBJ_FLAG_ALLOW_NO_REFS | ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, &gpuobj))) { ++ NV_ERROR(dev, "Error creating sgdma object: %d\n", ret); ++ return ret; ++ } ++ ++ dev_priv->gart_info.sg_dummy_page = ++ alloc_page(GFP_KERNEL|__GFP_DMA32); ++ set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); ++ dev_priv->gart_info.sg_dummy_bus = ++ pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, ++ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ if (dev_priv->card_type < NV_50) { ++ /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and ++ * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE ++ * on those cards? */ ++ INSTANCE_WR(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | ++ (1 << 12) /* PT present */ | ++ (0 << 13) /* PT *not* linear */ | ++ (NV_DMA_ACCESS_RW << 14) | ++ (NV_DMA_TARGET_PCI << 16)); ++ INSTANCE_WR(gpuobj, 1, aper_size - 1); ++ for (i=2; i<2+(aper_size>>12); i++) { ++ INSTANCE_WR(gpuobj, i, ++ dev_priv->gart_info.sg_dummy_bus | 3); ++ } ++ } else { ++ for (i=0; igart_info.sg_dummy_bus | 0x21); ++ INSTANCE_WR(gpuobj, (i+4)/4, 0); ++ } ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ dev_priv->gart_info.type = NOUVEAU_GART_SGDMA; ++ dev_priv->gart_info.aper_base = 0; ++ dev_priv->gart_info.aper_size = aper_size; ++ dev_priv->gart_info.sg_ctxdma = gpuobj; ++ return 0; ++} ++ ++void ++nouveau_sgdma_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->gart_info.sg_dummy_page) { ++ pci_unmap_page(dev->pdev, dev_priv->gart_info.sg_dummy_bus, ++ NV_CTXDMA_PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); ++ unlock_page(dev_priv->gart_info.sg_dummy_page); ++ __free_page(dev_priv->gart_info.sg_dummy_page); ++ dev_priv->gart_info.sg_dummy_page = NULL; ++ dev_priv->gart_info.sg_dummy_bus = 0; ++ } ++ ++ nouveau_gpuobj_del(dev, &dev_priv->gart_info.sg_ctxdma); ++} ++ ++int ++nouveau_sgdma_nottm_hack_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_ttm_backend *be; ++ struct drm_scatter_gather sgreq; ++ struct drm_mm_node mm_node; ++ struct drm_bo_mem_reg mem; ++ int ret; ++ ++ dev_priv->gart_info.sg_be = nouveau_sgdma_init_ttm(dev); ++ if (!dev_priv->gart_info.sg_be) ++ return -ENOMEM; ++ be = dev_priv->gart_info.sg_be; ++ ++ /* Hack the aperture size down to the amount of system memory ++ * we're going to bind into it. ++ */ ++ if (dev_priv->gart_info.aper_size > 32*1024*1024) ++ dev_priv->gart_info.aper_size = 32*1024*1024; ++ ++ sgreq.size = dev_priv->gart_info.aper_size; ++ if ((ret = drm_sg_alloc(dev, &sgreq))) { ++ NV_ERROR(dev, "drm_sg_alloc failed: %d\n", ret); ++ return ret; ++ } ++ dev_priv->gart_info.sg_handle = sgreq.handle; ++ ++ if ((ret = be->func->populate(be, dev->sg->pages, dev->sg->pagelist, dev->bm.dummy_read_page))) { ++ NV_ERROR(dev, "failed populate: %d\n", ret); ++ return ret; ++ } ++ ++ mm_node.start = 0; ++ mem.mm_node = &mm_node; ++ mem.proposed_flags = 0; ++ ++ if ((ret = be->func->bind(be, &mem))) { ++ NV_ERROR(dev, "failed bind: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void ++nouveau_sgdma_nottm_hack_takedown(struct drm_device *dev) ++{ ++} ++ ++int ++nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ int pte; ++ ++ pte = (offset >> NV_CTXDMA_PAGE_SHIFT); ++ if (dev_priv->card_type < NV_50) { ++ instmem->prepare_access(dev, false); ++ *page = INSTANCE_RD(gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK; ++ instmem->finish_access(dev); ++ return 0; ++ } ++ ++ NV_ERROR(dev, "Unimplemented on NV50\n"); ++ return -EINVAL; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c +new file mode 100644 +index 0000000..3e69c36 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_state.c +@@ -0,0 +1,1046 @@ ++/* ++ * Copyright 2005 Stephane Marchesin ++ * Copyright 2008 Stuart Bennett ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_sarea.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nv50_display.h" ++ ++static int nouveau_stub_init(struct drm_device *dev) { return 0; } ++static void nouveau_stub_takedown(struct drm_device *dev) {} ++ ++extern int drm_gem_object_name(struct drm_device *, struct drm_gem_object *, ++ uint64_t *); ++static int ++sfbhack_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t flags; ++ int ret, size; ++ ++ if (dev_priv->sfb_gem || dev_priv->sfb) ++ return 0; ++ ++ size = nouveau_mem_fb_amount(dev); ++ if (size > drm_get_resource_len(dev, 1)) ++ size = drm_get_resource_len(dev, 1); ++ size >>= 1; ++ ++ if (dev_priv->mm_enabled) { ++ flags = NOUVEAU_GEM_DOMAIN_VRAM; ++ if (dev_priv->card_type == NV_50) ++ flags |= NOUVEAU_GEM_DOMAIN_TILE; ++ ++ ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, ++ flags, &dev_priv->sfb_gem); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gem_pin(dev_priv->sfb_gem, ++ NOUVEAU_GEM_DOMAIN_VRAM); ++ if (ret) ++ return ret; ++ ++ ret = drm_gem_object_name(dev, dev_priv->sfb_gem, ++ &dev_priv->sfbhack_handle); ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(dev_priv->sfb_gem); ++ mutex_unlock(&dev->struct_mutex); ++ if (ret) { ++ dev_priv->sfb_gem = NULL; ++ return ret; ++ } ++ ++ dev_priv->sfbhack_size = dev_priv->sfb_gem->size; ++ return 0; ++ } ++ ++ flags = NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED; ++ if (dev_priv->card_type == NV_50) ++ flags |= NOUVEAU_MEM_TILE; ++ ++ dev_priv->sfb = nouveau_mem_alloc(dev, 0, size, flags, ++ (struct drm_file *)-2); ++ if (!dev_priv->sfb) ++ return -ENOMEM; ++ ++ dev_priv->sfbhack_handle = ((u64)dev_priv->sfb->map_handle << 32 | ++ dev_priv->sfb->start); ++ dev_priv->sfbhack_size = dev_priv->sfb->size; ++ return 0; ++} ++ ++static void ++sfbhack_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->sfb_gem) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(dev_priv->sfb_gem); ++ mutex_unlock(&dev->struct_mutex); ++ dev_priv->sfb_gem = NULL; ++ } ++ ++ if (dev_priv->sfb) { ++ nouveau_mem_free(dev, dev_priv->sfb); ++ dev_priv->sfb = NULL; ++ } ++} ++ ++static int nouveau_init_engine_ptrs(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ ++ switch (dev_priv->chipset & 0xf0) { ++ case 0x00: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown= nv04_instmem_takedown; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv04_mc_init; ++ engine->mc.takedown = nv04_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv04_fb_init; ++ engine->fb.takedown = nv04_fb_takedown; ++ engine->graph.init = nv04_graph_init; ++ engine->graph.takedown = nv04_graph_takedown; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.create_context = nv04_graph_create_context; ++ engine->graph.destroy_context = nv04_graph_destroy_context; ++ engine->graph.load_context = nv04_graph_load_context; ++ engine->graph.save_context = nv04_graph_save_context; ++ engine->fifo.channels = 16; ++ engine->fifo.init = nouveau_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.channel_id = nv04_fifo_channel_id; ++ engine->fifo.create_context = nv04_fifo_create_context; ++ engine->fifo.destroy_context = nv04_fifo_destroy_context; ++ engine->fifo.load_context = nv04_fifo_load_context; ++ engine->fifo.save_context = nv04_fifo_save_context; ++ break; ++ case 0x10: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown= nv04_instmem_takedown; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv04_mc_init; ++ engine->mc.takedown = nv04_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv10_fb_init; ++ engine->fb.takedown = nv10_fb_takedown; ++ engine->graph.init = nv10_graph_init; ++ engine->graph.takedown = nv10_graph_takedown; ++ engine->graph.create_context = nv10_graph_create_context; ++ engine->graph.destroy_context = nv10_graph_destroy_context; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.load_context = nv10_graph_load_context; ++ engine->graph.save_context = nv10_graph_save_context; ++ engine->fifo.channels = 32; ++ engine->fifo.init = nouveau_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.channel_id = nv10_fifo_channel_id; ++ engine->fifo.create_context = nv10_fifo_create_context; ++ engine->fifo.destroy_context = nv10_fifo_destroy_context; ++ engine->fifo.load_context = nv10_fifo_load_context; ++ engine->fifo.save_context = nv10_fifo_save_context; ++ break; ++ case 0x20: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown= nv04_instmem_takedown; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv04_mc_init; ++ engine->mc.takedown = nv04_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv10_fb_init; ++ engine->fb.takedown = nv10_fb_takedown; ++ engine->graph.init = nv20_graph_init; ++ engine->graph.takedown = nv20_graph_takedown; ++ engine->graph.create_context = nv20_graph_create_context; ++ engine->graph.destroy_context = nv20_graph_destroy_context; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.load_context = nv20_graph_load_context; ++ engine->graph.save_context = nv20_graph_save_context; ++ engine->fifo.channels = 32; ++ engine->fifo.init = nouveau_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.channel_id = nv10_fifo_channel_id; ++ engine->fifo.create_context = nv10_fifo_create_context; ++ engine->fifo.destroy_context = nv10_fifo_destroy_context; ++ engine->fifo.load_context = nv10_fifo_load_context; ++ engine->fifo.save_context = nv10_fifo_save_context; ++ break; ++ case 0x30: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown= nv04_instmem_takedown; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv04_mc_init; ++ engine->mc.takedown = nv04_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv10_fb_init; ++ engine->fb.takedown = nv10_fb_takedown; ++ engine->graph.init = nv30_graph_init; ++ engine->graph.takedown = nv20_graph_takedown; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.create_context = nv20_graph_create_context; ++ engine->graph.destroy_context = nv20_graph_destroy_context; ++ engine->graph.load_context = nv20_graph_load_context; ++ engine->graph.save_context = nv20_graph_save_context; ++ engine->fifo.channels = 32; ++ engine->fifo.init = nouveau_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.channel_id = nv10_fifo_channel_id; ++ engine->fifo.create_context = nv10_fifo_create_context; ++ engine->fifo.destroy_context = nv10_fifo_destroy_context; ++ engine->fifo.load_context = nv10_fifo_load_context; ++ engine->fifo.save_context = nv10_fifo_save_context; ++ break; ++ case 0x40: ++ case 0x60: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown= nv04_instmem_takedown; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv40_mc_init; ++ engine->mc.takedown = nv40_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv40_fb_init; ++ engine->fb.takedown = nv40_fb_takedown; ++ engine->graph.init = nv40_graph_init; ++ engine->graph.takedown = nv40_graph_takedown; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.create_context = nv40_graph_create_context; ++ engine->graph.destroy_context = nv40_graph_destroy_context; ++ engine->graph.load_context = nv40_graph_load_context; ++ engine->graph.save_context = nv40_graph_save_context; ++ engine->fifo.channels = 32; ++ engine->fifo.init = nv40_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.channel_id = nv10_fifo_channel_id; ++ engine->fifo.create_context = nv40_fifo_create_context; ++ engine->fifo.destroy_context = nv40_fifo_destroy_context; ++ engine->fifo.load_context = nv40_fifo_load_context; ++ engine->fifo.save_context = nv40_fifo_save_context; ++ break; ++ case 0x50: ++ case 0x80: /* gotta love NVIDIA's consistency.. */ ++ case 0x90: ++ case 0xA0: ++ engine->instmem.init = nv50_instmem_init; ++ engine->instmem.takedown= nv50_instmem_takedown; ++ engine->instmem.populate = nv50_instmem_populate; ++ engine->instmem.clear = nv50_instmem_clear; ++ engine->instmem.bind = nv50_instmem_bind; ++ engine->instmem.unbind = nv50_instmem_unbind; ++ engine->instmem.prepare_access = nv50_instmem_prepare_access; ++ engine->instmem.finish_access = nv50_instmem_finish_access; ++ engine->mc.init = nv50_mc_init; ++ engine->mc.takedown = nv50_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nouveau_stub_init; ++ engine->fb.takedown = nouveau_stub_takedown; ++ engine->graph.init = nv50_graph_init; ++ engine->graph.takedown = nv50_graph_takedown; ++ engine->graph.fifo_access = nv50_graph_fifo_access; ++ engine->graph.create_context = nv50_graph_create_context; ++ engine->graph.destroy_context = nv50_graph_destroy_context; ++ engine->graph.load_context = nv50_graph_load_context; ++ engine->graph.save_context = nv50_graph_save_context; ++ engine->fifo.channels = 128; ++ engine->fifo.init = nv50_fifo_init; ++ engine->fifo.takedown = nv50_fifo_takedown; ++ engine->fifo.channel_id = nv50_fifo_channel_id; ++ engine->fifo.create_context = nv50_fifo_create_context; ++ engine->fifo.destroy_context = nv50_fifo_destroy_context; ++ engine->fifo.load_context = nv50_fifo_load_context; ++ engine->fifo.save_context = nv50_fifo_save_context; ++ break; ++ default: ++ NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int ++nouveau_card_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine; ++ int ret; ++ ++ NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); ++ ++ if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE) ++ return 0; ++ ++ if (drm_core_check_feature(dev, DRIVER_GEM)) ++ dev_priv->mm_enabled = 1; ++ else ++ dev_priv->mm_enabled = 0; ++ ++ /* Determine exact chipset we're running on */ ++ if (dev_priv->card_type < NV_10) ++ dev_priv->chipset = dev_priv->card_type; ++ else ++ dev_priv->chipset = ++ (nv_rd32(NV03_PMC_BOOT_0) & 0x0ff00000) >> 20; ++ ++ /* Initialise internal driver API hooks */ ++ ret = nouveau_init_engine_ptrs(dev); ++ if (ret) return ret; ++ engine = &dev_priv->engine; ++ dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; ++ ++ ret = nouveau_gpuobj_early_init(dev); ++ if (ret) return ret; ++ ++ /* Initialise instance memory, must happen before mem_init so we ++ * know exactly how much VRAM we're able to use for "normal" ++ * purposes. ++ */ ++ ret = engine->instmem.init(dev); ++ if (ret) return ret; ++ ++ /* Setup the memory manager */ ++ if (dev_priv->mm_enabled) { ++ ret = nouveau_mem_init_ttm(dev); ++ if (ret) return ret; ++ } else { ++ ret = nouveau_mem_init(dev); ++ if (ret) return ret; ++ } ++ ++ ret = nouveau_gpuobj_init(dev); ++ if (ret) return ret; ++ ++ /* Parse BIOS tables / Run init tables? */ ++ ++ /* PMC */ ++ ret = engine->mc.init(dev); ++ if (ret) return ret; ++ ++ /* PTIMER */ ++ ret = engine->timer.init(dev); ++ if (ret) return ret; ++ ++ /* PFB */ ++ ret = engine->fb.init(dev); ++ if (ret) return ret; ++ ++ /* PGRAPH */ ++ ret = engine->graph.init(dev); ++ if (ret) return ret; ++ ++ /* PFIFO */ ++ ret = engine->fifo.init(dev); ++ if (ret) return ret; ++ ++ /* this call irq_preinstall, register irq handler and ++ * call irq_postinstall ++ */ ++ ret = drm_irq_install(dev); ++ if (ret) return ret; ++ ++ ret = drm_vblank_init(dev, 0); ++ if (ret) return ret; ++ ++ /* what about PVIDEO/PCRTC/PRAMDAC etc? */ ++ ++ ret = nouveau_dma_channel_init(dev); ++ if (ret) return ret; ++ ++ mutex_init(&dev_priv->submit_mutex); ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ ret = nouveau_parse_bios(dev); ++ if (ret) ++ return ret; ++ ++ if (dev_priv->card_type >= NV_50) { ++ ret = nv50_display_create(dev); ++ if (ret) ++ return ret; ++ } ++ } ++ ++ ret = nouveau_backlight_init(dev); ++ if (ret) ++ NV_ERROR(dev, "Error %d registering backlight\n", ret); ++ ++ dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_helper_initial_config(dev); ++ ++ return 0; ++} ++ ++static void nouveau_card_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ ++ NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); ++ ++ if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) { ++ nouveau_backlight_exit(dev); ++ ++ nouveau_dma_channel_takedown(dev); ++ ++ engine->fifo.takedown(dev); ++ engine->graph.takedown(dev); ++ engine->fb.takedown(dev); ++ engine->timer.takedown(dev); ++ engine->mc.takedown(dev); ++ ++ if (dev_priv->mm_enabled) { ++ mutex_lock(&dev->struct_mutex); ++ drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1); ++ mutex_unlock(&dev->struct_mutex); ++ } else { ++ nouveau_sgdma_nottm_hack_takedown(dev); ++ } ++ nouveau_sgdma_takedown(dev); ++ ++ nouveau_gpuobj_takedown(dev); ++ nouveau_mem_close(dev); ++ engine->instmem.takedown(dev); ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_irq_uninstall(dev); ++ ++ nouveau_gpuobj_late_takedown(dev); ++ ++ dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; ++ } ++} ++ ++/* here a client dies, release the stuff that was allocated for its ++ * file_priv */ ++void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ nouveau_fifo_cleanup(dev, file_priv); ++ ++ if (!dev_priv->mm_enabled) { ++ nouveau_mem_release(file_priv, dev_priv->fb_heap); ++ nouveau_mem_release(file_priv, dev_priv->agp_heap); ++ nouveau_mem_release(file_priv, dev_priv->pci_heap); ++ } ++} ++ ++/* first module load, setup the mmio/fb mapping */ ++/* KMS: we need mmio at load time, not when the first drm client opens. */ ++int nouveau_firstopen(struct drm_device *dev) ++{ ++ return 0; ++} ++ ++#define NV40_CHIPSET_MASK 0x00000baf ++#define NV44_CHIPSET_MASK 0x00005450 ++ ++int nouveau_load(struct drm_device *dev, unsigned long flags) ++{ ++ struct drm_nouveau_private *dev_priv; ++#if defined(__powerpc__) ++ struct device_node *dn; ++#endif ++ uint32_t reg0; ++ uint8_t architecture = 0; ++ int ret; ++ ++ dev_priv = drm_calloc(1, sizeof(*dev_priv), DRM_MEM_DRIVER); ++ if (!dev_priv) ++ return -ENOMEM; ++ dev->dev_private = dev_priv; ++ ++ dev_priv->flags = flags & NOUVEAU_FLAGS; ++ dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; ++ ++ NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", ++ dev->pci_vendor, dev->pci_device, dev->pdev->class); ++ ++ /* resource 0 is mmio regs */ ++ /* resource 1 is linear FB */ ++ /* resource 2 is RAMIN (mmio regs + 0x1000000) */ ++ /* resource 6 is bios */ ++ ++ /* Map 8MiB of the mmio regs, the only stuff beyond that we touch ++ * is the channel control regs, but we'll map them per-channel ++ * as required. ++ */ ++ ret = drm_addmap(dev, drm_get_resource_start(dev, 0), ++ 0x00800000, _DRM_REGISTERS, _DRM_READ_ONLY | ++ _DRM_DRIVER, &dev_priv->mmio); ++ if (ret) { ++ NV_ERROR(dev, "Unable to initialize the mmio mapping (%d). " ++ "Please report your setup to " DRIVER_EMAIL "\n", ++ ret); ++ return -EINVAL; ++ } ++ NV_DEBUG(dev, "regs mapped ok at 0x%lx\n", (unsigned long)dev_priv->mmio->offset); ++ ++#if defined(__powerpc__) ++ /* Put the card in BE mode if it's not */ ++ if (nv_rd32(NV03_PMC_BOOT_1)) ++ nv_wr32(NV03_PMC_BOOT_1,0x00000001); ++ ++ DRM_MEMORYBARRIER(); ++#endif ++ ++ /* Time to determine the card architecture */ ++ reg0 = nv_rd32(NV03_PMC_BOOT_0); ++ ++ /* We're dealing with >=NV10 */ ++ if ((reg0 & 0x0f000000) > 0 ) { ++ /* Bit 27-20 contain the architecture in hex */ ++ architecture = (reg0 & 0xff00000) >> 20; ++ /* NV04 or NV05 */ ++ } else if ((reg0 & 0xff00fff0) == 0x20004000) { ++ architecture = 0x04; ++ } ++ ++ if (architecture >= 0x80) { ++ dev_priv->card_type = NV_50; ++ } else if (architecture >= 0x60) { ++ /* FIXME we need to figure out who's who for NV6x */ ++ dev_priv->card_type = NV_44; ++ } else if (architecture >= 0x50) { ++ dev_priv->card_type = NV_50; ++ } else if (architecture >= 0x40) { ++ uint8_t subarch = architecture & 0xf; ++ /* Selection criteria borrowed from NV40EXA */ ++ if (NV40_CHIPSET_MASK & (1 << subarch)) { ++ dev_priv->card_type = NV_40; ++ } else if (NV44_CHIPSET_MASK & (1 << subarch)) { ++ dev_priv->card_type = NV_44; ++ } else { ++ dev_priv->card_type = NV_UNKNOWN; ++ } ++ } else if (architecture >= 0x30) { ++ dev_priv->card_type = NV_30; ++ } else if (architecture >= 0x20) { ++ dev_priv->card_type = NV_20; ++ } else if (architecture >= 0x17) { ++ dev_priv->card_type = NV_17; ++ } else if (architecture >= 0x11) { ++ dev_priv->card_type = NV_11; ++ } else if (architecture >= 0x10) { ++ dev_priv->card_type = NV_10; ++ } else if (architecture >= 0x04) { ++ dev_priv->card_type = NV_04; ++ } else { ++ dev_priv->card_type = NV_UNKNOWN; ++ } ++ ++ NV_INFO(dev, "Detected an NV%d generation card (0x%08x)\n", dev_priv->card_type,reg0); ++ ++ if (dev_priv->card_type == NV_UNKNOWN) { ++ return -EINVAL; ++ } ++ ++ /* map larger RAMIN aperture on NV40 cards */ ++ dev_priv->ramin_map = dev_priv->ramin = NULL; ++ if (dev_priv->card_type >= NV_40) { ++ int ramin_resource = 2; ++ if (drm_get_resource_len(dev, ramin_resource) == 0) ++ ramin_resource = 3; ++ ++ ret = drm_addmap(dev, ++ drm_get_resource_start(dev, ramin_resource), ++ drm_get_resource_len(dev, ramin_resource), ++ _DRM_REGISTERS, _DRM_READ_ONLY | ++ _DRM_DRIVER, &dev_priv->ramin); ++ if (ret) { ++ NV_ERROR(dev, "Failed to init RAMIN mapping, " ++ "limited instance memory available\n"); ++ dev_priv->ramin = NULL; ++ } ++ } ++ ++ /* On older cards (or if the above failed), create a map covering ++ * the BAR0 PRAMIN aperture */ ++ if (!dev_priv->ramin) { ++ ret = drm_addmap(dev, ++ drm_get_resource_start(dev, 0) + NV_RAMIN, ++ (1*1024*1024), ++ _DRM_REGISTERS, _DRM_READ_ONLY | _DRM_DRIVER, ++ &dev_priv->ramin); ++ if (ret) { ++ NV_ERROR(dev, "Failed to map BAR0 PRAMIN: %d\n", ret); ++ return ret; ++ } ++ } ++ ++#if defined(__powerpc__) ++ /* if we have an OF card, copy vbios to RAMIN */ ++ dn = pci_device_to_OF_node(dev->pdev); ++ if (dn) ++ { ++ int size, i; ++ const uint32_t *bios = of_get_property(dn, "NVDA,BMP", &size); ++ if (bios) { ++ for (i = 0; i < size; i+=4) ++ nv_out32(ramin, i, bios[i/4]); ++ NV_INFO(dev, "OF bios successfully copied (%d bytes)\n",size); ++ } else ++ NV_INFO(dev, "Unable to get the OF bios\n"); ++ } ++ else ++ NV_INFO(dev, "Unable to get the OF node\n"); ++#endif ++ ++ /* For those who think they want to be funny. */ ++ if (dev_priv->card_type < NV_50 && ++ drm_core_check_feature(dev, DRIVER_MODESET)) { ++ NV_ERROR(dev, "Kernel modesetting requested but not supported " ++ "on this chipset.\n"); ++ dev->driver->driver_features &= ~(DRIVER_MODESET|DRIVER_GEM); ++ } ++ ++ /* Special flags */ ++ if (dev->pci_device == 0x01a0) { ++ dev_priv->flags |= NV_NFORCE; ++ } else if (dev->pci_device == 0x01f0) { ++ dev_priv->flags |= NV_NFORCE2; ++ } ++ ++ dev->dev_private = (void *)dev_priv; ++ ++ /* For kernel modesetting, init card now and bring up fbcon */ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ ret = nouveau_card_init(dev); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void nouveau_close(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* In the case of an error dev_priv may not be be allocated yet */ ++ if (dev_priv && dev_priv->card_type) ++ nouveau_card_takedown(dev); ++} ++ ++/* KMS: we need mmio at load time, not when the first drm client opens. */ ++void nouveau_lastclose(struct drm_device *dev) ++{ ++ sfbhack_takedown(dev); ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return; ++ ++ nouveau_close(dev); ++} ++ ++int nouveau_unload(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ nv50_display_destroy(dev); ++ nouveau_close(dev); ++ } ++ ++ drm_rmmap(dev, dev_priv->mmio); ++ drm_rmmap(dev, dev_priv->ramin); ++ ++ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); ++ dev->dev_private = NULL; ++ return 0; ++} ++ ++int ++nouveau_ioctl_card_init(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return nouveau_card_init(dev); ++} ++ ++int nouveau_ioctl_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_getparam *getparam = data; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ switch (getparam->param) { ++ case NOUVEAU_GETPARAM_CHIPSET_ID: ++ getparam->value = dev_priv->chipset; ++ break; ++ case NOUVEAU_GETPARAM_PCI_VENDOR: ++ getparam->value=dev->pci_vendor; ++ break; ++ case NOUVEAU_GETPARAM_PCI_DEVICE: ++ getparam->value=dev->pci_device; ++ break; ++ case NOUVEAU_GETPARAM_BUS_TYPE: ++ if (drm_device_is_agp(dev)) ++ getparam->value=NV_AGP; ++ else if (drm_device_is_pcie(dev)) ++ getparam->value=NV_PCIE; ++ else ++ getparam->value=NV_PCI; ++ break; ++ case NOUVEAU_GETPARAM_FB_PHYSICAL: ++ getparam->value=dev_priv->fb_phys; ++ break; ++ case NOUVEAU_GETPARAM_AGP_PHYSICAL: ++ getparam->value=dev_priv->gart_info.aper_base; ++ break; ++ case NOUVEAU_GETPARAM_PCI_PHYSICAL: ++ if ( dev -> sg ) ++ getparam->value=(unsigned long)dev->sg->virtual; ++ else ++ { ++ NV_ERROR(dev, "Requested PCIGART address, " ++ "while no PCIGART was created\n"); ++ return -EINVAL; ++ } ++ break; ++ case NOUVEAU_GETPARAM_FB_SIZE: ++ getparam->value=dev_priv->fb_available_size; ++ break; ++ case NOUVEAU_GETPARAM_AGP_SIZE: ++ getparam->value=dev_priv->gart_info.aper_size; ++ break; ++ case NOUVEAU_GETPARAM_MM_ENABLED: ++ getparam->value = dev_priv->mm_enabled; ++ break; ++ case NOUVEAU_GETPARAM_VM_VRAM_BASE: ++ getparam->value = dev_priv->vm_vram_base; ++ break; ++ case 0xdeadcafe00000001: /* NOUVEAU_GETPARAM_SHAREDFB_HANDLE */ ++ ret = sfbhack_init(dev); ++ if (ret) ++ return ret; ++ ++ getparam->value = dev_priv->sfbhack_handle; ++ break; ++ case 0xdeadcafe00000002: /* NOUVEAU_GETPARAM_SHAREDFB_SIZE */ ++ ret = sfbhack_init(dev); ++ if (ret) ++ return ret; ++ ++ getparam->value = dev_priv->sfbhack_size; ++ break; ++ default: ++ NV_ERROR(dev, "unknown parameter %lld\n", getparam->param); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++int ++nouveau_ioctl_setparam(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_setparam *setparam = data; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ switch (setparam->param) { ++ case NOUVEAU_SETPARAM_CMDBUF_LOCATION: ++ switch (setparam->value) { ++ case NOUVEAU_MEM_AGP: ++ case NOUVEAU_MEM_FB: ++ case NOUVEAU_MEM_PCI: ++ case NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI_ACCEPTABLE: ++ break; ++ default: ++ NV_ERROR(dev, "invalid CMDBUF_LOCATION value=%lld\n", ++ setparam->value); ++ return -EINVAL; ++ } ++ ++ dev_priv->config.cmdbuf.location = setparam->value; ++ break; ++ case NOUVEAU_SETPARAM_CMDBUF_SIZE: ++ dev_priv->config.cmdbuf.size = setparam->value; ++ break; ++ default: ++ NV_ERROR(dev, "unknown parameter %lld\n", setparam->param); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Wait until (value(reg) & mask) == val, up until timeout has hit */ ++bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, ++ uint32_t reg, uint32_t mask, uint32_t val) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; ++ uint64_t start = ptimer->read(dev); ++ ++ do { ++ if ((nv_rd32(reg) & mask) == val) ++ return true; ++ } while (ptimer->read(dev) - start < timeout); ++ ++ return false; ++} ++ ++/* Waits for PGRAPH to go completely idle */ ++void nouveau_wait_for_idle(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv=dev->dev_private; ++ ++ switch(dev_priv->card_type) { ++ case NV_50: ++ break; ++ default: ++ if (!nv_wait(NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) { ++ NV_ERROR(dev, "timed out with status 0x%08x\n", ++ nv_rd32(NV04_PGRAPH_STATUS)); ++ } ++ } ++} ++ ++static int nouveau_suspend(struct drm_device *dev) ++{ ++ struct mem_block *p; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_suspend_resume *susres = &dev_priv->susres; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ int i; ++ ++ drm_free(susres->ramin_copy, susres->ramin_size, DRM_MEM_DRIVER); ++ susres->ramin_size = 0; ++ list_for_each(p, dev_priv->ramin_heap) ++ if (p->file_priv && (p->start + p->size) > susres->ramin_size) ++ susres->ramin_size = p->start + p->size; ++ if (!(susres->ramin_copy = drm_alloc(susres->ramin_size, DRM_MEM_DRIVER))) { ++ NV_ERROR(dev, "Couldn't alloc RAMIN backing for suspend\n"); ++ return -ENOMEM; ++ } ++ ++ for (i = 0; i < engine->fifo.channels; i++) { ++ uint64_t t_start = engine->timer.read(dev); ++ ++ if (dev_priv->fifos[i] == NULL) ++ continue; ++ ++ /* Give the channel a chance to idle, wait 2s (hopefully) */ ++ while (!nouveau_channel_idle(dev_priv->fifos[i])) ++ if (engine->timer.read(dev) - t_start > 2000000000ULL) { ++ NV_ERROR(dev, "Failed to idle channel %d before" ++ "suspend.", dev_priv->fifos[i]->id); ++ return -EBUSY; ++ } ++ } ++ nouveau_wait_for_idle(dev); ++ ++ nv_wr32(NV04_PGRAPH_FIFO, 0); ++ /* disable the fifo caches */ ++ nv_wr32(NV03_PFIFO_CACHES, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH, ++ nv_rd32(NV04_PFIFO_CACHE1_DMA_PUSH) & ~1); ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000000); ++ ++ susres->fifo_mode = nv_rd32(NV04_PFIFO_MODE); ++ ++ if (dev_priv->card_type >= NV_10) { ++ susres->graph_state = nv_rd32(NV10_PGRAPH_STATE); ++ susres->graph_ctx_control = nv_rd32(NV10_PGRAPH_CTX_CONTROL); ++ } else { ++ susres->graph_state = nv_rd32(NV04_PGRAPH_STATE); ++ susres->graph_ctx_control = nv_rd32(NV04_PGRAPH_CTX_CONTROL); ++ } ++ ++ engine->fifo.save_context(dev_priv->fifos[engine->fifo.channel_id(dev)]); ++ engine->graph.save_context(dev_priv->fifos[engine->fifo.channel_id(dev)]); ++ nouveau_wait_for_idle(dev); ++ ++ engine->instmem.prepare_access(dev, false); ++ for (i = 0; i < susres->ramin_size / 4; i++) ++ susres->ramin_copy[i] = nv_ri32(i << 2); ++ engine->instmem.finish_access(dev); ++ ++ /* reenable the fifo caches */ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH, ++ nv_rd32(NV04_PFIFO_CACHE1_DMA_PUSH) | 1); ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000001); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000001); ++ nv_wr32(NV03_PFIFO_CACHES, 0x00000001); ++ nv_wr32(NV04_PGRAPH_FIFO, 1); ++ ++ return 0; ++} ++ ++static int nouveau_resume(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_suspend_resume *susres = &dev_priv->susres; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ int i; ++ ++ if (!susres->ramin_copy) ++ return -EINVAL; ++ ++ NV_DEBUG(dev, "Doing resume\n"); ++ ++ if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { ++ struct drm_agp_info info; ++ struct drm_agp_mode mode; ++ ++ /* agp bridge drivers don't re-enable agp on resume. lame. */ ++ if ((i = drm_agp_info(dev, &info))) { ++ NV_ERROR(dev, "Unable to get AGP info: %d\n", i); ++ return i; ++ } ++ mode.mode = info.mode; ++ if ((i = drm_agp_enable(dev, mode))) { ++ NV_ERROR(dev, "Unable to enable AGP: %d\n", i); ++ return i; ++ } ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i = 0; i < susres->ramin_size / 4; i++) ++ nv_wi32(i << 2, susres->ramin_copy[i]); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ engine->mc.init(dev); ++ engine->timer.init(dev); ++ engine->fb.init(dev); ++ engine->graph.init(dev); ++ engine->fifo.init(dev); ++ ++ nv_wr32(NV04_PGRAPH_FIFO, 0); ++ /* disable the fifo caches */ ++ nv_wr32(NV03_PFIFO_CACHES, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH, ++ nv_rd32(NV04_PFIFO_CACHE1_DMA_PUSH) & ~1); ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000000); ++ ++ /* PMC power cycling PFIFO in init clobbers some of the stuff stored in ++ * PRAMIN (such as NV04_PFIFO_CACHE1_DMA_INSTANCE). this is unhelpful ++ */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i = 0; i < susres->ramin_size / 4; i++) ++ nv_wi32(i << 2, susres->ramin_copy[i]); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ engine->fifo.load_context(dev_priv->fifos[0]); ++ nv_wr32(NV04_PFIFO_MODE, susres->fifo_mode); ++ ++ engine->graph.load_context(dev_priv->fifos[0]); ++ nouveau_wait_for_idle(dev); ++ ++ if (dev_priv->card_type >= NV_10) { ++ nv_wr32(NV10_PGRAPH_STATE, susres->graph_state); ++ nv_wr32(NV10_PGRAPH_CTX_CONTROL, susres->graph_ctx_control); ++ } else { ++ nv_wr32(NV04_PGRAPH_STATE, susres->graph_state); ++ nv_wr32(NV04_PGRAPH_CTX_CONTROL, susres->graph_ctx_control); ++ } ++ ++ /* reenable the fifo caches */ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH, ++ nv_rd32(NV04_PFIFO_CACHE1_DMA_PUSH) | 1); ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH0, 0x00000001); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x00000001); ++ nv_wr32(NV03_PFIFO_CACHES, 0x00000001); ++ nv_wr32(NV04_PGRAPH_FIFO, 0x1); ++ ++ if (dev->irq_enabled) ++ nouveau_irq_postinstall(dev); ++ ++ drm_free(susres->ramin_copy, susres->ramin_size, DRM_MEM_DRIVER); ++ susres->ramin_copy = NULL; ++ susres->ramin_size = 0; ++ ++ return 0; ++} ++ ++int nouveau_ioctl_suspend(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ return nouveau_suspend(dev); ++} ++ ++int nouveau_ioctl_resume(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ return nouveau_resume(dev); ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_swmthd.c b/drivers/gpu/drm/nouveau/nouveau_swmthd.c +new file mode 100644 +index 0000000..fcb05fa +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_swmthd.c +@@ -0,0 +1,190 @@ ++/* ++ * Copyright (C) 2007 Arthur Huillet. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++/* ++ * Authors: ++ * Arthur Huillet ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_reg.h" ++ ++/*TODO: add a "card_type" attribute*/ ++typedef struct{ ++ uint32_t oclass; /* object class for this software method */ ++ uint32_t mthd; /* method number */ ++ void (*method_code)(struct drm_device *dev, uint32_t oclass, uint32_t mthd); /* pointer to the function that does the work */ ++ } nouveau_software_method_t; ++ ++ ++ /* This function handles the NV04 setcontext software methods. ++One function for all because they are very similar.*/ ++static void nouveau_NV04_setcontext_sw_method(struct drm_device *dev, uint32_t oclass, uint32_t mthd) { ++ uint32_t inst_loc = nv_rd32(NV04_PGRAPH_CTX_SWITCH4) & 0xFFFF; ++ uint32_t value_to_set = 0, bit_to_set = 0; ++ ++ switch ( oclass ) { ++ case 0x4a: ++ switch ( mthd ) { ++ case 0x188 : ++ case 0x18c : ++ bit_to_set = 0; ++ break; ++ case 0x198 : ++ bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ ++ break; ++ case 0x2fc : ++ bit_to_set = nv_rd32(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ ++ break; ++ default : ; ++ }; ++ break; ++ case 0x5c: ++ switch ( mthd ) { ++ case 0x184: ++ bit_to_set = 1 << 13; /*USER_CLIP_ENABLE*/ ++ break; ++ case 0x188: ++ case 0x18c: ++ bit_to_set = 0; ++ break; ++ case 0x198: ++ bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ ++ break; ++ case 0x2fc : ++ bit_to_set = nv_rd32(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ ++ break; ++ }; ++ break; ++ case 0x5f: ++ switch ( mthd ) { ++ case 0x184 : ++ bit_to_set = 1 << 12; /*CHROMA_KEY_ENABLE*/ ++ break; ++ case 0x188 : ++ bit_to_set = 1 << 13; /*USER_CLIP_ENABLE*/ ++ break; ++ case 0x18c : ++ case 0x190 : ++ bit_to_set = 0; ++ break; ++ case 0x19c : ++ bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ ++ break; ++ case 0x2fc : ++ bit_to_set = nv_rd32(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ ++ break; ++ }; ++ break; ++ case 0x61: ++ switch ( mthd ) { ++ case 0x188 : ++ bit_to_set = 1 << 13; /*USER_CLIP_ENABLE*/ ++ break; ++ case 0x18c : ++ case 0x190 : ++ bit_to_set = 0; ++ break; ++ case 0x19c : ++ bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ ++ break; ++ case 0x2fc : ++ bit_to_set = nv_rd32(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ ++ break; ++ }; ++ break; ++ case 0x77: ++ switch ( mthd ) { ++ case 0x198 : ++ bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ ++ break; ++ case 0x304 : ++ bit_to_set = nv_rd32(NV04_PGRAPH_TRAPPED_DATA) << 15; //PATCH_CONFIG ++ break; ++ }; ++ break; ++ default :; ++ }; ++ ++ value_to_set = (nv_rd32(0x00700000 | inst_loc << 4))| bit_to_set; ++ ++ /*RAMIN*/ ++ nouveau_wait_for_idle(dev); ++ nv_wr32(0x00700000 | inst_loc << 4, value_to_set); ++ ++ /*NV_DEBUG(dev, "CTX_SWITCH1 value is %#x\n", nv_rd32(NV04_PGRAPH_CTX_SWITCH1));*/ ++ nv_wr32(NV04_PGRAPH_CTX_SWITCH1, value_to_set); ++ ++ /*NV_DEBUG(dev, "CTX_CACHE1 + xxx value is %#x\n", nv_rd32(NV04_PGRAPH_CTX_CACHE1 + (((nv_rd32(NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7) << 2)));*/ ++ nv_wr32(NV04_PGRAPH_CTX_CACHE1 + (((nv_rd32(NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7) << 2), value_to_set); ++} ++ ++ nouveau_software_method_t nouveau_sw_methods[] = { ++ /*NV04 context software methods*/ ++ { 0x4a, 0x188, nouveau_NV04_setcontext_sw_method }, ++ { 0x4a, 0x18c, nouveau_NV04_setcontext_sw_method }, ++ { 0x4a, 0x198, nouveau_NV04_setcontext_sw_method }, ++ { 0x4a, 0x2fc, nouveau_NV04_setcontext_sw_method }, ++ { 0x5c, 0x184, nouveau_NV04_setcontext_sw_method }, ++ { 0x5c, 0x188, nouveau_NV04_setcontext_sw_method }, ++ { 0x5c, 0x18c, nouveau_NV04_setcontext_sw_method }, ++ { 0x5c, 0x198, nouveau_NV04_setcontext_sw_method }, ++ { 0x5c, 0x2fc, nouveau_NV04_setcontext_sw_method }, ++ { 0x5f, 0x184, nouveau_NV04_setcontext_sw_method }, ++ { 0x5f, 0x188, nouveau_NV04_setcontext_sw_method }, ++ { 0x5f, 0x18c, nouveau_NV04_setcontext_sw_method }, ++ { 0x5f, 0x190, nouveau_NV04_setcontext_sw_method }, ++ { 0x5f, 0x19c, nouveau_NV04_setcontext_sw_method }, ++ { 0x5f, 0x2fc, nouveau_NV04_setcontext_sw_method }, ++ { 0x61, 0x188, nouveau_NV04_setcontext_sw_method }, ++ { 0x61, 0x18c, nouveau_NV04_setcontext_sw_method }, ++ { 0x61, 0x190, nouveau_NV04_setcontext_sw_method }, ++ { 0x61, 0x19c, nouveau_NV04_setcontext_sw_method }, ++ { 0x61, 0x2fc, nouveau_NV04_setcontext_sw_method }, ++ { 0x77, 0x198, nouveau_NV04_setcontext_sw_method }, ++ { 0x77, 0x304, nouveau_NV04_setcontext_sw_method }, ++ /*terminator*/ ++ { 0x0, 0x0, NULL, }, ++ }; ++ ++ int nouveau_sw_method_execute(struct drm_device *dev, uint32_t oclass, uint32_t method) { ++ int i = 0; ++ while ( nouveau_sw_methods[ i ] . method_code != NULL ) ++ { ++ if ( nouveau_sw_methods[ i ] . oclass == oclass && nouveau_sw_methods[ i ] . mthd == method ) ++ { ++ nouveau_sw_methods[ i ] . method_code(dev, oclass, method); ++ return 0; ++ } ++ i ++; ++ } ++ ++ return 1; ++ } +diff --git a/drivers/gpu/drm/nouveau/nouveau_swmthd.h b/drivers/gpu/drm/nouveau/nouveau_swmthd.h +new file mode 100644 +index 0000000..5b9409f +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_swmthd.h +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (C) 2007 Arthur Huillet. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++/* ++ * Authors: ++ * Arthur Huillet ++ */ ++ ++int nouveau_sw_method_execute(struct drm_device *dev, uint32_t oclass, uint32_t method); /* execute the given software method, returns 0 on success */ +diff --git a/drivers/gpu/drm/nouveau/nv04_fb.c b/drivers/gpu/drm/nouveau/nv04_fb.c +new file mode 100644 +index 0000000..cfa04fe +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_fb.c +@@ -0,0 +1,21 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv04_fb_init(struct drm_device *dev) ++{ ++ /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows ++ * nvidia reading PFB_CFG_0, then writing back its original value. ++ * (which was 0x701114 in this case) ++ */ ++ ++ nv_wr32(NV04_PFB_CFG0, 0x1114); ++ return 0; ++} ++ ++void ++nv04_fb_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c +new file mode 100644 +index 0000000..4adaec0 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_fifo.c +@@ -0,0 +1,144 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++#define RAMFC_WR(offset,val) INSTANCE_WR(chan->ramfc->gpuobj, \ ++ NV04_RAMFC_##offset/4, (val)) ++#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \ ++ NV04_RAMFC_##offset/4) ++#define NV04_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV04_RAMFC__SIZE)) ++#define NV04_RAMFC__SIZE 32 ++ ++int ++nv04_fifo_channel_id(struct drm_device *dev) ++{ ++ return (nv_rd32(NV03_PFIFO_CACHE1_PUSH1) & ++ NV03_PFIFO_CACHE1_PUSH1_CHID_MASK); ++} ++ ++int ++nv04_fifo_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ if ((ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0, ++ NV04_RAMFC__SIZE, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, ++ NULL, &chan->ramfc))) ++ return ret; ++ ++ /* Setup initial state */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ RAMFC_WR(DMA_PUT, chan->pushbuf_base); ++ RAMFC_WR(DMA_GET, chan->pushbuf_base); ++ RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4); ++ RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | ++#ifdef __BIG_ENDIAN ++ NV_PFIFO_CACHE1_BIG_ENDIAN | ++#endif ++ 0)); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* enable the fifo dma operation */ ++ nv_wr32(NV04_PFIFO_MODE,nv_rd32(NV04_PFIFO_MODE) | (1<id)); ++ return 0; ++} ++ ++void ++nv04_fifo_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ nv_wr32(NV04_PFIFO_MODE, nv_rd32(NV04_PFIFO_MODE)&~(1<id)); ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++} ++ ++int ++nv04_fifo_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH1, ++ NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); ++ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_GET, RAMFC_RD(DMA_GET)); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUT, RAMFC_RD(DMA_PUT)); ++ ++ tmp = RAMFC_RD(DMA_INSTANCE); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16); ++ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_STATE, RAMFC_RD(DMA_STATE)); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_FETCH, RAMFC_RD(DMA_FETCH)); ++ nv_wr32(NV04_PFIFO_CACHE1_ENGINE, RAMFC_RD(ENGINE)); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL1, RAMFC_RD(PULL1_ENGINE)); ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ ++ tmp = nv_rd32(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_CTL, tmp); ++ ++ return 0; ++} ++ ++int ++nv04_fifo_save_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ++ RAMFC_WR(DMA_PUT, nv_rd32(NV04_PFIFO_CACHE1_DMA_PUT)); ++ RAMFC_WR(DMA_GET, nv_rd32(NV04_PFIFO_CACHE1_DMA_GET)); ++ ++ tmp = nv_rd32(NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; ++ tmp |= nv_rd32(NV04_PFIFO_CACHE1_DMA_INSTANCE); ++ RAMFC_WR(DMA_INSTANCE, tmp); ++ ++ RAMFC_WR(DMA_STATE, nv_rd32(NV04_PFIFO_CACHE1_DMA_STATE)); ++ RAMFC_WR(DMA_FETCH, nv_rd32(NV04_PFIFO_CACHE1_DMA_FETCH)); ++ RAMFC_WR(ENGINE, nv_rd32(NV04_PFIFO_CACHE1_ENGINE)); ++ RAMFC_WR(PULL1_ENGINE, nv_rd32(NV04_PFIFO_CACHE1_PULL1)); ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c +new file mode 100644 +index 0000000..c0033ba +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_graph.c +@@ -0,0 +1,521 @@ ++/* ++ * Copyright 2007 Stephane Marchesin ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drm.h" ++#include "nouveau_drv.h" ++ ++static uint32_t nv04_graph_ctx_regs [] = { ++ NV04_PGRAPH_CTX_SWITCH1, ++ NV04_PGRAPH_CTX_SWITCH2, ++ NV04_PGRAPH_CTX_SWITCH3, ++ NV04_PGRAPH_CTX_SWITCH4, ++ NV04_PGRAPH_CTX_CACHE1, ++ NV04_PGRAPH_CTX_CACHE2, ++ NV04_PGRAPH_CTX_CACHE3, ++ NV04_PGRAPH_CTX_CACHE4, ++ 0x00400184, ++ 0x004001a4, ++ 0x004001c4, ++ 0x004001e4, ++ 0x00400188, ++ 0x004001a8, ++ 0x004001c8, ++ 0x004001e8, ++ 0x0040018c, ++ 0x004001ac, ++ 0x004001cc, ++ 0x004001ec, ++ 0x00400190, ++ 0x004001b0, ++ 0x004001d0, ++ 0x004001f0, ++ 0x00400194, ++ 0x004001b4, ++ 0x004001d4, ++ 0x004001f4, ++ 0x00400198, ++ 0x004001b8, ++ 0x004001d8, ++ 0x004001f8, ++ 0x0040019c, ++ 0x004001bc, ++ 0x004001dc, ++ 0x004001fc, ++ 0x00400174, ++ NV04_PGRAPH_DMA_START_0, ++ NV04_PGRAPH_DMA_START_1, ++ NV04_PGRAPH_DMA_LENGTH, ++ NV04_PGRAPH_DMA_MISC, ++ NV04_PGRAPH_DMA_PITCH, ++ NV04_PGRAPH_BOFFSET0, ++ NV04_PGRAPH_BBASE0, ++ NV04_PGRAPH_BLIMIT0, ++ NV04_PGRAPH_BOFFSET1, ++ NV04_PGRAPH_BBASE1, ++ NV04_PGRAPH_BLIMIT1, ++ NV04_PGRAPH_BOFFSET2, ++ NV04_PGRAPH_BBASE2, ++ NV04_PGRAPH_BLIMIT2, ++ NV04_PGRAPH_BOFFSET3, ++ NV04_PGRAPH_BBASE3, ++ NV04_PGRAPH_BLIMIT3, ++ NV04_PGRAPH_BOFFSET4, ++ NV04_PGRAPH_BBASE4, ++ NV04_PGRAPH_BLIMIT4, ++ NV04_PGRAPH_BOFFSET5, ++ NV04_PGRAPH_BBASE5, ++ NV04_PGRAPH_BLIMIT5, ++ NV04_PGRAPH_BPITCH0, ++ NV04_PGRAPH_BPITCH1, ++ NV04_PGRAPH_BPITCH2, ++ NV04_PGRAPH_BPITCH3, ++ NV04_PGRAPH_BPITCH4, ++ NV04_PGRAPH_SURFACE, ++ NV04_PGRAPH_STATE, ++ NV04_PGRAPH_BSWIZZLE2, ++ NV04_PGRAPH_BSWIZZLE5, ++ NV04_PGRAPH_BPIXEL, ++ NV04_PGRAPH_NOTIFY, ++ NV04_PGRAPH_PATT_COLOR0, ++ NV04_PGRAPH_PATT_COLOR1, ++ NV04_PGRAPH_PATT_COLORRAM+0x00, ++ NV04_PGRAPH_PATT_COLORRAM+0x01, ++ NV04_PGRAPH_PATT_COLORRAM+0x02, ++ NV04_PGRAPH_PATT_COLORRAM+0x03, ++ NV04_PGRAPH_PATT_COLORRAM+0x04, ++ NV04_PGRAPH_PATT_COLORRAM+0x05, ++ NV04_PGRAPH_PATT_COLORRAM+0x06, ++ NV04_PGRAPH_PATT_COLORRAM+0x07, ++ NV04_PGRAPH_PATT_COLORRAM+0x08, ++ NV04_PGRAPH_PATT_COLORRAM+0x09, ++ NV04_PGRAPH_PATT_COLORRAM+0x0A, ++ NV04_PGRAPH_PATT_COLORRAM+0x0B, ++ NV04_PGRAPH_PATT_COLORRAM+0x0C, ++ NV04_PGRAPH_PATT_COLORRAM+0x0D, ++ NV04_PGRAPH_PATT_COLORRAM+0x0E, ++ NV04_PGRAPH_PATT_COLORRAM+0x0F, ++ NV04_PGRAPH_PATT_COLORRAM+0x10, ++ NV04_PGRAPH_PATT_COLORRAM+0x11, ++ NV04_PGRAPH_PATT_COLORRAM+0x12, ++ NV04_PGRAPH_PATT_COLORRAM+0x13, ++ NV04_PGRAPH_PATT_COLORRAM+0x14, ++ NV04_PGRAPH_PATT_COLORRAM+0x15, ++ NV04_PGRAPH_PATT_COLORRAM+0x16, ++ NV04_PGRAPH_PATT_COLORRAM+0x17, ++ NV04_PGRAPH_PATT_COLORRAM+0x18, ++ NV04_PGRAPH_PATT_COLORRAM+0x19, ++ NV04_PGRAPH_PATT_COLORRAM+0x1A, ++ NV04_PGRAPH_PATT_COLORRAM+0x1B, ++ NV04_PGRAPH_PATT_COLORRAM+0x1C, ++ NV04_PGRAPH_PATT_COLORRAM+0x1D, ++ NV04_PGRAPH_PATT_COLORRAM+0x1E, ++ NV04_PGRAPH_PATT_COLORRAM+0x1F, ++ NV04_PGRAPH_PATT_COLORRAM+0x20, ++ NV04_PGRAPH_PATT_COLORRAM+0x21, ++ NV04_PGRAPH_PATT_COLORRAM+0x22, ++ NV04_PGRAPH_PATT_COLORRAM+0x23, ++ NV04_PGRAPH_PATT_COLORRAM+0x24, ++ NV04_PGRAPH_PATT_COLORRAM+0x25, ++ NV04_PGRAPH_PATT_COLORRAM+0x26, ++ NV04_PGRAPH_PATT_COLORRAM+0x27, ++ NV04_PGRAPH_PATT_COLORRAM+0x28, ++ NV04_PGRAPH_PATT_COLORRAM+0x29, ++ NV04_PGRAPH_PATT_COLORRAM+0x2A, ++ NV04_PGRAPH_PATT_COLORRAM+0x2B, ++ NV04_PGRAPH_PATT_COLORRAM+0x2C, ++ NV04_PGRAPH_PATT_COLORRAM+0x2D, ++ NV04_PGRAPH_PATT_COLORRAM+0x2E, ++ NV04_PGRAPH_PATT_COLORRAM+0x2F, ++ NV04_PGRAPH_PATT_COLORRAM+0x30, ++ NV04_PGRAPH_PATT_COLORRAM+0x31, ++ NV04_PGRAPH_PATT_COLORRAM+0x32, ++ NV04_PGRAPH_PATT_COLORRAM+0x33, ++ NV04_PGRAPH_PATT_COLORRAM+0x34, ++ NV04_PGRAPH_PATT_COLORRAM+0x35, ++ NV04_PGRAPH_PATT_COLORRAM+0x36, ++ NV04_PGRAPH_PATT_COLORRAM+0x37, ++ NV04_PGRAPH_PATT_COLORRAM+0x38, ++ NV04_PGRAPH_PATT_COLORRAM+0x39, ++ NV04_PGRAPH_PATT_COLORRAM+0x3A, ++ NV04_PGRAPH_PATT_COLORRAM+0x3B, ++ NV04_PGRAPH_PATT_COLORRAM+0x3C, ++ NV04_PGRAPH_PATT_COLORRAM+0x3D, ++ NV04_PGRAPH_PATT_COLORRAM+0x3E, ++ NV04_PGRAPH_PATT_COLORRAM+0x3F, ++ NV04_PGRAPH_PATTERN, ++ 0x0040080c, ++ NV04_PGRAPH_PATTERN_SHAPE, ++ 0x00400600, ++ NV04_PGRAPH_ROP3, ++ NV04_PGRAPH_CHROMA, ++ NV04_PGRAPH_BETA_AND, ++ NV04_PGRAPH_BETA_PREMULT, ++ NV04_PGRAPH_CONTROL0, ++ NV04_PGRAPH_CONTROL1, ++ NV04_PGRAPH_CONTROL2, ++ NV04_PGRAPH_BLEND, ++ NV04_PGRAPH_STORED_FMT, ++ NV04_PGRAPH_SOURCE_COLOR, ++ 0x00400560, ++ 0x00400568, ++ 0x00400564, ++ 0x0040056c, ++ 0x00400400, ++ 0x00400480, ++ 0x00400404, ++ 0x00400484, ++ 0x00400408, ++ 0x00400488, ++ 0x0040040c, ++ 0x0040048c, ++ 0x00400410, ++ 0x00400490, ++ 0x00400414, ++ 0x00400494, ++ 0x00400418, ++ 0x00400498, ++ 0x0040041c, ++ 0x0040049c, ++ 0x00400420, ++ 0x004004a0, ++ 0x00400424, ++ 0x004004a4, ++ 0x00400428, ++ 0x004004a8, ++ 0x0040042c, ++ 0x004004ac, ++ 0x00400430, ++ 0x004004b0, ++ 0x00400434, ++ 0x004004b4, ++ 0x00400438, ++ 0x004004b8, ++ 0x0040043c, ++ 0x004004bc, ++ 0x00400440, ++ 0x004004c0, ++ 0x00400444, ++ 0x004004c4, ++ 0x00400448, ++ 0x004004c8, ++ 0x0040044c, ++ 0x004004cc, ++ 0x00400450, ++ 0x004004d0, ++ 0x00400454, ++ 0x004004d4, ++ 0x00400458, ++ 0x004004d8, ++ 0x0040045c, ++ 0x004004dc, ++ 0x00400460, ++ 0x004004e0, ++ 0x00400464, ++ 0x004004e4, ++ 0x00400468, ++ 0x004004e8, ++ 0x0040046c, ++ 0x004004ec, ++ 0x00400470, ++ 0x004004f0, ++ 0x00400474, ++ 0x004004f4, ++ 0x00400478, ++ 0x004004f8, ++ 0x0040047c, ++ 0x004004fc, ++ 0x0040053c, ++ 0x00400544, ++ 0x00400540, ++ 0x00400548, ++ 0x00400560, ++ 0x00400568, ++ 0x00400564, ++ 0x0040056c, ++ 0x00400534, ++ 0x00400538, ++ 0x00400514, ++ 0x00400518, ++ 0x0040051c, ++ 0x00400520, ++ 0x00400524, ++ 0x00400528, ++ 0x0040052c, ++ 0x00400530, ++ 0x00400d00, ++ 0x00400d40, ++ 0x00400d80, ++ 0x00400d04, ++ 0x00400d44, ++ 0x00400d84, ++ 0x00400d08, ++ 0x00400d48, ++ 0x00400d88, ++ 0x00400d0c, ++ 0x00400d4c, ++ 0x00400d8c, ++ 0x00400d10, ++ 0x00400d50, ++ 0x00400d90, ++ 0x00400d14, ++ 0x00400d54, ++ 0x00400d94, ++ 0x00400d18, ++ 0x00400d58, ++ 0x00400d98, ++ 0x00400d1c, ++ 0x00400d5c, ++ 0x00400d9c, ++ 0x00400d20, ++ 0x00400d60, ++ 0x00400da0, ++ 0x00400d24, ++ 0x00400d64, ++ 0x00400da4, ++ 0x00400d28, ++ 0x00400d68, ++ 0x00400da8, ++ 0x00400d2c, ++ 0x00400d6c, ++ 0x00400dac, ++ 0x00400d30, ++ 0x00400d70, ++ 0x00400db0, ++ 0x00400d34, ++ 0x00400d74, ++ 0x00400db4, ++ 0x00400d38, ++ 0x00400d78, ++ 0x00400db8, ++ 0x00400d3c, ++ 0x00400d7c, ++ 0x00400dbc, ++ 0x00400590, ++ 0x00400594, ++ 0x00400598, ++ 0x0040059c, ++ 0x004005a8, ++ 0x004005ac, ++ 0x004005b0, ++ 0x004005b4, ++ 0x004005c0, ++ 0x004005c4, ++ 0x004005c8, ++ 0x004005cc, ++ 0x004005d0, ++ 0x004005d4, ++ 0x004005d8, ++ 0x004005dc, ++ 0x004005e0, ++ NV04_PGRAPH_PASSTHRU_0, ++ NV04_PGRAPH_PASSTHRU_1, ++ NV04_PGRAPH_PASSTHRU_2, ++ NV04_PGRAPH_DVD_COLORFMT, ++ NV04_PGRAPH_SCALED_FORMAT, ++ NV04_PGRAPH_MISC24_0, ++ NV04_PGRAPH_MISC24_1, ++ NV04_PGRAPH_MISC24_2, ++ 0x00400500, ++ 0x00400504, ++ NV04_PGRAPH_VALID1, ++ NV04_PGRAPH_VALID2 ++ ++ ++}; ++ ++struct graph_state { ++ int nv04[sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0])]; ++}; ++ ++void nouveau_nv04_context_switch(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ struct nouveau_channel *next, *last; ++ int chid; ++ ++ if (!dev) { ++ NV_DEBUG(dev, "Invalid drm_device\n"); ++ return; ++ } ++ dev_priv = dev->dev_private; ++ if (!dev_priv) { ++ NV_DEBUG(dev, "Invalid drm_nouveau_private\n"); ++ return; ++ } ++ if (!dev_priv->fifos) { ++ NV_DEBUG(dev, "Invalid drm_nouveau_private->fifos\n"); ++ return; ++ } ++ ++ chid = engine->fifo.channel_id(dev); ++ next = dev_priv->fifos[chid]; ++ ++ if (!next) { ++ NV_DEBUG(dev, "Invalid next channel\n"); ++ return; ++ } ++ ++ chid = (nv_rd32(NV04_PGRAPH_CTX_USER) >> 24) & (engine->fifo.channels - 1); ++ last = dev_priv->fifos[chid]; ++ ++ if (!last) { ++ NV_DEBUG(dev, "WARNING: Invalid last channel, switch to %x\n", ++ next->id); ++ } else { ++ NV_INFO(dev, "NV: PGRAPH context switch interrupt channel %x -> %x\n", ++ last->id, next->id); ++ } ++ ++/* nv_wr32(NV03_PFIFO_CACHES, 0x0); ++ nv_wr32(NV04_PFIFO_CACHE0_PULL0, 0x0); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x0);*/ ++ nv_wr32(NV04_PGRAPH_FIFO,0x0); ++ ++ if (last) ++ nv04_graph_save_context(last); ++ ++ nouveau_wait_for_idle(dev); ++ ++ nv_wr32(NV04_PGRAPH_CTX_CONTROL, 0x10000000); ++ nv_wr32(NV04_PGRAPH_CTX_USER, (nv_rd32(NV04_PGRAPH_CTX_USER) & 0xffffff) | (0x0f << 24)); ++ ++ nouveau_wait_for_idle(dev); ++ ++ nv04_graph_load_context(next); ++ ++ nv_wr32(NV04_PGRAPH_CTX_CONTROL, 0x10010100); ++ nv_wr32(NV04_PGRAPH_CTX_USER, next->id << 24); ++ nv_wr32(NV04_PGRAPH_FFINTFC_ST2, nv_rd32(NV04_PGRAPH_FFINTFC_ST2)&0x000FFFFF); ++ ++/* nv_wr32(NV04_PGRAPH_FIFO,0x0); ++ nv_wr32(NV04_PFIFO_CACHE0_PULL0, 0x0); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL0, 0x1); ++ nv_wr32(NV03_PFIFO_CACHES, 0x1);*/ ++ nv_wr32(NV04_PGRAPH_FIFO,0x1); ++} ++ ++int nv04_graph_create_context(struct nouveau_channel *chan) { ++ struct graph_state* pgraph_ctx; ++ NV_DEBUG(chan-> dev, "nv04_graph_context_create %d\n", chan->id); ++ ++ chan->pgraph_ctx = pgraph_ctx = drm_calloc(1, sizeof(*pgraph_ctx), ++ DRM_MEM_DRIVER); ++ ++ if (pgraph_ctx == NULL) ++ return -ENOMEM; ++ ++ //dev_priv->fifos[channel].pgraph_ctx_user = channel << 24; ++ pgraph_ctx->nv04[0] = 0x0001ffff; ++ /* is it really needed ??? */ ++ //dev_priv->fifos[channel].pgraph_ctx[1] = nv_rd32(NV_PGRAPH_DEBUG_4); ++ //dev_priv->fifos[channel].pgraph_ctx[2] = nv_rd32(0x004006b0); ++ ++ return 0; ++} ++ ++void nv04_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ struct graph_state* pgraph_ctx = chan->pgraph_ctx; ++ ++ drm_free(pgraph_ctx, sizeof(*pgraph_ctx), DRM_MEM_DRIVER); ++ chan->pgraph_ctx = NULL; ++} ++ ++int nv04_graph_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct graph_state* pgraph_ctx = chan->pgraph_ctx; ++ int i; ++ ++ for (i = 0; i < sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) ++ nv_wr32(nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]); ++ ++ return 0; ++} ++ ++int nv04_graph_save_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct graph_state* pgraph_ctx = chan->pgraph_ctx; ++ int i; ++ ++ for (i = 0; i < sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) ++ pgraph_ctx->nv04[i] = nv_rd32(nv04_graph_ctx_regs[i]); ++ ++ return 0; ++} ++ ++int nv04_graph_init(struct drm_device *dev) { ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) & ++ ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ ++ /* Enable PGRAPH interrupts */ ++ nv_wr32(NV03_PGRAPH_INTR, 0xFFFFFFFF); ++ nv_wr32(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(NV04_PGRAPH_VALID1, 0); ++ nv_wr32(NV04_PGRAPH_VALID2, 0); ++ /*nv_wr32(NV04_PGRAPH_DEBUG_0, 0x000001FF); ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/ ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0x1231c000); ++ /*1231C000 blob, 001 haiku*/ ++ //*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/ ++ nv_wr32(NV04_PGRAPH_DEBUG_1, 0x72111100); ++ /*0x72111100 blob , 01 haiku*/ ++ /*nv_wr32(NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/ ++ nv_wr32(NV04_PGRAPH_DEBUG_2, 0x11d5f071); ++ /*haiku same*/ ++ ++ /*nv_wr32(NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/ ++ nv_wr32(NV04_PGRAPH_DEBUG_3, 0xf0d4ff31); ++ /*haiku and blob 10d4*/ ++ ++ nv_wr32(NV04_PGRAPH_STATE , 0xFFFFFFFF); ++ nv_wr32(NV04_PGRAPH_CTX_CONTROL , 0x10010100); ++ ++ /* These don't belong here, they're part of a per-channel context */ ++ nv_wr32(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); ++ nv_wr32(NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); ++ ++ return 0; ++} ++ ++void nv04_graph_takedown(struct drm_device *dev) ++{ ++} ++ ++void ++nv04_graph_fifo_access(struct drm_device *dev, bool enabled) ++{ ++ if (enabled) ++ nv_wr32(NV04_PGRAPH_FIFO, nv_rd32(NV04_PGRAPH_FIFO) | 1); ++ else ++ nv_wr32(NV04_PGRAPH_FIFO, nv_rd32(NV04_PGRAPH_FIFO) & ~1); ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c +new file mode 100644 +index 0000000..5994869 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_instmem.c +@@ -0,0 +1,190 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++static void ++nv04_instmem_determine_amount(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int i; ++ ++ /* Figure out how much instance memory we need */ ++ if (dev_priv->card_type >= NV_40) { ++ /* We'll want more instance memory than this on some NV4x cards. ++ * There's a 16MB aperture to play with that maps onto the end ++ * of vram. For now, only reserve a small piece until we know ++ * more about what each chipset requires. ++ */ ++ switch (dev_priv->chipset & 0xf0) { ++ case 0x40: ++ case 0x47: ++ case 0x49: ++ case 0x4b: ++ dev_priv->ramin_rsvd_vram = (2*1024* 1024); ++ break; ++ default: ++ dev_priv->ramin_rsvd_vram = (1*1024* 1024); ++ break; ++ } ++ } else { ++ /*XXX: what *are* the limits on ramin_rsvd_vram = (512*1024); ++ } ++ NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram>>10); ++ ++ /* Clear all of it, except the BIOS image that's in the first 64KiB */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i=(64*1024); iramin_rsvd_vram; i+=4) ++ nv_wi32(i, 0x00000000); ++ dev_priv->engine.instmem.finish_access(dev); ++} ++ ++static void ++nv04_instmem_configure_fixed_tables(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ ++ /* FIFO hash table (RAMHT) ++ * use 4k hash table at RAMIN+0x10000 ++ * TODO: extend the hash table ++ */ ++ dev_priv->ramht_offset = 0x10000; ++ dev_priv->ramht_bits = 9; ++ dev_priv->ramht_size = (1 << dev_priv->ramht_bits); /* nr entries */ ++ dev_priv->ramht_size *= 8; /* 2 32-bit values per entry in RAMHT */ ++ NV_DEBUG(dev, "RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset, ++ dev_priv->ramht_size); ++ ++ /* FIFO runout table (RAMRO) - 512k at 0x11200 */ ++ dev_priv->ramro_offset = 0x11200; ++ dev_priv->ramro_size = 512; ++ NV_DEBUG(dev, "RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset, ++ dev_priv->ramro_size); ++ ++ /* FIFO context table (RAMFC) ++ * NV40 : Not sure exactly how to position RAMFC on some cards, ++ * 0x30002 seems to position it at RAMIN+0x20000 on these ++ * cards. RAMFC is 4kb (32 fifos, 128byte entries). ++ * Others: Position RAMFC at RAMIN+0x11400 ++ */ ++ switch(dev_priv->card_type) ++ { ++ case NV_40: ++ case NV_44: ++ dev_priv->ramfc_offset = 0x20000; ++ dev_priv->ramfc_size = engine->fifo.channels * ++ nouveau_fifo_ctx_size(dev); ++ break; ++ case NV_30: ++ case NV_20: ++ case NV_17: ++ case NV_11: ++ case NV_10: ++ case NV_04: ++ default: ++ dev_priv->ramfc_offset = 0x11400; ++ dev_priv->ramfc_size = engine->fifo.channels * ++ nouveau_fifo_ctx_size(dev); ++ break; ++ } ++ NV_DEBUG(dev, "RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset, ++ dev_priv->ramfc_size); ++} ++ ++int nv04_instmem_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t offset; ++ int ret = 0; ++ ++ nv04_instmem_determine_amount(dev); ++ nv04_instmem_configure_fixed_tables(dev); ++ ++ /* Create a heap to manage RAMIN allocations, we don't allocate ++ * the space that was reserved for RAMHT/FC/RO. ++ */ ++ offset = dev_priv->ramfc_offset + dev_priv->ramfc_size; ++ ++ /* On my NV4E, there's *something* clobbering the 16KiB just after ++ * where we setup these fixed tables. No idea what it is just yet, ++ * so reserve this space on all NV4X cards for now. ++ */ ++ if (dev_priv->card_type >= NV_40) ++ offset += 16*1024; ++ ++ ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, ++ offset, dev_priv->ramin_rsvd_vram - offset); ++ if (ret) { ++ dev_priv->ramin_heap = NULL; ++ NV_ERROR(dev, "Failed to init RAMIN heap\n"); ++ } ++ ++ return ret; ++} ++ ++void ++nv04_instmem_takedown(struct drm_device *dev) ++{ ++} ++ ++int ++nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, uint32_t *sz) ++{ ++ if (gpuobj->im_backing) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++void ++nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (gpuobj && gpuobj->im_backing) { ++ if (gpuobj->im_bound) ++ dev_priv->engine.instmem.unbind(dev, gpuobj); ++ gpuobj->im_backing = NULL; ++ } ++} ++ ++int ++nv04_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ if (!gpuobj->im_pramin || gpuobj->im_bound) ++ return -EINVAL; ++ ++ gpuobj->im_bound = 1; ++ return 0; ++} ++ ++int ++nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ if (gpuobj->im_bound == 0) ++ return -EINVAL; ++ ++ gpuobj->im_bound = 0; ++ return 0; ++} ++ ++void ++nv04_instmem_prepare_access(struct drm_device *dev, bool write) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ BUG_ON(dev_priv->ramin_map != NULL); ++ dev_priv->ramin_map = dev_priv->ramin; ++} ++ ++void ++nv04_instmem_finish_access(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ BUG_ON(dev_priv->ramin_map == NULL); ++ dev_priv->ramin_map = NULL; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_mc.c b/drivers/gpu/drm/nouveau/nv04_mc.c +new file mode 100644 +index 0000000..963c484 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_mc.c +@@ -0,0 +1,20 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv04_mc_init(struct drm_device *dev) ++{ ++ /* Power up everything, resetting each individual unit will ++ * be done later if needed. ++ */ ++ ++ nv_wr32(NV03_PMC_ENABLE, 0xFFFFFFFF); ++ return 0; ++} ++ ++void ++nv04_mc_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv04_timer.c b/drivers/gpu/drm/nouveau/nv04_timer.c +new file mode 100644 +index 0000000..d7466cb +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_timer.c +@@ -0,0 +1,50 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv04_timer_init(struct drm_device *dev) ++{ ++ nv_wr32(NV04_PTIMER_INTR_EN_0, 0x00000000); ++ nv_wr32(NV04_PTIMER_INTR_0, 0xFFFFFFFF); ++ ++ /* Just use the pre-existing values when possible for now; these regs ++ * are not written in nv (driver writer missed a /4 on the address), and ++ * writing 8 and 3 to the correct regs breaks the timings on the LVDS ++ * hardware sequencing microcode. ++ * A correct solution (involving calculations with the GPU PLL) can ++ * be done when kernel modesetting lands ++ */ ++ if (!nv_rd32(NV04_PTIMER_NUMERATOR) || !nv_rd32(NV04_PTIMER_DENOMINATOR)) { ++ nv_wr32(NV04_PTIMER_NUMERATOR, 0x00000008); ++ nv_wr32(NV04_PTIMER_DENOMINATOR, 0x00000003); ++ } ++ ++ return 0; ++} ++ ++uint64_t ++nv04_timer_read(struct drm_device *dev) ++{ ++ uint32_t low; ++ /* From kmmio dumps on nv28 this looks like how the blob does this. ++ * It reads the high dword twice, before and after. ++ * The only explanation seems to be that the 64-bit timer counter ++ * advances between high and low dword reads and may corrupt the ++ * result. Not confirmed. ++ */ ++ uint32_t high2 = nv_rd32(NV04_PTIMER_TIME_1); ++ uint32_t high1; ++ do { ++ high1 = high2; ++ low = nv_rd32(NV04_PTIMER_TIME_0); ++ high2 = nv_rd32(NV04_PTIMER_TIME_1); ++ } while(high1 != high2); ++ return (((uint64_t)high2) << 32) | (uint64_t)low; ++} ++ ++void ++nv04_timer_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv10_fb.c b/drivers/gpu/drm/nouveau/nv10_fb.c +new file mode 100644 +index 0000000..2a9ca65 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv10_fb.c +@@ -0,0 +1,24 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv10_fb_init(struct drm_device *dev) ++{ ++ uint32_t fb_bar_size; ++ int i; ++ ++ fb_bar_size = drm_get_resource_len(dev, 0) - 1; ++ for (i=0; iramfc->gpuobj, \ ++ NV10_RAMFC_##offset/4, (val)) ++#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \ ++ NV10_RAMFC_##offset/4) ++#define NV10_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV10_RAMFC__SIZE)) ++#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32) ++ ++int ++nv10_fifo_channel_id(struct drm_device *dev) ++{ ++ return (nv_rd32(NV03_PFIFO_CACHE1_PUSH1) & ++ NV10_PFIFO_CACHE1_PUSH1_CHID_MASK); ++} ++ ++int ++nv10_fifo_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ if ((ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(chan->id), ~0, ++ NV10_RAMFC__SIZE, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, ++ NULL, &chan->ramfc))) ++ return ret; ++ ++ /* Fill entries that are seen filled in dumps of nvidia driver just ++ * after channel's is put into DMA mode ++ */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ RAMFC_WR(DMA_PUT , chan->pushbuf_base); ++ RAMFC_WR(DMA_GET , chan->pushbuf_base); ++ RAMFC_WR(DMA_INSTANCE , chan->pushbuf->instance >> 4); ++ RAMFC_WR(DMA_FETCH , NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | ++#ifdef __BIG_ENDIAN ++ NV_PFIFO_CACHE1_BIG_ENDIAN | ++#endif ++ 0); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* enable the fifo dma operation */ ++ nv_wr32(NV04_PFIFO_MODE,nv_rd32(NV04_PFIFO_MODE)|(1<id)); ++ return 0; ++} ++ ++void ++nv10_fifo_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ nv_wr32(NV04_PFIFO_MODE, nv_rd32(NV04_PFIFO_MODE)&~(1<id)); ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++} ++ ++int ++nv10_fifo_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH1, ++ NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); ++ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET)); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUT , RAMFC_RD(DMA_PUT)); ++ nv_wr32(NV10_PFIFO_CACHE1_REF_CNT , RAMFC_RD(REF_CNT)); ++ ++ tmp = RAMFC_RD(DMA_INSTANCE); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_INSTANCE , tmp & 0xFFFF); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_DCOUNT , tmp >> 16); ++ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_STATE , RAMFC_RD(DMA_STATE)); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_FETCH , RAMFC_RD(DMA_FETCH)); ++ nv_wr32(NV04_PFIFO_CACHE1_ENGINE , RAMFC_RD(ENGINE)); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL1 , RAMFC_RD(PULL1_ENGINE)); ++ ++ if (dev_priv->chipset >= 0x17) { ++ nv_wr32(NV10_PFIFO_CACHE1_ACQUIRE_VALUE, ++ RAMFC_RD(ACQUIRE_VALUE)); ++ nv_wr32(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, ++ RAMFC_RD(ACQUIRE_TIMESTAMP)); ++ nv_wr32(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, ++ RAMFC_RD(ACQUIRE_TIMEOUT)); ++ nv_wr32(NV10_PFIFO_CACHE1_SEMAPHORE, ++ RAMFC_RD(SEMAPHORE)); ++ nv_wr32(NV10_PFIFO_CACHE1_DMA_SUBROUTINE, ++ RAMFC_RD(DMA_SUBROUTINE)); ++ } ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ ++ tmp = nv_rd32(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_CTL, tmp); ++ ++ return 0; ++} ++ ++int ++nv10_fifo_save_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ++ RAMFC_WR(DMA_PUT , nv_rd32(NV04_PFIFO_CACHE1_DMA_PUT)); ++ RAMFC_WR(DMA_GET , nv_rd32(NV04_PFIFO_CACHE1_DMA_GET)); ++ RAMFC_WR(REF_CNT , nv_rd32(NV10_PFIFO_CACHE1_REF_CNT)); ++ ++ tmp = nv_rd32(NV04_PFIFO_CACHE1_DMA_INSTANCE) & 0xFFFF; ++ tmp |= (nv_rd32(NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16); ++ RAMFC_WR(DMA_INSTANCE , tmp); ++ ++ RAMFC_WR(DMA_STATE , nv_rd32(NV04_PFIFO_CACHE1_DMA_STATE)); ++ RAMFC_WR(DMA_FETCH , nv_rd32(NV04_PFIFO_CACHE1_DMA_FETCH)); ++ RAMFC_WR(ENGINE , nv_rd32(NV04_PFIFO_CACHE1_ENGINE)); ++ RAMFC_WR(PULL1_ENGINE , nv_rd32(NV04_PFIFO_CACHE1_PULL1)); ++ ++ if (dev_priv->chipset >= 0x17) { ++ RAMFC_WR(ACQUIRE_VALUE, ++ nv_rd32(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); ++ RAMFC_WR(ACQUIRE_TIMESTAMP, ++ nv_rd32(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP)); ++ RAMFC_WR(ACQUIRE_TIMEOUT, ++ nv_rd32(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); ++ RAMFC_WR(SEMAPHORE, ++ nv_rd32(NV10_PFIFO_CACHE1_SEMAPHORE)); ++ RAMFC_WR(DMA_SUBROUTINE, ++ nv_rd32(NV04_PFIFO_CACHE1_DMA_GET)); ++ } ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c +new file mode 100644 +index 0000000..2c11b8d +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv10_graph.c +@@ -0,0 +1,912 @@ ++/* ++ * Copyright 2007 Matthieu CASTET ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drm.h" ++#include "nouveau_drv.h" ++ ++#define NV10_FIFO_NUMBER 32 ++ ++struct pipe_state { ++ uint32_t pipe_0x0000[0x040/4]; ++ uint32_t pipe_0x0040[0x010/4]; ++ uint32_t pipe_0x0200[0x0c0/4]; ++ uint32_t pipe_0x4400[0x080/4]; ++ uint32_t pipe_0x6400[0x3b0/4]; ++ uint32_t pipe_0x6800[0x2f0/4]; ++ uint32_t pipe_0x6c00[0x030/4]; ++ uint32_t pipe_0x7000[0x130/4]; ++ uint32_t pipe_0x7400[0x0c0/4]; ++ uint32_t pipe_0x7800[0x0c0/4]; ++}; ++ ++static int nv10_graph_ctx_regs [] = { ++NV10_PGRAPH_CTX_SWITCH1, ++NV10_PGRAPH_CTX_SWITCH2, ++NV10_PGRAPH_CTX_SWITCH3, ++NV10_PGRAPH_CTX_SWITCH4, ++NV10_PGRAPH_CTX_SWITCH5, ++NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */ ++NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */ ++NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */ ++NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */ ++NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */ ++0x00400164, ++0x00400184, ++0x004001a4, ++0x004001c4, ++0x004001e4, ++0x00400168, ++0x00400188, ++0x004001a8, ++0x004001c8, ++0x004001e8, ++0x0040016c, ++0x0040018c, ++0x004001ac, ++0x004001cc, ++0x004001ec, ++0x00400170, ++0x00400190, ++0x004001b0, ++0x004001d0, ++0x004001f0, ++0x00400174, ++0x00400194, ++0x004001b4, ++0x004001d4, ++0x004001f4, ++0x00400178, ++0x00400198, ++0x004001b8, ++0x004001d8, ++0x004001f8, ++0x0040017c, ++0x0040019c, ++0x004001bc, ++0x004001dc, ++0x004001fc, ++NV10_PGRAPH_CTX_USER, ++NV04_PGRAPH_DMA_START_0, ++NV04_PGRAPH_DMA_START_1, ++NV04_PGRAPH_DMA_LENGTH, ++NV04_PGRAPH_DMA_MISC, ++NV10_PGRAPH_DMA_PITCH, ++NV04_PGRAPH_BOFFSET0, ++NV04_PGRAPH_BBASE0, ++NV04_PGRAPH_BLIMIT0, ++NV04_PGRAPH_BOFFSET1, ++NV04_PGRAPH_BBASE1, ++NV04_PGRAPH_BLIMIT1, ++NV04_PGRAPH_BOFFSET2, ++NV04_PGRAPH_BBASE2, ++NV04_PGRAPH_BLIMIT2, ++NV04_PGRAPH_BOFFSET3, ++NV04_PGRAPH_BBASE3, ++NV04_PGRAPH_BLIMIT3, ++NV04_PGRAPH_BOFFSET4, ++NV04_PGRAPH_BBASE4, ++NV04_PGRAPH_BLIMIT4, ++NV04_PGRAPH_BOFFSET5, ++NV04_PGRAPH_BBASE5, ++NV04_PGRAPH_BLIMIT5, ++NV04_PGRAPH_BPITCH0, ++NV04_PGRAPH_BPITCH1, ++NV04_PGRAPH_BPITCH2, ++NV04_PGRAPH_BPITCH3, ++NV04_PGRAPH_BPITCH4, ++NV10_PGRAPH_SURFACE, ++NV10_PGRAPH_STATE, ++NV04_PGRAPH_BSWIZZLE2, ++NV04_PGRAPH_BSWIZZLE5, ++NV04_PGRAPH_BPIXEL, ++NV10_PGRAPH_NOTIFY, ++NV04_PGRAPH_PATT_COLOR0, ++NV04_PGRAPH_PATT_COLOR1, ++NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */ ++0x00400904, ++0x00400908, ++0x0040090c, ++0x00400910, ++0x00400914, ++0x00400918, ++0x0040091c, ++0x00400920, ++0x00400924, ++0x00400928, ++0x0040092c, ++0x00400930, ++0x00400934, ++0x00400938, ++0x0040093c, ++0x00400940, ++0x00400944, ++0x00400948, ++0x0040094c, ++0x00400950, ++0x00400954, ++0x00400958, ++0x0040095c, ++0x00400960, ++0x00400964, ++0x00400968, ++0x0040096c, ++0x00400970, ++0x00400974, ++0x00400978, ++0x0040097c, ++0x00400980, ++0x00400984, ++0x00400988, ++0x0040098c, ++0x00400990, ++0x00400994, ++0x00400998, ++0x0040099c, ++0x004009a0, ++0x004009a4, ++0x004009a8, ++0x004009ac, ++0x004009b0, ++0x004009b4, ++0x004009b8, ++0x004009bc, ++0x004009c0, ++0x004009c4, ++0x004009c8, ++0x004009cc, ++0x004009d0, ++0x004009d4, ++0x004009d8, ++0x004009dc, ++0x004009e0, ++0x004009e4, ++0x004009e8, ++0x004009ec, ++0x004009f0, ++0x004009f4, ++0x004009f8, ++0x004009fc, ++NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */ ++0x0040080c, ++NV04_PGRAPH_PATTERN_SHAPE, ++NV03_PGRAPH_MONO_COLOR0, ++NV04_PGRAPH_ROP3, ++NV04_PGRAPH_CHROMA, ++NV04_PGRAPH_BETA_AND, ++NV04_PGRAPH_BETA_PREMULT, ++0x00400e70, ++0x00400e74, ++0x00400e78, ++0x00400e7c, ++0x00400e80, ++0x00400e84, ++0x00400e88, ++0x00400e8c, ++0x00400ea0, ++0x00400ea4, ++0x00400ea8, ++0x00400e90, ++0x00400e94, ++0x00400e98, ++0x00400e9c, ++NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00 to 0x400f1c */ ++NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20 to 0x400f3c */ ++0x00400f04, ++0x00400f24, ++0x00400f08, ++0x00400f28, ++0x00400f0c, ++0x00400f2c, ++0x00400f10, ++0x00400f30, ++0x00400f14, ++0x00400f34, ++0x00400f18, ++0x00400f38, ++0x00400f1c, ++0x00400f3c, ++NV10_PGRAPH_XFMODE0, ++NV10_PGRAPH_XFMODE1, ++NV10_PGRAPH_GLOBALSTATE0, ++NV10_PGRAPH_GLOBALSTATE1, ++NV04_PGRAPH_STORED_FMT, ++NV04_PGRAPH_SOURCE_COLOR, ++NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */ ++NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */ ++0x00400404, ++0x00400484, ++0x00400408, ++0x00400488, ++0x0040040c, ++0x0040048c, ++0x00400410, ++0x00400490, ++0x00400414, ++0x00400494, ++0x00400418, ++0x00400498, ++0x0040041c, ++0x0040049c, ++0x00400420, ++0x004004a0, ++0x00400424, ++0x004004a4, ++0x00400428, ++0x004004a8, ++0x0040042c, ++0x004004ac, ++0x00400430, ++0x004004b0, ++0x00400434, ++0x004004b4, ++0x00400438, ++0x004004b8, ++0x0040043c, ++0x004004bc, ++0x00400440, ++0x004004c0, ++0x00400444, ++0x004004c4, ++0x00400448, ++0x004004c8, ++0x0040044c, ++0x004004cc, ++0x00400450, ++0x004004d0, ++0x00400454, ++0x004004d4, ++0x00400458, ++0x004004d8, ++0x0040045c, ++0x004004dc, ++0x00400460, ++0x004004e0, ++0x00400464, ++0x004004e4, ++0x00400468, ++0x004004e8, ++0x0040046c, ++0x004004ec, ++0x00400470, ++0x004004f0, ++0x00400474, ++0x004004f4, ++0x00400478, ++0x004004f8, ++0x0040047c, ++0x004004fc, ++NV03_PGRAPH_ABS_UCLIP_XMIN, ++NV03_PGRAPH_ABS_UCLIP_XMAX, ++NV03_PGRAPH_ABS_UCLIP_YMIN, ++NV03_PGRAPH_ABS_UCLIP_YMAX, ++0x00400550, ++0x00400558, ++0x00400554, ++0x0040055c, ++NV03_PGRAPH_ABS_UCLIPA_XMIN, ++NV03_PGRAPH_ABS_UCLIPA_XMAX, ++NV03_PGRAPH_ABS_UCLIPA_YMIN, ++NV03_PGRAPH_ABS_UCLIPA_YMAX, ++NV03_PGRAPH_ABS_ICLIP_XMAX, ++NV03_PGRAPH_ABS_ICLIP_YMAX, ++NV03_PGRAPH_XY_LOGIC_MISC0, ++NV03_PGRAPH_XY_LOGIC_MISC1, ++NV03_PGRAPH_XY_LOGIC_MISC2, ++NV03_PGRAPH_XY_LOGIC_MISC3, ++NV03_PGRAPH_CLIPX_0, ++NV03_PGRAPH_CLIPX_1, ++NV03_PGRAPH_CLIPY_0, ++NV03_PGRAPH_CLIPY_1, ++NV10_PGRAPH_COMBINER0_IN_ALPHA, ++NV10_PGRAPH_COMBINER1_IN_ALPHA, ++NV10_PGRAPH_COMBINER0_IN_RGB, ++NV10_PGRAPH_COMBINER1_IN_RGB, ++NV10_PGRAPH_COMBINER_COLOR0, ++NV10_PGRAPH_COMBINER_COLOR1, ++NV10_PGRAPH_COMBINER0_OUT_ALPHA, ++NV10_PGRAPH_COMBINER1_OUT_ALPHA, ++NV10_PGRAPH_COMBINER0_OUT_RGB, ++NV10_PGRAPH_COMBINER1_OUT_RGB, ++NV10_PGRAPH_COMBINER_FINAL0, ++NV10_PGRAPH_COMBINER_FINAL1, ++0x00400e00, ++0x00400e04, ++0x00400e08, ++0x00400e0c, ++0x00400e10, ++0x00400e14, ++0x00400e18, ++0x00400e1c, ++0x00400e20, ++0x00400e24, ++0x00400e28, ++0x00400e2c, ++0x00400e30, ++0x00400e34, ++0x00400e38, ++0x00400e3c, ++NV04_PGRAPH_PASSTHRU_0, ++NV04_PGRAPH_PASSTHRU_1, ++NV04_PGRAPH_PASSTHRU_2, ++NV10_PGRAPH_DIMX_TEXTURE, ++NV10_PGRAPH_WDIMX_TEXTURE, ++NV10_PGRAPH_DVD_COLORFMT, ++NV10_PGRAPH_SCALED_FORMAT, ++NV04_PGRAPH_MISC24_0, ++NV04_PGRAPH_MISC24_1, ++NV04_PGRAPH_MISC24_2, ++NV03_PGRAPH_X_MISC, ++NV03_PGRAPH_Y_MISC, ++NV04_PGRAPH_VALID1, ++NV04_PGRAPH_VALID2, ++}; ++ ++static int nv17_graph_ctx_regs [] = { ++NV10_PGRAPH_DEBUG_4, ++0x004006b0, ++0x00400eac, ++0x00400eb0, ++0x00400eb4, ++0x00400eb8, ++0x00400ebc, ++0x00400ec0, ++0x00400ec4, ++0x00400ec8, ++0x00400ecc, ++0x00400ed0, ++0x00400ed4, ++0x00400ed8, ++0x00400edc, ++0x00400ee0, ++0x00400a00, ++0x00400a04, ++}; ++ ++struct graph_state { ++ int nv10[sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0])]; ++ int nv17[sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0])]; ++ struct pipe_state pipe_state; ++}; ++ ++static void nv10_graph_save_pipe(struct nouveau_channel *chan) { ++ struct drm_device *dev = chan->dev; ++ struct graph_state* pgraph_ctx = chan->pgraph_ctx; ++ struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; ++ int i; ++#define PIPE_SAVE(addr) \ ++ do { \ ++ nv_wr32(NV10_PGRAPH_PIPE_ADDRESS, addr); \ ++ for (i=0; i < sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]); i++) \ ++ fifo_pipe_state->pipe_##addr[i] = nv_rd32(NV10_PGRAPH_PIPE_DATA); \ ++ } while (0) ++ ++ PIPE_SAVE(0x4400); ++ PIPE_SAVE(0x0200); ++ PIPE_SAVE(0x6400); ++ PIPE_SAVE(0x6800); ++ PIPE_SAVE(0x6c00); ++ PIPE_SAVE(0x7000); ++ PIPE_SAVE(0x7400); ++ PIPE_SAVE(0x7800); ++ PIPE_SAVE(0x0040); ++ PIPE_SAVE(0x0000); ++ ++#undef PIPE_SAVE ++} ++ ++static void nv10_graph_load_pipe(struct nouveau_channel *chan) { ++ struct drm_device *dev = chan->dev; ++ struct graph_state* pgraph_ctx = chan->pgraph_ctx; ++ struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; ++ int i; ++ uint32_t xfmode0, xfmode1; ++#define PIPE_RESTORE(addr) \ ++ do { \ ++ nv_wr32(NV10_PGRAPH_PIPE_ADDRESS, addr); \ ++ for (i=0; i < sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]); i++) \ ++ nv_wr32(NV10_PGRAPH_PIPE_DATA, fifo_pipe_state->pipe_##addr[i]); \ ++ } while (0) ++ ++ ++ nouveau_wait_for_idle(dev); ++ /* XXX check haiku comments */ ++ xfmode0 = nv_rd32(NV10_PGRAPH_XFMODE0); ++ xfmode1 = nv_rd32(NV10_PGRAPH_XFMODE1); ++ nv_wr32(NV10_PGRAPH_XFMODE0, 0x10000000); ++ nv_wr32(NV10_PGRAPH_XFMODE1, 0x00000000); ++ nv_wr32(NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); ++ for (i = 0; i < 4; i++) ++ nv_wr32(NV10_PGRAPH_PIPE_DATA, 0x3f800000); ++ for (i = 0; i < 4; i++) ++ nv_wr32(NV10_PGRAPH_PIPE_DATA, 0x00000000); ++ ++ nv_wr32(NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); ++ for (i = 0; i < 3; i++) ++ nv_wr32(NV10_PGRAPH_PIPE_DATA, 0x3f800000); ++ ++ nv_wr32(NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); ++ for (i = 0; i < 3; i++) ++ nv_wr32(NV10_PGRAPH_PIPE_DATA, 0x00000000); ++ ++ nv_wr32(NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); ++ nv_wr32(NV10_PGRAPH_PIPE_DATA, 0x00000008); ++ ++ ++ PIPE_RESTORE(0x0200); ++ nouveau_wait_for_idle(dev); ++ ++ /* restore XFMODE */ ++ nv_wr32(NV10_PGRAPH_XFMODE0, xfmode0); ++ nv_wr32(NV10_PGRAPH_XFMODE1, xfmode1); ++ PIPE_RESTORE(0x6400); ++ PIPE_RESTORE(0x6800); ++ PIPE_RESTORE(0x6c00); ++ PIPE_RESTORE(0x7000); ++ PIPE_RESTORE(0x7400); ++ PIPE_RESTORE(0x7800); ++ PIPE_RESTORE(0x4400); ++ PIPE_RESTORE(0x0000); ++ PIPE_RESTORE(0x0040); ++ nouveau_wait_for_idle(dev); ++ ++#undef PIPE_RESTORE ++} ++ ++static void nv10_graph_create_pipe(struct nouveau_channel *chan) { ++ struct drm_device *dev = chan->dev; ++ struct graph_state* pgraph_ctx = chan->pgraph_ctx; ++ struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; ++ uint32_t *fifo_pipe_state_addr; ++ int i; ++#define PIPE_INIT(addr) \ ++ do { \ ++ fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \ ++ } while (0) ++#define PIPE_INIT_END(addr) \ ++ do { \ ++ if (fifo_pipe_state_addr != \ ++ sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]) + fifo_pipe_state->pipe_##addr) \ ++ NV_ERROR(dev, "incomplete pipe init for 0x%x : %p/%p\n", addr, fifo_pipe_state_addr, \ ++ sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]) + fifo_pipe_state->pipe_##addr); \ ++ } while (0) ++#define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value ++ ++ PIPE_INIT(0x0200); ++ for (i = 0; i < 48; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x0200); ++ ++ PIPE_INIT(0x6400); ++ for (i = 0; i < 211; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x40000000); ++ NV_WRITE_PIPE_INIT(0x40000000); ++ NV_WRITE_PIPE_INIT(0x40000000); ++ NV_WRITE_PIPE_INIT(0x40000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f000000); ++ NV_WRITE_PIPE_INIT(0x3f000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ PIPE_INIT_END(0x6400); ++ ++ PIPE_INIT(0x6800); ++ for (i = 0; i < 162; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ for (i = 0; i < 25; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x6800); ++ ++ PIPE_INIT(0x6c00); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0xbf800000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x6c00); ++ ++ PIPE_INIT(0x7000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ for (i = 0; i < 35; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x7000); ++ ++ PIPE_INIT(0x7400); ++ for (i = 0; i < 48; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x7400); ++ ++ PIPE_INIT(0x7800); ++ for (i = 0; i < 48; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x7800); ++ ++ PIPE_INIT(0x4400); ++ for (i = 0; i < 32; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x4400); ++ ++ PIPE_INIT(0x0000); ++ for (i = 0; i < 16; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x0000); ++ ++ PIPE_INIT(0x0040); ++ for (i = 0; i < 4; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x0040); ++ ++#undef PIPE_INIT ++#undef PIPE_INIT_END ++#undef NV_WRITE_PIPE_INIT ++} ++ ++static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) ++{ ++ int i; ++ for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) { ++ if (nv10_graph_ctx_regs[i] == reg) ++ return i; ++ } ++ NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg); ++ return -1; ++} ++ ++static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) ++{ ++ int i; ++ for (i = 0; i < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++) { ++ if (nv17_graph_ctx_regs[i] == reg) ++ return i; ++ } ++ NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg); ++ return -1; ++} ++ ++int nv10_graph_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct graph_state* pgraph_ctx = chan->pgraph_ctx; ++ int i; ++ ++ for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) ++ nv_wr32(nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]); ++ if (dev_priv->chipset>=0x17) { ++ for (i = 0; i < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++) ++ nv_wr32(nv17_graph_ctx_regs[i], pgraph_ctx->nv17[i]); ++ } ++ ++ nv10_graph_load_pipe(chan); ++ ++ return 0; ++} ++ ++int nv10_graph_save_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct graph_state* pgraph_ctx = chan->pgraph_ctx; ++ int i; ++ ++ for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) ++ pgraph_ctx->nv10[i] = nv_rd32(nv10_graph_ctx_regs[i]); ++ if (dev_priv->chipset>=0x17) { ++ for (i = 0; i < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++) ++ pgraph_ctx->nv17[i] = nv_rd32(nv17_graph_ctx_regs[i]); ++ } ++ ++ nv10_graph_save_pipe(chan); ++ ++ return 0; ++} ++ ++void nouveau_nv10_context_switch(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv; ++ struct nouveau_engine *engine; ++ struct nouveau_channel *next, *last; ++ int chid; ++ ++ if (!dev) { ++ NV_DEBUG(dev, "Invalid drm_device\n"); ++ return; ++ } ++ dev_priv = dev->dev_private; ++ if (!dev_priv) { ++ NV_DEBUG(dev, "Invalid drm_nouveau_private\n"); ++ return; ++ } ++ if (!dev_priv->fifos) { ++ NV_DEBUG(dev, "Invalid drm_nouveau_private->fifos\n"); ++ return; ++ } ++ engine = &dev_priv->engine; ++ ++ chid = (nv_rd32(NV04_PGRAPH_TRAPPED_ADDR) >> 20) & ++ (engine->fifo.channels - 1); ++ next = dev_priv->fifos[chid]; ++ ++ if (!next) { ++ NV_ERROR(dev, "Invalid next channel\n"); ++ return; ++ } ++ ++ chid = (nv_rd32(NV10_PGRAPH_CTX_USER) >> 24) & ++ (engine->fifo.channels - 1); ++ last = dev_priv->fifos[chid]; ++ ++ if (!last) { ++ NV_INFO(dev, "WARNING: Invalid last channel, switch to %x\n", ++ next->id); ++ } else { ++ NV_DEBUG(dev, "NV: PGRAPH context switch interrupt channel %x -> %x\n", ++ last->id, next->id); ++ } ++ ++ nv_wr32(NV04_PGRAPH_FIFO,0x0); ++ if (last) { ++ nouveau_wait_for_idle(dev); ++ nv10_graph_save_context(last); ++ } ++ ++ nouveau_wait_for_idle(dev); ++ ++ nv_wr32(NV10_PGRAPH_CTX_CONTROL, 0x10000000); ++ ++ nouveau_wait_for_idle(dev); ++ ++ nv10_graph_load_context(next); ++ ++ nv_wr32(NV10_PGRAPH_CTX_CONTROL, 0x10010100); ++ nv_wr32(NV10_PGRAPH_FFINTFC_ST2, nv_rd32(NV10_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF); ++ nv_wr32(NV04_PGRAPH_FIFO,0x1); ++} ++ ++#define NV_WRITE_CTX(reg, val) do { \ ++ int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \ ++ if (offset > 0) \ ++ pgraph_ctx->nv10[offset] = val; \ ++ } while (0) ++ ++#define NV17_WRITE_CTX(reg, val) do { \ ++ int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \ ++ if (offset > 0) \ ++ pgraph_ctx->nv17[offset] = val; \ ++ } while (0) ++ ++int nv10_graph_create_context(struct nouveau_channel *chan) { ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct graph_state* pgraph_ctx; ++ ++ NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id); ++ ++ chan->pgraph_ctx = pgraph_ctx = drm_calloc(1, sizeof(*pgraph_ctx), ++ DRM_MEM_DRIVER); ++ ++ if (pgraph_ctx == NULL) ++ return -ENOMEM; ++ ++ /* mmio trace suggest that should be done in ddx with methods/objects */ ++#if 0 ++ uint32_t tmp, vramsz; ++ /* per channel init from ddx */ ++ tmp = nv_rd32(NV10_PGRAPH_SURFACE) & 0x0007ff00; ++ /*XXX the original ddx code, does this in 2 steps : ++ * tmp = nv_rd32(NV10_PGRAPH_SURFACE) & 0x0007ff00; ++ * nv_wr32(NV10_PGRAPH_SURFACE, tmp); ++ * tmp = nv_rd32(NV10_PGRAPH_SURFACE) | 0x00020100; ++ * nv_wr32(NV10_PGRAPH_SURFACE, tmp); ++ */ ++ tmp |= 0x00020100; ++ NV_WRITE_CTX(NV10_PGRAPH_SURFACE, tmp); ++ ++ vramsz = drm_get_resource_len(dev, 0) - 1; ++ NV_WRITE_CTX(NV04_PGRAPH_BOFFSET0, 0); ++ NV_WRITE_CTX(NV04_PGRAPH_BOFFSET1, 0); ++ NV_WRITE_CTX(NV04_PGRAPH_BLIMIT0 , vramsz); ++ NV_WRITE_CTX(NV04_PGRAPH_BLIMIT1 , vramsz); ++ ++ NV_WRITE_CTX(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); ++ NV_WRITE_CTX(NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); ++ ++ NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_XMIN, 0); ++ NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMIN, 0); ++ NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); ++ NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); ++#endif ++ ++ NV_WRITE_CTX(0x00400e88, 0x08000000); ++ NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); ++ NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff); ++ NV_WRITE_CTX(0x00400e10, 0x00001000); ++ NV_WRITE_CTX(0x00400e14, 0x00001000); ++ NV_WRITE_CTX(0x00400e30, 0x00080008); ++ NV_WRITE_CTX(0x00400e34, 0x00080008); ++ if (dev_priv->chipset>=0x17) { ++ /* is it really needed ??? */ ++ NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4, nv_rd32(NV10_PGRAPH_DEBUG_4)); ++ NV17_WRITE_CTX(0x004006b0, nv_rd32(0x004006b0)); ++ NV17_WRITE_CTX(0x00400eac, 0x0fff0000); ++ NV17_WRITE_CTX(0x00400eb0, 0x0fff0000); ++ NV17_WRITE_CTX(0x00400ec0, 0x00000080); ++ NV17_WRITE_CTX(0x00400ed0, 0x00000080); ++ } ++ NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24); ++ ++ nv10_graph_create_pipe(chan); ++ return 0; ++} ++ ++void nv10_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ struct graph_state* pgraph_ctx = chan->pgraph_ctx; ++ int chid; ++ ++ drm_free(pgraph_ctx, sizeof(*pgraph_ctx), DRM_MEM_DRIVER); ++ chan->pgraph_ctx = NULL; ++ ++ chid = (nv_rd32(NV10_PGRAPH_CTX_USER) >> 24) & (engine->fifo.channels - 1); ++ ++ /* This code seems to corrupt the 3D pipe, but blob seems to do similar things ???? ++ */ ++#if 0 ++ /* does this avoid a potential context switch while we are written graph ++ * reg, or we should mask graph interrupt ??? ++ */ ++ nv_wr32(NV04_PGRAPH_FIFO,0x0); ++ if (chid == chan->id) { ++ NV_INFO(dev, "cleanning a channel with graph in current context\n"); ++ nouveau_wait_for_idle(dev); ++ NV_INFO(dev, "reseting current graph context\n"); ++ /* can't be call here because of dynamic mem alloc */ ++ //nv10_graph_create_context(chan); ++ nv10_graph_load_context(chan); ++ } ++ nv_wr32(NV04_PGRAPH_FIFO, 0x1); ++#else ++ if (chid == chan->id) { ++ NV_INFO(dev, "cleanning a channel with graph in current context\n"); ++ } ++#endif ++} ++ ++int nv10_graph_init(struct drm_device *dev) { ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int i; ++ ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) & ++ ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ ++ nv_wr32(NV03_PGRAPH_INTR , 0xFFFFFFFF); ++ nv_wr32(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0x00000000); ++ nv_wr32(NV04_PGRAPH_DEBUG_1, 0x00118700); ++ //nv_wr32(NV04_PGRAPH_DEBUG_2, 0x24E00810); /* 0x25f92ad9 */ ++ nv_wr32(NV04_PGRAPH_DEBUG_2, 0x25f92ad9); ++ nv_wr32(NV04_PGRAPH_DEBUG_3, 0x55DE0830 | ++ (1<<29) | ++ (1<<31)); ++ if (dev_priv->chipset>=0x17) { ++ nv_wr32(NV10_PGRAPH_DEBUG_4, 0x1f000000); ++ nv_wr32(0x004006b0, 0x40000020); ++ } ++ else ++ nv_wr32(NV10_PGRAPH_DEBUG_4, 0x00000000); ++ ++ /* copy tile info from PFB */ ++ for (i=0; idev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); ++ unsigned int ctx_size; ++ unsigned int idoffs = 0x28/4; ++ int ret; ++ ++ switch (dev_priv->chipset) { ++ case 0x20: ++ ctx_size = NV20_GRCTX_SIZE; ++ ctx_init = nv20_graph_context_init; ++ idoffs = 0; ++ break; ++ case 0x25: ++ case 0x28: ++ ctx_size = NV25_GRCTX_SIZE; ++ ctx_init = nv25_graph_context_init; ++ break; ++ case 0x2a: ++ ctx_size = NV2A_GRCTX_SIZE; ++ ctx_init = nv2a_graph_context_init; ++ idoffs = 0; ++ break; ++ case 0x30: ++ case 0x31: ++ ctx_size = NV30_31_GRCTX_SIZE; ++ ctx_init = nv30_31_graph_context_init; ++ break; ++ case 0x34: ++ ctx_size = NV34_GRCTX_SIZE; ++ ctx_init = nv34_graph_context_init; ++ break; ++ case 0x35: ++ case 0x36: ++ ctx_size = NV35_36_GRCTX_SIZE; ++ ctx_init = nv35_36_graph_context_init; ++ break; ++ default: ++ ctx_size = 0; ++ ctx_init = nv35_36_graph_context_init; ++ NV_ERROR(dev, "Please contact the devs if you want your NV%x" ++ " card to work\n", dev_priv->chipset); ++ return -ENOSYS; ++ break; ++ } ++ ++ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &chan->ramin_grctx))) ++ return ret; ++ ++ /* Initialise default context values */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ctx_init(dev, chan->ramin_grctx->gpuobj); ++ ++ /* nv20: INSTANCE_WR(chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ ++ INSTANCE_WR(chan->ramin_grctx->gpuobj, idoffs, (chan->id<<24)|0x1); ++ /* CTX_USER */ ++ ++ INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id, ++ chan->ramin_grctx->instance >> 4); ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ return 0; ++} ++ ++void nv20_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (chan->ramin_grctx) ++ nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id, 0); ++ dev_priv->engine.instmem.finish_access(dev); ++} ++ ++int nv20_graph_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t inst; ++ ++ if (!chan->ramin_grctx) ++ return -EINVAL; ++ inst = chan->ramin_grctx->instance >> 4; ++ ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_XFER, ++ NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD); ++ nv_wr32(NV10_PGRAPH_CTX_CONTROL, 0x10010100); ++ ++ nouveau_wait_for_idle(dev); ++ return 0; ++} ++ ++int nv20_graph_save_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t inst; ++ ++ if (!chan->ramin_grctx) ++ return -EINVAL; ++ inst = chan->ramin_grctx->instance >> 4; ++ ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_XFER, ++ NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE); ++ ++ nouveau_wait_for_idle(dev); ++ return 0; ++} ++ ++static void nv20_graph_rdi(struct drm_device *dev) { ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int i, writecount = 32; ++ uint32_t rdi_index = 0x2c80000; ++ ++ if (dev_priv->chipset == 0x20) { ++ rdi_index = 0x3d0000; ++ writecount = 15; ++ } ++ ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, rdi_index); ++ for (i = 0; i < writecount; i++) ++ nv_wr32(NV10_PGRAPH_RDI_DATA, 0); ++ ++ nouveau_wait_for_idle(dev); ++} ++ ++int nv20_graph_init(struct drm_device *dev) { ++ struct drm_nouveau_private *dev_priv = ++ (struct drm_nouveau_private *)dev->dev_private; ++ uint32_t tmp, vramsz; ++ int ret, i; ++ ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) & ++ ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ ++ if (!dev_priv->ctx_table) { ++ /* Create Context Pointer Table */ ++ dev_priv->ctx_table_size = 32 * 4; ++ if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, ++ dev_priv->ctx_table_size, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &dev_priv->ctx_table))) ++ return ret; ++ } ++ ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_TABLE, ++ dev_priv->ctx_table->instance >> 4); ++ ++ nv20_graph_rdi(dev); ++ ++ nv_wr32(NV03_PGRAPH_INTR , 0xFFFFFFFF); ++ nv_wr32(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0x00000000); ++ nv_wr32(NV04_PGRAPH_DEBUG_1, 0x00118700); ++ nv_wr32(NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */ ++ nv_wr32(NV10_PGRAPH_DEBUG_4, 0x00000000); ++ nv_wr32(0x40009C , 0x00000040); ++ ++ if (dev_priv->chipset >= 0x25) { ++ nv_wr32(0x400890, 0x00080000); ++ nv_wr32(0x400610, 0x304B1FB6); ++ nv_wr32(0x400B80, 0x18B82880); ++ nv_wr32(0x400B84, 0x44000000); ++ nv_wr32(0x400098, 0x40000080); ++ nv_wr32(0x400B88, 0x000000ff); ++ } else { ++ nv_wr32(0x400880, 0x00080000); /* 0x0008c7df */ ++ nv_wr32(0x400094, 0x00000005); ++ nv_wr32(0x400B80, 0x45CAA208); /* 0x45eae20e */ ++ nv_wr32(0x400B84, 0x24000000); ++ nv_wr32(0x400098, 0x00000040); ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00E00038); ++ nv_wr32(NV10_PGRAPH_RDI_DATA , 0x00000030); ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00E10038); ++ nv_wr32(NV10_PGRAPH_RDI_DATA , 0x00000030); ++ } ++ ++ /* copy tile info from PFB */ ++ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { ++ nv_wr32(0x00400904 + i*0x10, nv_rd32(NV10_PFB_TLIMIT(i))); ++ /* which is NV40_PGRAPH_TLIMIT0(i) ?? */ ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA0030+i*4); ++ nv_wr32(NV10_PGRAPH_RDI_DATA, nv_rd32(NV10_PFB_TLIMIT(i))); ++ nv_wr32(0x00400908 + i*0x10, nv_rd32(NV10_PFB_TSIZE(i))); ++ /* which is NV40_PGRAPH_TSIZE0(i) ?? */ ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA0050+i*4); ++ nv_wr32(NV10_PGRAPH_RDI_DATA, nv_rd32(NV10_PFB_TSIZE(i))); ++ nv_wr32(0x00400900 + i*0x10, nv_rd32(NV10_PFB_TILE(i))); ++ /* which is NV40_PGRAPH_TILE0(i) ?? */ ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA0010+i*4); ++ nv_wr32(NV10_PGRAPH_RDI_DATA, nv_rd32(NV10_PFB_TILE(i))); ++ } ++ for (i = 0; i < 8; i++) { ++ nv_wr32(0x400980+i*4, nv_rd32(0x100300+i*4)); ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA0090+i*4); ++ nv_wr32(NV10_PGRAPH_RDI_DATA, nv_rd32(0x100300+i*4)); ++ } ++ nv_wr32(0x4009a0, nv_rd32(0x100324)); ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA000C); ++ nv_wr32(NV10_PGRAPH_RDI_DATA, nv_rd32(0x100324)); ++ ++ nv_wr32(NV10_PGRAPH_CTX_CONTROL, 0x10000100); ++ nv_wr32(NV10_PGRAPH_STATE , 0xFFFFFFFF); ++ ++ tmp = nv_rd32(NV10_PGRAPH_SURFACE) & 0x0007ff00; ++ nv_wr32(NV10_PGRAPH_SURFACE, tmp); ++ tmp = nv_rd32(NV10_PGRAPH_SURFACE) | 0x00020100; ++ nv_wr32(NV10_PGRAPH_SURFACE, tmp); ++ ++ /* begin RAM config */ ++ vramsz = drm_get_resource_len(dev, 0) - 1; ++ nv_wr32(0x4009A4, nv_rd32(NV04_PFB_CFG0)); ++ nv_wr32(0x4009A8, nv_rd32(NV04_PFB_CFG1)); ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA0000); ++ nv_wr32(NV10_PGRAPH_RDI_DATA , nv_rd32(NV04_PFB_CFG0)); ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA0004); ++ nv_wr32(NV10_PGRAPH_RDI_DATA , nv_rd32(NV04_PFB_CFG1)); ++ nv_wr32(0x400820, 0); ++ nv_wr32(0x400824, 0); ++ nv_wr32(0x400864, vramsz-1); ++ nv_wr32(0x400868, vramsz-1); ++ ++ /* interesting.. the below overwrites some of the tile setup above.. */ ++ nv_wr32(0x400B20, 0x00000000); ++ nv_wr32(0x400B04, 0xFFFFFFFF); ++ ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_XMIN, 0); ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_YMIN, 0); ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); ++ ++ return 0; ++} ++ ++void nv20_graph_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table); ++} ++ ++int nv30_graph_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++// uint32_t vramsz, tmp; ++ int ret, i; ++ ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) & ++ ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ ++ if (!dev_priv->ctx_table) { ++ /* Create Context Pointer Table */ ++ dev_priv->ctx_table_size = 32 * 4; ++ if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, ++ dev_priv->ctx_table_size, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &dev_priv->ctx_table))) ++ return ret; ++ } ++ ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_TABLE, ++ dev_priv->ctx_table->instance >> 4); ++ ++ nv_wr32(NV03_PGRAPH_INTR , 0xFFFFFFFF); ++ nv_wr32(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0x00000000); ++ nv_wr32(NV04_PGRAPH_DEBUG_1, 0x401287c0); ++ nv_wr32(0x400890, 0x01b463ff); ++ nv_wr32(NV04_PGRAPH_DEBUG_3, 0xf2de0475); ++ nv_wr32(NV10_PGRAPH_DEBUG_4, 0x00008000); ++ nv_wr32(NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6); ++ nv_wr32(0x400B80, 0x1003d888); ++ nv_wr32(0x400B84, 0x0c000000); ++ nv_wr32(0x400098, 0x00000000); ++ nv_wr32(0x40009C, 0x0005ad00); ++ nv_wr32(0x400B88, 0x62ff00ff); // suspiciously like PGRAPH_DEBUG_2 ++ nv_wr32(0x4000a0, 0x00000000); ++ nv_wr32(0x4000a4, 0x00000008); ++ nv_wr32(0x4008a8, 0xb784a400); ++ nv_wr32(0x400ba0, 0x002f8685); ++ nv_wr32(0x400ba4, 0x00231f3f); ++ nv_wr32(0x4008a4, 0x40000020); ++ ++ if (dev_priv->chipset == 0x34) { ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA0004); ++ nv_wr32(NV10_PGRAPH_RDI_DATA , 0x00200201); ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA0008); ++ nv_wr32(NV10_PGRAPH_RDI_DATA , 0x00000008); ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00EA0000); ++ nv_wr32(NV10_PGRAPH_RDI_DATA , 0x00000032); ++ nv_wr32(NV10_PGRAPH_RDI_INDEX, 0x00E00004); ++ nv_wr32(NV10_PGRAPH_RDI_DATA , 0x00000002); ++ } ++ ++ nv_wr32(0x4000c0, 0x00000016); ++ ++ /* copy tile info from PFB */ ++ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { ++ nv_wr32(0x00400904 + i*0x10, nv_rd32(NV10_PFB_TLIMIT(i))); ++ /* which is NV40_PGRAPH_TLIMIT0(i) ?? */ ++ nv_wr32(0x00400908 + i*0x10, nv_rd32(NV10_PFB_TSIZE(i))); ++ /* which is NV40_PGRAPH_TSIZE0(i) ?? */ ++ nv_wr32(0x00400900 + i*0x10, nv_rd32(NV10_PFB_TILE(i))); ++ /* which is NV40_PGRAPH_TILE0(i) ?? */ ++ } ++ ++ nv_wr32(NV10_PGRAPH_CTX_CONTROL, 0x10000100); ++ nv_wr32(NV10_PGRAPH_STATE , 0xFFFFFFFF); ++ nv_wr32(0x0040075c , 0x00000001); ++ ++ /* begin RAM config */ ++// vramsz = drm_get_resource_len(dev, 0) - 1; ++ nv_wr32(0x4009A4, nv_rd32(NV04_PFB_CFG0)); ++ nv_wr32(0x4009A8, nv_rd32(NV04_PFB_CFG1)); ++ if (dev_priv->chipset != 0x34) { ++ nv_wr32(0x400750, 0x00EA0000); ++ nv_wr32(0x400754, nv_rd32(NV04_PFB_CFG0)); ++ nv_wr32(0x400750, 0x00EA0004); ++ nv_wr32(0x400754, nv_rd32(NV04_PFB_CFG1)); ++ } ++ ++#if 0 ++ nv_wr32(0x400820, 0); ++ nv_wr32(0x400824, 0); ++ nv_wr32(0x400864, vramsz-1); ++ nv_wr32(0x400868, vramsz-1); ++ ++ nv_wr32(0x400B20, 0x00000000); ++ nv_wr32(0x400B04, 0xFFFFFFFF); ++ ++ /* per-context state, doesn't belong here */ ++ tmp = nv_rd32(NV10_PGRAPH_SURFACE) & 0x0007ff00; ++ nv_wr32(NV10_PGRAPH_SURFACE, tmp); ++ tmp = nv_rd32(NV10_PGRAPH_SURFACE) | 0x00020100; ++ nv_wr32(NV10_PGRAPH_SURFACE, tmp); ++ ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_XMIN, 0); ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_YMIN, 0); ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); ++#endif ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c +new file mode 100644 +index 0000000..530bbee +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv40_fb.c +@@ -0,0 +1,62 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv40_fb_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t fb_bar_size, tmp; ++ int num_tiles; ++ int i; ++ ++ /* This is strictly a NV4x register (don't know about NV5x). */ ++ /* The blob sets these to all kinds of values, and they mess up our setup. */ ++ /* I got value 0x52802 instead. For some cards the blob even sets it back to 0x1. */ ++ /* Note: the blob doesn't read this value, so i'm pretty sure this is safe for all cards. */ ++ /* Any idea what this is? */ ++ nv_wr32(NV40_PFB_UNK_800, 0x1); ++ ++ switch (dev_priv->chipset) { ++ case 0x40: ++ case 0x45: ++ tmp = nv_rd32(NV10_PFB_CLOSE_PAGE2); ++ nv_wr32(NV10_PFB_CLOSE_PAGE2, tmp & ~(1<<15)); ++ num_tiles = NV10_PFB_TILE__SIZE; ++ break; ++ case 0x46: /* G72 */ ++ case 0x47: /* G70 */ ++ case 0x49: /* G71 */ ++ case 0x4b: /* G73 */ ++ case 0x4c: /* C51 (G7X version) */ ++ num_tiles = NV40_PFB_TILE__SIZE_1; ++ break; ++ default: ++ num_tiles = NV40_PFB_TILE__SIZE_0; ++ break; ++ } ++ ++ fb_bar_size = drm_get_resource_len(dev, 0) - 1; ++ switch (dev_priv->chipset) { ++ case 0x40: ++ for (i=0; iramfc->gpuobj, \ ++ NV40_RAMFC_##offset/4, (val)) ++#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \ ++ NV40_RAMFC_##offset/4) ++#define NV40_RAMFC(c) (dev_priv->ramfc_offset + ((c)*NV40_RAMFC__SIZE)) ++#define NV40_RAMFC__SIZE 128 ++ ++int ++nv40_fifo_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ if ((ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0, ++ NV40_RAMFC__SIZE, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, ++ NULL, &chan->ramfc))) ++ return ret; ++ ++ /* Fill entries that are seen filled in dumps of nvidia driver just ++ * after channel's is put into DMA mode ++ */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ RAMFC_WR(DMA_PUT , chan->pushbuf_base); ++ RAMFC_WR(DMA_GET , chan->pushbuf_base); ++ RAMFC_WR(DMA_INSTANCE , chan->pushbuf->instance >> 4); ++ RAMFC_WR(DMA_FETCH , NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | ++#ifdef __BIG_ENDIAN ++ NV_PFIFO_CACHE1_BIG_ENDIAN | ++#endif ++ 0x30000000 /* no idea.. */); ++ RAMFC_WR(DMA_SUBROUTINE, 0); ++ RAMFC_WR(GRCTX_INSTANCE, chan->ramin_grctx->instance >> 4); ++ RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* enable the fifo dma operation */ ++ nv_wr32(NV04_PFIFO_MODE,nv_rd32(NV04_PFIFO_MODE)|(1<id)); ++ return 0; ++} ++ ++void ++nv40_fifo_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ nv_wr32(NV04_PFIFO_MODE, nv_rd32(NV04_PFIFO_MODE)&~(1<id)); ++ ++ if (chan->ramfc) ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++} ++ ++int ++nv40_fifo_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp, tmp2; ++ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET)); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_PUT , RAMFC_RD(DMA_PUT)); ++ nv_wr32(NV10_PFIFO_CACHE1_REF_CNT , RAMFC_RD(REF_CNT)); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_INSTANCE , RAMFC_RD(DMA_INSTANCE)); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_DCOUNT , RAMFC_RD(DMA_DCOUNT)); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_STATE , RAMFC_RD(DMA_STATE)); ++ ++ /* No idea what 0x2058 is.. */ ++ tmp = RAMFC_RD(DMA_FETCH); ++ tmp2 = nv_rd32(0x2058) & 0xFFF; ++ tmp2 |= (tmp & 0x30000000); ++ nv_wr32(0x2058, tmp2); ++ tmp &= ~0x30000000; ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_FETCH , tmp); ++ ++ nv_wr32(NV04_PFIFO_CACHE1_ENGINE , RAMFC_RD(ENGINE)); ++ nv_wr32(NV04_PFIFO_CACHE1_PULL1 , RAMFC_RD(PULL1_ENGINE)); ++ nv_wr32(NV10_PFIFO_CACHE1_ACQUIRE_VALUE , RAMFC_RD(ACQUIRE_VALUE)); ++ nv_wr32(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, RAMFC_RD(ACQUIRE_TIMESTAMP)); ++ nv_wr32(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT , RAMFC_RD(ACQUIRE_TIMEOUT)); ++ nv_wr32(NV10_PFIFO_CACHE1_SEMAPHORE , RAMFC_RD(SEMAPHORE)); ++ nv_wr32(NV10_PFIFO_CACHE1_DMA_SUBROUTINE , RAMFC_RD(DMA_SUBROUTINE)); ++ nv_wr32(NV40_PFIFO_GRCTX_INSTANCE , RAMFC_RD(GRCTX_INSTANCE)); ++ nv_wr32(0x32e4, RAMFC_RD(UNK_40)); ++ /* NVIDIA does this next line twice... */ ++ nv_wr32(0x32e8, RAMFC_RD(UNK_44)); ++ nv_wr32(0x2088, RAMFC_RD(UNK_4C)); ++ nv_wr32(0x3300, RAMFC_RD(UNK_50)); ++ ++ /* not sure what part is PUT, and which is GET.. never seen a non-zero ++ * value appear in a mmio-trace yet.. ++ */ ++#if 0 ++ tmp = nv_rd32(UNK_84); ++ nv_wr32(NV_PFIFO_CACHE1_GET, tmp ???); ++ nv_wr32(NV_PFIFO_CACHE1_PUT, tmp ???); ++#endif ++ ++ /* Don't clobber the TIMEOUT_ENABLED flag when restoring from RAMFC */ ++ tmp = nv_rd32(NV04_PFIFO_DMA_TIMESLICE) & ~0x1FFFF; ++ tmp |= RAMFC_RD(DMA_TIMESLICE) & 0x1FFFF; ++ nv_wr32(NV04_PFIFO_DMA_TIMESLICE, tmp); ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* Set channel active, and in DMA mode */ ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH1, ++ NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); ++ ++ /* Reset DMA_CTL_AT_INFO to INVALID */ ++ tmp = nv_rd32(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_CTL, tmp); ++ ++ return 0; ++} ++ ++int ++nv40_fifo_save_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ++ RAMFC_WR(DMA_PUT , nv_rd32(NV04_PFIFO_CACHE1_DMA_PUT)); ++ RAMFC_WR(DMA_GET , nv_rd32(NV04_PFIFO_CACHE1_DMA_GET)); ++ RAMFC_WR(REF_CNT , nv_rd32(NV10_PFIFO_CACHE1_REF_CNT)); ++ RAMFC_WR(DMA_INSTANCE , nv_rd32(NV04_PFIFO_CACHE1_DMA_INSTANCE)); ++ RAMFC_WR(DMA_DCOUNT , nv_rd32(NV04_PFIFO_CACHE1_DMA_DCOUNT)); ++ RAMFC_WR(DMA_STATE , nv_rd32(NV04_PFIFO_CACHE1_DMA_STATE)); ++ ++ tmp = nv_rd32(NV04_PFIFO_CACHE1_DMA_FETCH); ++ tmp |= nv_rd32(0x2058) & 0x30000000; ++ RAMFC_WR(DMA_FETCH , tmp); ++ ++ RAMFC_WR(ENGINE , nv_rd32(NV04_PFIFO_CACHE1_ENGINE)); ++ RAMFC_WR(PULL1_ENGINE , nv_rd32(NV04_PFIFO_CACHE1_PULL1)); ++ RAMFC_WR(ACQUIRE_VALUE , nv_rd32(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); ++ tmp = nv_rd32(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP); ++ RAMFC_WR(ACQUIRE_TIMESTAMP, tmp); ++ RAMFC_WR(ACQUIRE_TIMEOUT , nv_rd32(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); ++ RAMFC_WR(SEMAPHORE , nv_rd32(NV10_PFIFO_CACHE1_SEMAPHORE)); ++ ++ /* NVIDIA read 0x3228 first, then write DMA_GET here.. maybe something ++ * more involved depending on the value of 0x3228? ++ */ ++ RAMFC_WR(DMA_SUBROUTINE , nv_rd32(NV04_PFIFO_CACHE1_DMA_GET)); ++ ++ RAMFC_WR(GRCTX_INSTANCE , nv_rd32(NV40_PFIFO_GRCTX_INSTANCE)); ++ ++ /* No idea what the below is for exactly, ripped from a mmio-trace */ ++ RAMFC_WR(UNK_40 , nv_rd32(NV40_PFIFO_UNK32E4)); ++ ++ /* NVIDIA do this next line twice.. bug? */ ++ RAMFC_WR(UNK_44 , nv_rd32(0x32e8)); ++ RAMFC_WR(UNK_4C , nv_rd32(0x2088)); ++ RAMFC_WR(UNK_50 , nv_rd32(0x3300)); ++ ++#if 0 /* no real idea which is PUT/GET in UNK_48.. */ ++ tmp = nv_rd32(NV04_PFIFO_CACHE1_GET); ++ tmp |= (nv_rd32(NV04_PFIFO_CACHE1_PUT) << 16); ++ RAMFC_WR(UNK_48 , tmp); ++#endif ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ return 0; ++} ++ ++int ++nv40_fifo_init(struct drm_device *dev) ++{ ++ int ret; ++ ++ if ((ret = nouveau_fifo_init(dev))) ++ return ret; ++ ++ nv_wr32(NV04_PFIFO_DMA_TIMESLICE, 0x2101ffff); ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c +new file mode 100644 +index 0000000..ba56db8 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv40_graph.c +@@ -0,0 +1,2179 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++/*TODO: deciper what each offset in the context represents. The below ++ * contexts are taken from dumps just after the 3D object is ++ * created. ++ */ ++static void ++nv40_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ /* Always has the "instance address" of itself at offset 0 */ ++ INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); ++ /* unknown */ ++ INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00030/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0011c/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x00120/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x00128/4, 0x02008821); ++ INSTANCE_WR(ctx, 0x0016c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00170/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00174/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x0017c/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00180/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00184/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00188/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x0018c/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x0019c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x001a0/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x001b0/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x001c0/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x001d0/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x00340/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00350/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00354/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00358/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x0035c/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00388/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x0039c/4, 0x00000010); ++ INSTANCE_WR(ctx, 0x00480/4, 0x00000100); ++ INSTANCE_WR(ctx, 0x00494/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00498/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x004b4/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x004b8/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x004bc/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x004d0/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x004ec/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x004f8/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x004fc/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00504/4, 0x00011100); ++ for (i=0x00520; i<=0x0055c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x00568/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x00594/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x00598/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x0059c/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x005a0/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x005b4/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x005cc/4, 0x00000004); ++ INSTANCE_WR(ctx, 0x005d8/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0060c/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x00610/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x00614/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x00618/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x00628/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x0062c/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x00630/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00640/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x0067c/4, 0x00ffff00); ++ /* 0x680-0x6BC - NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(0-15) */ ++ /* 0x6C0-0x6FC - NV30_TCL_PRIMITIVE_3D_TX_FORMAT_UNIT(0-15) */ ++ for (i=0x006C0; i<=0x006fc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ /* 0x700-0x73C - NV30_TCL_PRIMITIVE_3D_TX_WRAP_UNIT(0-15) */ ++ for (i=0x00700; i<=0x0073c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ /* 0x740-0x77C - NV30_TCL_PRIMITIVE_3D_TX_ENABLE_UNIT(0-15) */ ++ /* 0x780-0x7BC - NV30_TCL_PRIMITIVE_3D_TX_SWIZZLE_UNIT(0-15) */ ++ for (i=0x00780; i<=0x007bc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ /* 0x7C0-0x7FC - NV30_TCL_PRIMITIVE_3D_TX_FILTER_UNIT(0-15) */ ++ for (i=0x007c0; i<=0x007fc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ /* 0x800-0x83C - NV30_TCL_PRIMITIVE_3D_TX_XY_DIM_UNIT(0-15) */ ++ for (i=0x00800; i<=0x0083c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ /* 0x840-0x87C - NV30_TCL_PRIMITIVE_3D_TX_UNK07_UNIT(0-15) */ ++ /* 0x880-0x8BC - NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(0-15) */ ++ for (i=0x00880; i<=0x008bc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ /* unknown */ ++ for (i=0x00910; i<=0x0091c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0001bc80); ++ for (i=0x00920; i<=0x0092c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000202); ++ for (i=0x00940; i<=0x0094c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ for (i=0x00960; i<=0x0096c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ INSTANCE_WR(ctx, 0x00980/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x009b4/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x009c0/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x009c4/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x009c8/4, 0x60103f00); ++ INSTANCE_WR(ctx, 0x009d4/4, 0x00020000); ++ INSTANCE_WR(ctx, 0x00a08/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x00aac/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00af0/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00af8/4, 0x80800001); ++ INSTANCE_WR(ctx, 0x00bcc/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00bf8/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00bfc/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c00/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c04/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c08/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c0c/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c44/4, 0x00000001); ++ for (i=0x03008; i<=0x03080; i+=8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x05288; i<=0x08570; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x08628; i<=0x08e18; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x0bd28; i<=0x0f010; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x0f0c8; i<=0x0f8b8; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x127c8; i<=0x15ab0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x15b68; i<=0x16358; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x19268; i<=0x1c550; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x1c608; i<=0x1cdf8; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x1fd08; i<=0x22ff0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x230a8; i<=0x23898; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x267a8; i<=0x29a90; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x29b48; i<=0x2a338; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv41_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); ++ INSTANCE_WR(ctx, 0x00000024/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00000028/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00000030/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0000011c/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x00000120/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x00000128/4, 0x02008821); ++ for (i = 0x00000178; i <= 0x00000180; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00000188/4, 0x00000040); ++ for (i = 0x00000194; i <= 0x000001b0; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x000001d0/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x00000340/4, 0x00040000); ++ for (i = 0x00000350; i <= 0x0000035c; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00000388/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x0000039c/4, 0x00001010); ++ INSTANCE_WR(ctx, 0x000003cc/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x000003d0/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x000003ec/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x000003f0/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x000003f4/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00000408/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x00000418/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x00000424/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00000428/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00000430/4, 0x00011100); ++ for (i = 0x0000044c; i <= 0x00000488; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x00000494/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x000004bc/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x000004c0/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x000004c4/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x000004c8/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x000004dc/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x000004f8/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0000052c/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x00000530/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x00000534/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x00000538/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x00000548/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x0000054c/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x00000550/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00000560/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x00000598/4, 0x00ffff00); ++ for (i = 0x000005dc; i <= 0x00000618; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ for (i = 0x0000061c; i <= 0x00000658; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ for (i = 0x0000069c; i <= 0x000006d8; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ for (i = 0x000006dc; i <= 0x00000718; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ for (i = 0x0000071c; i <= 0x00000758; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ for (i = 0x0000079c; i <= 0x000007d8; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ for (i = 0x0000082c; i <= 0x00000838; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x0001bc80); ++ for (i = 0x0000083c; i <= 0x00000848; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x00000202); ++ for (i = 0x0000085c; i <= 0x00000868; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ for (i = 0x0000087c; i <= 0x00000888; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ INSTANCE_WR(ctx, 0x0000089c/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x000008d0/4, 0x00000021); ++ INSTANCE_WR(ctx, 0x000008d4/4, 0x030c30c3); ++ INSTANCE_WR(ctx, 0x000008e0/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x000008e4/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x000008e8/4, 0x20103f00); ++ INSTANCE_WR(ctx, 0x000008f4/4, 0x00020000); ++ INSTANCE_WR(ctx, 0x0000092c/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x000009b8/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x000009fc/4, 0x00001001); ++ INSTANCE_WR(ctx, 0x00000a04/4, 0x00000003); ++ INSTANCE_WR(ctx, 0x00000a08/4, 0x00888001); ++ INSTANCE_WR(ctx, 0x00000aac/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00000ab8/4, 0x0000ffff); ++ for (i = 0x00000ad4; i <= 0x00000ae4; i += 4) ++ INSTANCE_WR(ctx, i/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00000ae8/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00000b20/4, 0x00000001); ++ for (i = 0x00002ee8; i <= 0x00002f60; i += 8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i = 0x00005168; i <= 0x00007358; i += 24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i = 0x00007368; i <= 0x00007758; i += 16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i = 0x0000a068; i <= 0x0000c258; i += 24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i = 0x0000c268; i <= 0x0000c658; i += 16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i = 0x0000ef68; i <= 0x00011158; i += 24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i = 0x00011168; i <= 0x00011558; i += 16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i = 0x00013e68; i <= 0x00016058; i += 24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i = 0x00016068; i <= 0x00016458; i += 16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++}; ++ ++static void ++nv43_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); ++ INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00030/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0011c/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x00120/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x00128/4, 0x02008821); ++ INSTANCE_WR(ctx, 0x00178/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x0017c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00180/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00188/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00194/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00198/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x0019c/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x001a0/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x001a4/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x001a8/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x001ac/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x001b0/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x001d0/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x00340/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00350/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00354/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00358/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x0035c/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00388/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x0039c/4, 0x00001010); ++ INSTANCE_WR(ctx, 0x003cc/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003d0/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x003ec/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x003f0/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x003f4/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00408/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x00418/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x00424/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00428/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00430/4, 0x00011100); ++ for (i=0x0044c; i<=0x00488; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x00494/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x004bc/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x004c0/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x004c4/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x004c8/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x004dc/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x004f8/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0052c/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x00530/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x00534/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x00538/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x00548/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x0054c/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x00550/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00560/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x00598/4, 0x00ffff00); ++ for (i=0x005dc; i<=0x00618; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ for (i=0x0061c; i<=0x00658; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ for (i=0x0069c; i<=0x006d8; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ for (i=0x006dc; i<=0x00718; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ for (i=0x0071c; i<=0x00758; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ for (i=0x0079c; i<=0x007d8; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ for (i=0x0082c; i<=0x00838; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0001bc80); ++ for (i=0x0083c; i<=0x00848; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000202); ++ for (i=0x0085c; i<=0x00868; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ for (i=0x0087c; i<=0x00888; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ INSTANCE_WR(ctx, 0x0089c/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x008d0/4, 0x00000021); ++ INSTANCE_WR(ctx, 0x008d4/4, 0x030c30c3); ++ INSTANCE_WR(ctx, 0x008e0/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x008e4/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x008e8/4, 0x0c103f00); ++ INSTANCE_WR(ctx, 0x008f4/4, 0x00020000); ++ INSTANCE_WR(ctx, 0x0092c/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x009b8/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x009fc/4, 0x00001001); ++ INSTANCE_WR(ctx, 0x00a04/4, 0x00000003); ++ INSTANCE_WR(ctx, 0x00a08/4, 0x00888001); ++ INSTANCE_WR(ctx, 0x00a8c/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00a98/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00ab4/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00ab8/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00abc/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00ac0/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00af8/4, 0x00000001); ++ for (i=0x02ec0; i<=0x02f38; i+=8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x04c80; i<=0x06e70; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x06e80; i<=0x07270; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x096c0; i<=0x0b8b0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x0b8c0; i<=0x0bcb0; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x0e100; i<=0x102f0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x10300; i<=0x106f0; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++}; ++ ++static void ++nv46_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); ++ INSTANCE_WR(ctx, 0x00040/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00044/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0004c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00138/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x0013c/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x00144/4, 0x02008821); ++ INSTANCE_WR(ctx, 0x00174/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00178/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0017c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00180/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00184/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00188/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0018c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00190/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00194/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00198/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x0019c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x001a4/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x001ec/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x0035c/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x0036c/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00370/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00374/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00378/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x003a4/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x003b8/4, 0x00003010); ++ INSTANCE_WR(ctx, 0x003dc/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003e0/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003e4/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003e8/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003ec/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003f0/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003f4/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003f8/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003fc/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00400/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00404/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00408/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x0040c/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00410/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00414/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00418/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x004b0/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x004b4/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x004d0/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x004d4/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x004d8/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x004ec/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x004fc/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x00500/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00504/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00508/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0050c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00510/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00514/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00518/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0051c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00520/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00524/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00528/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0052c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00530/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00534/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00538/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0053c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00550/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00554/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x0055c/4, 0x00011100); ++ for (i=0x00578; i<0x005b4; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005c0/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x005e8/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x005ec/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x005f0/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x005f4/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x00608/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x00624/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00658/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x0065c/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x00660/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x00664/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x00674/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00678/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x0067c/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0068c/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x006c8/4, 0x00ffff00); ++ for (i=0x0070c; i<=0x00748; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ for (i=0x0074c; i<=0x00788; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ for (i=0x007cc; i<=0x00808; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ for (i=0x0080c; i<=0x00848; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ for (i=0x0084c; i<=0x00888; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ for (i=0x008cc; i<=0x00908; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ for (i=0x0095c; i<=0x00968; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0001bc80); ++ for (i=0x0096c; i<=0x00978; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000202); ++ for (i=0x0098c; i<=0x00998; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ for (i=0x009ac; i<=0x009b8; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ INSTANCE_WR(ctx, 0x009cc/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x00a00/4, 0x00000421); ++ INSTANCE_WR(ctx, 0x00a04/4, 0x030c30c3); ++ INSTANCE_WR(ctx, 0x00a08/4, 0x00011001); ++ INSTANCE_WR(ctx, 0x00a14/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x00a18/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x00a1c/4, 0x0c103f00); ++ INSTANCE_WR(ctx, 0x00a28/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00a60/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x00aec/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00b30/4, 0x00001001); ++ INSTANCE_WR(ctx, 0x00b38/4, 0x00000003); ++ INSTANCE_WR(ctx, 0x00b3c/4, 0x00888001); ++ INSTANCE_WR(ctx, 0x00bc0/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00bcc/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00be8/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00bec/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00bf0/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00bf4/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00c2c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00c30/4, 0x08e00001); ++ INSTANCE_WR(ctx, 0x00c34/4, 0x000e3000); ++ for (i=0x017f8; i<=0x01870; i+=8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x035b8; i<=0x057a8; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x057b8; i<=0x05ba8; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x07f38; i<=0x0a128; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x0a138; i<=0x0a528; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x0c8b8; i<=0x0eaa8; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x0eab8; i<=0x0eea8; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++} ++ ++/* This may only work on 7800 AGP cards, will include a warning */ ++static void ++nv47_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ INSTANCE_WR(ctx, 0x00000000/4, ctx->im_pramin->start); ++ INSTANCE_WR(ctx, 0x00000024/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00000028/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00000030/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0000011c/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x00000120/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x00000128/4, 0x02008821); ++ INSTANCE_WR(ctx, 0x00000178/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x0000017c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00000180/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00000188/4, 0x00000040); ++ for (i=0x00000194; i<=0x000001b0; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x000001d0/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x00000340/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00000350/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00000354/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00000358/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x0000035c/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00000388/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x0000039c/4, 0x00001010); ++ for (i=0x000003c0; i<=0x000003fc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00000454/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00000458/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x00000474/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x00000478/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x0000047c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00000490/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x000004a0/4, 0xffff0000); ++ for (i=0x000004a4; i<=0x000004e0; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x000004f4/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x000004f8/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00000500/4, 0x00011100); ++ for (i=0x0000051c; i<=0x00000558; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x00000564/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x0000058c/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x00000590/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x00000594/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x00000598/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x000005ac/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x000005c8/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x000005fc/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x00000600/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x00000604/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x00000608/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x00000618/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x0000061c/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x00000620/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00000630/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x0000066c/4, 0x00ffff00); ++ for (i=0x000006b0; i<=0x000006ec; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ for (i=0x000006f0; i<=0x0000072c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ for (i=0x00000770; i<=0x000007ac; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ for (i=0x000007b0; i<=0x000007ec; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ for (i=0x000007f0; i<=0x0000082c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ for (i=0x00000870; i<=0x000008ac; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ INSTANCE_WR(ctx, 0x00000900/4, 0x0001bc80); ++ INSTANCE_WR(ctx, 0x00000904/4, 0x0001bc80); ++ INSTANCE_WR(ctx, 0x00000908/4, 0x0001bc80); ++ INSTANCE_WR(ctx, 0x0000090c/4, 0x0001bc80); ++ INSTANCE_WR(ctx, 0x00000910/4, 0x00000202); ++ INSTANCE_WR(ctx, 0x00000914/4, 0x00000202); ++ INSTANCE_WR(ctx, 0x00000918/4, 0x00000202); ++ INSTANCE_WR(ctx, 0x0000091c/4, 0x00000202); ++ for (i=0x00000930; i<=0x0000095c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x00000970/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x000009a4/4, 0x00000021); ++ INSTANCE_WR(ctx, 0x000009a8/4, 0x030c30c3); ++ INSTANCE_WR(ctx, 0x000009b4/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x000009b8/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x000009bc/4, 0x40103f00); ++ INSTANCE_WR(ctx, 0x000009c8/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00000a00/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x00000a8c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00000ad0/4, 0x00001001); ++ INSTANCE_WR(ctx, 0x00000adc/4, 0x00000003); ++ INSTANCE_WR(ctx, 0x00000ae0/4, 0x00888001); ++ for (i=0x00000b10; i<=0x00000b8c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00000bb4/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00000bc0/4, 0x0000ffff); ++ for (i=0x00000bdc; i<=0x00000bf8; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00000bfc/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00000c34/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00000c38/4, 0x08e00001); ++ INSTANCE_WR(ctx, 0x00000c3c/4, 0x000e3000); ++ for (i=0x00003000; i<=0x00003078; i+=8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x00004dc0; i<=0x00006fb0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x00006fc0; i<=0x000073b0; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x00009800; i<=0x0000b9f0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x0000ba00; i<=0x00010430; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x00010440; i<=0x00010830; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x00012c80; i<=0x00014e70; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x00014e80; i<=0x00015270; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x000176c0; i<=0x000198b0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x000198c0; i<=0x00019cb0; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x0001c100; i<=0x0001e2f0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x0001e300; i<=0x0001e6f0; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv49_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); ++ INSTANCE_WR(ctx, 0x00004/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00008/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x0000c/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00010/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00014/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00018/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x0001c/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00020/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x000c4/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x000c8/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x000d0/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x001bc/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x001c0/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x001c8/4, 0x02008821); ++ INSTANCE_WR(ctx, 0x00218/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x0021c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00220/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00228/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00234/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00238/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x0023c/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00240/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00244/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00248/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x0024c/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00250/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00270/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x003e0/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x003f0/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x003f4/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x003f8/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x003fc/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00428/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x0043c/4, 0x00001010); ++ INSTANCE_WR(ctx, 0x00460/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00464/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00468/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x0046c/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00470/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00474/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00478/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x0047c/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00480/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00484/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00488/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x0048c/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00490/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00494/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00498/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x0049c/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x004f4/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x004f8/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x00514/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x00518/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x0051c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00530/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x00540/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x00544/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00548/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0054c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00550/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00554/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00558/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0055c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00560/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00564/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00568/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0056c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00570/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00574/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00578/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0057c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00580/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00594/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00598/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x005a0/4, 0x00011100); ++ INSTANCE_WR(ctx, 0x005bc/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005c0/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005c4/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005c8/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005cc/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005d0/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005d4/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005d8/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005dc/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005e0/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005e4/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005e8/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005ec/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005f0/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005f4/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005f8/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x00604/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x0062c/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x00630/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x00634/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x00638/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x0064c/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x00668/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0069c/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x006a0/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x006a4/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x006a8/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x006b8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x006bc/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x006c0/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x006d0/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x0070c/4, 0x00ffff00); ++ for (i=0x00750; i<=0x0078c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ for (i=0x00790; i<=0x007cc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ for (i=0x00810; i<=0x0084c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ for (i=0x00850; i<=0x0088c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ for (i=0x00890; i<=0x008cc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ for (i=0x00910; i<=0x0094c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ for (i=0x009a0; i<=0x009ac; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0001bc80); ++ for (i=0x009b0; i<=0x009bc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000202); ++ for (i=0x009d0; i<=0x009dc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ for (i=0x009f0; i<=0x009fc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ INSTANCE_WR(ctx, 0x00a10/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x00a44/4, 0x00000421); ++ INSTANCE_WR(ctx, 0x00a48/4, 0x030c30c3); ++ INSTANCE_WR(ctx, 0x00a54/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x00a58/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x00a5c/4, 0x20103f00); ++ INSTANCE_WR(ctx, 0x00a68/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00aa0/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x00b2c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00b70/4, 0x00001001); ++ INSTANCE_WR(ctx, 0x00b7c/4, 0x00000003); ++ INSTANCE_WR(ctx, 0x00b80/4, 0x00888001); ++ INSTANCE_WR(ctx, 0x00bb0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bb4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bb8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bbc/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bc0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bc4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bc8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bcc/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bd0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bd4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bd8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bdc/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00be0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00be4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00be8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bec/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bf0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bf4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bf8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bfc/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c00/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c04/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c08/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c0c/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c10/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c14/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c18/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c1c/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c20/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c24/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c28/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c2c/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c54/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00c60/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00c7c/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c80/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c84/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c88/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c8c/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c90/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c94/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c98/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c9c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00cd4/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00cd8/4, 0x08e00001); ++ INSTANCE_WR(ctx, 0x00cdc/4, 0x000e3000); ++ for(i=0x030a0; i<=0x03118; i+=8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x098a0; i<=0x0ba90; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x0baa0; i<=0x0be90; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x0e2e0; i<=0x0fff0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x10008; i<=0x104d0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x104e0; i<=0x108d0; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x12d20; i<=0x14f10; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x14f20; i<=0x15310; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x17760; i<=0x19950; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x19960; i<=0x19d50; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x1c1a0; i<=0x1e390; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x1e3a0; i<=0x1e790; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x20be0; i<=0x22dd0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x22de0; i<=0x231d0; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv4a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); ++ INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00030/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0011c/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x00120/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x00128/4, 0x02008821); ++ INSTANCE_WR(ctx, 0x00158/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0015c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00160/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00164/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00168/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0016c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00170/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00174/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00178/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x0017c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00180/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00188/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x001d0/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x00340/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00350/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00354/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00358/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x0035c/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00388/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x0039c/4, 0x00003010); ++ INSTANCE_WR(ctx, 0x003cc/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003d0/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x003ec/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x003f0/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x003f4/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00408/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x00418/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x00424/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00428/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00430/4, 0x00011100); ++ for (i=0x0044c; i<=0x00488; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x00494/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x004bc/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x004c0/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x004c4/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x004c8/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x004dc/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x004f8/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0052c/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x00530/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x00534/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x00538/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x00548/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x0054c/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x00550/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0055c/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x00594/4, 0x00ffff00); ++ for (i=0x005d8; i<=0x00614; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ for (i=0x00618; i<=0x00654; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ for (i=0x00698; i<=0x006d4; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ for (i=0x006d8; i<=0x00714; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ for (i=0x00718; i<=0x00754; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ for (i=0x00798; i<=0x007d4; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ for (i=0x00828; i<=0x00834; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0001bc80); ++ for (i=0x00838; i<=0x00844; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000202); ++ for (i=0x00858; i<=0x00864; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ for (i=0x00878; i<=0x00884; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ INSTANCE_WR(ctx, 0x00898/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x008cc/4, 0x00000021); ++ INSTANCE_WR(ctx, 0x008d0/4, 0x030c30c3); ++ INSTANCE_WR(ctx, 0x008d4/4, 0x00011001); ++ INSTANCE_WR(ctx, 0x008e0/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x008e4/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x008e8/4, 0x0c103f00); ++ INSTANCE_WR(ctx, 0x008f4/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x0092c/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x009b8/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x009fc/4, 0x00001001); ++ INSTANCE_WR(ctx, 0x00a04/4, 0x00000003); ++ INSTANCE_WR(ctx, 0x00a08/4, 0x00888001); ++ INSTANCE_WR(ctx, 0x00a8c/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00a98/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00ab4/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00ab8/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00abc/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00ac0/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00af8/4, 0x00000001); ++ for (i=0x016c0; i<=0x01738; i+=8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x03840; i<=0x05670; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x05680; i<=0x05a70; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x07e00; i<=0x09ff0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x0a000; i<=0x0a3f0; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x0c780; i<=0x0e970; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x0e980; i<=0x0ed70; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv4b_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); ++ INSTANCE_WR(ctx, 0x00004/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00008/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x0000c/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00010/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00014/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00018/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x0001c/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x00020/4, 0x0000c040); ++ INSTANCE_WR(ctx, 0x000c4/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x000c8/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x000d0/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x001bc/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x001c0/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x001c8/4, 0x02008821); ++ INSTANCE_WR(ctx, 0x00218/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x0021c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00220/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00228/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00234/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00238/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x0023c/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00240/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00244/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00248/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x0024c/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00250/4, 0x80000000); ++ INSTANCE_WR(ctx, 0x00270/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x003e0/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x003f0/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x003f4/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x003f8/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x003fc/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00428/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x0043c/4, 0x00001010); ++ INSTANCE_WR(ctx, 0x00460/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00464/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00468/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x0046c/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00470/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00474/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00478/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x0047c/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00480/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00484/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00488/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x0048c/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00490/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00494/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x00498/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x0049c/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x004f4/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x004f8/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x00514/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x00518/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x0051c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00530/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x00540/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x00544/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00548/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0054c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00550/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00554/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00558/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0055c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00560/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00564/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00568/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0056c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00570/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00574/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00578/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x0057c/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00580/4, 0x88888888); ++ INSTANCE_WR(ctx, 0x00594/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00598/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x005a0/4, 0x00011100); ++ INSTANCE_WR(ctx, 0x005bc/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005c0/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005c4/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005c8/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005cc/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005d0/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005d4/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005d8/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005dc/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005e0/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005e4/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005e8/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005ec/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005f0/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005f4/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x005f8/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x00604/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x0062c/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x00630/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x00634/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x00638/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x0064c/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x00668/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0069c/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x006a0/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x006a4/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x006a8/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x006b8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x006bc/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x006c0/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x006d0/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x0070c/4, 0x00ffff00); ++ for (i=0x00750; i<=0x0078c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ for (i=0x00790; i<=0x007cc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ for (i=0x00810; i<=0x0084c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ for (i=0x00850; i<=0x0088c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ for (i=0x00890; i<=0x008cc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ for (i=0x00910; i<=0x0094c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ for (i=0x009a0; i<=0x009ac; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0001bc80); ++ for (i=0x009b0; i<=0x009bc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000202); ++ for (i=0x009d0; i<=0x009dc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ for (i=0x009f0; i<=0x009fc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ INSTANCE_WR(ctx, 0x00a10/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x00a44/4, 0x00000421); ++ INSTANCE_WR(ctx, 0x00a48/4, 0x030c30c3); ++ INSTANCE_WR(ctx, 0x00a54/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x00a58/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x00a5c/4, 0x20103f00); ++ INSTANCE_WR(ctx, 0x00a68/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00aa0/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x00b2c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00b70/4, 0x00001001); ++ INSTANCE_WR(ctx, 0x00b7c/4, 0x00000003); ++ INSTANCE_WR(ctx, 0x00b80/4, 0x00888001); ++ INSTANCE_WR(ctx, 0x00bb0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bb4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bb8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bbc/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bc0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bc4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bc8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bcc/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bd0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bd4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bd8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bdc/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00be0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00be4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00be8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bec/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bf0/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bf4/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bf8/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00bfc/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c00/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c04/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c08/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c0c/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c10/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c14/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c18/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c1c/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c20/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c24/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c28/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c2c/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00c54/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00c60/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00c7c/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c80/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c84/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c88/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c8c/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c90/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c94/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c98/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00c9c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00cd4/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00cd8/4, 0x08e00001); ++ INSTANCE_WR(ctx, 0x00cdc/4, 0x000e3000); ++ for(i=0x030a0; i<=0x03118; i+=8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x098a0; i<=0x0ba90; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x0baa0; i<=0x0be90; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x0e2e0; i<=0x0fff0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x10008; i<=0x104d0; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x104e0; i<=0x108d0; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x12d20; i<=0x14f10; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x14f20; i<=0x15310; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for(i=0x17760; i<=0x19950; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for(i=0x19960; i<=0x19d50; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv4c_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); ++ INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00030/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0011c/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x00120/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x00128/4, 0x02008821); ++ INSTANCE_WR(ctx, 0x00158/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0015c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00160/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00164/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00168/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0016c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00170/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00174/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00178/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x0017c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00180/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00188/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x001d0/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x00340/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00350/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00354/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00358/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x0035c/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00388/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x0039c/4, 0x00001010); ++ INSTANCE_WR(ctx, 0x003d0/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003d4/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x003f0/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x003f4/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x003f8/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0040c/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x0041c/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x00428/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x0042c/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00434/4, 0x00011100); ++ for (i=0x00450; i<0x0048c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x00498/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x004c0/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x004c4/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x004c8/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x004cc/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x004e0/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x004fc/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00530/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x00534/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x00538/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x0053c/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x0054c/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x00550/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x00554/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00564/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x0059c/4, 0x00ffff00); ++ for (i=0x005e0; i<=0x0061c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ for (i=0x00620; i<=0x0065c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ for (i=0x006a0; i<=0x006dc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ for (i=0x006e0; i<=0x0071c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ for (i=0x00720; i<=0x0075c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ for (i=0x007a0; i<=0x007dc; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ for (i=0x00830; i<=0x0083c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0001bc80); ++ for (i=0x00840; i<=0x0084c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000202); ++ for (i=0x00860; i<=0x0086c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ for (i=0x00880; i<=0x0088c; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ INSTANCE_WR(ctx, 0x008a0/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x008d4/4, 0x00000020); ++ INSTANCE_WR(ctx, 0x008d8/4, 0x030c30c3); ++ INSTANCE_WR(ctx, 0x008dc/4, 0x00011001); ++ INSTANCE_WR(ctx, 0x008e8/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x008ec/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x008f0/4, 0x0c103f00); ++ INSTANCE_WR(ctx, 0x008fc/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00934/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x009c0/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00a04/4, 0x00001001); ++ INSTANCE_WR(ctx, 0x00a0c/4, 0x00000003); ++ INSTANCE_WR(ctx, 0x00a10/4, 0x00888001); ++ INSTANCE_WR(ctx, 0x00a74/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00a80/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00a9c/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00aa0/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00ad8/4, 0x00000001); ++ for (i=0x016a0; i<0x01718; i+=8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x03460; i<0x05650; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x05660; i<0x05a50; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv4e_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); ++ INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00030/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0011c/4, 0x20010001); ++ INSTANCE_WR(ctx, 0x00120/4, 0x0f73ef00); ++ INSTANCE_WR(ctx, 0x00128/4, 0x02008821); ++ INSTANCE_WR(ctx, 0x00158/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0015c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00160/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00164/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00168/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x0016c/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00170/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00174/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00178/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x0017c/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00180/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x00188/4, 0x00000040); ++ INSTANCE_WR(ctx, 0x001d0/4, 0x0b0b0b0c); ++ INSTANCE_WR(ctx, 0x00340/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x00350/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00354/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00358/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x0035c/4, 0x55555555); ++ INSTANCE_WR(ctx, 0x00388/4, 0x00000008); ++ INSTANCE_WR(ctx, 0x0039c/4, 0x00001010); ++ INSTANCE_WR(ctx, 0x003cc/4, 0x00000111); ++ INSTANCE_WR(ctx, 0x003d0/4, 0x00080060); ++ INSTANCE_WR(ctx, 0x003ec/4, 0x00000080); ++ INSTANCE_WR(ctx, 0x003f0/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x003f4/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00408/4, 0x46400000); ++ INSTANCE_WR(ctx, 0x00418/4, 0xffff0000); ++ INSTANCE_WR(ctx, 0x00424/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00428/4, 0x0fff0000); ++ INSTANCE_WR(ctx, 0x00430/4, 0x00011100); ++ for (i=0x0044c; i<=0x00488; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x07ff0000); ++ INSTANCE_WR(ctx, 0x00494/4, 0x4b7fffff); ++ INSTANCE_WR(ctx, 0x004bc/4, 0x30201000); ++ INSTANCE_WR(ctx, 0x004c0/4, 0x70605040); ++ INSTANCE_WR(ctx, 0x004c4/4, 0xb8a89888); ++ INSTANCE_WR(ctx, 0x004c8/4, 0xf8e8d8c8); ++ INSTANCE_WR(ctx, 0x004dc/4, 0x40100000); ++ INSTANCE_WR(ctx, 0x004f8/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0052c/4, 0x435185d6); ++ INSTANCE_WR(ctx, 0x00530/4, 0x2155b699); ++ INSTANCE_WR(ctx, 0x00534/4, 0xfedcba98); ++ INSTANCE_WR(ctx, 0x00538/4, 0x00000098); ++ INSTANCE_WR(ctx, 0x00548/4, 0xffffffff); ++ INSTANCE_WR(ctx, 0x0054c/4, 0x00ff7000); ++ INSTANCE_WR(ctx, 0x00550/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x0055c/4, 0x00ff0000); ++ INSTANCE_WR(ctx, 0x00594/4, 0x00ffff00); ++ for (i=0x005d8; i<=0x00614; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00018488); ++ for (i=0x00618; i<=0x00654; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00028202); ++ for (i=0x00698; i<=0x006d4; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0000aae4); ++ for (i=0x006d8; i<=0x00714; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x01012000); ++ for (i=0x00718; i<=0x00754; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ for (i=0x00798; i<=0x007d4; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00100008); ++ for (i=0x00828; i<=0x00834; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x0001bc80); ++ for (i=0x00838; i<=0x00844; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000202); ++ for (i=0x00858; i<=0x00864; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00000008); ++ for (i=0x00878; i<=0x00884; i+=4) ++ INSTANCE_WR(ctx, i/4, 0x00080008); ++ INSTANCE_WR(ctx, 0x00898/4, 0x00000002); ++ INSTANCE_WR(ctx, 0x008cc/4, 0x00000020); ++ INSTANCE_WR(ctx, 0x008d0/4, 0x030c30c3); ++ INSTANCE_WR(ctx, 0x008d4/4, 0x00011001); ++ INSTANCE_WR(ctx, 0x008e0/4, 0x3e020200); ++ INSTANCE_WR(ctx, 0x008e4/4, 0x00ffffff); ++ INSTANCE_WR(ctx, 0x008e8/4, 0x0c103f00); ++ INSTANCE_WR(ctx, 0x008f4/4, 0x00040000); ++ INSTANCE_WR(ctx, 0x0092c/4, 0x00008100); ++ INSTANCE_WR(ctx, 0x009b8/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x009fc/4, 0x00001001); ++ INSTANCE_WR(ctx, 0x00a04/4, 0x00000003); ++ INSTANCE_WR(ctx, 0x00a08/4, 0x00888001); ++ INSTANCE_WR(ctx, 0x00a6c/4, 0x00000005); ++ INSTANCE_WR(ctx, 0x00a78/4, 0x0000ffff); ++ INSTANCE_WR(ctx, 0x00a94/4, 0x00005555); ++ INSTANCE_WR(ctx, 0x00a98/4, 0x00000001); ++ INSTANCE_WR(ctx, 0x00aa4/4, 0x00000001); ++ for (i=0x01668; i<=0x016e0; i+=8) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++ for (i=0x03428; i<=0x05618; i+=24) ++ INSTANCE_WR(ctx, i/4, 0x00000001); ++ for (i=0x05628; i<=0x05a18; i+=16) ++ INSTANCE_WR(ctx, i/4, 0x3f800000); ++} ++ ++int ++nv40_graph_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); ++ int ret; ++ ++ /* These functions populate the graphics context with a whole heap ++ * of default state. All these functions are very similar, with ++ * a minimal amount of chipset-specific changes. However, as we're ++ * currently dependant on the context programs used by the NVIDIA ++ * binary driver these functions must match the layout expected by ++ * them. Hopefully at some point this will all change. ++ */ ++ switch (dev_priv->chipset) { ++ case 0x40: ++ ctx_init = nv40_graph_context_init; ++ break; ++ case 0x41: ++ case 0x42: ++ ctx_init = nv41_graph_context_init; ++ break; ++ case 0x43: ++ ctx_init = nv43_graph_context_init; ++ break; ++ case 0x46: ++ ctx_init = nv46_graph_context_init; ++ break; ++ case 0x47: ++ ctx_init = nv47_graph_context_init; ++ break; ++ case 0x49: ++ ctx_init = nv49_graph_context_init; ++ break; ++ case 0x44: ++ case 0x4a: ++ ctx_init = nv4a_graph_context_init; ++ break; ++ case 0x4b: ++ ctx_init = nv4b_graph_context_init; ++ break; ++ case 0x4c: ++ case 0x67: ++ ctx_init = nv4c_graph_context_init; ++ break; ++ case 0x4e: ++ ctx_init = nv4e_graph_context_init; ++ break; ++ default: ++ ctx_init = nv40_graph_context_init; ++ break; ++ } ++ ++ /* Allocate a 175KiB block of PRAMIN to store the context. This ++ * is massive overkill for a lot of chipsets, but it should be safe ++ * until we're able to implement this properly (will happen at more ++ * or less the same time we're able to write our own context programs. ++ */ ++ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 175*1024, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &chan->ramin_grctx))) ++ return ret; ++ ++ /* Initialise default context values */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ctx_init(dev, chan->ramin_grctx->gpuobj); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ return 0; ++} ++ ++void ++nv40_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ nouveau_gpuobj_ref_del(chan->dev, &chan->ramin_grctx); ++} ++ ++static int ++nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save) ++{ ++ uint32_t old_cp, tv = 1000, tmp; ++ int i; ++ ++ old_cp = nv_rd32(NV20_PGRAPH_CHANNEL_CTX_POINTER); ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ ++ tmp = nv_rd32(NV40_PGRAPH_CTXCTL_0310); ++ tmp |= save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE : ++ NV40_PGRAPH_CTXCTL_0310_XFER_LOAD; ++ nv_wr32(NV40_PGRAPH_CTXCTL_0310, tmp); ++ ++ tmp = nv_rd32(NV40_PGRAPH_CTXCTL_0304); ++ tmp |= NV40_PGRAPH_CTXCTL_0304_XFER_CTX; ++ nv_wr32(NV40_PGRAPH_CTXCTL_0304, tmp); ++ ++ nouveau_wait_for_idle(dev); ++ ++ for (i = 0; i < tv; i++) { ++ if (nv_rd32(NV40_PGRAPH_CTXCTL_030C) == 0) ++ break; ++ } ++ ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp); ++ ++ if (i == tv) { ++ uint32_t ucstat = nv_rd32(NV40_PGRAPH_CTXCTL_UCODE_STAT); ++ NV_ERROR(dev, "Failed: Instance=0x%08x Save=%d\n", inst, save); ++ NV_ERROR(dev, "IP: 0x%02x, Opcode: 0x%08x\n", ++ ucstat >> NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT, ++ ucstat & NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK); ++ NV_ERROR(dev, "0x40030C = 0x%08x\n", ++ nv_rd32(NV40_PGRAPH_CTXCTL_030C)); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++/* Save current context (from PGRAPH) into the channel's context */ ++int ++nv40_graph_save_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t inst; ++ ++ if (!chan->ramin_grctx) ++ return -EINVAL; ++ inst = chan->ramin_grctx->instance >> 4; ++ ++ return nv40_graph_transfer_context(dev, inst, 1); ++} ++ ++/* Restore the context for a specific channel into PGRAPH */ ++int ++nv40_graph_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t inst; ++ int ret; ++ ++ if (!chan->ramin_grctx) ++ return -EINVAL; ++ inst = chan->ramin_grctx->instance >> 4; ++ ++ ret = nv40_graph_transfer_context(dev, inst, 0); ++ if (ret) ++ return ret; ++ ++ /* 0x40032C, no idea of it's exact function. Could simply be a ++ * record of the currently active PGRAPH context. It's currently ++ * unknown as to what bit 24 does. The nv ddx has it set, so we will ++ * set it here too. ++ */ ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ nv_wr32(NV40_PGRAPH_CTXCTL_CUR, ++ (inst & NV40_PGRAPH_CTXCTL_CUR_INST_MASK) | ++ NV40_PGRAPH_CTXCTL_CUR_LOADED); ++ /* 0x32E0 records the instance address of the active FIFO's PGRAPH ++ * context. If at any time this doesn't match 0x40032C, you will ++ * recieve PGRAPH_INTR_CONTEXT_SWITCH ++ */ ++ nv_wr32(NV40_PFIFO_GRCTX_INSTANCE, inst); ++ return 0; ++} ++ ++/* These blocks of "magic numbers" are actually a microcode that the GPU uses ++ * to control how graphics contexts get saved and restored between PRAMIN ++ * and PGRAPH during a context switch. We're currently using values seen ++ * in mmio-traces of the binary driver. ++ */ ++static uint32_t nv40_ctx_prog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409406, ++ 0x0040a268, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004014e6, 0x007000a0, 0x00401a84, 0x00700082, 0x00600001, 0x00500061, ++ 0x00600002, 0x00401b68, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00110205, 0x0011420a, 0x00114210, 0x00110216, ++ 0x0012421b, 0x00120270, 0x001242c0, 0x00200040, 0x00100280, 0x00128100, ++ 0x00128120, 0x00128143, 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, ++ 0x00110400, 0x00104d10, 0x00500060, 0x00403b87, 0x0060000d, 0x004076e6, ++ 0x002000f0, 0x0060000a, 0x00200045, 0x00100620, 0x00108668, 0x0011466b, ++ 0x00120682, 0x0011068b, 0x00168691, 0x0010c6ae, 0x001206b4, 0x0020002a, ++ 0x001006c4, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, 0x001043e1, ++ 0x00500060, 0x00405600, 0x00405684, 0x00600003, 0x00500067, 0x00600008, ++ 0x00500060, 0x00700082, 0x0020026c, 0x0060000a, 0x00104800, 0x00104901, ++ 0x00120920, 0x00200035, 0x00100940, 0x00148a00, 0x00104a14, 0x00200038, ++ 0x00100b00, 0x00138d00, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, ++ 0x0020031a, 0x0060000a, 0x00300000, 0x00200680, 0x00406c00, 0x00200684, ++ 0x00800001, 0x00200b62, 0x0060000a, 0x0020a0b0, 0x0040728a, 0x00201b68, ++ 0x00800041, 0x00407684, 0x00203e60, 0x00800002, 0x00408700, 0x00600006, ++ 0x00700003, 0x004080e6, 0x00700080, 0x0020031a, 0x0060000a, 0x00200004, ++ 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a284, ++ 0x00700002, 0x00600004, 0x0040a268, 0x00700000, 0x00200000, 0x0060000a, ++ 0x00106002, 0x00700080, 0x00400a84, 0x00700002, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409388, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, ++ 0x0060000a, 0x00700000, 0x00106001, 0x00700083, 0x00910880, 0x00901ffe, ++ 0x00940400, 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00401b68, ++ 0x0040a406, 0x0040a505, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ++ ~0 ++}; ++ ++static uint32_t nv41_ctx_prog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409306, ++ 0x0040a068, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, ++ 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x001046ec, 0x00500060, 0x00404087, 0x0060000d, 0x004079e6, 0x002000f1, ++ 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x00200020, 0x001006cc, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200233, 0x0060000a, 0x00104800, ++ 0x00108901, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00148a00, ++ 0x00108a14, 0x00200020, 0x00100b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, ++ 0x00114d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, ++ 0x002002d2, 0x0060000a, 0x00300000, 0x00200680, 0x00407200, 0x00200684, ++ 0x00800001, 0x00200b1a, 0x0060000a, 0x00206380, 0x0040788a, 0x00201480, ++ 0x00800041, 0x00408900, 0x00600006, 0x004085e6, 0x00700080, 0x0020007a, ++ 0x0060000a, 0x00104280, 0x002002d2, 0x0060000a, 0x00200004, 0x00800001, ++ 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a068, 0x00700000, ++ 0x00200000, 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409388, 0x0060000f, 0x00500060, 0x00200000, 0x0060000a, ++ 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x00940400, 0x00200020, ++ 0x0060000b, 0x00500069, 0x0060000c, 0x00402168, 0x0040a206, 0x0040a305, ++ 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv43_ctx_prog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409565, 0x00409a06, ++ 0x0040a868, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004014e6, 0x007000a0, 0x00401a84, 0x00700082, 0x00600001, 0x00500061, ++ 0x00600002, 0x00401b68, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x001046ec, 0x00500060, 0x00403a87, 0x0060000d, 0x00407ce6, 0x002000f1, ++ 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x00200020, 0x001006cc, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00405800, 0x00405884, 0x00600003, ++ 0x00500067, 0x00600008, 0x00500060, 0x00700082, 0x00200233, 0x0060000a, ++ 0x00104800, 0x00108901, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, ++ 0x00148a00, 0x00108a14, 0x00160b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, ++ 0x0010cd08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, ++ 0x002002c8, 0x0060000a, 0x00300000, 0x00200680, 0x00407200, 0x00200684, ++ 0x00800001, 0x00200b10, 0x0060000a, 0x00203870, 0x0040788a, 0x00201350, ++ 0x00800041, 0x00407c84, 0x00201560, 0x00800002, 0x00408d00, 0x00600006, ++ 0x00700003, 0x004086e6, 0x00700080, 0x002002c8, 0x0060000a, 0x00200004, ++ 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a884, ++ 0x00700002, 0x00600004, 0x0040a868, 0x00700000, 0x00200000, 0x0060000a, ++ 0x00106002, 0x00700080, 0x00400a84, 0x00700002, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409988, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, ++ 0x0060000a, 0x00700000, 0x00106001, 0x00700083, 0x00910880, 0x00901ffe, ++ 0x00940400, 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00401b68, ++ 0x0040aa06, 0x0040ab05, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ++ ~0 ++}; ++ ++static uint32_t nv44_ctx_prog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409a65, 0x00409f06, ++ 0x0040ac68, 0x0040248f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x001041c6, 0x00104040, 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, ++ 0x00402320, 0x00402321, 0x00402322, 0x00402324, 0x00402326, 0x0040232b, ++ 0x001040c5, 0x00402328, 0x001040c5, 0x00402320, 0x00402468, 0x0060000d, ++ 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, 0x00402be6, ++ 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, 0x00110158, ++ 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, 0x001041c9, ++ 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, 0x001242c0, ++ 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, 0x0011415f, ++ 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, 0x001046ec, ++ 0x00500060, 0x00404b87, 0x0060000d, 0x004084e6, 0x002000f1, 0x0060000a, ++ 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, 0x00168691, ++ 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, 0x001646cc, ++ 0x001186e6, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, ++ 0x001043e1, 0x00500060, 0x00200232, 0x0060000a, 0x00104800, 0x00108901, ++ 0x00104910, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00148a00, ++ 0x00108a14, 0x00160b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, 0x0010cd08, ++ 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, 0x002002c8, ++ 0x0060000a, 0x00300000, 0x00200080, 0x00407d00, 0x00200084, 0x00800001, ++ 0x00200510, 0x0060000a, 0x002037e0, 0x0040838a, 0x00201320, 0x00800029, ++ 0x00409400, 0x00600006, 0x004090e6, 0x00700080, 0x0020007a, 0x0060000a, ++ 0x00104280, 0x002002c8, 0x0060000a, 0x00200004, 0x00800001, 0x00700000, ++ 0x00200000, 0x0060000a, 0x00106002, 0x0040ac68, 0x00700000, 0x00200000, ++ 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, 0x00500060, 0x00600007, ++ 0x00409e88, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, 0x0060000a, ++ 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000, 0x00200020, ++ 0x0060000b, 0x00500069, 0x0060000c, 0x00402c68, 0x0040ae06, 0x0040af05, ++ 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv46_ctx_prog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409306, ++ 0x0040a068, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, ++ 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004020e6, 0x007000a0, 0x00500060, 0x00200008, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x00500060, 0x00403f87, 0x0060000d, 0x004079e6, 0x002000f7, 0x0060000a, ++ 0x00200045, 0x00100620, 0x00104668, 0x0017466d, 0x0011068b, 0x00168691, ++ 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, 0x00200022, ++ 0x001006cc, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, 0x001043e1, ++ 0x00500060, 0x0020027f, 0x0060000a, 0x00104800, 0x00108901, 0x00104910, ++ 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00148a00, 0x00108a14, ++ 0x00160b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, 0x0010cd08, 0x00104d80, ++ 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, 0x00105406, 0x00105709, ++ 0x00200316, 0x0060000a, 0x00300000, 0x00200080, 0x00407200, 0x00200084, ++ 0x00800001, 0x0020055e, 0x0060000a, 0x002037e0, 0x0040788a, 0x00201320, ++ 0x00800029, 0x00408900, 0x00600006, 0x004085e6, 0x00700080, 0x00200081, ++ 0x0060000a, 0x00104280, 0x00200316, 0x0060000a, 0x00200004, 0x00800001, ++ 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a068, 0x00700000, ++ 0x00200000, 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409388, 0x0060000f, 0x00500060, 0x00200000, 0x0060000a, ++ 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000, 0x00200020, ++ 0x0060000b, 0x00500069, 0x0060000c, 0x00402168, 0x0040a206, 0x0040a305, ++ 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv47_ctx_prog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409265, 0x00409606, ++ 0x0040a368, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, ++ 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d12, ++ 0x00500060, 0x00403f87, 0x0060000d, 0x00407ce6, 0x002000f0, 0x0060000a, ++ 0x00200020, 0x00100620, 0x00154650, 0x00104668, 0x0017466d, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x00200022, 0x001006cc, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, ++ 0x001043e1, 0x00500060, 0x00200268, 0x0060000a, 0x00104800, 0x00108901, ++ 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00144a00, 0x00104a19, ++ 0x0010ca1c, 0x00110b00, 0x00200028, 0x00100b08, 0x00134c2e, 0x0010cd00, ++ 0x0010cd04, 0x00120d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, ++ 0x00104f06, 0x00105406, 0x00105709, 0x00200318, 0x0060000a, 0x00300000, ++ 0x00200680, 0x00407500, 0x00200684, 0x00800001, 0x00200b60, 0x0060000a, ++ 0x00209540, 0x00407b8a, 0x00201350, 0x00800041, 0x00408c00, 0x00600006, ++ 0x004088e6, 0x00700080, 0x0020007a, 0x0060000a, 0x00104280, 0x00200318, ++ 0x0060000a, 0x00200004, 0x00800001, 0x00700000, 0x00200000, 0x0060000a, ++ 0x00106002, 0x0040a368, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, ++ 0x00700080, 0x00400a68, 0x00500060, 0x00600007, 0x00409688, 0x0060000f, ++ 0x00500060, 0x00200000, 0x0060000a, 0x00700000, 0x00106001, 0x0091a880, ++ 0x00901ffe, 0x10940000, 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, ++ 0x00402168, 0x0040a506, 0x0040a605, 0x00600009, 0x00700005, 0x00700006, ++ 0x0060000e, ~0 ++}; ++ ++//this is used for nv49 and nv4b ++static uint32_t nv49_4b_ctx_prog[] ={ ++ 0x00400564, 0x00400505, 0x00408165, 0x00408206, 0x00409e68, 0x00200020, ++ 0x0060000a, 0x00700080, 0x00104042, 0x00200020, 0x0060000a, 0x00700000, ++ 0x001040c5, 0x00400f26, 0x00401068, 0x0060000d, 0x0070008f, 0x0070000e, ++ 0x00408d68, 0x004015e6, 0x007000a0, 0x00700080, 0x0040180f, 0x00700000, ++ 0x00200029, 0x0060000a, 0x0011814d, 0x00110158, 0x00105401, 0x0020003a, ++ 0x00100051, 0x001040c5, 0x0010c1c4, 0x001041c9, 0x0010c1dc, 0x00150210, ++ 0x0012c225, 0x00108238, 0x0010823e, 0x001242c0, 0x00200040, 0x00100280, ++ 0x00128100, 0x00128120, 0x00128143, 0x0011415f, 0x0010815c, 0x0010c140, ++ 0x00104029, 0x00110400, 0x00104d12, 0x00500060, 0x004071e6, 0x00200118, ++ 0x0060000a, 0x00200020, 0x00100620, 0x00154650, 0x00104668, 0x0017466d, ++ 0x0011068b, 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, ++ 0x001146c6, 0x00200022, 0x001006cc, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200290, 0x0060000a, 0x00104800, ++ 0x00108901, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00144a00, ++ 0x00104a19, 0x0010ca1c, 0x00110b00, 0x00200028, 0x00100b08, 0x00134c2e, ++ 0x0010cd00, 0x0010cd04, 0x00120d08, 0x00104d80, 0x00104e00, 0x0012d600, ++ 0x00105c00, 0x00104f06, 0x00105406, 0x00105709, 0x00200340, 0x0060000a, ++ 0x00300000, 0x00200680, 0x00406a0f, 0x00200684, 0x00800001, 0x00200b88, ++ 0x0060000a, 0x00209540, 0x0040708a, 0x00201350, 0x00800041, 0x00407c0f, ++ 0x00600006, 0x00407ce6, 0x00700080, 0x002000a2, 0x0060000a, 0x00104280, ++ 0x00200340, 0x0060000a, 0x00200004, 0x00800001, 0x0070008e, 0x00408d68, ++ 0x0040020f, 0x00600006, 0x00409e68, 0x00600007, 0x0070000f, 0x0070000e, ++ 0x00408d68, 0x0091a880, 0x00901ffe, 0x10940000, 0x00200020, 0x0060000b, ++ 0x00500069, 0x0060000c, 0x00401568, 0x00700000, 0x00200001, 0x0040910e, ++ 0x00200021, 0x0060000a, 0x00409b0d, 0x00104a40, 0x00104a50, 0x00104a60, ++ 0x00104a70, 0x00104a80, 0x00104a90, 0x00104aa0, 0x00104ab0, 0x00407e0e, ++ 0x0040130f, 0x00408568, 0x0040a006, 0x0040a105, 0x00600009, 0x00700005, ++ 0x00700006, 0x0060000e, ~0 ++}; ++ ++ ++static uint32_t nv4a_ctx_prog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409965, 0x00409e06, ++ 0x0040ac68, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004014e6, 0x007000a0, 0x00401a84, 0x00700082, 0x00600001, 0x00500061, ++ 0x00600002, 0x00401b68, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x001046ec, 0x00500060, 0x00403a87, 0x0060000d, 0x00407de6, 0x002000f1, ++ 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x001646cc, 0x001186e6, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00405800, 0x00405884, 0x00600003, ++ 0x00500067, 0x00600008, 0x00500060, 0x00700082, 0x00200232, 0x0060000a, ++ 0x00104800, 0x00108901, 0x00104910, 0x00124920, 0x0020001f, 0x00100940, ++ 0x00140965, 0x00148a00, 0x00108a14, 0x00160b00, 0x00134b2c, 0x0010cd00, ++ 0x0010cd04, 0x0010cd08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, ++ 0x00104f06, 0x002002c8, 0x0060000a, 0x00300000, 0x00200080, 0x00407300, ++ 0x00200084, 0x00800001, 0x00200510, 0x0060000a, 0x002037e0, 0x0040798a, ++ 0x00201320, 0x00800029, 0x00407d84, 0x00201560, 0x00800002, 0x00409100, ++ 0x00600006, 0x00700003, 0x00408ae6, 0x00700080, 0x0020007a, 0x0060000a, ++ 0x00104280, 0x002002c8, 0x0060000a, 0x00200004, 0x00800001, 0x00700000, ++ 0x00200000, 0x0060000a, 0x00106002, 0x0040ac84, 0x00700002, 0x00600004, ++ 0x0040ac68, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x00700080, ++ 0x00400a84, 0x00700002, 0x00400a68, 0x00500060, 0x00600007, 0x00409d88, ++ 0x0060000f, 0x00000000, 0x00500060, 0x00200000, 0x0060000a, 0x00700000, ++ 0x00106001, 0x00700083, 0x00910880, 0x00901ffe, 0x01940000, 0x00200020, ++ 0x0060000b, 0x00500069, 0x0060000c, 0x00401b68, 0x0040ae06, 0x0040af05, ++ 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv4c_ctx_prog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409065, 0x00409406, ++ 0x0040a168, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, ++ 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x0010427e, 0x001046ec, 0x00500060, 0x00404187, 0x0060000d, 0x00407ae6, ++ 0x002000f2, 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, ++ 0x0011068b, 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, ++ 0x001146c6, 0x00200020, 0x001006cc, 0x001046ed, 0x001246f0, 0x002000c0, ++ 0x00100700, 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200234, 0x0060000a, ++ 0x00104800, 0x00108901, 0x00104910, 0x00124920, 0x0020001f, 0x00100940, ++ 0x00140965, 0x00148a00, 0x00108a14, 0x00140b00, 0x00134b2c, 0x0010cd00, ++ 0x0010cd04, 0x00104d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, ++ 0x00104f06, 0x002002c0, 0x0060000a, 0x00300000, 0x00200080, 0x00407300, ++ 0x00200084, 0x00800001, 0x00200508, 0x0060000a, 0x00201320, 0x0040798a, ++ 0xfffffaf8, 0x00800029, 0x00408a00, 0x00600006, 0x004086e6, 0x00700080, ++ 0x0020007a, 0x0060000a, 0x00104280, 0x002002c0, 0x0060000a, 0x00200004, ++ 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a168, ++ 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, ++ 0x00500060, 0x00600007, 0x00409488, 0x0060000f, 0x00500060, 0x00200000, ++ 0x0060000a, 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000, ++ 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00402168, 0x0040a306, ++ 0x0040a405, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv4e_ctx_prog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409565, 0x00409a06, ++ 0x0040a868, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004014e6, 0x007000a0, 0x00401a84, 0x00700082, 0x00600001, 0x00500061, ++ 0x00600002, 0x00401b68, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x001046ec, 0x00500060, 0x00403a87, 0x0060000d, 0x00407ce6, 0x002000f1, ++ 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x001646cc, 0x001186e6, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00405800, 0x00405884, 0x00600003, ++ 0x00500067, 0x00600008, 0x00500060, 0x00700082, 0x00200232, 0x0060000a, ++ 0x00104800, 0x00108901, 0x00104910, 0x00124920, 0x0020001f, 0x00100940, ++ 0x00140965, 0x00148a00, 0x00108a14, 0x00140b00, 0x00134b2c, 0x0010cd00, ++ 0x0010cd04, 0x00104d08, 0x00104d80, 0x00104e00, 0x00105c00, 0x00104f06, ++ 0x002002b2, 0x0060000a, 0x00300000, 0x00200080, 0x00407200, 0x00200084, ++ 0x00800001, 0x002004fa, 0x0060000a, 0x00201320, 0x0040788a, 0xfffffb06, ++ 0x00800029, 0x00407c84, 0x00200b20, 0x00800002, 0x00408d00, 0x00600006, ++ 0x00700003, 0x004086e6, 0x00700080, 0x002002b2, 0x0060000a, 0x00200004, ++ 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a884, ++ 0x00700002, 0x00600004, 0x0040a868, 0x00700000, 0x00200000, 0x0060000a, ++ 0x00106002, 0x00700080, 0x00400a84, 0x00700002, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409988, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, ++ 0x0060000a, 0x00700000, 0x00106001, 0x00700083, 0x00910880, 0x00901ffe, ++ 0x01940000, 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00401b68, ++ 0x0040aa06, 0x0040ab05, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ++ ~0 ++}; ++ ++/* ++ * G70 0x47 ++ * G71 0x49 ++ * NV45 0x48 ++ * G72[M] 0x46 ++ * G73 0x4b ++ * C51_G7X 0x4c ++ * C51 0x4e ++ */ ++int ++nv40_graph_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = ++ (struct drm_nouveau_private *)dev->dev_private; ++ uint32_t *ctx_prog; ++ uint32_t vramsz, tmp; ++ int i, j; ++ ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) & ++ ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ ++ switch (dev_priv->chipset) { ++ case 0x40: ctx_prog = nv40_ctx_prog; break; ++ case 0x41: ++ case 0x42: ctx_prog = nv41_ctx_prog; break; ++ case 0x43: ctx_prog = nv43_ctx_prog; break; ++ case 0x44: ctx_prog = nv44_ctx_prog; break; ++ case 0x46: ctx_prog = nv46_ctx_prog; break; ++ case 0x47: ctx_prog = nv47_ctx_prog; break; ++ case 0x49: ctx_prog = nv49_4b_ctx_prog; break; ++ case 0x4a: ctx_prog = nv4a_ctx_prog; break; ++ case 0x4b: ctx_prog = nv49_4b_ctx_prog; break; ++ case 0x4c: ++ case 0x67: ctx_prog = nv4c_ctx_prog; break; ++ case 0x4e: ctx_prog = nv4e_ctx_prog; break; ++ default: ++ NV_ERROR(dev, "Context program for 0x%02x unavailable\n", ++ dev_priv->chipset); ++ return -EINVAL; ++ } ++ ++ /* Load the context program onto the card */ ++ NV_DEBUG(dev, "Loading context program\n"); ++ ++ i = 0; ++ nv_wr32(NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); ++ while (ctx_prog[i] != ~0) { ++ nv_wr32(NV40_PGRAPH_CTXCTL_UCODE_DATA, ctx_prog[i]); ++ i++; ++ } ++ ++ /* No context present currently */ ++ nv_wr32(NV40_PGRAPH_CTXCTL_CUR, 0x00000000); ++ ++ nv_wr32(NV03_PGRAPH_INTR , 0xFFFFFFFF); ++ nv_wr32(NV40_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); ++ nv_wr32(NV04_PGRAPH_DEBUG_0, 0x00000000); ++ nv_wr32(NV04_PGRAPH_DEBUG_1, 0x401287c0); ++ nv_wr32(NV04_PGRAPH_DEBUG_3, 0xe0de8055); ++ nv_wr32(NV10_PGRAPH_DEBUG_4, 0x00008000); ++ nv_wr32(NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f); ++ ++ nv_wr32(NV10_PGRAPH_CTX_CONTROL, 0x10010100); ++ nv_wr32(NV10_PGRAPH_STATE , 0xFFFFFFFF); ++ ++ j = nv_rd32(0x1540) & 0xff; ++ if (j) { ++ for (i=0; !(j&1); j>>=1, i++); ++ nv_wr32(0x405000, i); ++ } ++ ++ if (dev_priv->chipset == 0x40) { ++ nv_wr32(0x4009b0, 0x83280fff); ++ nv_wr32(0x4009b4, 0x000000a0); ++ } else { ++ nv_wr32(0x400820, 0x83280eff); ++ nv_wr32(0x400824, 0x000000a0); ++ } ++ ++ switch (dev_priv->chipset) { ++ case 0x40: ++ case 0x45: ++ nv_wr32(0x4009b8, 0x0078e366); ++ nv_wr32(0x4009bc, 0x0000014c); ++ break; ++ case 0x41: ++ case 0x42: /* pciid also 0x00Cx */ ++// case 0x0120: //XXX (pciid) ++ nv_wr32(0x400828, 0x007596ff); ++ nv_wr32(0x40082c, 0x00000108); ++ break; ++ case 0x43: ++ nv_wr32(0x400828, 0x0072cb77); ++ nv_wr32(0x40082c, 0x00000108); ++ break; ++ case 0x44: ++ case 0x46: /* G72 */ ++ case 0x4a: ++ case 0x4c: /* G7x-based C51 */ ++ case 0x4e: ++ nv_wr32(0x400860, 0); ++ nv_wr32(0x400864, 0); ++ break; ++ case 0x47: /* G70 */ ++ case 0x49: /* G71 */ ++ case 0x4b: /* G73 */ ++ nv_wr32(0x400828, 0x07830610); ++ nv_wr32(0x40082c, 0x0000016A); ++ break; ++ default: ++ break; ++ } ++ ++ nv_wr32(0x400b38, 0x2ffff800); ++ nv_wr32(0x400b3c, 0x00006000); ++ ++ /* copy tile info from PFB */ ++ switch (dev_priv->chipset) { ++ case 0x40: /* vanilla NV40 */ ++ for (i=0; ichipset) { ++ case 0x40: ++ nv_wr32(0x4009A4, nv_rd32(NV04_PFB_CFG0)); ++ nv_wr32(0x4009A8, nv_rd32(NV04_PFB_CFG1)); ++ nv_wr32(0x4069A4, nv_rd32(NV04_PFB_CFG0)); ++ nv_wr32(0x4069A8, nv_rd32(NV04_PFB_CFG1)); ++ nv_wr32(0x400820, 0); ++ nv_wr32(0x400824, 0); ++ nv_wr32(0x400864, vramsz); ++ nv_wr32(0x400868, vramsz); ++ break; ++ default: ++ switch (dev_priv->chipset) { ++ case 0x46: ++ case 0x47: ++ case 0x49: ++ case 0x4b: ++ nv_wr32(0x400DF0, nv_rd32(NV04_PFB_CFG0)); ++ nv_wr32(0x400DF4, nv_rd32(NV04_PFB_CFG1)); ++ break; ++ default: ++ nv_wr32(0x4009F0, nv_rd32(NV04_PFB_CFG0)); ++ nv_wr32(0x4009F4, nv_rd32(NV04_PFB_CFG1)); ++ break; ++ } ++ nv_wr32(0x4069F0, nv_rd32(NV04_PFB_CFG0)); ++ nv_wr32(0x4069F4, nv_rd32(NV04_PFB_CFG1)); ++ nv_wr32(0x400840, 0); ++ nv_wr32(0x400844, 0); ++ nv_wr32(0x4008A0, vramsz); ++ nv_wr32(0x4008A4, vramsz); ++ break; ++ } ++ ++ /* per-context state, doesn't belong here */ ++ nv_wr32(0x400B20, 0x00000000); ++ nv_wr32(0x400B04, 0xFFFFFFFF); ++ ++ tmp = nv_rd32(NV10_PGRAPH_SURFACE) & 0x0007ff00; ++ nv_wr32(NV10_PGRAPH_SURFACE, tmp); ++ tmp = nv_rd32(NV10_PGRAPH_SURFACE) | 0x00020100; ++ nv_wr32(NV10_PGRAPH_SURFACE, tmp); ++ ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_XMIN, 0); ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_YMIN, 0); ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); ++ nv_wr32(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); ++ ++ return 0; ++} ++ ++void nv40_graph_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv40_mc.c b/drivers/gpu/drm/nouveau/nv40_mc.c +new file mode 100644 +index 0000000..87c6213 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv40_mc.c +@@ -0,0 +1,38 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv40_mc_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ /* Power up everything, resetting each individual unit will ++ * be done later if needed. ++ */ ++ nv_wr32(NV03_PMC_ENABLE, 0xFFFFFFFF); ++ ++ switch (dev_priv->chipset) { ++ case 0x44: ++ case 0x46: /* G72 */ ++ case 0x4e: ++ case 0x4c: /* C51_G7X */ ++ tmp = nv_rd32(NV40_PFB_020C); ++ nv_wr32(NV40_PMC_1700, tmp); ++ nv_wr32(NV40_PMC_1704, 0); ++ nv_wr32(NV40_PMC_1708, 0); ++ nv_wr32(NV40_PMC_170C, tmp); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++void ++nv40_mc_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_connector.c b/drivers/gpu/drm/nouveau/nv50_connector.c +new file mode 100644 +index 0000000..afb9ac3 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_connector.c +@@ -0,0 +1,536 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm_edid.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_encoder.h" ++#include "nouveau_crtc.h" ++#include "nouveau_connector.h" ++#include "nv50_display.h" ++#include "nv50_display_commands.h" ++ ++static struct drm_display_mode * ++nv50_connector_lvds_native_mode(struct drm_device *dev) ++{ ++ struct drm_display_mode *mode; ++ uint32_t output, tmp; ++ ++ output = nv_rd32(0x610050); ++ if ((output & 0x00000003) == 0x00000002) ++ output = 0x00000000; ++ else ++ if ((output & 0x00000300) == 0x00000200) ++ output = 0x000000540; ++ else { ++ NV_ERROR(dev, "Unable to determine LVDS head: 0x%08x\n", output); ++ return NULL; ++ } ++ ++ mode = drm_mode_create(dev); ++ if (!mode) ++ return NULL; ++ ++ mode->clock = nv_rd32(0x610ad4 + output) & 0x003fffff; ++ tmp = nv_rd32(0x610b4c + output); ++ mode->hdisplay = (tmp & 0x00003fff); ++ mode->vdisplay = (tmp & 0x3fff0000) >> 16; ++ tmp = nv_rd32(0x610afc + output); ++ mode->htotal = tmp & 0x3fff; ++ mode->vtotal = tmp >> 16; ++ tmp = nv_rd32(0x610ae8 + output); ++ mode->hsync_start = mode->htotal - (tmp & 0x3fff) - 1; ++ mode->vsync_start = mode->vtotal - (tmp >> 16) - 1; ++ tmp = nv_rd32(0x610b00 + output); ++ mode->hsync_end = mode->hsync_start + (tmp & 0x3fff) + 1; ++ mode->vsync_end = mode->vsync_start + (tmp >> 16) + 1; ++ mode->flags = 0; ++ mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; ++ mode->vrefresh = drm_mode_vrefresh(mode); ++ ++ NV_DEBUG(dev, "Probed current LVDS mode:\n"); ++ drm_mode_debug_printmodeline(mode); ++ return mode; ++} ++ ++static struct nouveau_encoder * ++nv50_connector_to_encoder(struct nouveau_connector *connector, bool digital) ++{ ++ struct drm_device *dev = connector->base.dev; ++ struct drm_encoder *drm_encoder; ++ bool digital_possible = false; ++ bool analog_possible = false; ++ ++ switch (connector->base.connector_type) { ++ case DRM_MODE_CONNECTOR_VGA: ++ case DRM_MODE_CONNECTOR_SVIDEO: ++ analog_possible = true; ++ break; ++ case DRM_MODE_CONNECTOR_DVII: ++ analog_possible = true; ++ digital_possible = true; ++ break; ++ case DRM_MODE_CONNECTOR_DVID: ++ case DRM_MODE_CONNECTOR_LVDS: ++ digital_possible = true; ++ break; ++ default: ++ return NULL; ++ } ++ ++ /* Return early on bad situations. */ ++ if (!analog_possible && !digital) ++ return NULL; ++ ++ if (!digital_possible && digital) ++ return NULL; ++ ++ list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) { ++ struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); ++ ++ if (connector->bus != encoder->dcb_entry->bus) ++ continue; ++ ++ if (digital) { ++ switch (encoder->base.encoder_type) { ++ case DRM_MODE_ENCODER_TMDS: ++ case DRM_MODE_ENCODER_LVDS: ++ return encoder; ++ default: ++ break; ++ } ++ } else { ++ switch (encoder->base.encoder_type) { ++ case DRM_MODE_ENCODER_DAC: ++ case DRM_MODE_ENCODER_TVDAC: ++ return encoder; ++ default: ++ break; ++ } ++ } ++ } ++ ++ return NULL; ++} ++ ++static void nv50_connector_destroy(struct drm_connector *drm_connector) ++{ ++ struct nouveau_connector *connector = to_nouveau_connector(drm_connector); ++ struct drm_device *dev = connector->base.dev; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!connector) ++ return; ++ ++ nouveau_i2c_del(&connector->i2c_chan); ++ ++ drm_sysfs_connector_remove(drm_connector); ++ drm_connector_cleanup(drm_connector); ++ kfree(drm_connector); ++} ++ ++static void ++nv50_connector_set_digital(struct nouveau_connector *connector, bool digital) ++{ ++ struct drm_device *dev = connector->base.dev; ++ ++ if (connector->base.connector_type == DRM_MODE_CONNECTOR_DVII) { ++ struct drm_property *prop = ++ dev->mode_config.dvi_i_subconnector_property; ++ uint64_t val; ++ ++ if (digital) ++ val = DRM_MODE_SUBCONNECTOR_DVID; ++ else ++ val = DRM_MODE_SUBCONNECTOR_DVIA; ++ ++ drm_connector_property_set_value(&connector->base, prop, val); ++ } ++ ++ connector->digital = digital; ++} ++ ++void nv50_connector_detect_all(struct drm_device *dev) ++{ ++ struct drm_connector *drm_connector = NULL; ++ ++ list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) { ++ drm_connector->funcs->detect(drm_connector); ++ } ++} ++ ++static enum drm_connector_status ++nv50_connector_detect(struct drm_connector *drm_connector) ++{ ++ struct drm_device *dev = drm_connector->dev; ++ struct nouveau_connector *connector = to_nouveau_connector(drm_connector); ++ struct nouveau_encoder *encoder = NULL; ++ struct drm_encoder_helper_funcs *helper = NULL; ++ ++ if (drm_connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { ++ if (!connector->native_mode) { ++ NV_ERROR(dev, "No native mode for LVDS.\n"); ++ return connector_status_disconnected; ++ } ++ ++ nv50_connector_set_digital(connector, true); ++ return connector_status_connected; ++ } ++ ++ encoder = connector->to_encoder(connector, false); ++ if (encoder) ++ helper = encoder->base.helper_private; ++ ++ if (helper && helper->detect(&encoder->base, &connector->base) == ++ connector_status_connected) { ++ nv50_connector_set_digital(connector, false); ++ return connector_status_connected; ++ } ++ ++ if (nouveau_i2c_detect(connector)) { ++ nv50_connector_set_digital(connector, true); ++ return connector_status_connected; ++ } ++ ++ return connector_status_disconnected; ++} ++ ++static int nv50_connector_set_property(struct drm_connector *drm_connector, ++ struct drm_property *property, ++ uint64_t value) ++{ ++ struct drm_device *dev = drm_connector->dev; ++ struct nouveau_connector *connector = to_nouveau_connector(drm_connector); ++ int rval; ++ ++ /* DPMS */ ++ if (property == dev->mode_config.dpms_property) { ++ if (value > 3) ++ return -EINVAL; ++ ++ drm_helper_set_connector_dpms(drm_connector, value); ++ } ++ ++ /* Scaling mode */ ++ if (property == dev->mode_config.scaling_mode_property) { ++ struct nouveau_crtc *crtc = NULL; ++ bool modeset = false; ++ ++ switch (value) { ++ case DRM_MODE_SCALE_NON_GPU: ++ case DRM_MODE_SCALE_FULLSCREEN: ++ case DRM_MODE_SCALE_NO_SCALE: ++ case DRM_MODE_SCALE_ASPECT: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* LVDS always needs gpu scaling */ ++ if (connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS && ++ value == DRM_MODE_SCALE_NON_GPU) ++ return -EINVAL; ++ ++ /* Changing between GPU and panel scaling requires a full ++ * modeset ++ */ ++ if ((connector->scaling_mode == DRM_MODE_SCALE_NON_GPU) || ++ (value == DRM_MODE_SCALE_NON_GPU)) ++ modeset = true; ++ connector->scaling_mode = value; ++ ++ if (drm_connector->encoder && drm_connector->encoder->crtc) ++ crtc = to_nouveau_crtc(drm_connector->encoder->crtc); ++ ++ if (!crtc) ++ return 0; ++ ++ if (modeset) { ++ rval = drm_crtc_helper_set_mode(&crtc->base, ++ &crtc->base.mode, ++ crtc->base.x, ++ crtc->base.y, NULL, 0); ++ if (rval) ++ return rval; ++ } else { ++ rval = crtc->set_scale(crtc, value, true); ++ if (rval) ++ return rval; ++ } ++ ++ return 0; ++ } ++ ++ /* Dithering */ ++ if (property == dev->mode_config.dithering_mode_property) { ++ struct nouveau_crtc *crtc = NULL; ++ ++ if (value == DRM_MODE_DITHERING_ON) ++ connector->use_dithering = true; ++ else ++ connector->use_dithering = false; ++ ++ if (drm_connector->encoder && drm_connector->encoder->crtc) ++ crtc = to_nouveau_crtc(drm_connector->encoder->crtc); ++ ++ if (!crtc) ++ return 0; ++ ++ /* update hw state */ ++ crtc->use_dithering = connector->use_dithering; ++ rval = crtc->set_dither(crtc, true); ++ if (rval) ++ return rval; ++ ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++static struct drm_display_mode * ++nv50_connector_native_mode(struct nouveau_connector *connector) ++{ ++ struct drm_device *dev = connector->base.dev; ++ struct drm_display_mode *mode; ++ ++ if (!connector->digital) ++ return NULL; ++ ++ list_for_each_entry(mode, &connector->base.probed_modes, head) { ++ if (mode->type & DRM_MODE_TYPE_PREFERRED) ++ return drm_mode_duplicate(dev, mode); ++ } ++ ++ return NULL; ++} ++ ++static int nv50_connector_get_modes(struct drm_connector *drm_connector) ++{ ++ struct drm_device *dev = drm_connector->dev; ++ struct nouveau_connector *connector = to_nouveau_connector(drm_connector); ++ struct edid *edid = NULL; ++ int ret = 0; ++ ++ /* If we're not LVDS, destroy the previous native mode, the attached ++ * monitor could have changed. ++ */ ++ if (drm_connector->connector_type != DRM_MODE_CONNECTOR_LVDS && ++ connector->native_mode) { ++ drm_mode_destroy(dev, connector->native_mode); ++ connector->native_mode = NULL; ++ } ++ ++ if (connector->i2c_chan) ++ edid = drm_get_edid(drm_connector, &connector->i2c_chan->adapter); ++ drm_mode_connector_update_edid_property(drm_connector, edid); ++ ++ if (edid) { ++ ret = drm_add_edid_modes(drm_connector, edid); ++ kfree(edid); ++ } ++ ++ /* Find the native mode if this is a digital panel, if we didn't ++ * find any modes through DDC previously add the native mode to ++ * the list of modes. ++ */ ++ if (!connector->native_mode) ++ connector->native_mode = nv50_connector_native_mode(connector); ++ if (ret == 0 && connector->native_mode) { ++ struct drm_display_mode *mode; ++ ++ mode = drm_mode_duplicate(dev, connector->native_mode); ++ drm_mode_probed_add(drm_connector, mode); ++ ret = 1; ++ } ++ ++ return ret; ++} ++ ++static int nv50_connector_mode_valid(struct drm_connector *drm_connector, ++ struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = drm_connector->dev; ++ struct nouveau_connector *connector = to_nouveau_connector(drm_connector); ++ struct nouveau_encoder *encoder = ++ connector->to_encoder(connector, connector->digital); ++ unsigned min_clock, max_clock; ++ ++ min_clock = 25000; ++ ++ switch (encoder->base.encoder_type) { ++ case DRM_MODE_ENCODER_LVDS: ++ if (!connector->native_mode) { ++ NV_ERROR(dev, "AIIII no native mode\n"); ++ return MODE_PANEL; ++ } ++ ++ if (mode->hdisplay > connector->native_mode->hdisplay || ++ mode->vdisplay > connector->native_mode->vdisplay) ++ return MODE_PANEL; ++ ++ max_clock = 400000; ++ break; ++ case DRM_MODE_ENCODER_TMDS: ++ if (!encoder->dual_link) ++ max_clock = 165000; ++ else ++ max_clock = 330000; ++ break; ++ default: ++ max_clock = 400000; ++ break; ++ } ++ ++ if (mode->clock < min_clock) ++ return MODE_CLOCK_LOW; ++ ++ if (mode->clock > max_clock) ++ return MODE_CLOCK_HIGH; ++ ++ return MODE_OK; ++} ++ ++static struct drm_encoder * ++nv50_connector_best_encoder(struct drm_connector *drm_connector) ++{ ++ struct nouveau_connector *connector = to_nouveau_connector(drm_connector); ++ ++ return &connector->to_encoder(connector, connector->digital)->base; ++} ++ ++static const struct drm_connector_helper_funcs nv50_connector_helper_funcs = { ++ .get_modes = nv50_connector_get_modes, ++ .mode_valid = nv50_connector_mode_valid, ++ .best_encoder = nv50_connector_best_encoder, ++}; ++ ++static const struct drm_connector_funcs nv50_connector_funcs = { ++ .save = NULL, ++ .restore = NULL, ++ .detect = nv50_connector_detect, ++ .destroy = nv50_connector_destroy, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .set_property = nv50_connector_set_property ++}; ++ ++int nv50_connector_create(struct drm_device *dev, int bus, int i2c_index, int type) ++{ ++ struct nouveau_connector *connector = NULL; ++ int i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ connector = kzalloc(sizeof(*connector), GFP_KERNEL); ++ if (!connector) ++ return -ENOMEM; ++ ++ connector->bus = bus; ++ ++ switch (type) { ++ case DRM_MODE_CONNECTOR_VGA: ++ NV_INFO(dev, "Detected a VGA connector\n"); ++ break; ++ case DRM_MODE_CONNECTOR_DVID: ++ NV_INFO(dev, "Detected a DVI-D connector\n"); ++ break; ++ case DRM_MODE_CONNECTOR_DVII: ++ NV_INFO(dev, "Detected a DVI-I connector\n"); ++ break; ++ case DRM_MODE_CONNECTOR_LVDS: ++ connector->native_mode = nv50_connector_lvds_native_mode(dev); ++ NV_INFO(dev, "Detected a LVDS connector\n"); ++ break; ++ case DRM_MODE_CONNECTOR_SVIDEO: ++ NV_INFO(dev, "Detected a TV connector\n"); ++ break; ++ default: ++ NV_ERROR(dev, "Unknown connector, this is not good.\n"); ++ break; ++ } ++ ++ /* some reasonable defaults */ ++ switch (type) { ++ case DRM_MODE_CONNECTOR_DVII: ++ case DRM_MODE_CONNECTOR_DVID: ++ case DRM_MODE_CONNECTOR_LVDS: ++ connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; ++ break; ++ default: ++ connector->scaling_mode = DRM_MODE_SCALE_NON_GPU; ++ break; ++ } ++ ++ if (type == DRM_MODE_CONNECTOR_LVDS) ++ connector->use_dithering = true; ++ else ++ connector->use_dithering = false; ++ ++ if (i2c_index < 0xf) ++ nouveau_i2c_new(dev, "conn", i2c_index, &connector->i2c_chan); ++ ++ /* set function pointers */ ++ connector->to_encoder = nv50_connector_to_encoder; ++ ++ /* It should be allowed sometimes, but let's be safe for the moment. */ ++ connector->base.interlace_allowed = false; ++ connector->base.doublescan_allowed = false; ++ ++ drm_connector_init(dev, &connector->base, &nv50_connector_funcs, type); ++ drm_connector_helper_add(&connector->base, &nv50_connector_helper_funcs); ++ ++ /* Init DVI-I specific properties */ ++ if (type == DRM_MODE_CONNECTOR_DVII) { ++ drm_mode_create_dvi_i_properties(dev); ++ drm_connector_attach_property(&connector->base, dev->mode_config.dvi_i_subconnector_property, 0); ++ drm_connector_attach_property(&connector->base, dev->mode_config.dvi_i_select_subconnector_property, 0); ++ } ++ ++ /* If supported in the future, it will have to use the scalers ++ * internally and not expose them. ++ */ ++ if (type != DRM_MODE_CONNECTOR_SVIDEO) { ++ drm_connector_attach_property(&connector->base, dev->mode_config.scaling_mode_property, connector->scaling_mode); ++ } ++ ++ drm_connector_attach_property(&connector->base, dev->mode_config.dithering_mode_property, connector->use_dithering ? DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); ++ ++ /* attach encoders, possibilities are analog + digital */ ++ for (i = 0; i < 2; i++) { ++ struct nouveau_encoder *encoder = connector->to_encoder(connector, i); ++ if (!encoder) ++ continue; ++ ++ drm_mode_connector_attach_encoder(&connector->base, &encoder->base); ++ } ++ ++ drm_sysfs_connector_add(&connector->base); ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c +new file mode 100644 +index 0000000..8790d4c +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_crtc.c +@@ -0,0 +1,807 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm_mode.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_encoder.h" ++#include "nouveau_crtc.h" ++#include "nouveau_fb.h" ++#include "nouveau_fbcon.h" ++#include "nouveau_connector.h" ++#include "nv50_display.h" ++ ++#define NV50_LUT_INDEX(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8))) ++static int ++nv50_crtc_lut_load(struct nouveau_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ uint32_t index = 0, i; ++ void __iomem *lut = crtc->lut.mem->kmap.virtual; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* 16 bits, red, green, blue, unused, total of 64 bits per index */ ++ /* 10 bits lut, with 14 bits values. */ ++ switch (crtc->lut.depth) { ++ case 15: ++ /* R5G5B5 */ ++ for (i = 0; i < 32; i++) { ++ index = NV50_LUT_INDEX(i, 5); ++ writew(crtc->lut.r[i] >> 2, lut + 8*index + 0); ++ writew(crtc->lut.g[i] >> 2, lut + 8*index + 2); ++ writew(crtc->lut.b[i] >> 2, lut + 8*index + 4); ++ } ++ break; ++ case 16: ++ /* R5G6B5 */ ++ for (i = 0; i < 32; i++) { ++ index = NV50_LUT_INDEX(i, 5); ++ writew(crtc->lut.r[i] >> 2, lut + 8*index + 0); ++ writew(crtc->lut.b[i] >> 2, lut + 8*index + 4); ++ } ++ ++ /* Green has an extra bit. */ ++ for (i = 0; i < 64; i++) { ++ index = NV50_LUT_INDEX(i, 6); ++ writew(crtc->lut.g[i] >> 2, lut + 8*index + 2); ++ } ++ break; ++ default: ++ /* R8G8B8 */ ++ for (i = 0; i < 256; i++) { ++ writew(crtc->lut.r[i] >> 2, lut + 8*i + 0); ++ writew(crtc->lut.g[i] >> 2, lut + 8*i + 2); ++ writew(crtc->lut.b[i] >> 2, lut + 8*i + 4); ++ } ++ break; ++ } ++ ++ return 0; ++} ++ ++int ++nv50_crtc_blank(struct nouveau_crtc *crtc, bool blanked) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t offset = crtc->index * 0x400; ++ ++ NV_DEBUG(dev, "index %d\n", crtc->index); ++ NV_DEBUG(dev, "%s\n", blanked ? "blanked" : "unblanked"); ++ ++ if (blanked) { ++ crtc->cursor.hide(crtc, false); ++ ++ OUT_MODE(NV50_CRTC0_CLUT_MODE + offset, ++ NV50_CRTC0_CLUT_MODE_BLANK); ++ OUT_MODE(NV50_CRTC0_CLUT_OFFSET + offset, 0); ++ if (dev_priv->chipset != 0x50) ++ OUT_MODE(NV84_CRTC0_CLUT_DMA + offset, ++ NV84_CRTC0_CLUT_DMA_DISABLE); ++ ++ OUT_MODE(NV50_CRTC0_BLANK_CTRL + offset, ++ NV50_CRTC0_BLANK_CTRL_BLANK); ++ } else { ++ crtc->cursor.set_offset(crtc, crtc->cursor.offset); ++ if (crtc->cursor.visible) ++ crtc->cursor.show(crtc, false); ++ else ++ crtc->cursor.hide(crtc, false); ++ ++ OUT_MODE(NV50_CRTC0_CLUT_MODE + offset, crtc->lut.depth == 8 ? ++ NV50_CRTC0_CLUT_MODE_OFF : NV50_CRTC0_CLUT_MODE_ON); ++ OUT_MODE(NV50_CRTC0_CLUT_OFFSET + offset, ++ crtc->lut.mem->start >> 8); ++ if (dev_priv->chipset != 0x50) ++ OUT_MODE(NV84_CRTC0_CLUT_DMA + offset, ++ NV84_CRTC0_CLUT_DMA_LOCAL); ++ ++ OUT_MODE(NV50_CRTC0_FB_OFFSET + offset, crtc->fb.offset >> 8); ++ OUT_MODE(0x864 + offset, 0); ++ OUT_MODE(NV50_CRTC0_BLANK_CTRL + offset, ++ NV50_CRTC0_BLANK_CTRL_UNBLANK); ++ } ++ ++ return 0; ++} ++ ++static int nv50_crtc_set_dither(struct nouveau_crtc *crtc, bool update) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ uint32_t offset = crtc->index * 0x400; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ OUT_MODE(NV50_CRTC0_DITHERING_CTRL + offset, crtc->use_dithering ? ++ NV50_CRTC0_DITHERING_CTRL_ON : NV50_CRTC0_DITHERING_CTRL_OFF); ++ ++ if (update) ++ OUT_MODE(NV50_UPDATE_DISPLAY, 0); ++ return 0; ++} ++ ++static struct nouveau_encoder * ++nouveau_crtc_encoder_get(struct nouveau_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_encoder *drm_encoder; ++ ++ list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) { ++ if (drm_encoder->crtc == &crtc->base) ++ return to_nouveau_encoder(drm_encoder); ++ } ++ ++ return NULL; ++} ++ ++static struct nouveau_connector * ++nouveau_crtc_connector_get(struct nouveau_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_connector *drm_connector; ++ struct nouveau_encoder *encoder; ++ ++ encoder = nouveau_crtc_encoder_get(crtc); ++ if (!encoder) ++ return NULL; ++ ++ list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) { ++ if (drm_connector->encoder == &encoder->base) ++ return to_nouveau_connector(drm_connector); ++ } ++ ++ return NULL; ++} ++ ++static int ++nv50_crtc_set_scale(struct nouveau_crtc *crtc, int scaling_mode, bool update) ++{ ++ struct nouveau_connector *connector = nouveau_crtc_connector_get(crtc); ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_display_mode *native_mode = NULL; ++ struct drm_display_mode *mode = &crtc->base.mode; ++ uint32_t offset = crtc->index * 0x400; ++ uint32_t outX, outY, horiz, vert; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!connector->digital) ++ scaling_mode = DRM_MODE_SCALE_NON_GPU; ++ ++ switch (scaling_mode) { ++ case DRM_MODE_SCALE_NO_SCALE: ++ case DRM_MODE_SCALE_NON_GPU: ++ break; ++ default: ++ if (!connector || !connector->native_mode) { ++ NV_ERROR(dev, "No native mode, forcing panel scaling\n"); ++ scaling_mode = DRM_MODE_SCALE_NON_GPU; ++ } else { ++ native_mode = connector->native_mode; ++ } ++ break; ++ } ++ ++ switch (scaling_mode) { ++ case DRM_MODE_SCALE_ASPECT: ++ horiz = (native_mode->hdisplay << 19) / mode->hdisplay; ++ vert = (native_mode->vdisplay << 19) / mode->vdisplay; ++ ++ if (vert > horiz) { ++ outX = (mode->hdisplay * horiz) >> 19; ++ outY = (mode->vdisplay * horiz) >> 19; ++ } else { ++ outX = (mode->hdisplay * vert) >> 19; ++ outY = (mode->vdisplay * vert) >> 19; ++ } ++ break; ++ case DRM_MODE_SCALE_FULLSCREEN: ++ outX = native_mode->hdisplay; ++ outY = native_mode->vdisplay; ++ break; ++ case DRM_MODE_SCALE_NO_SCALE: ++ case DRM_MODE_SCALE_NON_GPU: ++ default: ++ outX = mode->hdisplay; ++ outY = mode->vdisplay; ++ break; ++ } ++ ++ /* Got a better name for SCALER_ACTIVE? */ ++ /* One day i've got to really figure out why this is needed. */ ++ if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) || ++ (mode->flags & DRM_MODE_FLAG_INTERLACE) || ++ mode->hdisplay != outX || mode->vdisplay != outY) { ++ OUT_MODE(NV50_CRTC0_SCALE_CTRL + offset, ++ NV50_CRTC0_SCALE_CTRL_SCALER_ACTIVE); ++ } else { ++ OUT_MODE(NV50_CRTC0_SCALE_CTRL + offset, ++ NV50_CRTC0_SCALE_CTRL_SCALER_INACTIVE); ++ } ++ ++ OUT_MODE(NV50_CRTC0_SCALE_RES1 + offset, outY << 16 | outX); ++ OUT_MODE(NV50_CRTC0_SCALE_RES2 + offset, outY << 16 | outX); ++ ++ if (update) ++ OUT_MODE(NV50_UPDATE_DISPLAY, 0); ++ ++ return 0; ++} ++ ++static int ++nv50_crtc_calc_clock(struct nouveau_crtc *crtc, struct drm_display_mode *mode, ++ uint32_t *bestN1, uint32_t *bestN2, uint32_t *bestM1, ++ uint32_t *bestM2, uint32_t *bestlog2P) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct pll_lims limits; ++ int clk = mode->clock, vco2, crystal; ++ int minvco1, minvco2, minU1, maxU1, minU2, maxU2, minM1, maxM1; ++ int maxvco1, maxvco2, minN1, maxN1, minM2, maxM2, minN2, maxN2; ++ bool fixedgain2; ++ int M1, N1, M2, N2, log2P; ++ int clkP, calcclk1, calcclk2, calcclkout; ++ int delta, bestdelta = INT_MAX; ++ int bestclk = 0; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* These are in the g80 bios tables, at least in mine. */ ++ ret = get_pll_limits(crtc->base.dev, ++ NV50_PDISPLAY_CRTC_CLK_CLK_CTRL1(crtc->index), ++ &limits); ++ if (ret) ++ return ret; ++ ++ minvco1 = limits.vco1.minfreq, maxvco1 = limits.vco1.maxfreq; ++ minvco2 = limits.vco2.minfreq, maxvco2 = limits.vco2.maxfreq; ++ minU1 = limits.vco1.min_inputfreq, minU2 = limits.vco2.min_inputfreq; ++ maxU1 = limits.vco1.max_inputfreq, maxU2 = limits.vco2.max_inputfreq; ++ minM1 = limits.vco1.min_m, maxM1 = limits.vco1.max_m; ++ minN1 = limits.vco1.min_n, maxN1 = limits.vco1.max_n; ++ minM2 = limits.vco2.min_m, maxM2 = limits.vco2.max_m; ++ minN2 = limits.vco2.min_n, maxN2 = limits.vco2.max_n; ++ crystal = limits.refclk; ++ fixedgain2 = (minM2 == maxM2 && minN2 == maxN2); ++ ++ vco2 = (maxvco2 - maxvco2/200) / 2; ++ /* log2P is maximum of 6 */ ++ for (log2P = 0; clk && log2P < 6 && clk <= (vco2 >> log2P); log2P++); ++ clkP = clk << log2P; ++ ++ if (maxvco2 < clk + clk/200) /* +0.5% */ ++ maxvco2 = clk + clk/200; ++ ++ for (M1 = minM1; M1 <= maxM1; M1++) { ++ if (crystal/M1 < minU1) ++ return bestclk; ++ if (crystal/M1 > maxU1) ++ continue; ++ ++ for (N1 = minN1; N1 <= maxN1; N1++) { ++ calcclk1 = crystal * N1 / M1; ++ if (calcclk1 < minvco1) ++ continue; ++ if (calcclk1 > maxvco1) ++ break; ++ ++ for (M2 = minM2; M2 <= maxM2; M2++) { ++ if (calcclk1/M2 < minU2) ++ break; ++ if (calcclk1/M2 > maxU2) ++ continue; ++ ++ /* add calcclk1/2 to round better */ ++ N2 = (clkP * M2 + calcclk1/2) / calcclk1; ++ if (N2 < minN2) ++ continue; ++ if (N2 > maxN2) ++ break; ++ ++ if (!fixedgain2) { ++ calcclk2 = calcclk1 * N2 / M2; ++ if (calcclk2 < minvco2) ++ break; ++ if (calcclk2 > maxvco2) ++ continue; ++ } else ++ calcclk2 = calcclk1; ++ ++ calcclkout = calcclk2 >> log2P; ++ delta = abs(calcclkout - clk); ++ /* we do an exhaustive search rather than ++ * terminating on an optimality condition... ++ */ ++ if (delta < bestdelta) { ++ bestdelta = delta; ++ bestclk = calcclkout; ++ *bestN1 = N1; ++ *bestN2 = N2; ++ *bestM1 = M1; ++ *bestM2 = M2; ++ *bestlog2P = log2P; ++ if (delta == 0) /* except this one */ ++ return bestclk; ++ } ++ } ++ } ++ } ++ ++ return bestclk; ++} ++ ++static int ++nv50_crtc_set_clock(struct nouveau_crtc *crtc, struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ uint32_t pll_reg = NV50_PDISPLAY_CRTC_CLK_CLK_CTRL1(crtc->index); ++ uint32_t N1 = 0, N2 = 0, M1 = 0, M2 = 0, log2P = 0; ++ uint32_t reg1 = nv_rd32(pll_reg + 4); ++ uint32_t reg2 = nv_rd32(pll_reg + 8); ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(pll_reg, NV50_PDISPLAY_CRTC_CLK_CLK_CTRL1_CONNECTED | 0x10000011); ++ ++ /* The other bits are typically empty, but let's be on the safe side. */ ++ reg1 &= 0xff00ff00; ++ reg2 &= 0x8000ff00; ++ ++ if (!nv50_crtc_calc_clock(crtc, mode, &N1, &N2, &M1, &M2, &log2P)) ++ return -EINVAL; ++ ++ NV_DEBUG(dev, "N1 %d N2 %d M1 %d M2 %d log2P %d\n", N1, N2, M1, M2, log2P); ++ ++ reg1 |= (M1 << 16) | N1; ++ reg2 |= (log2P << 28) | (M2 << 16) | N2; ++ ++ nv_wr32(pll_reg + 4, reg1); ++ nv_wr32(pll_reg + 8, reg2); ++ ++ return 0; ++} ++ ++static int nv50_crtc_set_clock_mode(struct nouveau_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* This acknowledges a clock request. */ ++ nv_wr32(NV50_PDISPLAY_CRTC_CLK_CLK_CTRL2(crtc->index), 0); ++ ++ return 0; ++} ++ ++static void nv50_crtc_destroy(struct drm_crtc *drm_crtc) ++{ ++ struct drm_device *dev = drm_crtc->dev; ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!crtc) ++ return; ++ ++ drm_crtc_cleanup(&crtc->base); ++ ++ nv50_cursor_fini(crtc); ++ ++ if (crtc->lut.mem) ++ nouveau_mem_free(dev, crtc->lut.mem); ++ kfree(crtc->mode); ++ kfree(crtc); ++} ++ ++static int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, ++ struct drm_file *file_priv, ++ uint32_t buffer_handle, ++ uint32_t width, uint32_t height) ++{ ++ struct drm_device *dev = drm_crtc->dev; ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ struct drm_gem_object *gem = NULL; ++ int ret = 0; ++ ++ if (width != 64 || height != 64) ++ return -EINVAL; ++ ++ if (crtc->cursor.gem) { ++ nouveau_gem_unpin(crtc->cursor.gem); ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(crtc->cursor.gem); ++ mutex_unlock(&dev->struct_mutex); ++ crtc->cursor.gem = NULL; ++ } ++ ++ if (buffer_handle) { ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gem_object *ngem; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); ++ if (!gem) ++ return -EINVAL; ++ ngem = gem->driver_private; ++ ++ ret = nouveau_gem_pin(gem, NOUVEAU_GEM_DOMAIN_VRAM); ++ if (ret) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++ } ++ ++ crtc->cursor.offset = ngem->bo->offset - ++ dev_priv->vm_vram_base; ++ crtc->cursor.set_offset(crtc, crtc->cursor.offset); ++ crtc->cursor.show(crtc, true); ++ crtc->cursor.gem = gem; ++ } else { ++ crtc->cursor.hide(crtc, true); ++ } ++ ++ return ret; ++} ++ ++static int ++nv50_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y) ++{ ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ ++ crtc->cursor.set_pos(crtc, x, y); ++ return 0; ++} ++ ++void ++nv50_crtc_gamma_set(struct drm_crtc *drm_crtc, u16 *r, u16 *g, u16 *b, ++ uint32_t size) ++{ ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ int i; ++ ++ if (size != 256) ++ return; ++ ++ for (i = 0; i < 256; i++) { ++ crtc->lut.r[i] = r[i]; ++ crtc->lut.g[i] = g[i]; ++ crtc->lut.b[i] = b[i]; ++ } ++ ++ /* We need to know the depth before we upload, but it's possible to ++ * get called before a framebuffer is bound. If this is the case, ++ * mark the lut values as dirty by setting depth==0, and it'll be ++ * uploaded on the first mode_set_base() ++ */ ++ if (!crtc->base.fb) { ++ crtc->lut.depth = 0; ++ return; ++ } ++ ++ nv50_crtc_lut_load(crtc); ++} ++ ++static int ++nv50_crtc_helper_set_config(struct drm_mode_set *set) ++{ ++ struct drm_nouveau_private *dev_priv = set->crtc->dev->dev_private; ++ int ret; ++ ++ dev_priv->in_modeset = true; ++ ret = drm_crtc_helper_set_config(set); ++ dev_priv->in_modeset = false; ++ return ret; ++} ++ ++static const struct drm_crtc_funcs nv50_crtc_funcs = { ++ .save = NULL, ++ .restore = NULL, ++ .cursor_set = nv50_crtc_cursor_set, ++ .cursor_move = nv50_crtc_cursor_move, ++ .gamma_set = nv50_crtc_gamma_set, ++ .set_config = nv50_crtc_helper_set_config, ++ .destroy = nv50_crtc_destroy, ++}; ++ ++static void nv50_crtc_dpms(struct drm_crtc *drm_crtc, int mode) ++{ ++ struct drm_nouveau_private *dev_priv = drm_crtc->dev->dev_private; ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ ++ if (dev_priv->in_modeset) ++ nv50_crtc_blank(crtc, true); ++} ++ ++static void nv50_crtc_prepare(struct drm_crtc *drm_crtc) ++{ ++} ++ ++static void nv50_crtc_commit(struct drm_crtc *drm_crtc) ++{ ++ struct drm_device *dev = drm_crtc->dev; ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ ++ nv50_crtc_blank(crtc, false); ++ ++ OUT_MODE(NV50_UPDATE_DISPLAY, 0); ++} ++ ++static bool nv50_crtc_mode_fixup(struct drm_crtc *drm_crtc, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ return true; ++} ++ ++static int ++nv50_crtc_do_mode_set_base(struct drm_crtc *drm_crtc, int x, int y, ++ struct drm_framebuffer *old_fb, bool update) ++{ ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_framebuffer *drm_fb = crtc->base.fb; ++ struct nouveau_framebuffer *fb = to_nouveau_framebuffer(drm_fb); ++ struct nouveau_gem_object *ngem = nouveau_gem_object(fb->gem); ++ uint32_t offset = crtc->index * 0x400; ++ int ret; ++ ++ ret = nouveau_gem_pin(fb->gem, NOUVEAU_GEM_DOMAIN_VRAM); ++ if (ret) ++ return ret; ++ ++ if (old_fb) { ++ struct nouveau_framebuffer *fb = to_nouveau_framebuffer(old_fb); ++ nouveau_gem_unpin(fb->gem); ++ } ++ ++ crtc->fb.offset = ngem->bo->offset - dev_priv->vm_vram_base; ++ ++ OUT_MODE(NV50_CRTC0_FB_OFFSET + offset, crtc->fb.offset >> 8); ++ OUT_MODE(0x864 + offset, 0); ++ ++ OUT_MODE(NV50_CRTC0_FB_SIZE + offset, ++ drm_fb->height << 16 | drm_fb->width); ++ ++ /* I suspect this flag indicates a linear fb. */ ++ OUT_MODE(NV50_CRTC0_FB_PITCH + offset, drm_fb->pitch | 0x100000); ++ ++ switch (drm_fb->depth) { ++ case 8: ++ OUT_MODE(NV50_CRTC0_DEPTH + offset, NV50_CRTC0_DEPTH_8BPP); ++ break; ++ case 15: ++ OUT_MODE(NV50_CRTC0_DEPTH + offset, NV50_CRTC0_DEPTH_15BPP); ++ break; ++ case 16: ++ OUT_MODE(NV50_CRTC0_DEPTH + offset, NV50_CRTC0_DEPTH_16BPP); ++ break; ++ case 24: ++ OUT_MODE(NV50_CRTC0_DEPTH + offset, NV50_CRTC0_DEPTH_24BPP); ++ break; ++ } ++ ++ OUT_MODE(NV50_CRTC0_COLOR_CTRL + offset, ++ NV50_CRTC_COLOR_CTRL_MODE_COLOR); ++ OUT_MODE(NV50_CRTC0_FB_POS + offset, (y << 16) | x); ++ ++ if (crtc->lut.depth != fb->base.depth) { ++ crtc->lut.depth = fb->base.depth; ++ nv50_crtc_lut_load(crtc); ++ } ++ ++ if (update) ++ OUT_MODE(NV50_UPDATE_DISPLAY, 0); ++ ++ return 0; ++} ++ ++static int ++nv50_crtc_mode_set(struct drm_crtc *drm_crtc, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct drm_device *dev = drm_crtc->dev; ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ struct drm_encoder *drm_encoder; ++ struct nouveau_encoder *encoder; ++ struct nouveau_connector *connector = NULL; ++ uint32_t hsync_dur, vsync_dur, hsync_start_to_end, vsync_start_to_end; ++ uint32_t hunk1, vunk1, vunk2a, vunk2b; ++ uint32_t offset = crtc->index * 0x400; ++ ++ /* Find the connector attached to this CRTC */ ++ list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) { ++ struct drm_connector *drm_connector; ++ ++ encoder = to_nouveau_encoder(drm_encoder); ++ if (drm_encoder->crtc != &crtc->base) ++ continue; ++ ++ list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) { ++ connector = to_nouveau_connector(drm_connector); ++ if (drm_connector->encoder != drm_encoder) ++ continue; ++ ++ break; ++ } ++ ++ break; /* no use in finding more than one mode */ ++ } ++ ++ *crtc->mode = *adjusted_mode; ++ crtc->use_dithering = connector->use_dithering; ++ ++ NV_DEBUG(dev, "index %d\n", crtc->index); ++ ++ hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start; ++ vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start; ++ hsync_start_to_end = adjusted_mode->htotal - adjusted_mode->hsync_start; ++ vsync_start_to_end = adjusted_mode->vtotal - adjusted_mode->vsync_start; ++ /* I can't give this a proper name, anyone else can? */ ++ hunk1 = adjusted_mode->htotal - ++ adjusted_mode->hsync_start + adjusted_mode->hdisplay; ++ vunk1 = adjusted_mode->vtotal - ++ adjusted_mode->vsync_start + adjusted_mode->vdisplay; ++ /* Another strange value, this time only for interlaced adjusted_modes. */ ++ vunk2a = 2 * adjusted_mode->vtotal - ++ adjusted_mode->vsync_start + adjusted_mode->vdisplay; ++ vunk2b = adjusted_mode->vtotal - ++ adjusted_mode->vsync_start + adjusted_mode->vtotal; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { ++ vsync_dur /= 2; ++ vsync_start_to_end /= 2; ++ vunk1 /= 2; ++ vunk2a /= 2; ++ vunk2b /= 2; ++ /* magic */ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) { ++ vsync_start_to_end -= 1; ++ vunk1 -= 1; ++ vunk2a -= 1; ++ vunk2b -= 1; ++ } ++ } ++ ++ OUT_MODE(NV50_CRTC0_CLOCK + offset, adjusted_mode->clock | 0x800000); ++ OUT_MODE(NV50_CRTC0_INTERLACE + offset, ++ (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 0); ++ OUT_MODE(NV50_CRTC0_DISPLAY_START + offset, 0); ++ OUT_MODE(NV50_CRTC0_UNK82C + offset, 0); ++ OUT_MODE(NV50_CRTC0_DISPLAY_TOTAL + offset, ++ adjusted_mode->vtotal << 16 | adjusted_mode->htotal); ++ OUT_MODE(NV50_CRTC0_SYNC_DURATION + offset, ++ (vsync_dur - 1) << 16 | (hsync_dur - 1)); ++ OUT_MODE(NV50_CRTC0_SYNC_START_TO_BLANK_END + offset, ++ (vsync_start_to_end - 1) << 16 | (hsync_start_to_end - 1)); ++ OUT_MODE(NV50_CRTC0_MODE_UNK1 + offset, ++ (vunk1 - 1) << 16 | (hunk1 - 1)); ++ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { ++ OUT_MODE(NV50_CRTC0_MODE_UNK2 + offset, ++ (vunk2b - 1) << 16 | (vunk2a - 1)); ++ } ++ ++ crtc->set_dither(crtc, false); ++ ++ /* This is the actual resolution of the mode. */ ++ OUT_MODE(NV50_CRTC0_REAL_RES + offset, ++ (crtc->base.mode.vdisplay << 16) | crtc->base.mode.hdisplay); ++ OUT_MODE(NV50_CRTC0_SCALE_CENTER_OFFSET + offset, ++ NV50_CRTC_SCALE_CENTER_OFFSET_VAL(0,0)); ++ ++ crtc->set_scale(crtc, connector->scaling_mode, false); ++ return nv50_crtc_do_mode_set_base(drm_crtc, x, y, old_fb, false); ++} ++ ++static int ++nv50_crtc_mode_set_base(struct drm_crtc *drm_crtc, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ return nv50_crtc_do_mode_set_base(drm_crtc, x, y, old_fb, true); ++} ++ ++static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = { ++ .dpms = nv50_crtc_dpms, ++ .prepare = nv50_crtc_prepare, ++ .commit = nv50_crtc_commit, ++ .mode_fixup = nv50_crtc_mode_fixup, ++ .mode_set = nv50_crtc_mode_set, ++ .mode_set_base = nv50_crtc_mode_set_base, ++}; ++ ++int nv50_crtc_create(struct drm_device *dev, int index) ++{ ++ struct nouveau_crtc *crtc = NULL; ++ int ret, i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ crtc = kzalloc(sizeof(*crtc) + ++ NOUVEAUFB_CONN_LIMIT * sizeof(struct drm_connector *), ++ GFP_KERNEL); ++ if (!crtc) ++ return -ENOMEM; ++ ++ crtc->mode = kzalloc(sizeof(*crtc->mode), GFP_KERNEL); ++ if (!crtc->mode) { ++ kfree(crtc); ++ return -ENOMEM; ++ } ++ ++ /* Default CLUT parameters, will be activated on the hw upon ++ * first mode set. ++ */ ++ for (i = 0; i < 256; i++) { ++ crtc->lut.r[i] = i << 8; ++ crtc->lut.g[i] = i << 8; ++ crtc->lut.b[i] = i << 8; ++ } ++ crtc->lut.depth = 0; ++ ++ crtc->lut.mem = nouveau_mem_alloc(dev, 0x100, 4096, NOUVEAU_MEM_FB | ++ NOUVEAU_MEM_NOVM | NOUVEAU_MEM_MAPPED, ++ (struct drm_file *)-2); ++ if (crtc->lut.mem) { ++ ret = drm_bo_kmap(crtc->lut.mem->bo, 0, ++ crtc->lut.mem->bo->mem.num_pages, ++ &crtc->lut.mem->kmap); ++ if (ret) { ++ nouveau_mem_free(dev, crtc->lut.mem); ++ crtc->lut.mem = NULL; ++ } ++ } ++ ++ if (!crtc->lut.mem) { ++ kfree(crtc->mode); ++ kfree(crtc); ++ return -ENOMEM; ++ } ++ ++ crtc->index = index; ++ ++ /* set function pointers */ ++ crtc->set_dither = nv50_crtc_set_dither; ++ crtc->set_scale = nv50_crtc_set_scale; ++ crtc->set_clock = nv50_crtc_set_clock; ++ crtc->set_clock_mode = nv50_crtc_set_clock_mode; ++ ++ crtc->mode_set.crtc = &crtc->base; ++ crtc->mode_set.connectors = (struct drm_connector **)(crtc + 1); ++ crtc->mode_set.num_connectors = 0; ++ ++ drm_crtc_init(dev, &crtc->base, &nv50_crtc_funcs); ++ drm_crtc_helper_add(&crtc->base, &nv50_crtc_helper_funcs); ++ drm_mode_crtc_set_gamma_size(&crtc->base, 256); ++ ++ nv50_cursor_init(crtc); ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c +new file mode 100644 +index 0000000..763cffe +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_cursor.c +@@ -0,0 +1,144 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm_mode.h" ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_crtc.h" ++#include "nv50_display.h" ++ ++static void ++nv50_cursor_show(struct nouveau_crtc *crtc, bool update) ++{ ++ struct drm_nouveau_private *dev_priv = crtc->base.dev->dev_private; ++ struct drm_device *dev = crtc->base.dev; ++ uint32_t offset = crtc->index * 0x400; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (dev_priv->chipset != 0x50) ++ OUT_MODE(NV84_CRTC0_CURSOR_DMA + offset, ++ NV84_CRTC0_CURSOR_DMA_LOCAL); ++ OUT_MODE(NV50_CRTC0_CURSOR_CTRL + offset, NV50_CRTC0_CURSOR_CTRL_SHOW); ++ ++ if (update) { ++ OUT_MODE(NV50_UPDATE_DISPLAY, 0); ++ crtc->cursor.visible = true; ++ } ++} ++ ++static void ++nv50_cursor_hide(struct nouveau_crtc *crtc, bool update) ++{ ++ struct drm_nouveau_private *dev_priv = crtc->base.dev->dev_private; ++ struct drm_device *dev = crtc->base.dev; ++ uint32_t offset = crtc->index * 0x400; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ OUT_MODE(NV50_CRTC0_CURSOR_CTRL + offset, NV50_CRTC0_CURSOR_CTRL_HIDE); ++ if (dev_priv->chipset != 0x50) ++ OUT_MODE(NV84_CRTC0_CURSOR_DMA + offset, ++ NV84_CRTC0_CURSOR_DMA_DISABLE); ++ ++ if (update) { ++ OUT_MODE(NV50_UPDATE_DISPLAY, 0); ++ crtc->cursor.visible = false; ++ } ++} ++ ++static void ++nv50_cursor_set_pos(struct nouveau_crtc *crtc, int x, int y) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ ++ nv_wr32(NV50_HW_CURSOR_POS(crtc->index), ++ ((y & 0xFFFF) << 16) | (x & 0xFFFF)); ++ /* Needed to make the cursor move. */ ++ nv_wr32(NV50_HW_CURSOR_POS_CTRL(crtc->index), 0); ++} ++ ++static void ++nv50_cursor_set_offset(struct nouveau_crtc *crtc, uint32_t offset) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ OUT_MODE(NV50_CRTC0_CURSOR_OFFSET + crtc->index * 0x0400, offset >> 8); ++} ++ ++int ++nv50_cursor_init(struct nouveau_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ int idx = crtc->index; ++ ++ nv_wr32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0x2000); ++ if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK, 0)) { ++ NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); ++ NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", ++ nv_rd32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); ++ return -EBUSY; ++ } ++ ++ nv_wr32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(crtc->index), ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); ++ if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE, ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { ++ NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", idx); ++ NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", idx, ++ nv_rd32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); ++ return -EBUSY; ++ } ++ ++ crtc->cursor.set_offset = nv50_cursor_set_offset; ++ crtc->cursor.set_pos = nv50_cursor_set_pos; ++ crtc->cursor.hide = nv50_cursor_hide; ++ crtc->cursor.show = nv50_cursor_show; ++ return 0; ++} ++ ++void ++nv50_cursor_fini(struct nouveau_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ int idx = crtc->index; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0); ++ if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK, 0)) { ++ NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); ++ NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", ++ nv_rd32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); ++ } ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c +new file mode 100644 +index 0000000..2ac1c95 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_dac.c +@@ -0,0 +1,280 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++#include "nouveau_encoder.h" ++#include "nouveau_crtc.h" ++#include "nv50_display.h" ++#include "nv50_display_commands.h" ++ ++static void ++nv50_dac_disconnect(struct nouveau_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ uint32_t offset = encoder->or * 0x80; ++ ++ NV_DEBUG(dev, "or %d\n", encoder->or); ++ ++ OUT_MODE(NV50_DAC0_MODE_CTRL + offset, NV50_DAC_MODE_CTRL_OFF); ++} ++ ++static int ++nv50_dac_set_clock_mode(struct nouveau_encoder *encoder, ++ struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ ++ NV_DEBUG(dev, "or %d\n", encoder->or); ++ ++ nv_wr32(NV50_PDISPLAY_DAC_CLK_CLK_CTRL2(encoder->or), 0); ++ return 0; ++} ++ ++static enum drm_connector_status ++nv50_dac_detect(struct drm_encoder *drm_encoder, ++ struct drm_connector *drm_connector) ++{ ++ struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ enum drm_connector_status status = connector_status_disconnected; ++ uint32_t dpms_state, load_pattern, load_state; ++ int or = encoder->or; ++ ++ nv_wr32(NV50_PDISPLAY_DAC_REGS_CLK_CTRL1(or), 0x00000001); ++ dpms_state = nv_rd32(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or)); ++ ++ nv_wr32(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or), ++ 0x00150000 | NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING); ++ if (!nv_wait(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or), ++ NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING, 0)) { ++ NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); ++ NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, ++ nv_rd32(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or))); ++ return status; ++ } ++ ++ /* Use bios provided value if possible. */ ++ if (dev_priv->vbios->dactestval) { ++ load_pattern = dev_priv->vbios->dactestval; ++ NV_DEBUG(dev, "Using bios provided load_pattern of %d\n", ++ load_pattern); ++ } else { ++ load_pattern = 340; ++ NV_DEBUG(dev, "Using default load_pattern of %d\n", ++ load_pattern); ++ } ++ ++ nv_wr32(NV50_PDISPLAY_DAC_REGS_LOAD_CTRL(or), ++ NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_ACTIVE | load_pattern); ++ udelay(10000); /* give it some time to process */ ++ load_state = nv_rd32(NV50_PDISPLAY_DAC_REGS_LOAD_CTRL(or)); ++ ++ nv_wr32(NV50_PDISPLAY_DAC_REGS_LOAD_CTRL(or), 0); ++ nv_wr32(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or), dpms_state); ++ ++ if ((load_state & NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_PRESENT) == ++ NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_PRESENT) ++ status = connector_status_connected; ++ ++ if (status == connector_status_connected) ++ NV_DEBUG(dev, "Load was detected on output with or %d\n", or); ++ else ++ NV_DEBUG(dev, "Load was not detected on output with or %d\n", or); ++ ++ return status; ++} ++ ++static void nv50_dac_dpms(struct drm_encoder *drm_encoder, int mode) ++{ ++ struct drm_device *dev = drm_encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); ++ uint32_t val; ++ int or = encoder->or; ++ ++ NV_DEBUG(dev, "or %d\n", or); ++ ++ if (dev_priv->in_modeset) { ++ nv50_dac_disconnect(encoder); ++ return; ++ } ++ ++ /* wait for it to be done */ ++ if (!nv_wait(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or), ++ NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING, 0)) { ++ NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); ++ NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, ++ nv_rd32(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or))); ++ return; ++ } ++ ++ val = nv_rd32(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or)) & ~0x7F; ++ ++ if (mode != DRM_MODE_DPMS_ON) ++ val |= NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_BLANKED; ++ ++ switch (mode) { ++ case DRM_MODE_DPMS_STANDBY: ++ val |= NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_HSYNC_OFF; ++ break; ++ case DRM_MODE_DPMS_SUSPEND: ++ val |= NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_VSYNC_OFF; ++ break; ++ case DRM_MODE_DPMS_OFF: ++ val |= NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_OFF; ++ val |= NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_HSYNC_OFF; ++ val |= NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_VSYNC_OFF; ++ break; ++ default: ++ break; ++ } ++ ++ nv_wr32(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or), ++ val | NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING); ++} ++ ++static void nv50_dac_save(struct drm_encoder *drm_encoder) ++{ ++ NV_ERROR(drm_encoder->dev, "!!\n"); ++} ++ ++static void nv50_dac_restore(struct drm_encoder *drm_encoder) ++{ ++ NV_ERROR(drm_encoder->dev, "!!\n"); ++} ++ ++static bool nv50_dac_mode_fixup(struct drm_encoder *drm_encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ return true; ++} ++ ++static void nv50_dac_prepare(struct drm_encoder *drm_encoder) ++{ ++} ++ ++static void nv50_dac_commit(struct drm_encoder *drm_encoder) ++{ ++} ++ ++static void nv50_dac_mode_set(struct drm_encoder *drm_encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); ++ struct drm_device *dev = drm_encoder->dev; ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_encoder->crtc); ++ uint32_t offset = encoder->or * 0x80; ++ uint32_t mode_ctl = NV50_DAC_MODE_CTRL_OFF; ++ uint32_t mode_ctl2 = 0; ++ ++ NV_DEBUG(dev, "or %d\n", encoder->or); ++ ++ if (crtc->index == 1) ++ mode_ctl |= NV50_DAC_MODE_CTRL_CRTC1; ++ else ++ mode_ctl |= NV50_DAC_MODE_CTRL_CRTC0; ++ ++ /* Lacking a working tv-out, this is not a 100% sure. */ ++ if (encoder->base.encoder_type == DRM_MODE_ENCODER_DAC) { ++ mode_ctl |= 0x40; ++ } else ++ if (encoder->base.encoder_type == DRM_MODE_ENCODER_TVDAC) { ++ mode_ctl |= 0x100; ++ } ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ++ mode_ctl2 |= NV50_DAC_MODE_CTRL2_NHSYNC; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ++ mode_ctl2 |= NV50_DAC_MODE_CTRL2_NVSYNC; ++ ++ OUT_MODE(NV50_DAC0_MODE_CTRL + offset, mode_ctl); ++ OUT_MODE(NV50_DAC0_MODE_CTRL2 + offset, mode_ctl2); ++} ++ ++static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { ++ .dpms = nv50_dac_dpms, ++ .save = nv50_dac_save, ++ .restore = nv50_dac_restore, ++ .mode_fixup = nv50_dac_mode_fixup, ++ .prepare = nv50_dac_prepare, ++ .commit = nv50_dac_commit, ++ .mode_set = nv50_dac_mode_set, ++ .detect = nv50_dac_detect ++}; ++ ++static void nv50_dac_destroy(struct drm_encoder *drm_encoder) ++{ ++ struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); ++ ++ NV_DEBUG(drm_encoder->dev, "\n"); ++ ++ if (!drm_encoder) ++ return; ++ ++ drm_encoder_cleanup(&encoder->base); ++ ++ kfree(encoder); ++} ++ ++static const struct drm_encoder_funcs nv50_dac_encoder_funcs = { ++ .destroy = nv50_dac_destroy, ++}; ++ ++int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) ++{ ++ struct nouveau_encoder *encoder = NULL; ++ ++ NV_DEBUG(dev, "\n"); ++ NV_INFO(dev, "Detected a DAC output\n"); ++ ++ encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); ++ if (!encoder) ++ return -ENOMEM; ++ ++ encoder->dcb_entry = entry; ++ encoder->or = ffs(entry->or) - 1; ++ ++ /* Set function pointers. */ ++ encoder->set_clock_mode = nv50_dac_set_clock_mode; ++ ++ drm_encoder_init(dev, &encoder->base, &nv50_dac_encoder_funcs, ++ DRM_MODE_ENCODER_DAC); ++ drm_encoder_helper_add(&encoder->base, &nv50_dac_helper_funcs); ++ ++ /* I've never seen possible crtc's restricted. */ ++ encoder->base.possible_crtcs = 3; ++ encoder->base.possible_clones = 0; ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c +new file mode 100644 +index 0000000..6abdad7 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_display.c +@@ -0,0 +1,433 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "nv50_display.h" ++#include "nouveau_crtc.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_fb.h" ++#include "drm_crtc_helper.h" ++ ++static int nv50_display_pre_init(struct drm_device *dev) ++{ ++ uint32_t ram_amount; ++ int i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(0x00610184, nv_rd32(0x00614004)); ++ /* ++ * I think the 0x006101XX range is some kind of main control area that enables things. ++ */ ++ /* CRTC? */ ++ nv_wr32(0x00610190 + 0 * 0x10, nv_rd32(0x00616100 + 0 * 0x800)); ++ nv_wr32(0x00610190 + 1 * 0x10, nv_rd32(0x00616100 + 1 * 0x800)); ++ nv_wr32(0x00610194 + 0 * 0x10, nv_rd32(0x00616104 + 0 * 0x800)); ++ nv_wr32(0x00610194 + 1 * 0x10, nv_rd32(0x00616104 + 1 * 0x800)); ++ nv_wr32(0x00610198 + 0 * 0x10, nv_rd32(0x00616108 + 0 * 0x800)); ++ nv_wr32(0x00610198 + 1 * 0x10, nv_rd32(0x00616108 + 1 * 0x800)); ++ nv_wr32(0x0061019c + 0 * 0x10, nv_rd32(0x0061610c + 0 * 0x800)); ++ nv_wr32(0x0061019c + 1 * 0x10, nv_rd32(0x0061610c + 1 * 0x800)); ++ /* DAC */ ++ nv_wr32(0x006101d0 + 0 * 0x4, nv_rd32(0x0061a000 + 0 * 0x800)); ++ nv_wr32(0x006101d0 + 1 * 0x4, nv_rd32(0x0061a000 + 1 * 0x800)); ++ nv_wr32(0x006101d0 + 2 * 0x4, nv_rd32(0x0061a000 + 2 * 0x800)); ++ /* SOR */ ++ nv_wr32(0x006101e0 + 0 * 0x4, nv_rd32(0x0061c000 + 0 * 0x800)); ++ nv_wr32(0x006101e0 + 1 * 0x4, nv_rd32(0x0061c000 + 1 * 0x800)); ++ nv_wr32(0x006101e0 + 2 * 0x4, nv_rd32(0x0061c000 + 2 * 0x800)); ++ /* Something not yet in use, tv-out maybe. */ ++ nv_wr32(0x006101f0 + 0 * 0x4, nv_rd32(0x0061e000 + 0 * 0x800)); ++ nv_wr32(0x006101f0 + 1 * 0x4, nv_rd32(0x0061e000 + 1 * 0x800)); ++ nv_wr32(0x006101f0 + 2 * 0x4, nv_rd32(0x0061e000 + 2 * 0x800)); ++ ++ for (i = 0; i < 3; i++) { ++ nv_wr32(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(i), 0x00550000 | ++ NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING); ++ nv_wr32(NV50_PDISPLAY_DAC_REGS_CLK_CTRL1(i), 0x00000001); ++ } ++ ++ /* This used to be in crtc unblank, but seems out of place there. */ ++ nv_wr32(NV50_PDISPLAY_UNK_380, 0); ++ /* RAM is clamped to 256 MiB. */ ++ ram_amount = nouveau_mem_fb_amount(dev); ++ NV_DEBUG(dev, "ram_amount %d\n", ram_amount); ++ if (ram_amount > 256*1024*1024) ++ ram_amount = 256*1024*1024; ++ nv_wr32(NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1); ++ nv_wr32(NV50_PDISPLAY_UNK_388, 0x150000); ++ nv_wr32(NV50_PDISPLAY_UNK_38C, 0); ++ ++ return 0; ++} ++ ++static int ++nv50_display_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; ++ uint64_t start; ++ uint32_t val; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* The precise purpose is unknown, i suspect it has something to do ++ * with text mode. ++ */ ++ if (nv_rd32(NV50_PDISPLAY_SUPERVISOR) & 0x100) { ++ nv_wr32(NV50_PDISPLAY_SUPERVISOR, 0x100); ++ nv_wr32(0x006194e8, nv_rd32(0x006194e8) & ~1); ++ if (!nv_wait(0x006194e8, 2, 0)) { ++ NV_ERROR(dev, "timeout: (0x6194e8 & 2) != 0\n"); ++ NV_ERROR(dev, "0x6194e8 = 0x%08x\n", nv_rd32(0x6194e8)); ++ return -EBUSY; ++ } ++ } ++ ++ /* taken from nv bug #12637, attempts to un-wedge the hw if it's ++ * stuck in some unspecified state ++ */ ++ start = ptimer->read(dev); ++ nv_wr32(NV50_PDISPLAY_UNK200_CTRL, 0x2b00); ++ while ((val = nv_rd32(NV50_PDISPLAY_UNK200_CTRL)) & 0x1e0000) { ++ if ((val & 0x9f0000) == 0x20000) ++ nv_wr32(NV50_PDISPLAY_UNK200_CTRL, val | 0x800000); ++ ++ if ((val & 0x3f0000) == 0x30000) ++ nv_wr32(NV50_PDISPLAY_UNK200_CTRL, val | 0x200000); ++ ++ if (ptimer->read(dev) - start > 1000000000ULL) { ++ NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) != 0\n"); ++ NV_ERROR(dev, "0x610200 = 0x%08x\n", val); ++ return -EBUSY; ++ } ++ } ++ ++ nv_wr32(NV50_PDISPLAY_CTRL_STATE, NV50_PDISPLAY_CTRL_STATE_ENABLE); ++ nv_wr32(NV50_PDISPLAY_UNK200_CTRL, 0x1000b03); ++ if (!nv_wait(NV50_PDISPLAY_UNK200_CTRL, 0x40000000, 0x40000000)) { ++ NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n"); ++ NV_ERROR(dev, "0x610200 = 0x%08x\n", ++ nv_rd32(NV50_PDISPLAY_UNK200_CTRL)); ++ return -EBUSY; ++ } ++ ++ /* For the moment this is just a wrapper, which should be replaced with a real fifo at some point. */ ++ OUT_MODE(NV50_UNK84, 0); ++ OUT_MODE(NV50_UNK88, 0); ++ OUT_MODE(NV50_CRTC0_BLANK_CTRL, NV50_CRTC0_BLANK_CTRL_BLANK); ++ OUT_MODE(NV50_CRTC0_UNK800, 0); ++ OUT_MODE(NV50_CRTC0_DISPLAY_START, 0); ++ OUT_MODE(NV50_CRTC0_UNK82C, 0); ++ ++ /* enable clock change interrupts. */ ++// nv_wr32(NV50_PDISPLAY_SUPERVISOR_INTR, nv_rd32(NV50_PDISPLAY_SUPERVISOR_INTR) | 0x70); ++ ++ /* enable hotplug interrupts */ ++ nv_wr32(NV50_PCONNECTOR_HOTPLUG_CTRL, 0x7FFF7FFF); ++// nv_wr32(NV50_PCONNECTOR_HOTPLUG_INTR, 0x7FFF7FFF); ++ ++ ++ return 0; ++} ++ ++static int nv50_display_disable(struct drm_device *dev) ++{ ++ struct drm_crtc *drm_crtc; ++ int i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ ++ nv50_crtc_blank(crtc, true); ++ } ++ ++ OUT_MODE(NV50_UPDATE_DISPLAY, 0); ++ ++ /* Almost like ack'ing a vblank interrupt, maybe in the spirit of cleaning up? */ ++ list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); ++ ++ if (crtc->base.enabled) { ++ uint32_t mask; ++ ++ if (crtc->index == 1) ++ mask = NV50_PDISPLAY_SUPERVISOR_CRTC1; ++ else ++ mask = NV50_PDISPLAY_SUPERVISOR_CRTC0; ++ ++ nv_wr32(NV50_PDISPLAY_SUPERVISOR, mask); ++ if (!nv_wait(NV50_PDISPLAY_SUPERVISOR, mask, mask)) { ++ NV_ERROR(dev, "timeout: (0x610024 & 0x%08x) == " ++ "0x%08x\n", mask, mask); ++ NV_ERROR(dev, "0x610024 = 0x%08x\n", ++ nv_rd32(0x610024)); ++ } ++ } ++ } ++ ++#if 0 ++ nv_wr32(NV50_PDISPLAY_UNK200_CTRL, 0); ++ nv_wr32(NV50_PDISPLAY_CTRL_STATE, 0); ++ if (!nv_wait(NV50_PDISPLAY_UNK200_CTRL, 0x1e0000, 0)) { ++ NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); ++ NV_ERROR(dev, "0x610200 = 0x%08x\n", ++ nv_rd32(NV50_PDISPLAY_UNK200_CTRL)); ++ } ++#endif ++ ++ for (i = 0; i < NV50_PDISPLAY_SOR_REGS__LEN; i++) { ++ if (!nv_wait(NV50_PDISPLAY_SOR_REGS_DPMS_STATE(i), ++ NV50_PDISPLAY_SOR_REGS_DPMS_STATE_WAIT, 0)) { ++ NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i); ++ NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", i, ++ nv_rd32(NV50_PDISPLAY_SOR_REGS_DPMS_STATE(i))); ++ } ++ } ++ ++ /* disable clock change interrupts. */ ++ nv_wr32(NV50_PDISPLAY_SUPERVISOR_INTR, ++ nv_rd32(NV50_PDISPLAY_SUPERVISOR_INTR) & ~0x70); ++ ++ /* disable hotplug interrupts */ ++ nv_wr32(NV50_PCONNECTOR_HOTPLUG_INTR, 0); ++ ++ return 0; ++} ++ ++int nv50_display_create(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct parsed_dcb *dcb = dev_priv->vbios->dcb; ++ uint32_t bus_mask = 0; ++ uint32_t bus_digital = 0, bus_analog = 0; ++ int ret, i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* init basic kernel modesetting */ ++ drm_mode_config_init(dev); ++ ++ /* Initialise some optional connector properties. */ ++ drm_mode_create_scaling_mode_property(dev); ++ drm_mode_create_dithering_property(dev); ++ ++ dev->mode_config.min_width = 0; ++ dev->mode_config.min_height = 0; ++ ++ dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs; ++ ++ dev->mode_config.max_width = 8192; ++ dev->mode_config.max_height = 8192; ++ ++ dev->mode_config.fb_base = dev_priv->fb_phys; ++ ++ ret = nv50_display_pre_init(dev); ++ if (ret) ++ return ret; ++ ++ /* Create CRTC objects */ ++ for (i = 0; i < 2; i++) { ++ nv50_crtc_create(dev, i); ++ } ++ ++ /* we setup the outputs up from the BIOS table */ ++ for (i = 0 ; i < dcb->entries; i++) { ++ struct dcb_entry *entry = &dcb->entry[i]; ++ ++ switch (entry->type) { ++ case OUTPUT_TMDS: ++ case OUTPUT_LVDS: ++ bus_digital |= (1 << entry->bus); ++ nv50_sor_create(dev, entry); ++ break; ++ case OUTPUT_ANALOG: ++ bus_analog |= (1 << entry->bus); ++ nv50_dac_create(dev, entry); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /* setup the connectors based on the output tables. */ ++ for (i = 0 ; i < dcb->entries; i++) { ++ struct dcb_entry *entry = &dcb->entry[i]; ++ int connector = 0; ++ ++ /* already done? */ ++ if (bus_mask & (1 << entry->bus)) ++ continue; ++ ++ /* only do it for supported outputs */ ++ if (entry->type != OUTPUT_ANALOG && ++ entry->type != OUTPUT_TMDS && ++ entry->type != OUTPUT_LVDS) ++ continue; ++ ++ switch (entry->type) { ++ case OUTPUT_TMDS: ++ case OUTPUT_ANALOG: ++ if ((bus_digital & (1 << entry->bus)) && ++ (bus_analog & (1 << entry->bus))) ++ connector = DRM_MODE_CONNECTOR_DVII; ++ else ++ if (bus_digital & (1 << entry->bus)) ++ connector = DRM_MODE_CONNECTOR_DVID; ++ else ++ if (bus_analog & (1 << entry->bus)) ++ connector = DRM_MODE_CONNECTOR_VGA; ++ break; ++ case OUTPUT_LVDS: ++ connector = DRM_MODE_CONNECTOR_LVDS; ++ break; ++ default: ++ connector = DRM_MODE_CONNECTOR_Unknown; ++ break; ++ } ++ ++ if (connector == DRM_MODE_CONNECTOR_Unknown) ++ continue; ++ ++ nv50_connector_create(dev, entry->bus, entry->i2c_index, ++ connector); ++ bus_mask |= (1 << entry->bus); ++ } ++ ++ ret = nv50_display_init(dev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++int nv50_display_destroy(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv50_display_disable(dev); ++ ++ drm_mode_config_cleanup(dev); ++ ++ return 0; ++} ++ ++/* This can be replaced with a real fifo in the future. */ ++static void nv50_display_vclk_update(struct drm_device *dev) ++{ ++ struct drm_encoder *drm_encoder; ++ struct drm_crtc *drm_crtc; ++ struct nouveau_encoder *encoder = NULL; ++ struct nouveau_crtc *crtc = NULL; ++ int crtc_index; ++ uint32_t unk30 = nv_rd32(NV50_PDISPLAY_UNK30_CTRL); ++ ++ for (crtc_index = 0; crtc_index < 2; crtc_index++) { ++ bool clock_change = false; ++ bool clock_ack = false; ++ ++ if (crtc_index == 0 && (unk30 & NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0)) ++ clock_change = true; ++ ++ if (crtc_index == 1 && (unk30 & NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1)) ++ clock_change = true; ++ ++ if (clock_change) ++ clock_ack = true; ++ ++#if 0 ++ if (dev_priv->last_crtc == crtc_index) ++#endif ++ clock_ack = true; ++ ++ list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { ++ crtc = to_nouveau_crtc(drm_crtc); ++ if (crtc->index == crtc_index) ++ break; ++ } ++ ++ if (clock_change) ++ crtc->set_clock(crtc, crtc->mode); ++ ++ NV_DEBUG(dev, "index %d clock_change %d clock_ack %d\n", crtc_index, clock_change, clock_ack); ++ ++ if (!clock_ack) ++ continue; ++ ++ crtc->set_clock_mode(crtc); ++ ++ list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) { ++ encoder = to_nouveau_encoder(drm_encoder); ++ ++ if (!drm_encoder->crtc) ++ continue; ++ ++ if (drm_encoder->crtc == drm_crtc) ++ encoder->set_clock_mode(encoder, crtc->mode); ++ } ++ } ++} ++ ++void nv50_display_command(struct drm_device *dev, uint32_t mthd, uint32_t val) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; ++ uint64_t start; ++ ++ NV_DEBUG(dev, "mthd 0x%03X val 0x%08X\n", mthd, val); ++ ++ nv_wr32(NV50_PDISPLAY_CTRL_VAL, val); ++ nv_wr32(NV50_PDISPLAY_CTRL_STATE, NV50_PDISPLAY_CTRL_STATE_PENDING | ++ NV50_PDISPLAY_CTRL_STATE_ENABLE | ++ 0x10000 | mthd); ++ ++ start = ptimer->read(dev); ++ while (nv_rd32(NV50_PDISPLAY_CTRL_STATE) & NV50_PDISPLAY_CTRL_STATE_PENDING) { ++ const uint32_t super = nv_rd32(NV50_PDISPLAY_SUPERVISOR); ++ uint32_t state; ++ ++ state = (super & NV50_PDISPLAY_SUPERVISOR_CLK_MASK); ++ state >>= NV50_PDISPLAY_SUPERVISOR_CLK_MASK__SHIFT; ++ if (state) { ++ if (state == 2) ++ nv50_display_vclk_update(dev); ++ ++ nv_wr32(NV50_PDISPLAY_SUPERVISOR, ++ (super & NV50_PDISPLAY_SUPERVISOR_CLK_MASK)); ++ nv_wr32(NV50_PDISPLAY_UNK30_CTRL, ++ NV50_PDISPLAY_UNK30_CTRL_PENDING); ++ } ++ ++ if (ptimer->read(dev) - start > 1000000000ULL) { ++ NV_ERROR(dev, "timeout: 0x610300 = 0x%08x\n", ++ nv_rd32(NV50_PDISPLAY_CTRL_STATE)); ++ break; ++ } ++ } ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h +new file mode 100644 +index 0000000..8cd7fe6 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_display.h +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __NV50_DISPLAY_H__ ++#define __NV50_DISPLAY_H__ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++#include "nouveau_reg.h" ++#include "nouveau_crtc.h" ++#include "nv50_display_commands.h" ++ ++void nv50_display_command(struct drm_device *dev, uint32_t mthd, uint32_t val); ++int nv50_display_create(struct drm_device *dev); ++int nv50_display_destroy(struct drm_device *dev); ++int nv50_crtc_blank(struct nouveau_crtc *, bool blank); ++ ++#endif /* __NV50_DISPLAY_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nv50_display_commands.h b/drivers/gpu/drm/nouveau/nv50_display_commands.h +new file mode 100644 +index 0000000..4fd10c9 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_display_commands.h +@@ -0,0 +1,195 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++/* copied from ddx definitions, until rules-ng can handle this */ ++ ++#define NV50_UPDATE_DISPLAY 0x80 ++#define NV50_UNK84 0x84 ++#define NV50_UNK88 0x88 ++ ++#define NV50_DAC0_MODE_CTRL 0x400 ++ #define NV50_DAC_MODE_CTRL_OFF (0 << 0) ++ #define NV50_DAC_MODE_CTRL_CRTC0 (1 << 0) ++ #define NV50_DAC_MODE_CTRL_CRTC1 (1 << 1) ++#define NV50_DAC1_MODE_CTRL 0x480 ++#define NV50_DAC2_MODE_CTRL 0x500 ++ ++#define NV50_DAC0_MODE_CTRL2 0x404 ++ #define NV50_DAC_MODE_CTRL2_NHSYNC (1 << 0) ++ #define NV50_DAC_MODE_CTRL2_NVSYNC (2 << 0) ++#define NV50_DAC1_MODE_CTRL2 0x484 ++#define NV50_DAC2_MODE_CTRL2 0x504 ++ ++#define NV50_SOR0_MODE_CTRL 0x600 ++ #define NV50_SOR_MODE_CTRL_OFF (0 << 0) ++ #define NV50_SOR_MODE_CTRL_CRTC0 (1 << 0) ++ #define NV50_SOR_MODE_CTRL_CRTC1 (1 << 1) ++ #define NV50_SOR_MODE_CTRL_LVDS (0 << 8) ++ #define NV50_SOR_MODE_CTRL_TMDS (1 << 8) ++ #define NV50_SOR_MODE_CTRL_TMDS_DUAL_LINK (4 << 8) ++ #define NV50_SOR_MODE_CTRL_NHSYNC (1 << 12) ++ #define NV50_SOR_MODE_CTRL_NVSYNC (2 << 12) ++#define NV50_SOR1_MODE_CTRL 0x640 ++ ++#define NV50_CRTC0_UNK800 0x800 ++#define NV50_CRTC0_CLOCK 0x804 ++#define NV50_CRTC0_INTERLACE 0x808 ++ ++/* 0x810 is a reasonable guess, nothing more. */ ++#define NV50_CRTC0_DISPLAY_START 0x810 ++#define NV50_CRTC0_DISPLAY_TOTAL 0x814 ++#define NV50_CRTC0_SYNC_DURATION 0x818 ++#define NV50_CRTC0_SYNC_START_TO_BLANK_END 0x81C ++#define NV50_CRTC0_MODE_UNK1 0x820 ++#define NV50_CRTC0_MODE_UNK2 0x824 ++ ++#define NV50_CRTC0_UNK82C 0x82C ++ ++/* You can't have a palette in 8 bit mode (=OFF) */ ++#define NV50_CRTC0_CLUT_MODE 0x840 ++ #define NV50_CRTC0_CLUT_MODE_BLANK 0x00000000 ++ #define NV50_CRTC0_CLUT_MODE_OFF 0x80000000 ++ #define NV50_CRTC0_CLUT_MODE_ON 0xC0000000 ++#define NV50_CRTC0_CLUT_OFFSET 0x844 ++ ++#define NV84_CRTC0_CLUT_DMA 0x85C ++ #define NV84_CRTC0_CLUT_DMA_DISABLE 0x0 ++ #define NV84_CRTC0_CLUT_DMA_LOCAL 0x1 ++ ++#define NV50_CRTC0_FB_OFFSET 0x860 ++ ++#define NV50_CRTC0_FB_SIZE 0x868 ++#define NV50_CRTC0_FB_PITCH 0x86C ++ ++#define NV50_CRTC0_DEPTH 0x870 ++ #define NV50_CRTC0_DEPTH_8BPP 0x1E00 ++ #define NV50_CRTC0_DEPTH_15BPP 0xE900 ++ #define NV50_CRTC0_DEPTH_16BPP 0xE800 ++ #define NV50_CRTC0_DEPTH_24BPP 0xCF00 ++ ++/* I'm openminded to better interpretations. */ ++/* This is an educated guess. */ ++/* NV50 has RAMDAC and TMDS offchip, so it's unlikely to be that. */ ++#define NV50_CRTC0_BLANK_CTRL 0x874 ++ #define NV50_CRTC0_BLANK_CTRL_BLANK 0x0 ++ #define NV50_CRTC0_BLANK_CTRL_UNBLANK 0x1 ++ ++#define NV50_CRTC0_CURSOR_CTRL 0x880 ++ #define NV50_CRTC0_CURSOR_CTRL_SHOW 0x85000000 ++ #define NV50_CRTC0_CURSOR_CTRL_HIDE 0x05000000 ++ ++#define NV50_CRTC0_CURSOR_OFFSET 0x884 ++ ++/* Anyone know what part of the chip is triggered here precisely? */ ++#define NV84_CRTC0_CURSOR_DMA 0x89C ++ #define NV84_CRTC0_CURSOR_DMA_DISABLE 0x0 ++ #define NV84_CRTC0_CURSOR_DMA_LOCAL 0x1 ++ ++#define NV50_CRTC0_DITHERING_CTRL 0x8A0 ++ #define NV50_CRTC0_DITHERING_CTRL_ON 0x11 ++ #define NV50_CRTC0_DITHERING_CTRL_OFF 0x0 ++ ++#define NV50_CRTC0_SCALE_CTRL 0x8A4 ++ #define NV50_CRTC0_SCALE_CTRL_SCALER_INACTIVE (0 << 0) ++ /* It doesn't seem to be needed, hence i wonder what it does precisely. */ ++ #define NV50_CRTC0_SCALE_CTRL_SCALER_ACTIVE (9 << 0) ++#define NV50_CRTC0_COLOR_CTRL 0x8A8 ++ #define NV50_CRTC_COLOR_CTRL_MODE_COLOR (4 << 16) ++ ++#define NV50_CRTC0_FB_POS 0x8C0 ++#define NV50_CRTC0_REAL_RES 0x8C8 ++ ++/* Added a macro, because the signed stuff can cause you problems very quickly. */ ++#define NV50_CRTC0_SCALE_CENTER_OFFSET 0x8D4 ++ #define NV50_CRTC_SCALE_CENTER_OFFSET_VAL(x, y) ((((unsigned)y << 16) & 0xFFFF0000) | (((unsigned)x) & 0x0000FFFF)) ++/* Both of these are needed, otherwise nothing happens. */ ++#define NV50_CRTC0_SCALE_RES1 0x8D8 ++#define NV50_CRTC0_SCALE_RES2 0x8DC ++ ++#define NV50_CRTC1_UNK800 0xC00 ++#define NV50_CRTC1_CLOCK 0xC04 ++#define NV50_CRTC1_INTERLACE 0xC08 ++ ++/* 0xC10 is a reasonable guess, nothing more. */ ++#define NV50_CRTC1_DISPLAY_START 0xC10 ++#define NV50_CRTC1_DISPLAY_TOTAL 0xC14 ++#define NV50_CRTC1_SYNC_DURATION 0xC18 ++#define NV50_CRTC1_SYNC_START_TO_BLANK_END 0xC1C ++#define NV50_CRTC1_MODE_UNK1 0xC20 ++#define NV50_CRTC1_MODE_UNK2 0xC24 ++ ++#define NV50_CRTC1_CLUT_MODE 0xC40 ++ #define NV50_CRTC1_CLUT_MODE_BLANK 0x00000000 ++ #define NV50_CRTC1_CLUT_MODE_OFF 0x80000000 ++ #define NV50_CRTC1_CLUT_MODE_ON 0xC0000000 ++#define NV50_CRTC1_CLUT_OFFSET 0xC44 ++ ++/* Anyone know what part of the chip is triggered here precisely? */ ++#define NV84_CRTC1_BLANK_UNK1 0xC5C ++ #define NV84_CRTC1_BLANK_UNK1_BLANK 0x0 ++ #define NV84_CRTC1_BLANK_UNK1_UNBLANK 0x1 ++ ++#define NV50_CRTC1_FB_OFFSET 0xC60 ++ ++#define NV50_CRTC1_FB_SIZE 0xC68 ++#define NV50_CRTC1_FB_PITCH 0xC6C ++ ++#define NV50_CRTC1_DEPTH 0xC70 ++ #define NV50_CRTC1_DEPTH_8BPP 0x1E00 ++ #define NV50_CRTC1_DEPTH_15BPP 0xE900 ++ #define NV50_CRTC1_DEPTH_16BPP 0xE800 ++ #define NV50_CRTC1_DEPTH_24BPP 0xCF00 ++ ++/* I'm openminded to better interpretations. */ ++#define NV50_CRTC1_BLANK_CTRL 0xC74 ++ #define NV50_CRTC1_BLANK_CTRL_BLANK 0x0 ++ #define NV50_CRTC1_BLANK_CTRL_UNBLANK 0x1 ++ ++#define NV50_CRTC1_CURSOR_CTRL 0xC80 ++ #define NV50_CRTC1_CURSOR_CTRL_SHOW 0x85000000 ++ #define NV50_CRTC1_CURSOR_CTRL_HIDE 0x05000000 ++ ++#define NV50_CRTC1_CURSOR_OFFSET 0xC84 ++ ++/* Anyone know what part of the chip is triggered here precisely? */ ++#define NV84_CRTC1_BLANK_UNK2 0xC9C ++ #define NV84_CRTC1_BLANK_UNK2_BLANK 0x0 ++ #define NV84_CRTC1_BLANK_UNK2_UNBLANK 0x1 ++ ++#define NV50_CRTC1_DITHERING_CTRL 0xCA0 ++ #define NV50_CRTC1_DITHERING_CTRL_ON 0x11 ++ #define NV50_CRTC1_DITHERING_CTRL_OFF 0x0 ++ ++#define NV50_CRTC1_SCALE_CTRL 0xCA4 ++#define NV50_CRTC1_COLOR_CTRL 0xCA8 ++ ++#define NV50_CRTC1_FB_POS 0xCC0 ++#define NV50_CRTC1_REAL_RES 0xCC8 ++ ++#define NV50_CRTC1_SCALE_CENTER_OFFSET 0xCD4 ++/* Both of these are needed, otherwise nothing happens. */ ++#define NV50_CRTC1_SCALE_RES1 0xCD8 ++#define NV50_CRTC1_SCALE_RES2 0xCDC +diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c +new file mode 100644 +index 0000000..9ca1c1e +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c +@@ -0,0 +1,222 @@ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++#include "nouveau_fbcon.h" ++ ++static int ++nv50_fbcon_sync(struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ int ret, i; ++ ++ if (!chan->accel_done || ++ info->state != FBINFO_STATE_RUNNING || ++ info->flags & FBINFO_HWACCEL_DISABLED) ++ return 0; ++ ++ if (RING_SPACE(chan, 4)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ return 0; ++ } ++ ++ BEGIN_RING(chan, 0, 0x0104, 1); ++ OUT_RING (chan, 0); ++ BEGIN_RING(chan, 0, 0x0100, 1); ++ OUT_RING (chan, 0); ++ chan->m2mf_ntfy_map[3] = 0xffffffff; ++ FIRE_RING (chan); ++ ++ ret = -EBUSY; ++ for (i = 0; i < 100000; i++) { ++ if (chan->m2mf_ntfy_map[3] == 0) { ++ ret = 0; ++ break; ++ } ++ DRM_UDELAY(1); ++ } ++ ++ if (ret) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ return 0; ++ } ++ ++ chan->accel_done = false; ++ return 0; ++} ++ ++static void ++nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ ++ if (info->flags & FBINFO_HWACCEL_DISABLED) { ++ cfb_fillrect(info, rect); ++ return; ++ } ++ ++ if (RING_SPACE(chan, 9)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ cfb_fillrect(info, rect); ++ return; ++ } ++ ++ BEGIN_RING(chan, NvSub2D, 0x02ac, 1); ++ OUT_RING (chan, rect->rop == ROP_COPY ? 3 : 1); ++ BEGIN_RING(chan, NvSub2D, 0x0588, 1); ++ OUT_RING (chan, rect->color); ++ BEGIN_RING(chan, NvSub2D, 0x0600, 4); ++ OUT_RING (chan, rect->dx); ++ OUT_RING (chan, rect->dy); ++ OUT_RING (chan, rect->dx + rect->width); ++ OUT_RING (chan, rect->dy + rect->height); ++ FIRE_RING (chan); ++} ++ ++static void ++nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ ++ if (info->flags & FBINFO_HWACCEL_DISABLED) { ++ cfb_copyarea(info, region); ++ return; ++ } ++ ++ if (RING_SPACE(chan, 17)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ cfb_copyarea(info, region); ++ return; ++ } ++ ++ BEGIN_RING(chan, NvSub2D, 0x02ac, 1); ++ OUT_RING (chan, 3); ++ BEGIN_RING(chan, NvSub2D, 0x0110, 1); ++ OUT_RING (chan, 0); ++ BEGIN_RING(chan, NvSub2D, 0x08b0, 12); ++ OUT_RING (chan, region->dx); ++ OUT_RING (chan, region->dy); ++ OUT_RING (chan, region->width); ++ OUT_RING (chan, region->height); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, region->sx); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, region->sy); ++ FIRE_RING (chan); ++} ++ ++static void ++nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) ++{ ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ ++ if (info->flags & FBINFO_HWACCEL_DISABLED) { ++ cfb_imageblit(info, image); ++ return; ++ } ++ ++ cfb_imageblit(info, image); ++} ++ ++int ++nv50_fbcon_accel_init(struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ struct nouveau_gpuobj *eng2d = NULL; ++ int ret, format; ++ ++ switch (info->var.bits_per_pixel) { ++ case 16: ++ format = 0xe8; ++ break; ++ default: ++ format = 0xe6; ++ break; ++ } ++ ++ ret = nouveau_gpuobj_gr_new(dev_priv->channel, 0x502d, &eng2d); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, Nv2D, eng2d, NULL); ++ if (ret) ++ return ret; ++ ++ ret = RING_SPACE(chan, 34); ++ if (ret) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ return ret; ++ } ++ ++ BEGIN_RING(chan, NvSub2D, 0x0000, 1); ++ OUT_RING (chan, Nv2D); ++ BEGIN_RING(chan, NvSub2D, 0x0180, 4); ++ OUT_RING (chan, NvNotify0); ++ OUT_RING (chan, chan->vram_handle); ++ OUT_RING (chan, chan->vram_handle); ++ OUT_RING (chan, chan->vram_handle); ++ BEGIN_RING(chan, NvSub2D, 0x0290, 1); ++ OUT_RING (chan, 0); ++ BEGIN_RING(chan, NvSub2D, 0x0888, 1); ++ OUT_RING (chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x02a0, 1); ++ OUT_RING (chan, 0x55); ++ BEGIN_RING(chan, NvSub2D, 0x0580, 2); ++ OUT_RING (chan, 4); ++ OUT_RING (chan, format); ++ BEGIN_RING(chan, NvSub2D, 0x0200, 2); ++ OUT_RING (chan, format); ++ OUT_RING (chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x0214, 5); ++ OUT_RING (chan, info->fix.line_length); ++ OUT_RING (chan, info->var.xres_virtual); ++ OUT_RING (chan, info->var.yres_virtual); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, info->fix.smem_start - dev_priv->fb_phys + ++ dev_priv->vm_vram_base); ++ BEGIN_RING(chan, NvSub2D, 0x0230, 2); ++ OUT_RING (chan, format); ++ OUT_RING (chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x0244, 5); ++ OUT_RING (chan, info->fix.line_length); ++ OUT_RING (chan, info->var.xres_virtual); ++ OUT_RING (chan, info->var.yres_virtual); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, info->fix.smem_start - dev_priv->fb_phys + ++ dev_priv->vm_vram_base); ++ ++ info->fbops->fb_fillrect = nv50_fbcon_fillrect; ++ info->fbops->fb_copyarea = nv50_fbcon_copyarea; ++ info->fbops->fb_imageblit = nv50_fbcon_imageblit; ++ info->fbops->fb_sync = nv50_fbcon_sync; ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c +new file mode 100644 +index 0000000..fbbc235 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_fifo.c +@@ -0,0 +1,343 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++struct nv50_fifo_priv { ++ struct nouveau_gpuobj_ref *thingo[2]; ++ int cur_thingo; ++}; ++ ++#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) ++ ++static void ++nv50_fifo_init_thingo(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; ++ struct nouveau_gpuobj_ref *cur; ++ int i, nr; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ cur = priv->thingo[priv->cur_thingo]; ++ priv->cur_thingo = !priv->cur_thingo; ++ ++ /* We never schedule channel 0 or 127 */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i = 1, nr = 0; i < 127; i++) { ++ if (dev_priv->fifos[i]) { ++ INSTANCE_WR(cur->gpuobj, nr++, i); ++ } ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(0x32f4, cur->instance >> 12); ++ nv_wr32(0x32ec, nr); ++ nv_wr32(0x2500, 0x101); ++} ++ ++static int ++nv50_fifo_channel_enable(struct drm_device *dev, int channel, int nt) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->fifos[channel]; ++ uint32_t inst; ++ ++ NV_DEBUG(dev, "ch%d\n", channel); ++ ++ if (!chan->ramfc) ++ return -EINVAL; ++ ++ if (IS_G80) inst = chan->ramfc->instance >> 12; ++ else inst = chan->ramfc->instance >> 8; ++ nv_wr32(NV50_PFIFO_CTX_TABLE(channel), ++ inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); ++ ++ if (!nt) nv50_fifo_init_thingo(dev); ++ return 0; ++} ++ ++static void ++nv50_fifo_channel_disable(struct drm_device *dev, int channel, int nt) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t inst; ++ ++ NV_DEBUG(dev, "ch%d, nt=%d\n", channel, nt); ++ ++ if (IS_G80) inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; ++ else inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; ++ nv_wr32(NV50_PFIFO_CTX_TABLE(channel), inst); ++ ++ if (!nt) nv50_fifo_init_thingo(dev); ++} ++ ++static void ++nv50_fifo_init_reset(struct drm_device *dev) ++{ ++ uint32_t pmc_e = NV_PMC_ENABLE_PFIFO; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) & ~pmc_e); ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) | pmc_e); ++} ++ ++static void ++nv50_fifo_init_intr(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(NV03_PFIFO_INTR_0, 0xFFFFFFFF); ++ nv_wr32(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); ++} ++ ++static void ++nv50_fifo_init_context_table(struct drm_device *dev) ++{ ++ int i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) ++ nv50_fifo_channel_disable(dev, i, 1); ++ nv50_fifo_init_thingo(dev); ++} ++ ++static void ++nv50_fifo_init_regs__nv(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(0x250c, 0x6f3cfc34); ++} ++ ++static void ++nv50_fifo_init_regs(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(0x2500, 0); ++ nv_wr32(0x3250, 0); ++ nv_wr32(0x3220, 0); ++ nv_wr32(0x3204, 0); ++ nv_wr32(0x3210, 0); ++ nv_wr32(0x3270, 0); ++ ++ /* Enable dummy channels setup by nv50_instmem.c */ ++ nv50_fifo_channel_enable(dev, 0, 1); ++ nv50_fifo_channel_enable(dev, 127, 1); ++} ++ ++int ++nv50_fifo_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_fifo_priv *priv; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ priv = drm_calloc(1, sizeof(*priv), DRM_MEM_DRIVER); ++ if (!priv) ++ return -ENOMEM; ++ dev_priv->engine.fifo.priv = priv; ++ ++ nv50_fifo_init_reset(dev); ++ nv50_fifo_init_intr(dev); ++ ++ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]); ++ if (ret) { ++ NV_ERROR(dev, "error creating thingo0: %d\n", ret); ++ return ret; ++ } ++ ++ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]); ++ if (ret) { ++ NV_ERROR(dev, "error creating thingo1: %d\n", ret); ++ return ret; ++ } ++ ++ nv50_fifo_init_context_table(dev); ++ nv50_fifo_init_regs__nv(dev); ++ nv50_fifo_init_regs(dev); ++ ++ return 0; ++} ++ ++void ++nv50_fifo_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!priv) ++ return; ++ ++ nouveau_gpuobj_ref_del(dev, &priv->thingo[0]); ++ nouveau_gpuobj_ref_del(dev, &priv->thingo[1]); ++ ++ dev_priv->engine.fifo.priv = NULL; ++ drm_free(priv, sizeof(*priv), DRM_MEM_DRIVER); ++} ++ ++int ++nv50_fifo_channel_id(struct drm_device *dev) ++{ ++ return (nv_rd32(NV03_PFIFO_CACHE1_PUSH1) & ++ NV50_PFIFO_CACHE1_PUSH1_CHID_MASK); ++} ++ ++int ++nv50_fifo_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *ramfc = NULL; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ if (IS_G80) { ++ uint32_t ramfc_offset = chan->ramin->gpuobj->im_pramin->start; ++ uint32_t vram_offset = chan->ramin->gpuobj->im_backing->start; ++ ret = nouveau_gpuobj_new_fake(dev, ramfc_offset, vram_offset, ++ 0x100, NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, &ramfc, ++ &chan->ramfc); ++ if (ret) ++ return ret; ++ } else { ++ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100, 256, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, ++ &chan->ramfc); ++ if (ret) ++ return ret; ++ ramfc = chan->ramfc->gpuobj; ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ++ INSTANCE_WR(ramfc, 0x08/4, chan->pushbuf_base); ++ INSTANCE_WR(ramfc, 0x10/4, chan->pushbuf_base); ++ INSTANCE_WR(ramfc, 0x48/4, chan->pushbuf->instance >> 4); ++ INSTANCE_WR(ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4)); ++ INSTANCE_WR(ramfc, 0x3c/4, 0x000f0078); /* fetch? */ ++ INSTANCE_WR(ramfc, 0x44/4, 0x2101ffff); ++ INSTANCE_WR(ramfc, 0x60/4, 0x7fffffff); ++ INSTANCE_WR(ramfc, 0x40/4, 0x00000000); ++ INSTANCE_WR(ramfc, 0x50/4, 0x2039b2e0); ++ INSTANCE_WR(ramfc, 0x54/4, 0x000f0000); ++ INSTANCE_WR(ramfc, 0x7c/4, 0x30000001); ++ INSTANCE_WR(ramfc, 0x78/4, 0x00000000); ++ INSTANCE_WR(ramfc, 0x4c/4, chan->pushbuf_mem->size - 1); ++ ++ if (!IS_G80) { ++ INSTANCE_WR(chan->ramin->gpuobj, 0, chan->id); ++ INSTANCE_WR(chan->ramin->gpuobj, 1, chan->ramfc->instance >> 8); ++ ++ INSTANCE_WR(ramfc, 0x88/4, 0x3d520); /* some vram addy >> 10 */ ++ INSTANCE_WR(ramfc, 0x98/4, chan->ramin->instance >> 12); ++ } ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ ret = nv50_fifo_channel_enable(dev, chan->id, 0); ++ if (ret) { ++ NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret); ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void ++nv50_fifo_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ nv50_fifo_channel_disable(dev, chan->id, 0); ++ ++ /* Dummy channel, also used on ch 127 */ ++ if (chan->id == 0) ++ nv50_fifo_channel_disable(dev, 127, 0); ++ ++ if ((nv_rd32(NV03_PFIFO_CACHE1_PUSH1) & 0xffff) == chan->id) ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH1, 127); ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++} ++ ++int ++nv50_fifo_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ /*XXX: incomplete, only touches the regs that NV does */ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ ++ nv_wr32(0x3244, INSTANCE_RD(ramfc, 0x08/4)); ++ nv_wr32(0x3240, INSTANCE_RD(ramfc, 0x10/4)); ++ ++ nv_wr32(0x3224, INSTANCE_RD(ramfc, 0x3c/4)); ++ nv_wr32(NV04_PFIFO_CACHE1_DMA_INSTANCE, INSTANCE_RD(ramfc, 0x48/4)); ++ nv_wr32(0x3234, INSTANCE_RD(ramfc, 0x4c/4)); ++ nv_wr32(0x3254, 1); ++ nv_wr32(NV03_PFIFO_RAMHT, INSTANCE_RD(ramfc, 0x80/4)); ++ ++ if (!IS_G80) { ++ nv_wr32(0x340c, INSTANCE_RD(ramfc, 0x88/4)); ++ nv_wr32(0x3410, INSTANCE_RD(ramfc, 0x98/4)); ++ } ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); ++ return 0; ++} ++ ++int ++nv50_fifo_save_context(struct nouveau_channel *chan) ++{ ++ NV_DEBUG(chan->dev, "ch%d\n", chan->id); ++ NV_ERROR(chan->dev, "stub!\n"); ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c +new file mode 100644 +index 0000000..1832c3f +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_graph.c +@@ -0,0 +1,336 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nv50_grctx.h" ++ ++#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) ++ ++static void ++nv50_graph_init_reset(struct drm_device *dev) ++{ ++ uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21); ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) & ~pmc_e); ++ nv_wr32(NV03_PMC_ENABLE, nv_rd32(NV03_PMC_ENABLE) | pmc_e); ++} ++ ++static void ++nv50_graph_init_intr(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(NV03_PGRAPH_INTR, 0xffffffff); ++ nv_wr32(0x400138, 0xffffffff); ++ nv_wr32(NV40_PGRAPH_INTR_EN, 0xffffffff); ++} ++ ++static void ++nv50_graph_init_regs__nv(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(0x400804, 0xc0000000); ++ nv_wr32(0x406800, 0xc0000000); ++ nv_wr32(0x400c04, 0xc0000000); ++ nv_wr32(0x401804, 0xc0000000); ++ nv_wr32(0x405018, 0xc0000000); ++ nv_wr32(0x402000, 0xc0000000); ++ ++ nv_wr32(0x400108, 0xffffffff); ++ ++ nv_wr32(0x400824, 0x00004000); ++ nv_wr32(0x400500, 0x00000000); ++} ++ ++static void ++nv50_graph_init_regs(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(NV04_PGRAPH_DEBUG_3, (1<<2) /* HW_CONTEXT_SWITCH_ENABLED */); ++} ++ ++static int ++nv50_graph_init_ctxctl(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t *voodoo = NULL; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ switch (dev_priv->chipset) { ++ case 0x50: ++ voodoo = nv50_ctxprog; ++ break; ++ case 0x84: ++ voodoo = nv84_ctxprog; ++ break; ++ case 0x86: ++ voodoo = nv86_ctxprog; ++ break; ++ case 0x92: ++ voodoo = nv92_ctxprog; ++ break; ++ case 0x94: ++ case 0x96: ++ voodoo = nv94_ctxprog; ++ break; ++ case 0x98: ++ voodoo = nv98_ctxprog; ++ break; ++ case 0xa0: ++ voodoo = nva0_ctxprog; ++ break; ++ case 0xaa: ++ voodoo = nvaa_ctxprog; ++ break; ++ default: ++ NV_ERROR(dev, "no ctxprog for chipset NV%02x\n", dev_priv->chipset); ++ return -EINVAL; ++ } ++ ++ nv_wr32(NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); ++ while (*voodoo != ~0) { ++ nv_wr32(NV40_PGRAPH_CTXCTL_UCODE_DATA, *voodoo); ++ voodoo++; ++ } ++ ++ nv_wr32(0x400320, 4); ++ nv_wr32(NV40_PGRAPH_CTXCTL_CUR, 0); ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_POINTER, 0); ++ ++ return 0; ++} ++ ++int ++nv50_graph_init(struct drm_device *dev) ++{ ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv50_graph_init_reset(dev); ++ nv50_graph_init_regs__nv(dev); ++ nv50_graph_init_regs(dev); ++ nv50_graph_init_intr(dev); ++ ++ ret = nv50_graph_init_ctxctl(dev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void ++nv50_graph_takedown(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++} ++ ++void ++nv50_graph_fifo_access(struct drm_device *dev, bool enabled) ++{ ++ const uint32_t mask = 0x00010001; ++ ++ if (enabled) ++ nv_wr32(0x400500, nv_rd32(0x400500) | mask); ++ else ++ nv_wr32(0x400500, nv_rd32(0x400500) & ~mask); ++} ++ ++int ++nv50_graph_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; ++ struct nouveau_gpuobj *ctx; ++ uint32_t *ctxvals = NULL; ++ int grctx_size = 0x70000, hdr; ++ int ret, pos; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, grctx_size, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); ++ if (ret) ++ return ret; ++ ctx = chan->ramin_grctx->gpuobj; ++ ++ hdr = IS_G80 ? 0x200 : 0x20; ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ INSTANCE_WR(ramin, (hdr + 0x00)/4, 0x00190002); ++ INSTANCE_WR(ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + ++ grctx_size - 1); ++ INSTANCE_WR(ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance); ++ INSTANCE_WR(ramin, (hdr + 0x0c)/4, 0); ++ INSTANCE_WR(ramin, (hdr + 0x10)/4, 0); ++ INSTANCE_WR(ramin, (hdr + 0x14)/4, 0x00010000); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ switch (dev_priv->chipset) { ++ case 0x50: ++ ctxvals = nv50_ctxvals; ++ break; ++ case 0x84: ++ ctxvals = nv84_ctxvals; ++ break; ++ case 0x86: ++ ctxvals = nv86_ctxvals; ++ break; ++ case 0x92: ++ ctxvals = nv92_ctxvals; ++ break; ++ case 0x94: ++ ctxvals = nv94_ctxvals; ++ break; ++ case 0x96: ++ ctxvals = nv96_ctxvals; ++ break; ++ case 0x98: ++ ctxvals = nv98_ctxvals; ++ break; ++ case 0xa0: ++ ctxvals = nva0_ctxvals; ++ break; ++ case 0xaa: ++ ctxvals = nvaa_ctxvals; ++ break; ++ default: ++ break; ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ++ pos = 0; ++ while (*ctxvals) { ++ int cnt = *ctxvals++; ++ ++ while (cnt--) ++ INSTANCE_WR(ctx, pos++, *ctxvals); ++ ctxvals++; ++ } ++ ++ INSTANCE_WR(ctx, 0x00000/4, chan->ramin->instance >> 12); ++ if ((dev_priv->chipset & 0xf0) == 0xa0) ++ INSTANCE_WR(ctx, 0x00004/4, 0x00000002); ++ else ++ INSTANCE_WR(ctx, 0x0011c/4, 0x00000002); ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ return 0; ++} ++ ++void ++nv50_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ if (chan->ramin && chan->ramin->gpuobj) { ++ int i, hdr; ++ ++ hdr = IS_G80 ? 0x200 : 0x20; ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i=hdr; iramin->gpuobj, i/4, 0); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); ++ } ++} ++ ++static int ++nv50_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save) ++{ ++ uint32_t old_cp, tv = 20000; ++ int i; ++ ++ NV_DEBUG(dev, "inst=0x%08x, save=%d\n", inst, save); ++ ++ old_cp = nv_rd32(NV20_PGRAPH_CHANNEL_CTX_POINTER); ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ nv_wr32(0x400824, nv_rd32(0x400824) | ++ (save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE : ++ NV40_PGRAPH_CTXCTL_0310_XFER_LOAD)); ++ nv_wr32(NV40_PGRAPH_CTXCTL_0304, NV40_PGRAPH_CTXCTL_0304_XFER_CTX); ++ ++ for (i = 0; i < tv; i++) { ++ if (nv_rd32(NV40_PGRAPH_CTXCTL_030C) == 0) ++ break; ++ } ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp); ++ ++ if (i == tv) { ++ NV_ERROR(dev, "failed: inst=0x%08x save=%d\n", inst, save); ++ NV_ERROR(dev, "0x40030C = 0x%08x\n", ++ nv_rd32(NV40_PGRAPH_CTXCTL_030C)); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++int ++nv50_graph_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t inst = chan->ramin->instance >> 12; ++ int ret; (void)ret; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++#if 0 ++ if ((ret = nv50_graph_transfer_context(dev, inst, 0))) ++ return ret; ++#endif ++ ++ nv_wr32(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ nv_wr32(0x400320, 4); ++ nv_wr32(NV40_PGRAPH_CTXCTL_CUR, inst | (1<<31)); ++ ++ return 0; ++} ++ ++int ++nv50_graph_save_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t inst = chan->ramin->instance >> 12; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ return nv50_graph_transfer_context(dev, inst, 1); ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.h b/drivers/gpu/drm/nouveau/nv50_grctx.h +new file mode 100644 +index 0000000..a63796f +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_grctx.h +@@ -0,0 +1,20935 @@ ++#ifndef __NV50_GRCTX_H__ ++#define __NV50_GRCTX_H__ ++ ++static uint32_t nv50_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0041874d, 0x00401e44, 0x00401e05, 0x00401e0d, 0x00416306, ++ 0x00600005, 0x004015c5, 0x00600011, 0x00401c0b, 0x0090ffff, 0x0091ffff, ++ 0x00200020, 0x00600008, 0x0050004c, 0x00600009, 0x00416345, 0x00417e4d, ++ 0x0070009d, 0x004022cf, 0x0070009f, 0x0050009f, 0x00401fc0, 0x00200080, ++ 0x00600008, 0x00401f4f, 0x00401fc0, 0x004025cc, 0x00700081, 0x00200000, ++ 0x00600006, 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00215900, ++ 0x00600007, 0x00c00b01, 0x0020001c, 0x00800001, 0x005000cb, 0x00c000ff, ++ 0x00700080, 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x002005c0, ++ 0x00600007, 0x00300000, 0x00c000ff, 0x00c800ff, 0x00416e07, 0x00202627, ++ 0x008000ff, 0x0040458c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, ++ 0x0070000f, 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001b0242, ++ 0x00120302, 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, ++ 0x001e0607, 0x00110700, 0x00110900, 0x00110902, 0x00110a00, 0x00160b02, ++ 0x00110b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000ea, 0x00101500, 0x00406d0f, 0x00406d4b, ++ 0x00213700, 0x00600007, 0x00200440, 0x008800ff, 0x0070008f, 0x00406d8c, ++ 0x005000cb, 0x00000000, 0x001118f8, 0x0020002b, 0x00101a05, 0x00131c00, ++ 0x00111c04, 0x00141c20, 0x00111c25, 0x00131c40, 0x00111c44, 0x00141c60, ++ 0x00111c65, 0x00131c80, 0x00111c84, 0x00141ca0, 0x00111ca5, 0x00131cc0, ++ 0x00111cc4, 0x00141ce0, 0x00111ce5, 0x00131d00, 0x00111d04, 0x00141d20, ++ 0x00111d25, 0x00131d40, 0x00111d44, 0x00141d60, 0x00111d65, 0x00131f00, ++ 0x00191f40, 0x0040a7e0, 0x00200217, 0x00600006, 0x00200044, 0x00102080, ++ 0x001120c6, 0x001520c9, 0x001920d0, 0x00122100, 0x00122103, 0x00162200, ++ 0x00409f0f, 0x00409f4b, 0x00213700, 0x00600007, 0x00200440, 0x008800ff, ++ 0x0070008f, 0x00409f8c, 0x005000cb, 0x00000000, 0x00122207, 0x00112280, ++ 0x00112300, 0x00112302, 0x00122380, 0x0011238b, 0x00192394, 0x0040b9e1, ++ 0x00200285, 0x00600006, 0x00200044, 0x00102480, 0x001124c6, 0x001524c9, ++ 0x001924d0, 0x00122500, 0x00122503, 0x00162600, 0x00122607, 0x00112680, ++ 0x00112700, 0x00112702, 0x00122780, 0x0011278b, 0x00192794, 0x0040d5e2, ++ 0x002002f3, 0x00600006, 0x00200044, 0x00102880, 0x001128c6, 0x001528c9, ++ 0x0040c90f, 0x0040c94b, 0x00213700, 0x00600007, 0x00200440, 0x008800ff, ++ 0x0070008f, 0x0040c98c, 0x005000cb, 0x00000000, 0x001928d0, 0x00122900, ++ 0x00122903, 0x00162a00, 0x00122a07, 0x00112a80, 0x00112b00, 0x00112b02, ++ 0x00122b80, 0x00112b8b, 0x00192b94, 0x0040e7e3, 0x00200361, 0x00600006, ++ 0x00200044, 0x00102c80, 0x00112cc6, 0x00152cc9, 0x00192cd0, 0x00122d00, ++ 0x00122d03, 0x00162e00, 0x00122e07, 0x00112e80, 0x00112f00, 0x00112f02, ++ 0x00122f80, 0x00112f8b, 0x00192f94, 0x004103e4, 0x002003cf, 0x00600006, ++ 0x00200044, 0x00103080, 0x0040f50f, 0x0040f54b, 0x00213700, 0x00600007, ++ 0x00200440, 0x008800ff, 0x0070008f, 0x0040f58c, 0x005000cb, 0x00000000, ++ 0x001130c6, 0x001530c9, 0x001930d0, 0x00123100, 0x00123103, 0x00163200, ++ 0x00123207, 0x00113280, 0x00113300, 0x00113302, 0x00123380, 0x0011338b, ++ 0x00193394, 0x004115e5, 0x0020043d, 0x00600006, 0x00200044, 0x00103480, ++ 0x001134c6, 0x001534c9, 0x001934d0, 0x00123500, 0x00123503, 0x00163600, ++ 0x00123607, 0x00113680, 0x00113700, 0x00113702, 0x00123780, 0x0011378b, ++ 0x00193794, 0x004131e6, 0x002004ab, 0x00600006, 0x00200044, 0x00103880, ++ 0x0041230f, 0x0041234b, 0x00213700, 0x00600007, 0x00200440, 0x008800ff, ++ 0x0070008f, 0x0041238c, 0x005000cb, 0x00000000, 0x001138c6, 0x001538c9, ++ 0x001938d0, 0x00123900, 0x00123903, 0x00163a00, 0x00123a07, 0x00113a80, ++ 0x00113b00, 0x00113b02, 0x00123b80, 0x00113b8b, 0x00193b94, 0x004143e7, ++ 0x00200519, 0x00600006, 0x00200044, 0x00103c80, 0x00113cc6, 0x00153cc9, ++ 0x00193cd0, 0x00123d00, 0x00123d03, 0x00163e00, 0x00123e07, 0x00113e80, ++ 0x00113f00, 0x00113f02, 0x00123f80, 0x00113f8b, 0x00193f94, 0x00000000, ++ 0x00414a0f, 0x005000cb, 0x00213700, 0x00600007, 0x00200440, 0x008800ff, ++ 0x005000cb, 0x00414d87, 0x0060000a, 0x00000000, 0x00415c00, 0x007000a0, ++ 0x00700080, 0x002005c0, 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, ++ 0x005000cb, 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x00417e4d, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, ++ 0x0040114d, 0x00700081, 0x00600004, 0x0050004a, 0x00416888, 0x0060000b, ++ 0x00200000, 0x00600006, 0x00700000, 0x00417e0b, 0x00111bfd, 0x0040374d, ++ 0x00202627, 0x008000fd, 0x005000cb, 0x00c00002, 0x002005c0, 0x00600007, ++ 0x0020015f, 0x00800002, 0x005000cb, 0x00c01802, 0x002024c8, 0x00800002, ++ 0x005000cb, 0x0040434d, 0x0060000b, 0x00417c4d, 0x00700001, 0x00700003, ++ 0x00418206, 0x00418305, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, ++ 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ~0 ++}; ++ ++static uint32_t nv50_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0004, 0x00000000, ++ 0x0001, 0xff400040, ++ 0x0001, 0xfff00080, ++ 0x0001, 0xfff70090, ++ 0x0001, 0xffe806a8, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x0001fd87, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x0001005f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0001, 0x00000006, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00300080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000000a, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000026, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000f80, ++ 0x0011, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0046, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00608080, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0040, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x03020100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0013, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0004, 0x00000003, ++ 0x0003, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x001c, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0099, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0061, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1905, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0032, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0077, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x0032, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0029, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0011, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x002a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0011, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0001, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0054, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x001a, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x000003ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x00ea, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0061, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x001e, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000020, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x004c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x0002, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0019, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x2a712488, ++ 0x000c, 0x00000000, ++ 0x0004, 0x4085c000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x02800000, ++ 0x007c, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x30201000, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0004, 0x70605040, ++ 0x0004, 0x00000000, ++ 0x0004, 0xb8a89888, ++ 0x0004, 0x00000000, ++ 0x0004, 0xf8e8d8c8, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0004, 0x0000001a, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x00ac, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00608080, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x008a, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0079, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x03020100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0012, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x012a, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x2a17, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x2321, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x008c, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x005c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0064, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0054, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000003ff, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0154, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x00000020, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x004c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x00bc, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x2a712488, ++ 0x000c, 0x00000000, ++ 0x0004, 0x4085c000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x02800000, ++ 0x007c, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x30201000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x70605040, ++ 0x0004, 0x00000000, ++ 0x0004, 0xb8a89888, ++ 0x0004, 0x00000000, ++ 0x0004, 0xf8e8d8c8, ++ 0x000c, 0x00000000, ++ 0x0004, 0x0000001a, ++ 0x4c70, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0087, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000080, ++ 0x0008, 0x80007004, ++ 0x0008, 0x04000400, ++ 0x0008, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0010, 0x00001000, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0008, 0x00000080, ++ 0x0008, 0x80007004, ++ 0x0008, 0x04000400, ++ 0x0008, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0010, 0x00001000, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0008, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0020, 0x0000ffff, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00010001, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0008, 0x08100c12, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000002, ++ 0x0008, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0008, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0008, 0x00000002, ++ 0x0010, 0x00000001, ++ 0x0008, 0x00000002, ++ 0x0018, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x1d00, 0x00000000, ++ 0x0008, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nv84_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0041634d, 0x00402944, 0x00402905, 0x0040290d, 0x00413e06, ++ 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00216f40, 0x00600007, 0x00c02801, ++ 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020, ++ 0x00600008, 0x0050004c, 0x00600009, 0x00413e45, 0x0041594d, 0x0070009d, ++ 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200200, 0x00600008, ++ 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00216f40, 0x00600007, ++ 0x00c00b01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200480, 0x00600007, ++ 0x00300000, 0x00c000ff, 0x00c800ff, 0x00414907, 0x00202916, 0x008000ff, ++ 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f, ++ 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, ++ 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000cb, 0x00101500, 0x0040790f, 0x0040794b, ++ 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x0040798c, ++ 0x005000cb, 0x00000000, 0x0020002b, 0x00101a05, 0x00131c00, 0x00121c04, ++ 0x00141c20, 0x00111c25, 0x00131c40, 0x00121c44, 0x00141c60, 0x00111c65, ++ 0x00131c80, 0x00121c84, 0x00141ca0, 0x00111ca5, 0x00131cc0, 0x00121cc4, ++ 0x00141ce0, 0x00111ce5, 0x00131f00, 0x00191f40, 0x0040a1e0, 0x002001ed, ++ 0x00600006, 0x00200044, 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, ++ 0x00122100, 0x00122103, 0x00162200, 0x00122207, 0x00112280, 0x00112300, ++ 0x00112302, 0x00122380, 0x0011238b, 0x00112394, 0x0011239c, 0x0040bee1, ++ 0x00200254, 0x00600006, 0x00200044, 0x00102480, 0x0040af0f, 0x0040af4b, ++ 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x0040af8c, ++ 0x005000cb, 0x00000000, 0x001124c6, 0x001524c9, 0x001924d0, 0x00122500, ++ 0x00122503, 0x00162600, 0x00122607, 0x00112680, 0x00112700, 0x00112702, ++ 0x00122780, 0x0011278b, 0x00112794, 0x0011279c, 0x0040d1e2, 0x002002bb, ++ 0x00600006, 0x00200044, 0x00102880, 0x001128c6, 0x001528c9, 0x001928d0, ++ 0x00122900, 0x00122903, 0x00162a00, 0x00122a07, 0x00112a80, 0x00112b00, ++ 0x00112b02, 0x00122b80, 0x00112b8b, 0x00112b94, 0x00112b9c, 0x0040eee3, ++ 0x00200322, 0x00600006, 0x00200044, 0x00102c80, 0x0040df0f, 0x0040df4b, ++ 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x0040df8c, ++ 0x005000cb, 0x00000000, 0x00112cc6, 0x00152cc9, 0x00192cd0, 0x00122d00, ++ 0x00122d03, 0x00162e00, 0x00122e07, 0x00112e80, 0x00112f00, 0x00112f02, ++ 0x00122f80, 0x00112f8b, 0x00112f94, 0x00112f9c, 0x004101e4, 0x00200389, ++ 0x00600006, 0x00200044, 0x00103080, 0x001130c6, 0x001530c9, 0x001930d0, ++ 0x00123100, 0x00123103, 0x00163200, 0x00123207, 0x00113280, 0x00113300, ++ 0x00113302, 0x00123380, 0x0011338b, 0x00113394, 0x0011339c, 0x00411ee5, ++ 0x002003f0, 0x00600006, 0x00200044, 0x00103480, 0x00410f0f, 0x00410f4b, ++ 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x00410f8c, ++ 0x005000cb, 0x00000000, 0x001134c6, 0x001534c9, 0x001934d0, 0x00123500, ++ 0x00123503, 0x00163600, 0x00123607, 0x00113680, 0x00113700, 0x00113702, ++ 0x00123780, 0x0011378b, 0x00113794, 0x0011379c, 0x00000000, 0x0041250f, ++ 0x005000cb, 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x005000cb, ++ 0x00412887, 0x0060000a, 0x00000000, 0x00413700, 0x007000a0, 0x00700080, ++ 0x00200480, 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, 0x005000cb, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x0041594d, 0x00700000, ++ 0x00200000, 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, 0x0040114d, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00414388, 0x0060000b, 0x00200000, ++ 0x00600006, 0x00700000, 0x0041590b, 0x00111bfd, 0x0040424d, 0x00202916, ++ 0x008000fd, 0x005000cb, 0x00c00002, 0x00200480, 0x00600007, 0x00200160, ++ 0x00800002, 0x005000cb, 0x00c01802, 0x002027b6, 0x00800002, 0x005000cb, ++ 0x00404e4d, 0x0060000b, 0x0041574d, 0x00700001, 0x005000cf, 0x00700003, ++ 0x00415e06, 0x00415f05, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, ++ 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ~0 ++}; ++ ++static uint32_t nv84_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x044d00df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000e0080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000f80, ++ 0x0011, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00608080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0026, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0c04, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2647, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0c78, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x001a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0077, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0035, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0029, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0041, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00dc, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000003, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0019, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0045, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0019, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0097, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0035, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0061, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00608080, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00fd, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0035, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x4a17, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0291, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x008f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0157, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0097, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x637b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0001, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0001, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0001, 0x00001000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0001, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0001, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0001, 0x00001000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00010001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d10, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nv86_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0040dd4d, 0x00402944, 0x00402905, 0x0040290d, 0x0040b906, ++ 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00216d80, 0x00600007, 0x00c02801, ++ 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020, ++ 0x00600008, 0x0050004c, 0x00600009, 0x0040b945, 0x0040d44d, 0x0070009d, ++ 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200200, 0x00600008, ++ 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00216d80, 0x00600007, ++ 0x00c00b01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200280, 0x00600007, ++ 0x00300000, 0x00c000ff, 0x00c800ff, 0x0040c407, 0x00202916, 0x008000ff, ++ 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f, ++ 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, ++ 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000cb, 0x00101500, 0x0040790f, 0x0040794b, ++ 0x00214b40, 0x00600007, 0x00200442, 0x008800ff, 0x0070008f, 0x0040798c, ++ 0x005000cb, 0x00000000, 0x0020002b, 0x00101a05, 0x00131c00, 0x00121c04, ++ 0x00141c20, 0x00111c25, 0x00131c40, 0x00121c44, 0x00141c60, 0x00111c65, ++ 0x00131f00, 0x00191f40, 0x004099e0, 0x002001d9, 0x00600006, 0x00200044, ++ 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, 0x00122100, 0x00122103, ++ 0x00162200, 0x00122207, 0x00112280, 0x00112300, 0x00112302, 0x00122380, ++ 0x0011238b, 0x00112394, 0x0011239c, 0x00000000, 0x0040a00f, 0x005000cb, ++ 0x00214b40, 0x00600007, 0x00200442, 0x008800ff, 0x005000cb, 0x0040a387, ++ 0x0060000a, 0x00000000, 0x0040b200, 0x007000a0, 0x00700080, 0x00200280, ++ 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, 0x005000cb, 0x00700000, ++ 0x00200000, 0x00600006, 0x00111bfe, 0x0040d44d, 0x00700000, 0x00200000, ++ 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, 0x0040114d, 0x00700081, ++ 0x00600004, 0x0050004a, 0x0040be88, 0x0060000b, 0x00200000, 0x00600006, ++ 0x00700000, 0x0040d40b, 0x00111bfd, 0x0040424d, 0x00202916, 0x008000fd, ++ 0x005000cb, 0x00c00002, 0x00200280, 0x00600007, 0x00200160, 0x00800002, ++ 0x005000cb, 0x00c01802, 0x002027b6, 0x00800002, 0x005000cb, 0x00404e4d, ++ 0x0060000b, 0x0040d24d, 0x00700001, 0x00700003, 0x0040d806, 0x0040d905, ++ 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, 0x0070000b, 0x0070000e, ++ 0x0060000c, ~0 ++}; ++ ++static uint32_t nv86_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0031, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x044d00df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000f80, ++ 0x0011, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x008c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x008c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00608080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000d, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0089, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00b5, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0b84, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2647, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0c78, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x005d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0031, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x003d, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001d, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0041, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x003c, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0029, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00c5, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0079, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0097, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x2a17, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x933d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0000 ++}; ++ ++static uint32_t nv92_ctxprog[] = { ++ 0x0070008E, 0x0070009C, 0x00200020, 0x00600008, 0x0050004C, 0x00400E89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00C000FF, 0x00200000, 0x008000FF, ++ 0x00700009, 0x0041924D, 0x00402944, 0x00402905, 0x0040290D, 0x00416E06, ++ 0x00600005, 0x004015C5, 0x00600011, 0x0040270B, 0x004021C5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004A, 0x00219600, 0x00600007, 0x00C02701, ++ 0x0020002E, 0x00800001, 0x005000CB, 0x0090FFFF, 0x0091FFFF, 0x00200020, ++ 0x00600008, 0x0050004C, 0x00600009, 0x00416E45, 0x0041894D, 0x0070009D, ++ 0x00402DCF, 0x0070009F, 0x0050009F, 0x00402AC0, 0x00200080, 0x00600008, ++ 0x00402A4F, 0x00402AC0, 0x004030CC, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111BFC, 0x00700083, 0x00300000, 0x00219600, 0x00600007, ++ 0x00C00A01, 0x0020001E, 0x00800001, 0x005000CB, 0x00C000FF, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020A, 0x00200540, 0x00600007, ++ 0x00300000, 0x00C000FF, 0x00C800FF, 0x00417907, 0x00202DD2, 0x008000FF, ++ 0x0040508C, 0x005000CB, 0x00A0023F, 0x00200040, 0x00600006, 0x0070000F, ++ 0x00170202, 0x0011020A, 0x00200032, 0x0010020D, 0x001C0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000F, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110A00, 0x00160B02, ++ 0x00120B28, 0x00140B2B, 0x00110C01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140B, 0x002000CB, 0x00101500, 0x0040790F, 0x0040794B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x0040798C, ++ 0x005000CB, 0x00000000, 0x00141A05, 0x00131A0C, 0x00131C00, 0x00121C04, ++ 0x00141C20, 0x00111C25, 0x00131C40, 0x00121C44, 0x00141C60, 0x00111C65, ++ 0x00131C80, 0x00121C84, 0x00141CA0, 0x00111CA5, 0x00131CC0, 0x00121CC4, ++ 0x00141CE0, 0x00111CE5, 0x00131F00, 0x00191F40, 0x0040A1E0, 0x002001C9, ++ 0x00600006, 0x00200044, 0x00102080, 0x001120C6, 0x001520C9, 0x001920D0, ++ 0x00122100, 0x00122103, 0x00162200, 0x00122207, 0x00112280, 0x00112300, ++ 0x00112302, 0x00122380, 0x0011238B, 0x00112394, 0x0011239C, 0x0040BEE1, ++ 0x00200230, 0x00600006, 0x00200044, 0x00102480, 0x0040AF0F, 0x0040AF4B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x0040AF8C, ++ 0x005000CB, 0x00000000, 0x001124C6, 0x001524C9, 0x001924D0, 0x00122500, ++ 0x00122503, 0x00162600, 0x00122607, 0x00112680, 0x00112700, 0x00112702, ++ 0x00122780, 0x0011278B, 0x00112794, 0x0011279C, 0x0040D1E2, 0x00200297, ++ 0x00600006, 0x00200044, 0x00102880, 0x001128C6, 0x001528C9, 0x001928D0, ++ 0x00122900, 0x00122903, 0x00162A00, 0x00122A07, 0x00112A80, 0x00112B00, ++ 0x00112B02, 0x00122B80, 0x00112B8B, 0x00112B94, 0x00112B9C, 0x0040EEE3, ++ 0x002002FE, 0x00600006, 0x00200044, 0x00102C80, 0x0040DF0F, 0x0040DF4B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x0040DF8C, ++ 0x005000CB, 0x00000000, 0x00112CC6, 0x00152CC9, 0x00192CD0, 0x00122D00, ++ 0x00122D03, 0x00162E00, 0x00122E07, 0x00112E80, 0x00112F00, 0x00112F02, ++ 0x00122F80, 0x00112F8B, 0x00112F94, 0x00112F9C, 0x004101E4, 0x00200365, ++ 0x00600006, 0x00200044, 0x00103080, 0x001130C6, 0x001530C9, 0x001930D0, ++ 0x00123100, 0x00123103, 0x00163200, 0x00123207, 0x00113280, 0x00113300, ++ 0x00113302, 0x00123380, 0x0011338B, 0x00113394, 0x0011339C, 0x00411EE5, ++ 0x002003CC, 0x00600006, 0x00200044, 0x00103480, 0x00410F0F, 0x00410F4B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x00410F8C, ++ 0x005000CB, 0x00000000, 0x001134C6, 0x001534C9, 0x001934D0, 0x00123500, ++ 0x00123503, 0x00163600, 0x00123607, 0x00113680, 0x00113700, 0x00113702, ++ 0x00123780, 0x0011378B, 0x00113794, 0x0011379C, 0x004131E6, 0x00200433, ++ 0x00600006, 0x00200044, 0x00103880, 0x001138C6, 0x001538C9, 0x001938D0, ++ 0x00123900, 0x00123903, 0x00163A00, 0x00123A07, 0x00113A80, 0x00113B00, ++ 0x00113B02, 0x00123B80, 0x00113B8B, 0x00113B94, 0x00113B9C, 0x00414EE7, ++ 0x0020049A, 0x00600006, 0x00200044, 0x00103C80, 0x00413F0F, 0x00413F4B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x00413F8C, ++ 0x005000CB, 0x00000000, 0x00113CC6, 0x00153CC9, 0x00193CD0, 0x00123D00, ++ 0x00123D03, 0x00163E00, 0x00123E07, 0x00113E80, 0x00113F00, 0x00113F02, ++ 0x00123F80, 0x00113F8B, 0x00113F94, 0x00113F9C, 0x00000000, 0x0041550F, ++ 0x005000CB, 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x005000CB, ++ 0x00415887, 0x0060000A, 0x00000000, 0x00416700, 0x007000A0, 0x00700080, ++ 0x00200540, 0x00600007, 0x00200004, 0x00C000FF, 0x008000FF, 0x005000CB, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111BFE, 0x0041894D, 0x00700000, ++ 0x00200000, 0x00600006, 0x00111BFE, 0x00700080, 0x0070001D, 0x0040114D, ++ 0x00700081, 0x00600004, 0x0050004A, 0x00417388, 0x0060000B, 0x00200000, ++ 0x00600006, 0x00700000, 0x0041890B, 0x00111BFD, 0x0040424D, 0x00202DD2, ++ 0x008000FD, 0x005000CB, 0x00C00002, 0x00200540, 0x00600007, 0x00200160, ++ 0x00800002, 0x005000CB, 0x00C01802, 0x00202C72, 0x00800002, 0x005000CB, ++ 0x00404E4D, 0x0060000B, 0x0041874D, 0x00700001, 0x00700003, 0x00418D06, ++ 0x00418E05, 0x0060000D, 0x00700005, 0x0070000D, 0x00700006, 0x0070000B, ++ 0x0070000E, 0x0070001C, 0x0060000C, ~0 ++}; ++ ++static uint32_t nv92_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0031, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x004e, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00608080, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0004, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0004, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000d, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0082, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x03020100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0013, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00b5, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0184, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x013a, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2aed, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x001a, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x000a, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0069, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0011, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0019, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001a, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0001, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0022, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0031, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0031, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0004, 0x000007ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x00ff, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0039, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0009, 0x00000000, ++ 0x0004, 0x00000020, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x004c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x0052, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x001a, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0019, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x2a712488, ++ 0x000c, 0x00000000, ++ 0x0004, 0x4085c000, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x02800000, ++ 0x0094, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x30201000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x70605040, ++ 0x0004, 0x00000000, ++ 0x0004, 0xb8a89888, ++ 0x0004, 0x00000000, ++ 0x0004, 0xf8e8d8c8, ++ 0x000c, 0x00000000, ++ 0x0004, 0x0000001a, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0042, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0051, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00608080, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x010a, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0011, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x03020100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0042, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x02c5, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x4749, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0281, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x008c, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x005c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0064, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0054, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000007ff, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0154, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x00000020, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0024, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x004c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x00bc, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x2a712488, ++ 0x000c, 0x00000000, ++ 0x0004, 0x4085c000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x02800000, ++ 0x0094, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x30201000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x70605040, ++ 0x0004, 0x00000000, ++ 0x0004, 0xb8a89888, ++ 0x0004, 0x00000000, ++ 0x0004, 0xf8e8d8c8, ++ 0x000c, 0x00000000, ++ 0x0004, 0x0000001a, ++ 0x8958, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0047, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000080, ++ 0x0008, 0x80007004, ++ 0x0008, 0x04000400, ++ 0x0008, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0008, 0x00000080, ++ 0x0008, 0x80007004, ++ 0x0008, 0x04000400, ++ 0x0008, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0008, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0020, 0x0000ffff, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00010001, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0008, 0x08100c12, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000002, ++ 0x0008, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0008, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0008, 0x00000002, ++ 0x0010, 0x00000001, ++ 0x0008, 0x00000002, ++ 0x0018, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x1d10, 0x00000000, ++ 0x0008, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0000 ++}; ++ ++static unsigned nv96_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0029, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0013, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00608080, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0038, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0025, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000003, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0244, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x007a, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2bed, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0010, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0077, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0097, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0137, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000005, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0046, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x00b0, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0137, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x018f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0037, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x02e5, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1af3, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x008e, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x005e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0066, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0056, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000007ff, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0156, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0026, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x00be, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0002, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x02800000, ++ 0x0096, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x70605040, ++ 0x0006, 0x00000000, ++ 0x0002, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0002, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0000001a, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x00ae, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00608080, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0126, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x1c5c, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x62a1, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x008e, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x005e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0066, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0056, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000007ff, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0156, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0026, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x00be, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0002, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x02800000, ++ 0x0096, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x70605040, ++ 0x0006, 0x00000000, ++ 0x0002, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0002, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0000001a, ++ 0x295a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0047, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0003, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0003, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d18, 0x00000000, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nv98_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0040d94d, 0x00402944, 0x00402905, 0x0040290d, 0x0040b506, ++ 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00216c40, 0x00600007, 0x00c02701, ++ 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020, ++ 0x00600008, 0x0050004c, 0x00600009, 0x0040b545, 0x0040d04d, 0x0070009d, ++ 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200080, 0x00600008, ++ 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00216c40, 0x00600007, ++ 0x00c00a01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200240, 0x00600007, ++ 0x00300000, 0x00c000ff, 0x00c800ff, 0x0040c007, 0x00202912, 0x008000ff, ++ 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f, ++ 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, ++ 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000cc, 0x00101500, 0x0040790f, 0x0040794b, ++ 0x00214b00, 0x00600007, 0x00200425, 0x008800ff, 0x0070008f, 0x0040798c, ++ 0x005000cb, 0x00000000, 0x00141a05, 0x00131a0c, 0x00131c00, 0x00121c04, ++ 0x00141c20, 0x00111c25, 0x00131f00, 0x00191f40, 0x004095e0, 0x002001ac, ++ 0x00600006, 0x00200044, 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, ++ 0x00122100, 0x00122103, 0x00162200, 0x00122207, 0x00112280, 0x00112300, ++ 0x00112302, 0x00122380, 0x0011238b, 0x00112394, 0x0011239c, 0x00000000, ++ 0x00409c0f, 0x005000cb, 0x00214b00, 0x00600007, 0x00200425, 0x008800ff, ++ 0x005000cb, 0x00409f87, 0x0060000a, 0x00000000, 0x0040ae00, 0x007000a0, ++ 0x00700080, 0x00200240, 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, ++ 0x005000cb, 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x0040d04d, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, ++ 0x0040114d, 0x00700081, 0x00600004, 0x0050004a, 0x0040ba88, 0x0060000b, ++ 0x00200000, 0x00600006, 0x00700000, 0x0040d00b, 0x00111bfd, 0x0040424d, ++ 0x00202912, 0x008000fd, 0x005000cb, 0x00c00002, 0x00200240, 0x00600007, ++ 0x00200160, 0x00800002, 0x005000cb, 0x00c01802, 0x002027b2, 0x00800002, ++ 0x005000cb, 0x00404e4d, 0x0060000b, 0x0040ce4d, 0x00700001, 0x00700003, ++ 0x0040d406, 0x0040d505, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, ++ 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ~0 ++}; ++ ++static unsigned nv98_ctxvals[] = { ++ 0x0001, 0x00007f3c, ++ 0x0042, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00380040, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x003c, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00608080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000d, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0089, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x03fd, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x02d7, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0e5e, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2647, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0c98, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x005d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0031, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x003d, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001d, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0041, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x003c, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0029, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00c5, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0079, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0097, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x2a17, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x931d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0047, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0057, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0047, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1cff, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nva0_ctxprog[] = { ++ 0x0070009c, 0x00300000, 0x00452c09, 0x00402d09, 0x00412051, 0x00400a44, ++ 0x00400a05, 0x00400a0d, 0x0070008e, 0x0040124d, 0x0070009d, 0x00453b4d, ++ 0x00700097, 0x00453c21, 0x004446a1, 0x0044914d, 0x00449d4d, 0x0070001d, ++ 0x00401806, 0x00600005, 0x00444445, 0x0044308b, 0x00401845, 0x0040234d, ++ 0x00700081, 0x00401ccf, 0x0070009f, 0x0050009f, 0x0045174d, 0x00700017, ++ 0x0040230b, 0x0044984d, 0x00453d21, 0x004456a1, 0x007000a0, 0x00700001, ++ 0x00700003, 0x00402706, 0x00402805, 0x0060000d, 0x00700005, 0x0070000d, ++ 0x00700006, 0x00700002, 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ++ 0x00000000, 0x0090ffff, 0x0091ffff, 0x00450f4d, 0x00600009, 0x0048004d, ++ 0x00700096, 0x00403acf, 0x0070009f, 0x0050009f, 0x00412051, 0x004036c0, ++ 0x00200080, 0x00600008, 0x0040364f, 0x004036c0, 0x00403ecc, 0x00403651, ++ 0x00700016, 0x0048004d, 0x00600011, 0x0048004d, 0x0044364d, 0x0070008e, ++ 0x00700081, 0x00448b4d, 0x0044984d, 0x00700083, 0x00300000, 0x00217c80, ++ 0x00600007, 0x00c00a01, 0x00200022, 0x00800001, 0x005000cb, 0x00c000ff, ++ 0x00445e4d, 0x0048004d, 0x00450908, 0x00448e4d, 0x0044a64d, 0x00445e4d, ++ 0x00451d4d, 0x0044914d, 0x00449d4d, 0x0048004d, 0x00700083, 0x00453e4d, ++ 0x00a0023f, 0x00200040, 0x00600006, 0x0045374d, 0x0044a84d, 0x0020022b, ++ 0x0044ef60, 0x002002ba, 0x00300001, 0x0044ef61, 0x00200349, 0x00300002, ++ 0x0044ef62, 0x002003d8, 0x00300003, 0x0044ef63, 0x00200467, 0x00300004, ++ 0x0044ef64, 0x002004f6, 0x00300005, 0x0044ef65, 0x00200585, 0x00300006, ++ 0x0044ef66, 0x00200614, 0x00300007, 0x0044ef67, 0x002006a3, 0x00300008, ++ 0x0044ef68, 0x00200732, 0x00300009, 0x0044ef69, 0x00200800, 0x0038ffff, ++ 0x0045044d, 0x00300000, 0x005000cb, 0x0045564d, 0x005000cb, 0x00450b07, ++ 0x0048004d, 0x0044944d, 0x00111bfc, 0x0048004d, 0x0044944d, 0x00111bfd, ++ 0x0048004d, 0x0044944d, 0x00111bfe, 0x0048004d, 0x00200000, 0x00700000, ++ 0x00600006, 0x0048004d, 0x00200001, 0x00600006, 0x0045374d, 0x0011020a, ++ 0x0048004d, 0x00300000, 0x00c3ffff, 0x00200000, 0x00600007, 0x00700000, ++ 0x00200008, 0x008000ff, 0x005000cb, 0x0048004d, 0x00000000, 0x0048004d, ++ 0x00000000, 0x00170202, 0x00200032, 0x0010020d, 0x001e0242, 0x001102c0, ++ 0x00120302, 0x00150402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, ++ 0x00200013, 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, ++ 0x00160b02, 0x00120b28, 0x00140b2b, 0x00110c01, 0x00110d01, 0x00111400, ++ 0x00111405, 0x00111407, 0x00111409, 0x0011140b, 0x002000d4, 0x00101500, ++ 0x00141a05, 0x00131a0c, 0x00131c00, 0x00131c04, 0x00141c20, 0x00131c25, ++ 0x00131c40, 0x00131c44, 0x00141c60, 0x00131c65, 0x00131c80, 0x00131c84, ++ 0x00141ca0, 0x00131ca5, 0x00131cc0, 0x00131cc4, 0x00141ce0, 0x00131ce5, ++ 0x00131d00, 0x00131d04, 0x00141d20, 0x00131d25, 0x00131d40, 0x00131d44, ++ 0x00141d60, 0x00131d65, 0x00131d80, 0x00131d84, 0x00141da0, 0x00131da5, ++ 0x00131dc0, 0x00131dc4, 0x00141de0, 0x00131de5, 0x00131f00, 0x00131f04, ++ 0x00111f08, 0x00111f0b, 0x00200015, 0x00101f40, 0x0048004d, 0x00600006, ++ 0x0045564d, 0x00112020, 0x00112022, 0x00200060, 0x00102040, 0x001520c0, ++ 0x001120c8, 0x001420ca, 0x001b20cf, 0x00122100, 0x00122103, 0x00162140, ++ 0x00122147, 0x00122153, 0x001121a0, 0x001221c0, 0x001121cb, 0x001121d4, ++ 0x001521d8, 0x0048004d, 0x00000000, 0x00700000, 0x00600006, 0x0045374d, ++ 0x0048004d, 0x0060000b, 0x0048004d, 0x0060000a, 0x0048004d, 0x0060000b, ++ 0x00410d4d, 0x00200020, 0x00600008, 0x0050004c, 0x0048004d, 0x002003e8, ++ 0x00600008, 0x0050004c, 0x0048004d, 0x00600004, 0x0050004a, 0x0048004d, ++ 0x00c000ff, 0x00c800ff, 0x0048004d, 0x00c000ff, 0x00c800ff, 0x0048004d, ++ 0x00700016, 0x0070008e, 0x00700082, 0x00500041, 0x0045134d, 0x00700095, ++ 0x005000d1, 0x00600016, 0x00500052, 0x00700002, 0x00700015, 0x0040284d, ++ 0x0070008e, 0x00450f4d, 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, ++ 0x00200000, 0x008000ff, 0x00700009, 0x0070000e, 0x0048004d, 0x00700080, ++ 0x00480017, 0x00700000, 0x0048004d, 0x0048004d, 0x0048004d, 0x0048004d, ++ 0x0070008e, 0x00450f4d, 0x00700083, 0x00451a4d, 0x0045474d, 0x0070000f, ++ 0x0041468c, 0x005000cb, 0x0048004d, 0x00200800, 0x00600007, 0x00454b87, ++ 0x0048004d, 0x00000000, 0x0020216c, 0x0045374d, 0x008000ff, 0x0048004d, ++ 0x00211380, 0x00600007, 0x00200d20, 0x0045374d, 0x008800ff, 0x0048004d, ++ 0x0048000f, 0x0048004b, 0x0045504d, 0x0070008f, 0x0048008c, 0x005000cb, ++ 0x0048004d, ~0 ++}; ++ ++static unsigned nva0_ctxvals[] = { ++ 0x0001, 0x00007f30, ++ 0x0042, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x0012, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000800, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x000e0080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000009, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0007, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000022, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00080c14, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000c, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000020, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x4085c000, ++ 0x0002, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000040, ++ 0x0005, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0012, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x000c, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000c, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0002, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001c, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x000007ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000ffff, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0013, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000c, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0001, 0x000000cf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000015, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x04444480, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0034, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000c, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x000c, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0058, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0003, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0013, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001c, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x002e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x003c, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0019, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x0000000f, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000080, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0058, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0030, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x006e, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x009e, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00df, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x02b4, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0011, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x008d, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0031, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0076, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x003e, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0019, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x002d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x0000000f, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0031, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0050, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0056, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00d8, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x030e, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00c9, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x00df, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000d, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0035, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0039, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0060, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0008, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002d, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x002e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x0000000f, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x09a0, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0066, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0040, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0076, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0048, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x002e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x0000000f, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0021, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001d, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000004, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0071, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0015, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0081, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b5, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x09a0, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x00df, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0076, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x00d8, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x10a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x00df, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0157, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x10a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x03c3, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x1a66, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x15c6, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0800, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x002d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0068, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0068, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0060, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0003, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d18, 0x00000000, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0170, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0068, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0068, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0060, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0003, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d18, 0x00000000, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0171, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000c0, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001000, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x006e, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000c0, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001000, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x006e, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000c0, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001000, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0066, 0x00000000, ++ 0x0002, 0x08100c12, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0001fe21, ++ 0x002e, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0001fe21, ++ 0x002e, 0x00000000, ++ 0x0002, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0046, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x1d1e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nvaa_ctxprog[] = { ++ 0x0070009c, 0x00300000, 0x0044f109, 0x00402d09, 0x0040e551, 0x00400a44, ++ 0x00400a05, 0x00400a0d, 0x0070008e, 0x0040124d, 0x0070009d, 0x0045004d, ++ 0x00700097, 0x00450121, 0x004446a1, 0x0044764d, 0x0044824d, 0x0070001d, ++ 0x00401806, 0x00600005, 0x00444445, 0x0044308b, 0x00401845, 0x0040234d, ++ 0x00700081, 0x00401ccf, 0x0070009f, 0x0050009f, 0x0044dc4d, 0x00700017, ++ 0x0040230b, 0x00447d4d, 0x00450221, 0x004456a1, 0x007000a0, 0x00700001, ++ 0x00700003, 0x00402706, 0x00402805, 0x0060000d, 0x00700005, 0x0070000d, ++ 0x00700006, 0x00700002, 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ++ 0x00000000, 0x0090ffff, 0x0091ffff, 0x0044d44d, 0x00600009, 0x0048004d, ++ 0x00700096, 0x00403acf, 0x0070009f, 0x0050009f, 0x0040e551, 0x004036c0, ++ 0x00200080, 0x00600008, 0x0040364f, 0x004036c0, 0x00403ecc, 0x00403651, ++ 0x00700016, 0x0048004d, 0x00600011, 0x0048004d, 0x0044364d, 0x0070008e, ++ 0x00700081, 0x0044704d, 0x00447d4d, 0x00700083, 0x00300000, 0x00212740, ++ 0x00600007, 0x00c00b01, 0x00200022, 0x00800001, 0x005000cb, 0x00c000ff, ++ 0x00445e4d, 0x0048004d, 0x0044ce08, 0x0044734d, 0x00448b4d, 0x00445e4d, ++ 0x0044e24d, 0x0044764d, 0x0044824d, 0x0048004d, 0x00700083, 0x0045034d, ++ 0x00a0023f, 0x00200040, 0x00600006, 0x0044fc4d, 0x00448d4d, 0x002001d0, ++ 0x0044b860, 0x00200280, 0x0038ffff, 0x0044cc4d, 0x00300000, 0x005000cb, ++ 0x00451c4d, 0x005000cb, 0x0044d007, 0x0048004d, 0x0044794d, 0x00111bfc, ++ 0x0048004d, 0x0044794d, 0x00111bfd, 0x0048004d, 0x0044794d, 0x00111bfe, ++ 0x0048004d, 0x00200000, 0x00700000, 0x00600006, 0x0048004d, 0x00200001, ++ 0x00600006, 0x0044fc4d, 0x0011020a, 0x0048004d, 0x00300000, 0x00c3ffff, ++ 0x00200000, 0x00600007, 0x00700000, 0x00200008, 0x008000ff, 0x005000cb, ++ 0x0048004d, 0x00000000, 0x0048004d, 0x00000000, 0x00170202, 0x00200032, ++ 0x0010020d, 0x001e0242, 0x001102c0, 0x00120302, 0x00150402, 0x00180500, ++ 0x00130509, 0x00150550, 0x00110605, 0x00200013, 0x00100607, 0x00110700, ++ 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, 0x00120b28, 0x00140b2b, ++ 0x00110c01, 0x00110d01, 0x00111400, 0x00111405, 0x00111407, 0x00111409, ++ 0x0011140b, 0x002000d4, 0x00101500, 0x00141a05, 0x00131a0c, 0x00131c00, ++ 0x00131c04, 0x00141c20, 0x00131c25, 0x00131f00, 0x00131f04, 0x00111f08, ++ 0x00111f0b, 0x00200015, 0x00101f40, 0x0048004d, 0x00600006, 0x00451c4d, ++ 0x00112020, 0x00112022, 0x00200085, 0x00102040, 0x001120c8, 0x001420ca, ++ 0x001b20cf, 0x00122100, 0x00122103, 0x00162140, 0x00122147, 0x00122153, ++ 0x001121a0, 0x001221c0, 0x001121cb, 0x001121d4, 0x001521d8, 0x0048004d, ++ 0x00000000, 0x0048004d, 0x0060000b, 0x0048004d, 0x0060000a, 0x0048004d, ++ 0x0060000b, 0x0040d24d, 0x00200020, 0x00600008, 0x0050004c, 0x0048004d, ++ 0x002003e8, 0x00600008, 0x0050004c, 0x0048004d, 0x00600004, 0x0050004a, ++ 0x0048004d, 0x00c000ff, 0x00c800ff, 0x0048004d, 0x00c000ff, 0x00c800ff, ++ 0x0048004d, 0x00700016, 0x0070008e, 0x00700082, 0x00500041, 0x0044d84d, ++ 0x00700095, 0x005000d1, 0x00600016, 0x00500052, 0x00700002, 0x00700015, ++ 0x0040284d, 0x0070008e, 0x0044d44d, 0x00200000, 0x00600007, 0x00300000, ++ 0x00c000ff, 0x00200000, 0x008000ff, 0x00700009, 0x0070000e, 0x0048004d, ++ 0x00700080, 0x00480017, 0x00700000, 0x0048004d, 0x0048004d, 0x0048004d, ++ 0x0048004d, 0x0070008e, 0x0044d44d, 0x00700083, 0x0044df4d, 0x00450c4d, ++ 0x0070000f, 0x00410b8c, 0x005000cb, 0x0048004d, 0x00200280, 0x00600007, ++ 0x00452307, 0x00451187, 0x0048004d, 0x00000000, 0x00202070, 0x0044fc4d, ++ 0x008000ff, 0x0048004d, 0x00210600, 0x00600007, 0x00200428, 0x0044fc4d, ++ 0x008800ff, 0x0048004d, 0x0048000f, 0x0048004b, 0x0045164d, 0x0070008f, ++ 0x0048008c, 0x005000cb, 0x0048004d, 0x00202070, 0x0044fc4d, 0x008000fd, ++ 0x005000cb, 0x00c00002, 0x00200280, 0x00600007, 0x00200161, 0x0044fc4d, ++ 0x00800002, 0x005000cb, 0x00c00002, 0x00201f0e, 0x0044fc4d, 0x00800002, ++ 0x005000cb, 0x0048004d, ~0 ++}; ++ ++static uint32_t nvaa_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x0012, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000800, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000007, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000009, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0007, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000022, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00030201, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00008000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02bf7fff, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x08100c12, ++ 0x0005, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000d, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x000007ff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00080c14, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x003d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000088, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00000088, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x04444480, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0011, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0058, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0048, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x004c, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0084, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00d2, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x03d1, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0c75, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x010a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x24f9, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0440, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x1383, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x032f, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0097, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0137, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x01e7, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x6ee1, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x005f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0047, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1cff, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nv94_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0041324d, 0x00402944, 0x00402905, 0x0040290d, 0x00410e06, ++ 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00219440, 0x00600007, 0x00c02701, ++ 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020, ++ 0x00600008, 0x0050004c, 0x00600009, 0x00410e45, 0x0041294d, 0x0070009d, ++ 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200080, 0x00600008, ++ 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00219440, 0x00600007, ++ 0x00c00a01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200380, 0x00600007, ++ 0x00300000, 0x00c000ff, 0x00c800ff, 0x00411907, 0x00202dd2, 0x008000ff, ++ 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f, ++ 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, ++ 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000cc, 0x00101500, 0x0040790f, 0x0040794b, ++ 0x00217240, 0x00600007, 0x0020043f, 0x008800ff, 0x0070008f, 0x0040798c, ++ 0x005000cb, 0x00000000, 0x00141a05, 0x00131a0c, 0x00131c00, 0x00121c04, ++ 0x00141c20, 0x00111c25, 0x00131c40, 0x00121c44, 0x00141c60, 0x00111c65, ++ 0x00131c80, 0x00121c84, 0x00141ca0, 0x00111ca5, 0x00131cc0, 0x00121cc4, ++ 0x00141ce0, 0x00111ce5, 0x00131f00, 0x00191f40, 0x0040a1e0, 0x002001ca, ++ 0x00600006, 0x00200044, 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, ++ 0x00122100, 0x00122103, 0x00162200, 0x00122207, 0x00112280, 0x00112300, ++ 0x00112302, 0x00122380, 0x0011238b, 0x00112394, 0x0011239c, 0x0040bee1, ++ 0x00200231, 0x00600006, 0x00200044, 0x00102480, 0x0040af0f, 0x0040af4b, ++ 0x00217240, 0x00600007, 0x0020043f, 0x008800ff, 0x0070008f, 0x0040af8c, ++ 0x005000cb, 0x00000000, 0x001124c6, 0x001524c9, 0x001924d0, 0x00122500, ++ 0x00122503, 0x00162600, 0x00122607, 0x00112680, 0x00112700, 0x00112702, ++ 0x00122780, 0x0011278b, 0x00112794, 0x0011279c, 0x0040d1e2, 0x00200298, ++ 0x00600006, 0x00200044, 0x00102880, 0x001128c6, 0x001528c9, 0x001928d0, ++ 0x00122900, 0x00122903, 0x00162a00, 0x00122a07, 0x00112a80, 0x00112b00, ++ 0x00112b02, 0x00122b80, 0x00112b8b, 0x00112b94, 0x00112b9c, 0x0040eee3, ++ 0x002002ff, 0x00600006, 0x00200044, 0x00102c80, 0x0040df0f, 0x0040df4b, ++ 0x00217240, 0x00600007, 0x0020043f, 0x008800ff, 0x0070008f, 0x0040df8c, ++ 0x005000cb, 0x00000000, 0x00112cc6, 0x00152cc9, 0x00192cd0, 0x00122d00, ++ 0x00122d03, 0x00162e00, 0x00122e07, 0x00112e80, 0x00112f00, 0x00112f02, ++ 0x00122f80, 0x00112f8b, 0x00112f94, 0x00112f9c, 0x00000000, 0x0040f50f, ++ 0x005000cb, 0x00217240, 0x00600007, 0x0020043f, 0x008800ff, 0x005000cb, ++ 0x0040f887, 0x0060000a, 0x00000000, 0x00410700, 0x007000a0, 0x00700080, ++ 0x00200380, 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, 0x005000cb, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x0041294d, 0x00700000, ++ 0x00200000, 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, 0x0040114d, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00411388, 0x0060000b, 0x00200000, ++ 0x00600006, 0x00700000, 0x0041290b, 0x00111bfd, 0x0040424d, 0x00202dd2, ++ 0x008000fd, 0x005000cb, 0x00c00002, 0x00200380, 0x00600007, 0x00200160, ++ 0x00800002, 0x005000cb, 0x00c01802, 0x00202c72, 0x00800002, 0x005000cb, ++ 0x00404e4d, 0x0060000b, 0x0041274d, 0x00700001, 0x00700003, 0x00412d06, ++ 0x00412e05, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, 0x0070000b, ++ 0x0070000e, 0x0070001c, 0x0060000c, ~0 ++}; ++ ++static unsigned nv94_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x044d00df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0029, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0013, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00608080, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0038, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0025, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000003, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0244, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x007a, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2bed, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0010, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0077, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0097, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0137, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000005, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0046, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x00b0, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0137, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x018f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0037, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x02e5, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1af3, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x008e, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x005e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0066, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0056, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000007ff, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0156, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0026, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x00be, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0002, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x02800000, ++ 0x0096, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x70605040, ++ 0x0006, 0x00000000, ++ 0x0002, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0002, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0000001a, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x00ae, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00608080, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0126, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x1c5c, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x62a1, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x008e, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x005e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0066, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0056, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000007ff, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0156, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0026, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x00be, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0002, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x02800000, ++ 0x0096, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x70605040, ++ 0x0006, 0x00000000, ++ 0x0002, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0002, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0000001a, ++ 0x295a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0047, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0003, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0003, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d18, 0x00000000, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++#endif +diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c +new file mode 100644 +index 0000000..0659f1b +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_instmem.c +@@ -0,0 +1,379 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++struct nv50_instmem_priv { ++ uint32_t save1700[5]; /* 0x1700->0x1710 */ ++ ++ struct nouveau_gpuobj_ref *pramin_pt; ++ struct nouveau_gpuobj_ref *pramin_bar; ++ ++ bool last_access_wr; ++}; ++ ++#define NV50_INSTMEM_PAGE_SHIFT 12 ++#define NV50_INSTMEM_PAGE_SIZE (1 << NV50_INSTMEM_PAGE_SHIFT) ++#define NV50_INSTMEM_PT_SIZE(a) (((a) >> 12) << 3) ++ ++/*NOTE: - Assumes 0x1700 already covers the correct MiB of PRAMIN ++ */ ++#define BAR0_WI32(g,o,v) do { \ ++ uint32_t offset; \ ++ if ((g)->im_backing) { \ ++ offset = (g)->im_backing->start; \ ++ } else { \ ++ offset = chan->ramin->gpuobj->im_backing->start; \ ++ offset += (g)->im_pramin->start; \ ++ } \ ++ offset += (o); \ ++ nv_wr32(NV_RAMIN + (offset & 0xfffff), (v)); \ ++} while(0) ++ ++int ++nv50_instmem_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan; ++ uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size; ++ struct nv50_instmem_priv *priv; ++ int ret, i; ++ uint32_t v; ++ ++ priv = drm_calloc(1, sizeof(*priv), DRM_MEM_DRIVER); ++ if (!priv) ++ return -ENOMEM; ++ dev_priv->engine.instmem.priv = priv; ++ ++ /* Save state, will restore at takedown. */ ++ for (i = 0x1700; i <= 0x1710; i+=4) ++ priv->save1700[(i-0x1700)/4] = nv_rd32(i); ++ ++ /* Reserve the last MiB of VRAM, we should probably try to avoid ++ * setting up the below tables over the top of the VBIOS image at ++ * some point. ++ */ ++ dev_priv->ramin_rsvd_vram = 1 << 20; ++ c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram; ++ c_size = 128 << 10; ++ c_vmpd = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200; ++ c_ramfc = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20; ++ c_base = c_vmpd + 0x4000; ++ pt_size = NV50_INSTMEM_PT_SIZE(dev_priv->ramin->size); ++ ++ NV_DEBUG(dev, " Rsvd VRAM base: 0x%08x\n", c_offset); ++ NV_DEBUG(dev, " VBIOS image: 0x%08x\n", (nv_rd32(0x619f04)&~0xff)<<8); ++ NV_DEBUG(dev, " Aperture size: %d MiB\n", ++ (uint32_t)dev_priv->ramin->size >> 20); ++ NV_DEBUG(dev, " PT size: %d KiB\n", pt_size >> 10); ++ ++ nv_wr32(NV50_PUNK_BAR0_PRAMIN, (c_offset >> 16)); ++ ++ /* Create a fake channel, and use it as our "dummy" channels 0/127. ++ * The main reason for creating a channel is so we can use the gpuobj ++ * code. However, it's probably worth noting that NVIDIA also setup ++ * their channels 0/127 with the same values they configure here. ++ * So, there may be some other reason for doing this. ++ * ++ * Have to create the entire channel manually, as the real channel ++ * creation code assumes we have PRAMIN access, and we don't until ++ * we're done here. ++ */ ++ chan = drm_calloc(1, sizeof(*chan), DRM_MEM_DRIVER); ++ if (!chan) ++ return -ENOMEM; ++ chan->id = 0; ++ chan->dev = dev; ++ chan->file_priv = (struct drm_file *)-2; ++ dev_priv->fifos[0] = dev_priv->fifos[127] = chan; ++ ++ /* Channel's PRAMIN object + heap */ ++ if ((ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, 128<<10, 0, ++ NULL, &chan->ramin))) ++ return ret; ++ ++ if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base)) ++ return -ENOMEM; ++ ++ /* RAMFC + zero channel's PRAMIN up to start of VM pagedir */ ++ if ((ret = nouveau_gpuobj_new_fake(dev, c_ramfc, c_offset + c_ramfc, ++ 0x4000, 0, NULL, &chan->ramfc))) ++ return ret; ++ ++ for (i = 0; i < c_vmpd; i += 4) ++ BAR0_WI32(chan->ramin->gpuobj, i, 0); ++ ++ /* VM page directory */ ++ if ((ret = nouveau_gpuobj_new_fake(dev, c_vmpd, c_offset + c_vmpd, ++ 0x4000, 0, &chan->vm_pd, NULL))) ++ return ret; ++ for (i = 0; i < 0x4000; i += 8) { ++ BAR0_WI32(chan->vm_pd, i + 0x00, 0x00000000); ++ BAR0_WI32(chan->vm_pd, i + 0x04, 0x00000000); ++ } ++ ++ /* PRAMIN page table, cheat and map into VM at 0x0000000000. ++ * We map the entire fake channel into the start of the PRAMIN BAR ++ */ ++ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000, ++ 0, &priv->pramin_pt))) ++ return ret; ++ ++ for (i = 0, v = c_offset; i < pt_size; i+=8, v+=0x1000) { ++ if (v < (c_offset + c_size)) ++ BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v | 1); ++ else ++ BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000009); ++ BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); ++ } ++ ++ BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63); ++ BAR0_WI32(chan->vm_pd, 0x04, 0x00000000); ++ ++ /* DMA object for PRAMIN BAR */ ++ if ((ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0, ++ &priv->pramin_bar))) ++ return ret; ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x00, 0x7fc00000); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x04, dev_priv->ramin->size - 1); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x08, 0x00000000); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x0c, 0x00000000); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x10, 0x00000000); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x14, 0x00000000); ++ ++ /* Poke the relevant regs, and pray it works :) */ ++ nv_wr32(NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12)); ++ nv_wr32(NV50_PUNK_UNK1710, 0); ++ nv_wr32(NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) | ++ NV50_PUNK_BAR_CFG_BASE_VALID); ++ nv_wr32(NV50_PUNK_BAR1_CTXDMA, 0); ++ nv_wr32(NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) | ++ NV50_PUNK_BAR3_CTXDMA_VALID); ++ ++ for (i = 0; i < 8; i++) ++ nv_wr32(0x1900 + (i*4), 0); ++ ++ /* Assume that praying isn't enough, check that we can re-read the ++ * entire fake channel back from the PRAMIN BAR */ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ for (i = 0; i < c_size; i+=4) { ++ if (nv_rd32(NV_RAMIN + i) != nv_ri32(i)) { ++ NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n", i); ++ return -EINVAL; ++ } ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* Global PRAMIN heap */ ++ if (nouveau_mem_init_heap(&dev_priv->ramin_heap, ++ c_size, dev_priv->ramin->size - c_size)) { ++ dev_priv->ramin_heap = NULL; ++ NV_ERROR(dev, "Failed to init RAMIN heap\n"); ++ } ++ ++ /*XXX: incorrect, but needed to make hash func "work" */ ++ dev_priv->ramht_offset = 0x10000; ++ dev_priv->ramht_bits = 9; ++ dev_priv->ramht_size = (1 << dev_priv->ramht_bits); ++ return 0; ++} ++ ++void ++nv50_instmem_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ struct nouveau_channel *chan = dev_priv->fifos[0]; ++ int i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!priv) ++ return; ++ ++ /* Restore state from before init */ ++ for (i = 0x1700; i <= 0x1710; i+=4) ++ nv_wr32(i, priv->save1700[(i-0x1700)/4]); ++ ++ nouveau_gpuobj_ref_del(dev, &priv->pramin_bar); ++ nouveau_gpuobj_ref_del(dev, &priv->pramin_pt); ++ ++ /* Destroy dummy channel */ ++ if (chan) { ++ nouveau_gpuobj_del(dev, &chan->vm_pd); ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++ nouveau_gpuobj_ref_del(dev, &chan->ramin); ++ nouveau_mem_takedown(&chan->ramin_heap); ++ ++ dev_priv->fifos[0] = dev_priv->fifos[127] = NULL; ++ drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); ++ } ++ ++ dev_priv->engine.instmem.priv = NULL; ++ drm_free(priv, sizeof(*priv), DRM_MEM_DRIVER); ++} ++ ++int ++nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, uint32_t *sz) ++{ ++ if (gpuobj->im_backing) ++ return -EINVAL; ++ ++ *sz = (*sz + (NV50_INSTMEM_PAGE_SIZE-1)) & ~(NV50_INSTMEM_PAGE_SIZE-1); ++ if (*sz == 0) ++ return -EINVAL; ++ ++ gpuobj->im_backing = nouveau_mem_alloc(dev, NV50_INSTMEM_PAGE_SIZE, ++ *sz, NOUVEAU_MEM_FB | ++ NOUVEAU_MEM_NOVM, ++ (struct drm_file *)-2); ++ if (!gpuobj->im_backing) { ++ NV_ERROR(dev, "Couldn't allocate vram to back PRAMIN pages\n"); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++void ++nv50_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (gpuobj && gpuobj->im_backing) { ++ if (gpuobj->im_bound) ++ dev_priv->engine.instmem.unbind(dev, gpuobj); ++ nouveau_mem_free(dev, gpuobj->im_backing); ++ gpuobj->im_backing = NULL; ++ } ++} ++ ++int ++nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ uint32_t pte, pte_end, vram; ++ ++ if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) ++ return -EINVAL; ++ ++ NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n", ++ gpuobj->im_pramin->start, gpuobj->im_pramin->size); ++ ++ pte = (gpuobj->im_pramin->start >> 12) << 3; ++ pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; ++ vram = gpuobj->im_backing->start; ++ ++ NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n", ++ gpuobj->im_pramin->start, pte, pte_end); ++ NV_DEBUG(dev, "first vram page: 0x%llx\n", ++ gpuobj->im_backing->start); ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ while (pte < pte_end) { ++ INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 0)/4, vram | 1); ++ INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); ++ ++ pte += 8; ++ vram += NV50_INSTMEM_PAGE_SIZE; ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(0x100c80, 0x00040001); ++ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { ++ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (1)\n"); ++ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(0x100c80)); ++ return -EBUSY; ++ } ++ ++ nv_wr32(0x100c80, 0x00060001); ++ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { ++ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); ++ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(0x100c80)); ++ return -EBUSY; ++ } ++ ++ gpuobj->im_bound = 1; ++ return 0; ++} ++ ++int ++nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ uint32_t pte, pte_end; ++ ++ if (gpuobj->im_bound == 0) ++ return -EINVAL; ++ ++ pte = (gpuobj->im_pramin->start >> 12) << 3; ++ pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ while (pte < pte_end) { ++ INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 0)/4, 0x00000009); ++ INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); ++ pte += 8; ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ gpuobj->im_bound = 0; ++ return 0; ++} ++ ++void ++nv50_instmem_prepare_access(struct drm_device *dev, bool write) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ ++ BUG_ON(dev_priv->ramin_map != NULL); ++ dev_priv->ramin_map = dev_priv->ramin; ++ ++ priv->last_access_wr = write; ++} ++ ++void ++nv50_instmem_finish_access(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ ++ BUG_ON(dev_priv->ramin_map == NULL); ++ dev_priv->ramin_map = NULL; ++ ++ if (priv->last_access_wr) { ++ nv_wr32(0x070000, 0x00000001); ++ if (!nv_wait(0x070000, 0x00000001, 0x00000000)) ++ NV_ERROR(dev, "PRAMIN flush timeout\n"); ++ } ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_mc.c b/drivers/gpu/drm/nouveau/nv50_mc.c +new file mode 100644 +index 0000000..6572f12 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_mc.c +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++int ++nv50_mc_init(struct drm_device *dev) ++{ ++ nv_wr32(NV03_PMC_ENABLE, 0xFFFFFFFF); ++ return 0; ++} ++ ++void nv50_mc_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c +new file mode 100644 +index 0000000..c913950 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_sor.c +@@ -0,0 +1,275 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_crtc.h" ++#include "nv50_display.h" ++#include "nv50_display_commands.h" ++ ++extern int nouveau_duallink; ++ ++static void ++nv50_sor_disconnect(struct nouveau_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ uint32_t offset = encoder->or * 0x40; ++ ++ NV_DEBUG(dev, "Disconnecting SOR %d\n", encoder->or); ++ ++ OUT_MODE(NV50_SOR0_MODE_CTRL + offset, NV50_SOR_MODE_CTRL_OFF); ++} ++ ++static int ++nv50_sor_set_clock_mode(struct nouveau_encoder *encoder, ++ struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ uint32_t limit = 165000; ++ ++ NV_DEBUG(dev, "or %d\n", encoder->or); ++ ++ /* We don't yet know what to do, if anything at all. */ ++ if (encoder->base.encoder_type == DRM_MODE_ENCODER_LVDS) ++ return 0; ++ ++ /* 0x70000 was a late addition to nv, mentioned as fixing tmds ++ * initialisation on certain gpu's. I presume it's some kind of ++ * clock setting, but what precisely i do not know. ++ */ ++ nv_wr32(NV50_PDISPLAY_SOR_CLK_CLK_CTRL2(encoder->or), ++ 0x70000 | ((mode->clock > limit) ? 0x101 : 0)); ++ ++ return 0; ++} ++ ++static void nv50_sor_dpms(struct drm_encoder *drm_encoder, int mode) ++{ ++ struct drm_device *dev = drm_encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); ++ uint32_t val; ++ int or = encoder->or; ++ ++ NV_DEBUG(dev, "or %d\n", encoder->or); ++ ++ if (dev_priv->in_modeset) { ++ nv50_sor_disconnect(encoder); ++ return; ++ } ++ ++ /* wait for it to be done */ ++ if (!nv_wait(NV50_PDISPLAY_SOR_REGS_DPMS_CTRL(or), ++ NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_PENDING, 0)) { ++ NV_ERROR(dev, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or); ++ NV_ERROR(dev, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or, ++ nv_rd32(NV50_PDISPLAY_SOR_REGS_DPMS_CTRL(or))); ++ } ++ ++ val = nv_rd32(NV50_PDISPLAY_SOR_REGS_DPMS_CTRL(or)); ++ ++ if (mode == DRM_MODE_DPMS_ON) ++ val |= NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_ON; ++ else ++ val &= ~NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_ON; ++ ++ nv_wr32(NV50_PDISPLAY_SOR_REGS_DPMS_CTRL(or), val | ++ NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_PENDING); ++} ++ ++static void nv50_sor_save(struct drm_encoder *drm_encoder) ++{ ++ NV_ERROR(drm_encoder->dev, "!!\n"); ++} ++ ++static void nv50_sor_restore(struct drm_encoder *drm_encoder) ++{ ++ NV_ERROR(drm_encoder->dev, "!!\n"); ++} ++ ++static struct nouveau_connector * ++nouveau_encoder_connector_get(struct nouveau_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_connector *drm_connector; ++ ++ list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) { ++ if (drm_connector->encoder == &encoder->base) ++ return to_nouveau_connector(drm_connector); ++ } ++ ++ return NULL; ++} ++ ++static bool nv50_sor_mode_fixup(struct drm_encoder *drm_encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); ++ struct nouveau_connector *connector; ++ ++ connector = nouveau_encoder_connector_get(encoder); ++ if (!connector) ++ return false; ++ ++ if ((connector->scaling_mode != DRM_MODE_SCALE_NON_GPU && ++ connector->scaling_mode != DRM_MODE_SCALE_NO_SCALE) && ++ connector->native_mode) { ++ int id = adjusted_mode->base.id; ++ *adjusted_mode = *connector->native_mode; ++ adjusted_mode->base.id = id; ++ } ++ ++ return true; ++} ++ ++static void nv50_sor_prepare(struct drm_encoder *drm_encoder) ++{ ++} ++ ++static void nv50_sor_commit(struct drm_encoder *drm_encoder) ++{ ++} ++ ++static void nv50_sor_mode_set(struct drm_encoder *drm_encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); ++ struct drm_device *dev = drm_encoder->dev; ++ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_encoder->crtc); ++ uint32_t offset = encoder->or * 0x40; ++ uint32_t mode_ctl = NV50_SOR_MODE_CTRL_OFF; ++ ++ NV_DEBUG(dev, "or %d\n", encoder->or); ++ ++ if (encoder->base.encoder_type == DRM_MODE_ENCODER_LVDS) { ++ mode_ctl |= NV50_SOR_MODE_CTRL_LVDS; ++ } else { ++ mode_ctl |= NV50_SOR_MODE_CTRL_TMDS; ++ if (adjusted_mode->clock > 165000) ++ mode_ctl |= NV50_SOR_MODE_CTRL_TMDS_DUAL_LINK; ++ } ++ ++ if (crtc->index == 1) ++ mode_ctl |= NV50_SOR_MODE_CTRL_CRTC1; ++ else ++ mode_ctl |= NV50_SOR_MODE_CTRL_CRTC0; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ++ mode_ctl |= NV50_SOR_MODE_CTRL_NHSYNC; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ++ mode_ctl |= NV50_SOR_MODE_CTRL_NVSYNC; ++ ++ OUT_MODE(NV50_SOR0_MODE_CTRL + offset, mode_ctl); ++} ++ ++static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { ++ .dpms = nv50_sor_dpms, ++ .save = nv50_sor_save, ++ .restore = nv50_sor_restore, ++ .mode_fixup = nv50_sor_mode_fixup, ++ .prepare = nv50_sor_prepare, ++ .commit = nv50_sor_commit, ++ .mode_set = nv50_sor_mode_set, ++ .detect = NULL ++}; ++ ++static void nv50_sor_destroy(struct drm_encoder *drm_encoder) ++{ ++ struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); ++ ++ NV_DEBUG(drm_encoder->dev, "\n"); ++ ++ if (!drm_encoder) ++ return; ++ ++ drm_encoder_cleanup(&encoder->base); ++ ++ kfree(encoder); ++} ++ ++static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { ++ .destroy = nv50_sor_destroy, ++}; ++ ++int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) ++{ ++ struct nouveau_encoder *encoder = NULL; ++ int type; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ switch (entry->type) { ++ case OUTPUT_TMDS: ++ NV_INFO(dev, "Detected a TMDS output\n"); ++ type = DRM_MODE_ENCODER_TMDS; ++ break; ++ case OUTPUT_LVDS: ++ NV_INFO(dev, "Detected a LVDS output\n"); ++ type = DRM_MODE_ENCODER_LVDS; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); ++ if (!encoder) ++ return -ENOMEM; ++ ++ encoder->dcb_entry = entry; ++ encoder->or = ffs(entry->or) - 1; ++ ++ encoder->dual_link = nouveau_duallink; ++ ++ /* Set function pointers. */ ++ encoder->set_clock_mode = nv50_sor_set_clock_mode; ++ ++ drm_encoder_init(dev, &encoder->base, &nv50_sor_encoder_funcs, type); ++ drm_encoder_helper_add(&encoder->base, &nv50_sor_helper_funcs); ++ ++ /* I've never seen possible crtc's restricted. */ ++ encoder->base.possible_crtcs = 3; ++ encoder->base.possible_clones = 0; ++ ++ /* Some default state, unknown what it precisely means. */ ++ if (encoder->base.encoder_type == DRM_MODE_ENCODER_TMDS) { ++ int or = encoder->or; ++ ++ nv_wr32(NV50_PDISPLAY_SOR_REGS_UNK_00C(or), 0x03010700); ++ nv_wr32(NV50_PDISPLAY_SOR_REGS_UNK_010(or), 0x0000152f); ++ nv_wr32(NV50_PDISPLAY_SOR_REGS_UNK_014(or), 0x00000000); ++ nv_wr32(NV50_PDISPLAY_SOR_REGS_UNK_018(or), 0x00245af8); ++ } ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h +new file mode 100644 +index 0000000..6f142b3 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nvreg.h +@@ -0,0 +1,498 @@ ++/* $XConsortium: nvreg.h /main/2 1996/10/28 05:13:41 kaleb $ */ ++/* ++ * Copyright 1996-1997 David J. McKay ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF ++ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h,v 1.6 2002/01/25 21:56:06 tsi Exp $ */ ++ ++#ifndef __NVREG_H_ ++#define __NVREG_H_ ++ ++#define NV_PMC_OFFSET 0x00000000 ++#define NV_PMC_SIZE 0x00001000 ++ ++#define NV_PBUS_OFFSET 0x00001000 ++#define NV_PBUS_SIZE 0x00001000 ++ ++#define NV_PFIFO_OFFSET 0x00002000 ++#define NV_PFIFO_SIZE 0x00002000 ++ ++#define NV_HDIAG_OFFSET 0x00005000 ++#define NV_HDIAG_SIZE 0x00001000 ++ ++#define NV_PRAM_OFFSET 0x00006000 ++#define NV_PRAM_SIZE 0x00001000 ++ ++#define NV_PVIDEO_OFFSET 0x00008000 ++#define NV_PVIDEO_SIZE 0x00001000 ++ ++#define NV_PTIMER_OFFSET 0x00009000 ++#define NV_PTIMER_SIZE 0x00001000 ++ ++#define NV_PPM_OFFSET 0x0000A000 ++#define NV_PPM_SIZE 0x00001000 ++ ++#define NV_PRMVGA_OFFSET 0x000A0000 ++#define NV_PRMVGA_SIZE 0x00020000 ++ ++#define NV_PRMVIO0_OFFSET 0x000C0000 ++#define NV_PRMVIO_SIZE 0x00002000 ++#define NV_PRMVIO1_OFFSET 0x000C2000 ++ ++#define NV_PFB_OFFSET 0x00100000 ++#define NV_PFB_SIZE 0x00001000 ++ ++#define NV_PEXTDEV_OFFSET 0x00101000 ++#define NV_PEXTDEV_SIZE 0x00001000 ++ ++#define NV_PME_OFFSET 0x00200000 ++#define NV_PME_SIZE 0x00001000 ++ ++#define NV_PROM_OFFSET 0x00300000 ++#define NV_PROM_SIZE 0x00010000 ++ ++#define NV_PGRAPH_OFFSET 0x00400000 ++#define NV_PGRAPH_SIZE 0x00010000 ++ ++#define NV_PCRTC0_OFFSET 0x00600000 ++#define NV_PCRTC0_SIZE 0x00002000 /* empirical */ ++ ++#define NV_PRMCIO0_OFFSET 0x00601000 ++#define NV_PRMCIO_SIZE 0x00002000 ++#define NV_PRMCIO1_OFFSET 0x00603000 ++ ++#define NV50_DISPLAY_OFFSET 0x00610000 ++#define NV50_DISPLAY_SIZE 0x0000FFFF ++ ++#define NV_PRAMDAC0_OFFSET 0x00680000 ++#define NV_PRAMDAC0_SIZE 0x00002000 ++ ++#define NV_PRMDIO0_OFFSET 0x00681000 ++#define NV_PRMDIO_SIZE 0x00002000 ++#define NV_PRMDIO1_OFFSET 0x00683000 ++ ++#define NV_PRAMIN_OFFSET 0x00700000 ++#define NV_PRAMIN_SIZE 0x00100000 ++ ++#define NV_FIFO_OFFSET 0x00800000 ++#define NV_FIFO_SIZE 0x00800000 ++ ++#define NV_PMC_BOOT_0 0x00000000 ++#define NV_PMC_ENABLE 0x00000200 ++ ++#define NV_VIO_VSE2 0x000003c3 ++#define NV_VIO_SRX 0x000003c4 ++ ++#define NV_CIO_CRX__COLOR 0x000003d4 ++#define NV_CIO_CR__COLOR 0x000003d5 ++ ++#define NV_PBUS_DEBUG_1 0x00001084 ++#define NV_PBUS_DEBUG_4 0x00001098 ++#define NV_PBUS_DEBUG_DUALHEAD_CTL 0x000010f0 ++#define NV_PBUS_POWERCTRL_1 0x00001584 ++#define NV_PBUS_POWERCTRL_2 0x00001588 ++#define NV_PBUS_POWERCTRL_4 0x00001590 ++#define NV_PBUS_PCI_NV_19 0x0000184C ++#define NV_PBUS_PCI_NV_20 0x00001850 ++# define NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED (0 << 0) ++# define NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED (1 << 0) ++ ++#define NV_PFIFO_RAMHT 0x00002210 ++ ++#define NV_PRMVIO_MISC__WRITE 0x000c03c2 ++#define NV_PRMVIO_SRX 0x000c03c4 ++#define NV_PRMVIO_SR 0x000c03c5 ++# define NV_VIO_SR_RESET_INDEX 0x00 ++# define NV_VIO_SR_CLOCK_INDEX 0x01 ++# define NV_VIO_SR_PLANE_MASK_INDEX 0x02 ++# define NV_VIO_SR_CHAR_MAP_INDEX 0x03 ++# define NV_VIO_SR_MEM_MODE_INDEX 0x04 ++#define NV_PRMVIO_MISC__READ 0x000c03cc ++#define NV_PRMVIO_GRX 0x000c03ce ++#define NV_PRMVIO_GX 0x000c03cf ++# define NV_VIO_GX_SR_INDEX 0x00 ++# define NV_VIO_GX_SREN_INDEX 0x01 ++# define NV_VIO_GX_CCOMP_INDEX 0x02 ++# define NV_VIO_GX_ROP_INDEX 0x03 ++# define NV_VIO_GX_READ_MAP_INDEX 0x04 ++# define NV_VIO_GX_MODE_INDEX 0x05 ++# define NV_VIO_GX_MISC_INDEX 0x06 ++# define NV_VIO_GX_DONT_CARE_INDEX 0x07 ++# define NV_VIO_GX_BIT_MASK_INDEX 0x08 ++ ++#define NV_PFB_BOOT_0 0x00100000 ++#define NV_PFB_CFG0 0x00100200 ++#define NV_PFB_CFG1 0x00100204 ++#define NV_PFB_CSTATUS 0x0010020C ++#define NV_PFB_REFCTRL 0x00100210 ++# define NV_PFB_REFCTRL_VALID_1 (1 << 31) ++#define NV_PFB_PAD 0x0010021C ++# define NV_PFB_PAD_CKE_NORMAL (1 << 0) ++#define NV_PFB_TILE_NV10 0x00100240 ++#define NV_PFB_TILE_SIZE_NV10 0x00100244 ++#define NV_PFB_REF 0x001002D0 ++# define NV_PFB_REF_CMD_REFRESH (1 << 0) ++#define NV_PFB_PRE 0x001002D4 ++# define NV_PFB_PRE_CMD_PRECHARGE (1 << 0) ++#define NV_PFB_CLOSE_PAGE2 0x0010033C ++#define NV_PFB_TILE_NV40 0x00100600 ++#define NV_PFB_TILE_SIZE_NV40 0x00100604 ++ ++#define NV_PEXTDEV_BOOT_0 0x00101000 ++# define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12) ++#define NV_PEXTDEV_BOOT_3 0x0010100c ++ ++#define NV_PCRTC_INTR_0 0x00600100 ++# define NV_PCRTC_INTR_0_VBLANK (1 << 0) ++#define NV_PCRTC_INTR_EN_0 0x00600140 ++#define NV_PCRTC_START 0x00600800 ++#define NV_PCRTC_CONFIG 0x00600804 ++# define NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA (1 << 0) ++# define NV_PCRTC_CONFIG_START_ADDRESS_HSYNC (2 << 0) ++#define NV_PCRTC_CURSOR_CONFIG 0x00600810 ++# define NV_PCRTC_CURSOR_CONFIG_ENABLE_ENABLE (1 << 0) ++# define NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE (1 << 4) ++# define NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM (1 << 8) ++# define NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32 (1 << 12) ++# define NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64 (1 << 16) ++# define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_32 (2 << 24) ++# define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64 (4 << 24) ++# define NV_PCRTC_CURSOR_CONFIG_CUR_BLEND_ALPHA (1 << 28) ++ ++/* note: PCRTC_GPIO is not available on nv10, and in fact aliases 0x600810 */ ++#define NV_PCRTC_GPIO 0x00600818 ++#define NV_PCRTC_GPIO_EXT 0x0060081c ++#define NV_PCRTC_830 0x00600830 ++#define NV_PCRTC_834 0x00600834 ++#define NV_PCRTC_850 0x00600850 ++#define NV_PCRTC_ENGINE_CTRL 0x00600860 ++# define NV_CRTC_FSEL_I2C (1 << 4) ++# define NV_CRTC_FSEL_OVERLAY (1 << 12) ++ ++#define NV_PRMCIO_ARX 0x006013c0 ++#define NV_PRMCIO_AR__WRITE 0x006013c0 ++#define NV_PRMCIO_AR__READ 0x006013c1 ++# define NV_CIO_AR_MODE_INDEX 0x10 ++# define NV_CIO_AR_OSCAN_INDEX 0x11 ++# define NV_CIO_AR_PLANE_INDEX 0x12 ++# define NV_CIO_AR_HPP_INDEX 0x13 ++# define NV_CIO_AR_CSEL_INDEX 0x14 ++#define NV_PRMCIO_CRX__COLOR 0x006013d4 ++#define NV_PRMCIO_CR__COLOR 0x006013d5 ++ /* Standard VGA CRTC registers */ ++# define NV_CIO_CR_HDT_INDEX 0x00 /* horizontal display total */ ++# define NV_CIO_CR_HDE_INDEX 0x01 /* horizontal display end */ ++# define NV_CIO_CR_HBS_INDEX 0x02 /* horizontal blanking start */ ++# define NV_CIO_CR_HBE_INDEX 0x03 /* horizontal blanking end */ ++# define NV_CIO_CR_HBE_4_0 4:0 ++# define NV_CIO_CR_HRS_INDEX 0x04 /* horizontal retrace start */ ++# define NV_CIO_CR_HRE_INDEX 0x05 /* horizontal retrace end */ ++# define NV_CIO_CR_HRE_4_0 4:0 ++# define NV_CIO_CR_HRE_HBE_5 7:7 ++# define NV_CIO_CR_VDT_INDEX 0x06 /* vertical display total */ ++# define NV_CIO_CR_OVL_INDEX 0x07 /* overflow bits */ ++# define NV_CIO_CR_OVL_VDT_8 0:0 ++# define NV_CIO_CR_OVL_VDE_8 1:1 ++# define NV_CIO_CR_OVL_VRS_8 2:2 ++# define NV_CIO_CR_OVL_VBS_8 3:3 ++# define NV_CIO_CR_OVL_VDT_9 5:5 ++# define NV_CIO_CR_OVL_VDE_9 6:6 ++# define NV_CIO_CR_OVL_VRS_9 7:7 ++# define NV_CIO_CR_RSAL_INDEX 0x08 /* normally "preset row scan" */ ++# define NV_CIO_CR_CELL_HT_INDEX 0x09 /* cell height?! normally "max scan line" */ ++# define NV_CIO_CR_CELL_HT_VBS_9 5:5 ++# define NV_CIO_CR_CELL_HT_SCANDBL 7:7 ++# define NV_CIO_CR_CURS_ST_INDEX 0x0a /* cursor start */ ++# define NV_CIO_CR_CURS_END_INDEX 0x0b /* cursor end */ ++# define NV_CIO_CR_SA_HI_INDEX 0x0c /* screen start address high */ ++# define NV_CIO_CR_SA_LO_INDEX 0x0d /* screen start address low */ ++# define NV_CIO_CR_TCOFF_HI_INDEX 0x0e /* cursor offset high */ ++# define NV_CIO_CR_TCOFF_LO_INDEX 0x0f /* cursor offset low */ ++# define NV_CIO_CR_VRS_INDEX 0x10 /* vertical retrace start */ ++# define NV_CIO_CR_VRE_INDEX 0x11 /* vertical retrace end */ ++# define NV_CIO_CR_VRE_3_0 3:0 ++# define NV_CIO_CR_VDE_INDEX 0x12 /* vertical display end */ ++# define NV_CIO_CR_OFFSET_INDEX 0x13 /* sets screen pitch */ ++# define NV_CIO_CR_ULINE_INDEX 0x14 /* underline location */ ++# define NV_CIO_CR_VBS_INDEX 0x15 /* vertical blank start */ ++# define NV_CIO_CR_VBE_INDEX 0x16 /* vertical blank end */ ++# define NV_CIO_CR_MODE_INDEX 0x17 /* crtc mode control */ ++# define NV_CIO_CR_LCOMP_INDEX 0x18 /* line compare */ ++ /* Extended VGA CRTC registers */ ++# define NV_CIO_CRE_RPC0_INDEX 0x19 /* repaint control 0 */ ++# define NV_CIO_CRE_RPC0_OFFSET_10_8 7:5 ++# define NV_CIO_CRE_RPC1_INDEX 0x1a /* repaint control 1 */ ++# define NV_CIO_CRE_RPC1_LARGE 2:2 ++# define NV_CIO_CRE_FF_INDEX 0x1b /* fifo control */ ++# define NV_CIO_CRE_ENH_INDEX 0x1c /* enhanced? */ ++# define NV_CIO_SR_LOCK_INDEX 0x1f /* crtc lock */ ++# define NV_CIO_SR_UNLOCK_RW_VALUE 0x57 ++# define NV_CIO_SR_LOCK_VALUE 0x99 ++# define NV_CIO_CRE_FFLWM__INDEX 0x20 /* fifo low water mark */ ++# define NV_CIO_CRE_21 0x21 /* referred to by some .scp as `shadow lock' */ ++# define NV_CIO_CRE_LSR_INDEX 0x25 /* ? */ ++# define NV_CIO_CRE_LSR_VDT_10 0:0 ++# define NV_CIO_CRE_LSR_VDE_10 1:1 ++# define NV_CIO_CRE_LSR_VRS_10 2:2 ++# define NV_CIO_CRE_LSR_VBS_10 3:3 ++# define NV_CIO_CRE_LSR_HBE_6 4:4 ++# define NV_CIO_CR_ARX_INDEX 0x26 /* attribute index -- ro copy of 0x60.3c0 */ ++# define NV_CIO_CRE_CHIP_ID_INDEX 0x27 /* chip revision */ ++# define NV_CIO_CRE_PIXEL_INDEX 0x28 ++# define NV_CIO_CRE_HEB__INDEX 0x2d /* horizontal extra bits? */ ++# define NV_CIO_CRE_HEB_HDT_8 0:0 ++# define NV_CIO_CRE_HEB_HDE_8 1:1 ++# define NV_CIO_CRE_HEB_HBS_8 2:2 ++# define NV_CIO_CRE_HEB_HRS_8 3:3 ++# define NV_CIO_CRE_HEB_ILC_8 4:4 ++# define NV_CIO_CRE_2E 0x2e /* some scratch or dummy reg to force writes to sink in */ ++# define NV_CIO_CRE_HCUR_ADDR2_INDEX 0x2f /* cursor */ ++# define NV_CIO_CRE_HCUR_ADDR0_INDEX 0x30 /* pixmap */ ++# define NV_CIO_CRE_HCUR_ADDR0_ADR 6:0 ++# define NV_CIO_CRE_HCUR_ASI 7:7 ++# define NV_CIO_CRE_HCUR_ADDR1_INDEX 0x31 /* address */ ++# define NV_CIO_CRE_HCUR_ADDR1_ENABLE 0:0 ++# define NV_CIO_CRE_HCUR_ADDR1_CUR_DBL 1:1 ++# define NV_CIO_CRE_HCUR_ADDR1_ADR 7:2 ++# define NV_CIO_CRE_LCD__INDEX 0x33 ++# define NV_CIO_CRE_LCD_LCD_SELECT 0:0 ++# define NV_CIO_CRE_DDC0_STATUS__INDEX 0x36 ++# define NV_CIO_CRE_DDC0_WR__INDEX 0x37 ++# define NV_CIO_CRE_ILACE__INDEX 0x39 /* interlace */ ++# define NV_CIO_CRE_SCRATCH3__INDEX 0x3b ++# define NV_CIO_CRE_SCRATCH4__INDEX 0x3c ++# define NV_CIO_CRE_DDC_STATUS__INDEX 0x3e ++# define NV_CIO_CRE_DDC_WR__INDEX 0x3f ++# define NV_CIO_CRE_EBR_INDEX 0x41 /* extra bits ? (vertical) */ ++# define NV_CIO_CRE_EBR_VDT_11 0:0 ++# define NV_CIO_CRE_EBR_VDE_11 2:2 ++# define NV_CIO_CRE_EBR_VRS_11 4:4 ++# define NV_CIO_CRE_EBR_VBS_11 6:6 ++# define NV_CIO_CRE_44 0x44 /* head control */ ++# define NV_CIO_CRE_CSB 0x45 /* colour saturation boost */ ++# define NV_CIO_CRE_RCR 0x46 ++# define NV_CIO_CRE_RCR_ENDIAN_BIG 7:7 ++# define NV_CIO_CRE_47 0x47 /* extended fifo lwm, used on nv30+ */ ++# define NV_CIO_CRE_4B 0x4b /* given patterns in 0x[2-3][a-c] regs, probably scratch 6 */ ++# define NV_CIO_CRE_TVOUT_LATENCY 0x52 ++# define NV_CIO_CRE_53 0x53 /* `fp_htiming' according to Haiku */ ++# define NV_CIO_CRE_54 0x54 /* `fp_vtiming' according to Haiku */ ++# define NV_CIO_CRE_57 0x57 /* index reg for cr58 */ ++# define NV_CIO_CRE_58 0x58 /* data reg for cr57 */ ++# define NV_CIO_CRE_59 0x59 ++# define NV_CIO_CRE_5B 0x5B /* newer colour saturation reg */ ++# define NV_CIO_CRE_85 0x85 ++# define NV_CIO_CRE_86 0x86 ++#define NV_PRMCIO_INP0__COLOR 0x006013da ++ ++#define NV_PRAMDAC_CU_START_POS 0x00680300 ++# define NV_PRAMDAC_CU_START_POS_X 15:0 ++# define NV_PRAMDAC_CU_START_POS_Y 31:16 ++#define NV_RAMDAC_NV10_CURSYNC 0x00680404 ++ ++#define NV_PRAMDAC_NVPLL_COEFF 0x00680500 ++#define NV_PRAMDAC_MPLL_COEFF 0x00680504 ++#define NV_PRAMDAC_VPLL_COEFF 0x00680508 ++# define NV30_RAMDAC_ENABLE_VCO2 (8 << 4) ++ ++#define NV_PRAMDAC_PLL_COEFF_SELECT 0x0068050c ++# define NV_RAMDAC_PLL_SELECT_USE_VPLL2_TRUE (4 << 0) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL (1 << 8) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL (2 << 8) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL (4 << 8) ++# define NV_RAMDAC_PLL_SELECT_PLL_SOURCE_VPLL2 (8 << 8) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2 (1 << 28) ++# define NV_RAMDAC_PLL_SELECT_VCLK2_RATIO_DB2 (2 << 28) ++ ++#define NV_PRAMDAC_PLL_SETUP_CONTROL 0x00680510 ++#define NV_RAMDAC_VPLL2 0x00680520 ++#define NV_PRAMDAC_SEL_CLK 0x00680524 ++#define NV_RAMDAC_DITHER_NV11 0x00680528 ++#define NV_PRAMDAC_DACCLK 0x0068052c ++# define NV_PRAMDAC_DACCLK_SEL_DACCLK (1 << 0) ++ ++#define NV_RAMDAC_NVPLL_B 0x00680570 ++#define NV_RAMDAC_MPLL_B 0x00680574 ++#define NV_RAMDAC_VPLL_B 0x00680578 ++#define NV_RAMDAC_VPLL2_B 0x0068057c ++# define NV31_RAMDAC_ENABLE_VCO2 (8 << 28) ++#define NV_PRAMDAC_580 0x00680580 ++# define NV_RAMDAC_580_VPLL1_ACTIVE (1 << 8) ++# define NV_RAMDAC_580_VPLL2_ACTIVE (1 << 28) ++ ++#define NV_PRAMDAC_GENERAL_CONTROL 0x00680600 ++#define NV_PRAMDAC_TEST_CONTROL 0x00680608 ++# define NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED (1 << 12) ++# define NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF (1 << 16) ++# define NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI (1 << 28) ++#define NV_PRAMDAC_TESTPOINT_DATA 0x00680610 ++# define NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK (8 << 28) ++#define NV_PRAMDAC_630 0x00680630 ++#define NV_PRAMDAC_634 0x00680634 ++ ++#define NV_PRAMDAC_FP_VDISPLAY_END 0x00680800 ++#define NV_PRAMDAC_FP_VTOTAL 0x00680804 ++#define NV_PRAMDAC_FP_VCRTC 0x00680808 ++#define NV_PRAMDAC_FP_VSYNC_START 0x0068080c ++#define NV_PRAMDAC_FP_VSYNC_END 0x00680810 ++#define NV_PRAMDAC_FP_VVALID_START 0x00680814 ++#define NV_PRAMDAC_FP_VVALID_END 0x00680818 ++#define NV_PRAMDAC_FP_HDISPLAY_END 0x00680820 ++#define NV_PRAMDAC_FP_HTOTAL 0x00680824 ++#define NV_PRAMDAC_FP_HCRTC 0x00680828 ++#define NV_PRAMDAC_FP_HSYNC_START 0x0068082c ++#define NV_PRAMDAC_FP_HSYNC_END 0x00680830 ++#define NV_PRAMDAC_FP_HVALID_START 0x00680834 ++#define NV_PRAMDAC_FP_HVALID_END 0x00680838 ++ ++#define NV_RAMDAC_FP_DITHER 0x0068083c ++#define NV_PRAMDAC_FP_TG_CONTROL 0x00680848 ++# define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS (1 << 0) ++# define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE (2 << 0) ++# define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS (1 << 4) ++# define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE (2 << 4) ++# define NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE (0 << 8) ++# define NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER (1 << 8) ++# define NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE (2 << 8) ++# define NV_PRAMDAC_FP_TG_CONTROL_READ_PROG (1 << 20) ++# define NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 (1 << 24) ++# define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS (1 << 28) ++# define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE (2 << 28) ++#define NV_PRAMDAC_850 0x00680850 ++#define NV_PRAMDAC_85C 0x0068085c ++#define NV_PRAMDAC_FP_DEBUG_0 0x00680880 ++# define NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE (1 << 0) ++# define NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE (1 << 4) ++/* This doesn't seem to be essential for tmds, but still often set */ ++# define NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED (8 << 4) ++# define NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR (1 << 8) ++# define NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR (1 << 12) ++# define NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND (1 << 20) ++# define NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND (1 << 24) ++#define NV_PRAMDAC_FP_DEBUG_1 0x00680884 ++# define NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE 11:0 ++# define NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE (1 << 12) ++# define NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE 27:16 ++# define NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE (1 << 28) ++#define NV_PRAMDAC_FP_DEBUG_2 0x00680888 ++#define NV_PRAMDAC_FP_DEBUG_3 0x0068088C ++ ++/* Some unknown regs, purely for NV30 it seems. */ ++#define NV_PRAMDAC_890 0x00680890 ++#define NV_PRAMDAC_89C 0x0068089C ++ ++/* see NV_PRAMDAC_INDIR_TMDS in rules.xml */ ++#define NV_PRAMDAC_FP_TMDS_CONTROL 0x006808b0 ++# define NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE (1 << 16) ++#define NV_PRAMDAC_FP_TMDS_DATA 0x006808b4 ++ ++/* Some kind of switch */ ++#define NV_PRAMDAC_900 0x00680900 ++#define NV_PRAMDAC_A20 0x00680A20 ++#define NV_PRAMDAC_A24 0x00680A24 ++#define NV_PRAMDAC_A34 0x00680A34 ++ ++/* names fabricated from NV_USER_DAC info */ ++#define NV_PRMDIO_PIXEL_MASK 0x006813c6 ++# define NV_PRMDIO_PIXEL_MASK_MASK 0xff ++#define NV_PRMDIO_READ_MODE_ADDRESS 0x006813c7 ++#define NV_PRMDIO_WRITE_MODE_ADDRESS 0x006813c8 ++#define NV_PRMDIO_PALETTE_DATA 0x006813c9 ++ ++#define NV_PGRAPH_DEBUG_0 0x00400080 ++#define NV_PGRAPH_DEBUG_1 0x00400084 ++#define NV_PGRAPH_DEBUG_2_NV04 0x00400088 ++#define NV_PGRAPH_DEBUG_2 0x00400620 ++#define NV_PGRAPH_DEBUG_3 0x0040008c ++#define NV_PGRAPH_DEBUG_4 0x00400090 ++#define NV_PGRAPH_INTR 0x00400100 ++#define NV_PGRAPH_INTR_EN 0x00400140 ++#define NV_PGRAPH_CTX_CONTROL 0x00400144 ++#define NV_PGRAPH_CTX_CONTROL_NV04 0x00400170 ++#define NV_PGRAPH_ABS_UCLIP_XMIN 0x0040053C ++#define NV_PGRAPH_ABS_UCLIP_YMIN 0x00400540 ++#define NV_PGRAPH_ABS_UCLIP_XMAX 0x00400544 ++#define NV_PGRAPH_ABS_UCLIP_YMAX 0x00400548 ++#define NV_PGRAPH_BETA_AND 0x00400608 ++#define NV_PGRAPH_LIMIT_VIOL_PIX 0x00400610 ++#define NV_PGRAPH_BOFFSET0 0x00400640 ++#define NV_PGRAPH_BOFFSET1 0x00400644 ++#define NV_PGRAPH_BOFFSET2 0x00400648 ++#define NV_PGRAPH_BLIMIT0 0x00400684 ++#define NV_PGRAPH_BLIMIT1 0x00400688 ++#define NV_PGRAPH_BLIMIT2 0x0040068c ++#define NV_PGRAPH_STATUS 0x00400700 ++#define NV_PGRAPH_SURFACE 0x00400710 ++#define NV_PGRAPH_STATE 0x00400714 ++#define NV_PGRAPH_FIFO 0x00400720 ++#define NV_PGRAPH_PATTERN_SHAPE 0x00400810 ++#define NV_PGRAPH_TILE 0x00400b00 ++ ++#define NV_PVIDEO_INTR_EN 0x00008140 ++#define NV_PVIDEO_BUFFER 0x00008700 ++#define NV_PVIDEO_STOP 0x00008704 ++#define NV_PVIDEO_UVPLANE_BASE(buff) (0x00008800+(buff)*4) ++#define NV_PVIDEO_UVPLANE_LIMIT(buff) (0x00008808+(buff)*4) ++#define NV_PVIDEO_UVPLANE_OFFSET_BUFF(buff) (0x00008820+(buff)*4) ++#define NV_PVIDEO_BASE(buff) (0x00008900+(buff)*4) ++#define NV_PVIDEO_LIMIT(buff) (0x00008908+(buff)*4) ++#define NV_PVIDEO_LUMINANCE(buff) (0x00008910+(buff)*4) ++#define NV_PVIDEO_CHROMINANCE(buff) (0x00008918+(buff)*4) ++#define NV_PVIDEO_OFFSET_BUFF(buff) (0x00008920+(buff)*4) ++#define NV_PVIDEO_SIZE_IN(buff) (0x00008928+(buff)*4) ++#define NV_PVIDEO_POINT_IN(buff) (0x00008930+(buff)*4) ++#define NV_PVIDEO_DS_DX(buff) (0x00008938+(buff)*4) ++#define NV_PVIDEO_DT_DY(buff) (0x00008940+(buff)*4) ++#define NV_PVIDEO_POINT_OUT(buff) (0x00008948+(buff)*4) ++#define NV_PVIDEO_SIZE_OUT(buff) (0x00008950+(buff)*4) ++#define NV_PVIDEO_FORMAT(buff) (0x00008958+(buff)*4) ++# define NV_PVIDEO_FORMAT_PLANAR (1 << 0) ++# define NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8 (1 << 16) ++# define NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY (1 << 20) ++# define NV_PVIDEO_FORMAT_MATRIX_ITURBT709 (1 << 24) ++#define NV_PVIDEO_COLOR_KEY 0x00008B00 ++ ++/* NV04 overlay defines from VIDIX & Haiku */ ++#define NV_PVIDEO_INTR_EN_0 0x00680140 ++#define NV_PVIDEO_STEP_SIZE 0x00680200 ++#define NV_PVIDEO_CONTROL_Y 0x00680204 ++#define NV_PVIDEO_CONTROL_X 0x00680208 ++#define NV_PVIDEO_BUFF0_START_ADDRESS 0x0068020c ++#define NV_PVIDEO_BUFF0_PITCH_LENGTH 0x00680214 ++#define NV_PVIDEO_BUFF0_OFFSET 0x0068021c ++#define NV_PVIDEO_BUFF1_START_ADDRESS 0x00680210 ++#define NV_PVIDEO_BUFF1_PITCH_LENGTH 0x00680218 ++#define NV_PVIDEO_BUFF1_OFFSET 0x00680220 ++#define NV_PVIDEO_OE_STATE 0x00680224 ++#define NV_PVIDEO_SU_STATE 0x00680228 ++#define NV_PVIDEO_RM_STATE 0x0068022c ++#define NV_PVIDEO_WINDOW_START 0x00680230 ++#define NV_PVIDEO_WINDOW_SIZE 0x00680234 ++#define NV_PVIDEO_FIFO_THRES_SIZE 0x00680238 ++#define NV_PVIDEO_FIFO_BURST_LENGTH 0x0068023c ++#define NV_PVIDEO_KEY 0x00680240 ++#define NV_PVIDEO_OVERLAY 0x00680244 ++#define NV_PVIDEO_RED_CSC_OFFSET 0x00680280 ++#define NV_PVIDEO_GREEN_CSC_OFFSET 0x00680284 ++#define NV_PVIDEO_BLUE_CSC_OFFSET 0x00680288 ++#define NV_PVIDEO_CSC_ADJUST 0x0068028c ++ ++#endif +diff --git a/include/drm/Kbuild b/include/drm/Kbuild +index b940fdf..cfa6af4 100644 +--- a/include/drm/Kbuild ++++ b/include/drm/Kbuild +@@ -8,3 +8,4 @@ unifdef-y += radeon_drm.h + unifdef-y += sis_drm.h + unifdef-y += savage_drm.h + unifdef-y += via_drm.h ++unifdef-y += nouveau_drm.h +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 04fbd1e..f2a6bff 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1267,6 +1267,8 @@ extern void drm_idlelock_release(struct drm_lock_data *lock_data); + extern int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv); + + /* Buffer management support (drm_bufs.h) */ ++extern struct drm_map_list *drm_find_matching_map(struct drm_device *dev, ++ drm_local_map_t *map); + extern int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc * request); + extern int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc * request); + extern int drm_addmap(struct drm_device *dev, resource_size_t offset, +diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h +new file mode 100644 +index 0000000..4147f35 +--- /dev/null ++++ b/include/drm/nouveau_drm.h +@@ -0,0 +1,299 @@ ++/* ++ * Copyright 2005 Stephane Marchesin. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef __NOUVEAU_DRM_H__ ++#define __NOUVEAU_DRM_H__ ++ ++#define NOUVEAU_DRM_HEADER_PATCHLEVEL 12 ++ ++struct drm_nouveau_channel_alloc { ++ uint32_t fb_ctxdma_handle; ++ uint32_t tt_ctxdma_handle; ++ ++ int channel; ++ ++ /* Notifier memory */ ++ drm_handle_t notifier; ++ int notifier_size; ++ ++ /* DRM-enforced subchannel assignments */ ++ struct { ++ uint32_t handle; ++ uint32_t grclass; ++ } subchan[8]; ++ uint32_t nr_subchan; ++ ++/* !MM_ENABLED ONLY */ ++ uint32_t put_base; ++ /* FIFO control regs */ ++ drm_handle_t ctrl; ++ int ctrl_size; ++ /* DMA command buffer */ ++ drm_handle_t cmdbuf; ++ int cmdbuf_size; ++}; ++ ++struct drm_nouveau_channel_free { ++ int channel; ++}; ++ ++struct drm_nouveau_grobj_alloc { ++ int channel; ++ uint32_t handle; ++ int class; ++}; ++ ++#define NOUVEAU_MEM_ACCESS_RO 1 ++#define NOUVEAU_MEM_ACCESS_WO 2 ++#define NOUVEAU_MEM_ACCESS_RW 3 ++struct drm_nouveau_notifierobj_alloc { ++ int channel; ++ uint32_t handle; ++ int count; ++ ++ uint32_t offset; ++}; ++ ++struct drm_nouveau_gpuobj_free { ++ int channel; ++ uint32_t handle; ++}; ++ ++/* This is needed to avoid a race condition. ++ * Otherwise you may be writing in the fetch area. ++ * Is this large enough, as it's only 32 bytes, and the maximum fetch size is 256 bytes? ++ */ ++#define NOUVEAU_DMA_SKIPS 8 ++ ++#define NOUVEAU_MEM_FB 0x00000001 ++#define NOUVEAU_MEM_AGP 0x00000002 ++#define NOUVEAU_MEM_FB_ACCEPTABLE 0x00000004 ++#define NOUVEAU_MEM_AGP_ACCEPTABLE 0x00000008 ++#define NOUVEAU_MEM_PCI 0x00000010 ++#define NOUVEAU_MEM_PCI_ACCEPTABLE 0x00000020 ++#define NOUVEAU_MEM_PINNED 0x00000040 ++#define NOUVEAU_MEM_USER_BACKED 0x00000080 ++#define NOUVEAU_MEM_MAPPED 0x00000100 ++#define NOUVEAU_MEM_TILE 0x00000200 ++#define NOUVEAU_MEM_TILE_ZETA 0x00000400 ++#define NOUVEAU_MEM_INSTANCE 0x01000000 /* internal */ ++#define NOUVEAU_MEM_NOTIFIER 0x02000000 /* internal */ ++#define NOUVEAU_MEM_NOVM 0x04000000 /* internal */ ++#define NOUVEAU_MEM_USER 0x08000000 /* internal */ ++#define NOUVEAU_MEM_INTERNAL (NOUVEAU_MEM_INSTANCE | \ ++ NOUVEAU_MEM_NOTIFIER | \ ++ NOUVEAU_MEM_NOVM | \ ++ NOUVEAU_MEM_USER) ++ ++struct drm_nouveau_mem_alloc { ++ int flags; ++ int alignment; ++ uint64_t size; // in bytes ++ uint64_t offset; ++ drm_handle_t map_handle; ++}; ++ ++struct drm_nouveau_mem_free { ++ uint64_t offset; ++ int flags; ++}; ++ ++struct drm_nouveau_mem_tile { ++ uint64_t offset; ++ uint64_t delta; ++ uint64_t size; ++ int flags; ++}; ++ ++/* FIXME : maybe unify {GET,SET}PARAMs */ ++#define NOUVEAU_GETPARAM_PCI_VENDOR 3 ++#define NOUVEAU_GETPARAM_PCI_DEVICE 4 ++#define NOUVEAU_GETPARAM_BUS_TYPE 5 ++#define NOUVEAU_GETPARAM_FB_PHYSICAL 6 ++#define NOUVEAU_GETPARAM_AGP_PHYSICAL 7 ++#define NOUVEAU_GETPARAM_FB_SIZE 8 ++#define NOUVEAU_GETPARAM_AGP_SIZE 9 ++#define NOUVEAU_GETPARAM_PCI_PHYSICAL 10 ++#define NOUVEAU_GETPARAM_CHIPSET_ID 11 ++#define NOUVEAU_GETPARAM_MM_ENABLED 12 ++#define NOUVEAU_GETPARAM_VM_VRAM_BASE 13 ++struct drm_nouveau_getparam { ++ uint64_t param; ++ uint64_t value; ++}; ++ ++#define NOUVEAU_SETPARAM_CMDBUF_LOCATION 1 ++#define NOUVEAU_SETPARAM_CMDBUF_SIZE 2 ++struct drm_nouveau_setparam { ++ uint64_t param; ++ uint64_t value; ++}; ++ ++#define NOUVEAU_GEM_DOMAIN_CPU (1 << 0) ++#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) ++#define NOUVEAU_GEM_DOMAIN_GART (1 << 2) ++#define NOUVEAU_GEM_DOMAIN_NOMAP (1 << 3) ++#define NOUVEAU_GEM_DOMAIN_TILE (1 << 30) ++#define NOUVEAU_GEM_DOMAIN_TILE_ZETA (1 << 31) ++ ++struct drm_nouveau_gem_new { ++ uint64_t size; ++ uint32_t channel_hint; ++ uint32_t align; ++ uint32_t handle; ++ uint32_t domain; ++ uint32_t offset; ++}; ++ ++struct drm_nouveau_gem_pushbuf_bo { ++ uint64_t user_priv; ++ uint32_t handle; ++ uint32_t read_domains; ++ uint32_t write_domains; ++ uint32_t valid_domains; ++ uint32_t presumed_ok; ++ uint32_t presumed_domain; ++ uint64_t presumed_offset; ++}; ++ ++#define NOUVEAU_GEM_RELOC_LOW (1 << 0) ++#define NOUVEAU_GEM_RELOC_HIGH (1 << 1) ++#define NOUVEAU_GEM_RELOC_OR (1 << 2) ++struct drm_nouveau_gem_pushbuf_reloc { ++ uint32_t bo_index; ++ uint32_t reloc_index; ++ uint32_t flags; ++ uint32_t data; ++ uint32_t vor; ++ uint32_t tor; ++}; ++ ++#define NOUVEAU_GEM_MAX_BUFFERS 1024 ++#define NOUVEAU_GEM_MAX_RELOCS 1024 ++ ++struct drm_nouveau_gem_pushbuf { ++ uint32_t channel; ++ uint32_t nr_dwords; ++ uint32_t nr_buffers; ++ uint32_t nr_relocs; ++ uint64_t dwords; ++ uint64_t buffers; ++ uint64_t relocs; ++}; ++ ++struct drm_nouveau_gem_pushbuf_call { ++ uint32_t channel; ++ uint32_t handle; ++ uint32_t offset; ++ uint32_t nr_buffers; ++ uint32_t nr_relocs; ++ uint32_t pad0; ++ uint64_t buffers; ++ uint64_t relocs; ++}; ++ ++struct drm_nouveau_gem_pin { ++ uint32_t handle; ++ uint32_t domain; ++ uint64_t offset; ++}; ++ ++struct drm_nouveau_gem_unpin { ++ uint32_t handle; ++}; ++ ++struct drm_nouveau_gem_mmap { ++ uint32_t handle; ++ uint32_t pad; ++ uint64_t vaddr; ++}; ++ ++struct drm_nouveau_gem_cpu_prep { ++ uint32_t handle; ++}; ++ ++struct drm_nouveau_gem_cpu_fini { ++ uint32_t handle; ++}; ++ ++struct drm_nouveau_gem_tile { ++ uint32_t handle; ++ uint32_t delta; ++ uint32_t size; ++ uint32_t flags; ++}; ++ ++enum nouveau_card_type { ++ NV_UNKNOWN =0, ++ NV_04 =4, ++ NV_05 =5, ++ NV_10 =10, ++ NV_11 =11, ++ NV_17 =17, ++ NV_20 =20, ++ NV_30 =30, ++ NV_40 =40, ++ NV_44 =44, ++ NV_50 =50, ++ NV_LAST =0xffff, ++}; ++ ++enum nouveau_bus_type { ++ NV_AGP =0, ++ NV_PCI =1, ++ NV_PCIE =2, ++}; ++ ++#define NOUVEAU_MAX_SAREA_CLIPRECTS 16 ++ ++struct drm_nouveau_sarea { ++ /* the cliprects */ ++ struct drm_clip_rect boxes[NOUVEAU_MAX_SAREA_CLIPRECTS]; ++ unsigned int nbox; ++}; ++ ++#define DRM_NOUVEAU_CARD_INIT 0x00 ++#define DRM_NOUVEAU_GETPARAM 0x01 ++#define DRM_NOUVEAU_SETPARAM 0x02 ++#define DRM_NOUVEAU_CHANNEL_ALLOC 0x03 ++#define DRM_NOUVEAU_CHANNEL_FREE 0x04 ++#define DRM_NOUVEAU_GROBJ_ALLOC 0x05 ++#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x06 ++#define DRM_NOUVEAU_GPUOBJ_FREE 0x07 ++#define DRM_NOUVEAU_MEM_ALLOC 0x08 ++#define DRM_NOUVEAU_MEM_FREE 0x09 ++#define DRM_NOUVEAU_MEM_TILE 0x0a ++#define DRM_NOUVEAU_SUSPEND 0x0b ++#define DRM_NOUVEAU_RESUME 0x0c ++#define DRM_NOUVEAU_GEM_NEW 0x40 ++#define DRM_NOUVEAU_GEM_PUSHBUF 0x41 ++#define DRM_NOUVEAU_GEM_PUSHBUF_CALL 0x42 ++#define DRM_NOUVEAU_GEM_PIN 0x43 ++#define DRM_NOUVEAU_GEM_UNPIN 0x44 ++#define DRM_NOUVEAU_GEM_MMAP 0x45 ++#define DRM_NOUVEAU_GEM_CPU_PREP 0x46 ++#define DRM_NOUVEAU_GEM_CPU_FINI 0x47 ++#define DRM_NOUVEAU_GEM_TILE 0x48 ++ ++#endif /* __NOUVEAU_DRM_H__ */ diff --git a/packages/linux/patches/1818_drm-i915-resume-force-mode.diff b/packages/linux/patches/1818_drm-i915-resume-force-mode.diff new file mode 100644 index 0000000000..3e6c6484bf --- /dev/null +++ b/packages/linux/patches/1818_drm-i915-resume-force-mode.diff @@ -0,0 +1,50 @@ +http://lists.freedesktop.org/archives/intel-gfx/2009-February/001313.html + +--- a/drivers/gpu/drm/i915/i915_suspend.c.orig 2009-02-18 22:59:19.000000000 -0500 ++++ b/drivers/gpu/drm/i915/i915_suspend.c 2009-02-18 22:59:58.000000000 -0500 +@@ -28,6 +28,7 @@ + #include "drm.h" + #include "i915_drm.h" + #include "i915_drv.h" ++#include + + static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) + { +@@ -519,6 +520,8 @@ + + i915_restore_vga(dev); + ++ drm_helper_resume_force_mode(dev); ++ + return 0; + } + +From f5192bce8be69e5b33d7579bc282fef4d673e2c1 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Sun, 15 Mar 2009 13:55:55 +0100 +Subject: [PATCH] Fix i915 nomodeset NULL deref. during PM resume + +drm_helper_resume_force_mode() would crash while attempting to +iterate through crtc_list, which is uninitialized when is modesetting +disabled. +--- + drivers/gpu/drm/i915/i915_suspend.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c +index ef5fb6e..b138032 100644 +--- a/drivers/gpu/drm/i915/i915_suspend.c ++++ b/drivers/gpu/drm/i915/i915_suspend.c +@@ -520,7 +520,8 @@ int i915_restore_state(struct drm_device *dev) + + i915_restore_vga(dev); + +- drm_helper_resume_force_mode(dev); ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_helper_resume_force_mode(dev); + + return 0; + } +-- +1.6.2 + diff --git a/packages/linux/patches/1819_drm-intel-big-hammer.diff b/packages/linux/patches/1819_drm-intel-big-hammer.diff new file mode 100644 index 0000000000..e7047508d4 --- /dev/null +++ b/packages/linux/patches/1819_drm-intel-big-hammer.diff @@ -0,0 +1,16 @@ +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 37427e4..08af9db 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2553,6 +2553,11 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + + mutex_lock(&dev->struct_mutex); + ++ /* We don't get the flushing right for these chipsets, use the ++ * big hamer for now to avoid random crashiness. */ ++ if (IS_I855(dev) || IS_I865G(dev)) ++ wbinvd(); ++ + i915_verify_inactive(dev, __FILE__, __LINE__); + + if (dev_priv->mm.wedged) { diff --git a/packages/linux/patches/1821_drm-intel-lying-systems-without-lvds.diff b/packages/linux/patches/1821_drm-intel-lying-systems-without-lvds.diff new file mode 100644 index 0000000000..cc7fef2694 --- /dev/null +++ b/packages/linux/patches/1821_drm-intel-lying-systems-without-lvds.diff @@ -0,0 +1,95 @@ +[PATCH] drm: ignore LVDS on intel graphics systems that lie about having it + +There are a number of small form factor desktop systems with Intel mobile +graphics chips that lie and say they have an LVDS. With kernel mode-setting, +this becomes a problem, and makes native resolution boot go haywire -- for +example, my Dell Studio Hybrid, hooked to a 1920x1080 display claims to +have a 1024x768 LVDS, and the resulting graphical boot on the 1920x1080 +display uses only the top left 1024x768, and auto-configured X will end +up only 1024x768 as well. With this change, graphical boot and X +both do 1920x1080 as expected. + +Nb: one minor issue... Current Fedora rawhide, video playback using Xv +makes X go off into the weeds with this patch added... But that's a bug +elsewhere, still confident this patch DTRT. + +Signed-off-by: Jarod Wilson + +--- + drivers/gpu/drm/i915/intel_lvds.c | 46 ++++++++++++++++++++++++++++++------ + 1 files changed, 38 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 6619f26..4d64686 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -384,7 +384,51 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = { + .destroy = intel_lvds_enc_destroy, + }; + ++static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) ++{ ++ DRM_DEBUG("Skipping LVDS initialization for %s\n", id->ident); ++ return 1; ++} + ++/* These systems claim to have LVDS, but really don't */ ++static const struct dmi_system_id __initdata intel_no_lvds[] = { ++ { ++ .callback = intel_no_lvds_dmi_callback, ++ .ident = "Apple Mac Mini (Core series)", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), ++ }, ++ }, ++ { ++ .callback = intel_no_lvds_dmi_callback, ++ .ident = "Apple Mac Mini (Core 2 series)", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), ++ }, ++ }, ++ { ++ .callback = intel_no_lvds_dmi_callback, ++ .ident = "MSI IM-945GSE-A", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "MSI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"), ++ }, ++ }, ++ { ++ .callback = intel_no_lvds_dmi_callback, ++ .ident = "Dell Studio Hybrid", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"), ++ }, ++ }, ++ ++ /* FIXME: add a check for the Aopen Mini PC */ ++ ++ { } /* terminating entry */ ++}; + + /** + * intel_lvds_init - setup LVDS connectors on this device +@@ -404,15 +440,9 @@ void intel_lvds_init(struct drm_device *dev) + u32 lvds; + int pipe; + +- /* Blacklist machines that we know falsely report LVDS. */ +- /* FIXME: add a check for the Aopen Mini PC */ +- +- /* Apple Mac Mini Core Duo and Mac Mini Core 2 Duo */ +- if(dmi_match(DMI_PRODUCT_NAME, "Macmini1,1") || +- dmi_match(DMI_PRODUCT_NAME, "Macmini2,1")) { +- DRM_DEBUG("Skipping LVDS initialization for Apple Mac Mini\n"); ++ /* Skip init on machines we know falsely report LVDS */ ++ if (dmi_check_system(intel_no_lvds)) + return; +- } + + intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); + if (!intel_output) { diff --git a/packages/linux/patches/1822_drm-intel-gen3-fb-hack.diff b/packages/linux/patches/1822_drm-intel-gen3-fb-hack.diff new file mode 100644 index 0000000000..234b73c9be --- /dev/null +++ b/packages/linux/patches/1822_drm-intel-gen3-fb-hack.diff @@ -0,0 +1,14 @@ +diff -up linux-2.6.29.noarch/drivers/gpu/drm/i915/intel_display.c.jx linux-2.6.29.noarch/drivers/gpu/drm/i915/intel_display.c +--- linux-2.6.29.noarch/drivers/gpu/drm/i915/intel_display.c.jx 2009-04-09 13:42:51.000000000 -0400 ++++ linux-2.6.29.noarch/drivers/gpu/drm/i915/intel_display.c 2009-04-09 13:44:14.000000000 -0400 +@@ -2011,8 +2011,8 @@ void intel_modeset_init(struct drm_devic + dev->mode_config.max_width = 8192; + dev->mode_config.max_height = 8192; + } else { +- dev->mode_config.max_width = 2048; +- dev->mode_config.max_height = 2048; ++ dev->mode_config.max_width = 4096; ++ dev->mode_config.max_height = 4096; + } + + /* set memory base */ diff --git a/packages/linux/patches/1823_drm-intel-tiled-front.diff b/packages/linux/patches/1823_drm-intel-tiled-front.diff new file mode 100644 index 0000000000..ef446b6bc0 --- /dev/null +++ b/packages/linux/patches/1823_drm-intel-tiled-front.diff @@ -0,0 +1,65 @@ +From: Jesse Barnes +Date: Tue, 14 Apr 2009 21:17:47 +0000 (-0700) +Subject: drm/i915: allow tiled front buffers on 965+ +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fanholt%2Fdrm-intel.git;a=commitdiff_plain;h=f544847fbaf099278343f875987a983f2b913134 + +drm/i915: allow tiled front buffers on 965+ + +This patch corrects a pretty big oversight in the KMS code for 965+ +chips. The current code is missing tiled surface register programming, +so userland can allocate a tiled surface and use it for mode setting, +resulting in corruption. This patch fixes that, allowing for tiled +front buffers on 965+. + +Cc: stable@kernel.org +Tested-by: Arkadiusz Miskiewicz +Signed-off-by: Jesse Barnes +Signed-off-by: Eric Anholt +--- + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index e805b59..5211947 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1446,6 +1446,7 @@ + #define DISPPLANE_NO_LINE_DOUBLE 0 + #define DISPPLANE_STEREO_POLARITY_FIRST 0 + #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) ++#define DISPPLANE_TILED (1<<10) + #define DSPAADDR 0x70184 + #define DSPASTRIDE 0x70188 + #define DSPAPOS 0x7018C /* reserved */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index c2c8e95..bdcda36 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -657,6 +657,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR); + int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); + int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; ++ int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF); + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + u32 dspcntr, alignment; + int ret; +@@ -733,6 +734,13 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + mutex_unlock(&dev->struct_mutex); + return -EINVAL; + } ++ if (IS_I965G(dev)) { ++ if (obj_priv->tiling_mode != I915_TILING_NONE) ++ dspcntr |= DISPPLANE_TILED; ++ else ++ dspcntr &= ~DISPPLANE_TILED; ++ } ++ + I915_WRITE(dspcntr_reg, dspcntr); + + Start = obj_priv->gtt_offset; +@@ -745,6 +753,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + I915_READ(dspbase); + I915_WRITE(dspsurf, Start); + I915_READ(dspsurf); ++ I915_WRITE(dsptileoff, (y << 16) | x); + } else { + I915_WRITE(dspbase, Start + Offset); + I915_READ(dspbase); diff --git a/packages/x11/driver/xf86-video-nouveau/build b/packages/x11/driver/xf86-video-nouveau/build new file mode 100755 index 0000000000..3b5440a9bf --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/build @@ -0,0 +1,20 @@ +#!/bin/sh + +. config/options + +$SCRIPTS/build toolchain +$SCRIPTS/build $MESA +$SCRIPTS/build $LIBDRM + +cd $BUILD/$1* +./configure --host=$TARGET_NAME \ + --build=$HOST_NAME \ + --prefix=/usr \ + --sysconfdir=/etc \ + --disable-static \ + --enable-shared \ + --with-xorg-module-dir=$XORG_PATH_MODULES + +make + +$STRIP src/.libs/*.so \ No newline at end of file diff --git a/packages/x11/driver/xf86-video-nouveau/install b/packages/x11/driver/xf86-video-nouveau/install new file mode 100755 index 0000000000..ff1f178f9c --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/install @@ -0,0 +1,6 @@ +#!/bin/sh + +. config/options + +mkdir -p $INSTALL/$XORG_PATH_MODULES/drivers +cp $BUILD/$1*/src/.libs/*_drv.so $INSTALL/$XORG_PATH_MODULES/drivers diff --git a/packages/x11/driver/xf86-video-nouveau/patches/21_nouveau-transition-hack.diff b/packages/x11/driver/xf86-video-nouveau/patches/21_nouveau-transition-hack.diff new file mode 100644 index 0000000000..b85fe0f0ef --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/patches/21_nouveau-transition-hack.diff @@ -0,0 +1,181 @@ +From 98cd8bd95073e6248a0f63a2b5299736e6d097ef Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Mon, 13 Apr 2009 19:12:25 +1000 +Subject: [PATCH 1/6] kms/f11: hack in transition support without driver pixmaps + +--- + src/drmmode_display.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 142 insertions(+), 2 deletions(-) + +diff --git a/src/drmmode_display.c b/src/drmmode_display.c +index aa8befe..4909e51 100644 +--- a/src/drmmode_display.c ++++ b/src/drmmode_display.c +@@ -185,6 +185,139 @@ drmmode_fb_pixmap(ScrnInfoPtr pScrn, int id, int *w, int *h) + } + + static void ++drmmode_fb_copy_sw(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, ++ int src_id, int x, int y) ++{ ++ drmModeFBPtr fb; ++ NVPtr pNv = NVPTR(pScrn); ++ char *dst = NULL, *src = NULL; ++ struct drm_nouveau_gem_mmap req; ++ int ret, h; ++ ++ /* This is not what this should look like. Until we can do driver ++ * pixmaps, this will be a nasty hack! ++ */ ++ ++ fb = drmModeGetFB(nouveau_device(pNv->dev)->fd, src_id); ++ if (!fb) { ++ ErrorF("src fb\n"); ++ return; ++ } ++ ++ req.handle = fb->handle; ++ ret = drmCommandWriteRead(nouveau_device(pNv->dev)->fd, ++ DRM_NOUVEAU_GEM_MMAP, &req, sizeof(req)); ++ if (ret) { ++ ErrorF("src bo map: %d\n", ret); ++ drmFree(fb); ++ return; ++ } ++ src = (void *)req.vaddr; ++ ++ nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR); ++ dst = pNv->FB->map; ++ dst += (y * fb->pitch) + (x * (fb->bpp >> 3)); ++ ++ h = fb->height; ++ while (h--) { ++ memcpy(dst, src, fb->width * (fb->bpp >> 3)); ++ src += fb->pitch; ++ dst += pScrn->displayWidth * (pScrn->bitsPerPixel / 8); ++ } ++ ++ nouveau_bo_unmap(pNv->FB); ++ drmFree(fb); ++} ++ ++static void ++drmmode_fb_copy_nv50(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, ++ int src_id, int x, int y) ++{ ++ drmModeFBPtr fb; ++ NVPtr pNv = NVPTR(pScrn); ++ struct nouveau_channel *chan = pNv->chan; ++ struct nouveau_grobj *eng2d = pNv->Nv2D; ++ struct nouveau_bo *src = NULL, *dst = NULL; ++ struct drm_gem_flink req; ++ int ret; ++ ++ /* This is not what this should look like. Until we can do driver ++ * pixmaps, this will be a nasty hack! ++ */ ++ ++ fb = drmModeGetFB(nouveau_device(pNv->dev)->fd, src_id); ++ if (!fb) { ++ ErrorF("src fb\n"); ++ return; ++ } ++ ++ req.handle = fb->handle; ++ ret = ioctl(nouveau_device(pNv->dev)->fd, DRM_IOCTL_GEM_FLINK, &req); ++ if (ret) { ++ ErrorF("name bo: %d\n", ret); ++ drmFree(fb); ++ return; ++ } ++ ++ ret = nouveau_bo_handle_ref(pNv->dev, req.name, &src); ++ if (ret) { ++ ErrorF("src bo: %d\n", ret); ++ drmFree(fb); ++ return; ++ } ++ ++ nouveau_bo_ref(pNv->scanout, &dst); ++ ++ BEGIN_RING(chan, eng2d, 0x02ac, 1); ++ OUT_RING (chan, 3); ++ BEGIN_RING(chan, eng2d, 0x0200, 2); ++ OUT_RING (chan, pScrn->bitsPerPixel == 16 ? 0xe8 : 0xcf); ++ OUT_RING (chan, 1); ++ BEGIN_RING(chan, eng2d, 0x0214, 5); ++ OUT_RING (chan, pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); ++ OUT_RING (chan, pScrn->virtualX); ++ OUT_RING (chan, pScrn->virtualY); ++ OUT_RELOCh(chan, dst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ OUT_RELOCl(chan, dst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ BEGIN_RING(chan, eng2d, 0x0280, 4); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, pScrn->virtualX); ++ OUT_RING (chan, pScrn->virtualY); ++ BEGIN_RING(chan, eng2d, 0x0230, 2); ++ OUT_RING (chan, fb->bpp == 16 ? 0xe8 : 0xcf); ++ OUT_RING (chan, 1); ++ BEGIN_RING(chan, eng2d, 0x0244, 5); ++ OUT_RING (chan, fb->pitch); ++ OUT_RING (chan, fb->width); ++ OUT_RING (chan, fb->height); ++ OUT_RELOCh(chan, src, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ OUT_RELOCl(chan, src, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ BEGIN_RING(chan, eng2d, 0x0110, 1); ++ OUT_RING (chan, 0); ++ BEGIN_RING(chan, eng2d, 0x08b0, 12); ++ OUT_RING (chan, x); ++ OUT_RING (chan, y); ++ OUT_RING (chan, fb->width); ++ OUT_RING (chan, fb->height); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ FIRE_RING (chan); ++ ++ nouveau_bo_map(dst, NOUVEAU_BO_RD); ++ nouveau_bo_unmap(dst); ++ nouveau_bo_ref(NULL, &dst); ++ nouveau_bo_ref(NULL, &src); ++ drmFree(fb); ++} ++ ++static void + drmmode_fb_copy(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, int src_id, + int x, int y) + { +@@ -194,6 +327,14 @@ drmmode_fb_copy(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, int src_id, + PixmapPtr pspix, pdpix; + int w, h; + ++ if (!pNv->exa_driver_pixmaps) { ++ if (pNv->NoAccel) ++ drmmode_fb_copy_sw(pScrn, drmmode, dst_id, src_id, x, y); ++ else ++ drmmode_fb_copy_nv50(pScrn, drmmode, dst_id, src_id, x, y); ++ return; ++ } ++ + pspix = drmmode_fb_pixmap(pScrn, src_id, NULL, NULL); + if (!pspix) + return; +@@ -292,8 +433,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, + if (drmmode_crtc->rotate_fb_id) + fb_id = drmmode_crtc->rotate_fb_id; + else +- if (fb_id != drmmode_crtc->mode_crtc->buffer_id && +- pNv->exa_driver_pixmaps) { ++ if (fb_id != drmmode_crtc->mode_crtc->buffer_id) { + drmmode_fb_copy(pScrn, drmmode, fb_id, + drmmode_crtc->mode_crtc->buffer_id, x, y); + } +-- +1.6.2.2 + diff --git a/packages/x11/driver/xf86-video-nouveau/patches/22_nouveau-store-vbios.diff b/packages/x11/driver/xf86-video-nouveau/patches/22_nouveau-store-vbios.diff new file mode 100644 index 0000000000..899366f3a3 --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/patches/22_nouveau-store-vbios.diff @@ -0,0 +1,51 @@ +From 514eb5a03b8ca223a4d832e1675cda3a6a56b02d Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Mon, 13 Apr 2009 19:13:26 +1000 +Subject: [PATCH 2/6] bios/f11: store a copy of used vbios image in /var/run + +--- + src/nv_bios.c | 13 +++++++++++++ + 1 files changed, 13 insertions(+), 0 deletions(-) + +diff --git a/src/nv_bios.c b/src/nv_bios.c +index ebf4027..ad4ff1f 100644 +--- a/src/nv_bios.c ++++ b/src/nv_bios.c +@@ -22,6 +22,9 @@ + * SOFTWARE. + */ + ++#include ++#include ++#include + #include "nv_include.h" + + #if defined(__FreeBSD__) || defined(__NetBSD__) +@@ -4492,7 +4495,10 @@ uint8_t * nouveau_bios_embedded_edid(ScrnInfoPtr pScrn) + + bool NVInitVBIOS(ScrnInfoPtr pScrn) + { ++ NVPtr pNv = NVPTR(pScrn); + struct nvbios *bios = &NVPTR(pScrn)->VBIOS; ++ char img[128]; ++ int fd; + + memset(bios, 0, sizeof(struct nvbios)); + +@@ -4503,6 +4509,13 @@ bool NVInitVBIOS(ScrnInfoPtr pScrn) + if (bios->length > NV_PROM_SIZE) + bios->length = NV_PROM_SIZE; + ++ sprintf(img, "/var/run/nv%02x_%04x.rom", pNv->NVArch, pNv->Chipset); ++ fd = open(img, O_CREAT|O_RDWR|O_EXCL, 0700); ++ if (fd >= 0) { ++ write(fd, bios->data, bios->length); ++ close(fd); ++ } ++ + return true; + } + +-- +1.6.2.2 + diff --git a/packages/x11/driver/xf86-video-nouveau/patches/23_nouveau-multiple-xserver.diff b/packages/x11/driver/xf86-video-nouveau/patches/23_nouveau-multiple-xserver.diff new file mode 100644 index 0000000000..a4233c5938 --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/patches/23_nouveau-multiple-xserver.diff @@ -0,0 +1,202 @@ +From e278ea7300169355b17b17a785aef938c3fbc1e3 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Mon, 13 Apr 2009 19:25:25 +1000 +Subject: [PATCH 3/6] f11: hack to support multiple xserver instances + +--- + src/nv_driver.c | 126 ++++++++++++++++++++++++++++++++++++++++++------------ + 1 files changed, 98 insertions(+), 28 deletions(-) + +diff --git a/src/nv_driver.c b/src/nv_driver.c +index 92232dd..9f4c96f 100644 +--- a/src/nv_driver.c ++++ b/src/nv_driver.c +@@ -21,6 +21,7 @@ + */ + + #include ++#include + + #include "nv_include.h" + +@@ -654,14 +655,27 @@ NV50ReleaseDisplay(ScrnInfoPtr pScrn) + */ + + /* Mandatory */ ++static void NVMapMemGART(ScrnInfoPtr); + static Bool + NVEnterVT(int scrnIndex, int flags) + { + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + NVPtr pNv = NVPTR(pScrn); ++ int ret; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n"); + ++ if (pNv->dev) { ++ ret = ioctl(nouveau_device(pNv->dev)->fd, ++ DRM_IOCTL_SET_MASTER, NULL); ++ if (ret) { ++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, ++ "Unable to set master\n"); ++ } ++ ++ NVMapMemGART(pScrn); ++ } ++ + if (!pNv->NoAccel) + NVAccelCommonInit(pScrn); + +@@ -718,6 +732,12 @@ NVLeaveVT(int scrnIndex, int flags) + + NVSync(pScrn); + ++ if (pNv->dev) { ++ nouveau_bo_ref(NULL, &pNv->GART); ++ ++ ioctl(nouveau_device(pNv->dev)->fd, DRM_IOCTL_DROP_MASTER, NULL); ++ } ++ + if (!pNv->kms_enable) { + if (pNv->Architecture < NV_ARCH_50) + NVRestore(pScrn); +@@ -1629,11 +1649,81 @@ NVMapMemSW(ScrnInfoPtr pScrn) + } + + static Bool ++NVMapMemSharedFB(ScrnInfoPtr pScrn) ++{ ++ NVPtr pNv = NVPTR(pScrn); ++ uint64_t handle, size; ++ void *map; ++ int ret; ++ ++ ret = nouveau_device_get_param(pNv->dev, 0xdeadcafe00000001, &handle); ++ if (ret) ++ return FALSE; ++ ++ ret = nouveau_device_get_param(pNv->dev, 0xdeadcafe00000002, &size); ++ if (ret) ++ return FALSE; ++ ++ if (nouveau_device(pNv->dev)->mm_enabled) { ++ ret = nouveau_bo_handle_ref(pNv->dev, handle, &pNv->FB); ++ if (ret) { ++ ErrorF("%d\n", ret); ++ return FALSE; ++ } ++ ++ pNv->FB->size = size; ++ pNv->FB->tiled = (pNv->Architecture == NV_ARCH_50); ++ return TRUE; ++ } ++ ++ ret = drmMap(nouveau_device(pNv->dev)->fd, handle >> 32, size, &map); ++ if (ret) ++ return FALSE; ++ ++ ret = nouveau_bo_fake(pNv->dev, handle & 0xffffffff, NOUVEAU_BO_VRAM | ++ NOUVEAU_BO_PIN, size, map, &pNv->FB); ++ if (ret) ++ return FALSE; ++ ++ pNv->FB->tiled = (pNv->Architecture == NV_ARCH_50); ++ return TRUE; ++} ++ ++static void ++NVMapMemGART(ScrnInfoPtr pScrn) { ++ NVPtr pNv = NVPTR(pScrn); ++ int size; ++ ++ if (pNv->AGPSize) { ++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, ++ "AGPGART: %dMiB available\n", ++ (unsigned int)(pNv->AGPSize >> 20)); ++ if (pNv->AGPSize > (16*1024*1024)) ++ size = 16*1024*1024; ++ else ++ /* always leave 512kb for other things like the fifos */ ++ size = pNv->AGPSize - 512*1024; ++ } else { ++ size = (4 << 20) - (1 << 18) ; ++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, ++ "GART: PCI DMA - using %dKiB\n", ++ size >> 10); ++ } ++ ++ if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_PIN, 0, ++ size, &pNv->GART)) { ++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, ++ "Unable to allocate GART memory\n"); ++ } ++} ++ ++static Bool + NVMapMem(ScrnInfoPtr pScrn) + { + NVPtr pNv = NVPTR(pScrn); + uint64_t res; + int size; ++ uint32_t flags; + + if (!pNv->dev) + return NVMapMemSW(pScrn); +@@ -1650,46 +1740,26 @@ NVMapMem(ScrnInfoPtr pScrn) + size = size * (pScrn->bitsPerPixel >> 3); + size = size * pScrn->virtualY; + } else { ++ if (NVMapMemSharedFB(pScrn)) ++ goto skip_fb; + size = pNv->VRAMPhysicalSize / 2; + } + +- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, +- 0, size, &pNv->FB)) { ++ flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN; ++ if (pNv->Architecture >= NV_ARCH_50) ++ flags |= NOUVEAU_BO_TILED; ++ ++ if (nouveau_bo_new(pNv->dev, flags, 0, size, &pNv->FB)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate framebuffer memory\n"); + return FALSE; + } ++skip_fb: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocated %dMiB VRAM for framebuffer + offscreen pixmaps, " + "at offset 0x%X\n", + (uint32_t)(pNv->FB->size >> 20), (uint32_t) pNv->FB->offset); + +- if (pNv->AGPSize) { +- xf86DrvMsg(pScrn->scrnIndex, X_INFO, +- "AGPGART: %dMiB available\n", +- (unsigned int)(pNv->AGPSize >> 20)); +- if (pNv->AGPSize > (16*1024*1024)) +- size = 16*1024*1024; +- else +- /* always leave 512kb for other things like the fifos */ +- size = pNv->AGPSize - 512*1024; +- } else { +- size = (4 << 20) - (1 << 18) ; +- xf86DrvMsg(pScrn->scrnIndex, X_INFO, +- "GART: PCI DMA - using %dKiB\n", +- size >> 10); +- } +- +- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_PIN, 0, +- size, &pNv->GART)) { +- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, +- "Unable to allocate GART memory\n"); +- } +- if (pNv->GART) { +- xf86DrvMsg(pScrn->scrnIndex, X_INFO, +- "GART: Allocated %dMiB as a scratch buffer\n", +- (unsigned int)(pNv->GART->size >> 20)); +- } + + /* We don't need to allocate cursors / lut here if we're using + * kernel modesetting +-- +1.6.2.2 + diff --git a/packages/x11/driver/xf86-video-nouveau/patches/24_nouveau-nv50-fb-accel.diff b/packages/x11/driver/xf86-video-nouveau/patches/24_nouveau-nv50-fb-accel.diff new file mode 100644 index 0000000000..654173f4e3 --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/patches/24_nouveau-nv50-fb-accel.diff @@ -0,0 +1,644 @@ +From e31aa5217c97dfd1e2c678ce7391fcd255abb0bf Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Mon, 13 Apr 2009 19:30:38 +1000 +Subject: [PATCH 4/6] nv50/f11: accelerate front-buffer rendering, linear shadow for scanout + +--- + src/Makefile.am | 1 + + src/drmmode_display.c | 8 +- + src/nouveau_exa.c | 37 ++++-- + src/nv50_randr.c | 2 +- + src/nv50_shadow_damage.c | 306 ++++++++++++++++++++++++++++++++++++++++++++++ + src/nv_dri.c | 2 +- + src/nv_driver.c | 38 +++++- + src/nv_proto.h | 4 + + src/nv_shadow.c | 8 +- + src/nv_type.h | 4 + + 10 files changed, 387 insertions(+), 23 deletions(-) + create mode 100644 src/nv50_shadow_damage.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index 29253a6..0c9e4e9 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -81,6 +81,7 @@ nouveau_drv_la_SOURCES = \ + nv50_xv.c \ + nv50_texture.h \ + nv50reg.h \ ++ nv50_shadow_damage.c \ + nouveau_crtc.h \ + nouveau_output.h \ + nouveau_connector.h \ +diff --git a/src/drmmode_display.c b/src/drmmode_display.c +index 4909e51..ca1a60b 100644 +--- a/src/drmmode_display.c ++++ b/src/drmmode_display.c +@@ -214,8 +214,8 @@ drmmode_fb_copy_sw(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, + } + src = (void *)req.vaddr; + +- nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR); +- dst = pNv->FB->map; ++ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR); ++ dst = pNv->scanout->map; + dst += (y * fb->pitch) + (x * (fb->bpp >> 3)); + + h = fb->height; +@@ -225,7 +225,7 @@ drmmode_fb_copy_sw(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, + dst += pScrn->displayWidth * (pScrn->bitsPerPixel / 8); + } + +- nouveau_bo_unmap(pNv->FB); ++ nouveau_bo_unmap(pNv->scanout); + drmFree(fb); + } + +@@ -380,7 +380,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, + ret = drmModeAddFB(drmmode->fd, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, +- pitch, pNv->FB->handle, &drmmode->fb_id); ++ pitch, pNv->scanout->handle, &drmmode->fb_id); + if (ret < 0) { + ErrorF("failed to add fb\n"); + return FALSE; +diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c +index b7bcc87..aee2794 100644 +--- a/src/nouveau_exa.c ++++ b/src/nouveau_exa.c +@@ -265,7 +265,8 @@ nouveau_exa_wait_marker(ScreenPtr pScreen, int marker) + static Bool + nouveau_exa_prepare_access(PixmapPtr ppix, int index) + { +- ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; ++ ScreenPtr pScreen = ppix->drawable.pScreen; ++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + NVPtr pNv = NVPTR(pScrn); + + if (pNv->exa_driver_pixmaps) { +@@ -275,20 +276,33 @@ nouveau_exa_prepare_access(PixmapPtr ppix, int index) + return FALSE; + + ppix->devPrivate.ptr = map; +- return TRUE; ++ } else ++ if (ppix == pScreen->GetScreenPixmap(pScreen)) { ++ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR); ++ ppix->devPrivate.ptr = pNv->scanout->map; ++ } else { ++ /* force migration */ ++ return FALSE; + } + +- return FALSE; ++ return TRUE; + } + + static void + nouveau_exa_finish_access(PixmapPtr ppix, int index) + { +- ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; ++ ScreenPtr pScreen = ppix->drawable.pScreen; ++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + NVPtr pNv = NVPTR(pScrn); + +- if (pNv->exa_driver_pixmaps) ++ if (pNv->exa_driver_pixmaps) { + nouveau_exa_pixmap_unmap(ppix); ++ } else ++ if (ppix == pScreen->GetScreenPixmap(pScreen)) { ++ ppix->devPrivate.ptr = NULL; ++ nouveau_bo_unmap(pNv->scanout); ++ nv50_shadow_damage_frontbuffer_fallback(pScrn); ++ } + } + + static Bool +@@ -393,8 +407,7 @@ nouveau_exa_pixmap_is_tiled(PixmapPtr ppix) + if (!nouveau_pixmap_bo(ppix)->tiled) + return false; + } else +- if (pNv->Architecture < NV_ARCH_50 || +- exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase) ++ if (pNv->Architecture < NV_ARCH_50) + return false; + + return true; +@@ -406,7 +419,7 @@ nouveau_exa_pixmap_map(PixmapPtr ppix) + struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); + unsigned delta = nouveau_pixmap_offset(ppix); + +- if (bo->tiled) { ++ if (NVPTR(xf86Screens[ppix->drawable.pScreen->myNum])->GART && bo->tiled) { + struct nouveau_pixmap *nvpix = nouveau_pixmap(ppix); + + nvpix->map_refcount++; +@@ -432,7 +445,7 @@ nouveau_exa_pixmap_unmap(PixmapPtr ppix) + { + struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); + +- if (bo->tiled) { ++ if (NVPTR(xf86Screens[ppix->drawable.pScreen->myNum])->GART && bo->tiled) { + struct nouveau_pixmap *nvpix = nouveau_pixmap(ppix); + + if (--nvpix->map_refcount) +@@ -616,6 +629,12 @@ nouveau_exa_init(ScreenPtr pScreen) + exa->maxY = 2048; + } + ++ /* Needed for frontbuffer fallbacks (to ensure it accesses the linear fb). */ ++ if (pNv->Architecture >= NV_ARCH_50) { ++ exa->PrepareAccess = nouveau_exa_prepare_access; ++ exa->FinishAccess = nouveau_exa_finish_access; ++ } ++ + exa->MarkSync = nouveau_exa_mark_sync; + exa->WaitMarker = nouveau_exa_wait_marker; + +diff --git a/src/nv50_randr.c b/src/nv50_randr.c +index 8a9281b..538c883 100644 +--- a/src/nv50_randr.c ++++ b/src/nv50_randr.c +@@ -99,7 +99,7 @@ nv50_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjuste + nv_crtc->crtc->SetFB(nv_crtc->crtc, nv_crtc->shadow); + nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, 0, 0); + } else { +- nv_crtc->crtc->SetFB(nv_crtc->crtc, pNv->FB); ++ nv_crtc->crtc->SetFB(nv_crtc->crtc, pNv->scanout); + nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, x, y); + } + nv_crtc->crtc->ModeSet(nv_crtc->crtc, mode); +diff --git a/src/nv50_shadow_damage.c b/src/nv50_shadow_damage.c +new file mode 100644 +index 0000000..790b09c +--- /dev/null ++++ b/src/nv50_shadow_damage.c +@@ -0,0 +1,306 @@ ++/* ++ * Copyright 2009 Maarten Maathuis ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF ++ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++/** ++ * This file serves to process all damage to the frontbuffer pixmap. ++ * This is needed until we can/have: ++ * - Tiled frontbufffer support. ++ * - Working wfb support. ++ * - Widespread wfb exa support. ++ */ ++ ++#include "nv_include.h" ++#include "damagestr.h" ++ ++/* When driver allocated pixmaps are used we can easily fold this back into exa code. */ ++ ++static void ++nv50_shadow_damage_blit_state_emit(struct nouveau_channel *chan) ++{ ++ ScrnInfoPtr pScrn = chan->user_private; ++ NVPtr pNv = NVPTR(pScrn); ++ PixmapPtr ppix = pNv->pspix; ++ struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); ++ struct nouveau_grobj *eng2d = pNv->Nv2D; ++ unsigned delta = nouveau_pixmap_offset(ppix), fmt; ++ ++ WAIT_RING (chan, 27 + 13); ++ ++ switch (ppix->drawable.depth) { ++ case 8 : fmt = NV50_2D_SRC_FORMAT_8BPP; break; ++ case 15: fmt = NV50_2D_SRC_FORMAT_15BPP; break; ++ case 16: fmt = NV50_2D_SRC_FORMAT_16BPP; break; ++ case 24: fmt = NV50_2D_SRC_FORMAT_24BPP; break; ++ case 32: fmt = NV50_2D_SRC_FORMAT_32BPP; break; ++ default: ++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, ++ "Unknown surface format for bpp=%d\n", ++ ppix->drawable.depth); ++ return; ++ } ++ ++ /* tiled source */ ++ BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 5); ++ OUT_RING (chan, fmt); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ ++ BEGIN_RING(chan, eng2d, NV50_2D_SRC_WIDTH, 4); ++ OUT_RING (chan, ppix->drawable.width); ++ OUT_RING (chan, ppix->drawable.height); ++ OUT_RELOCh(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ OUT_RELOCl(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ ++ /* untiled destination */ ++ BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); ++ OUT_RING (chan, fmt); ++ OUT_RING (chan, 1); ++ BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); ++ OUT_RING (chan, NOUVEAU_ALIGN(pScrn->virtualX, 64) * ++ (pScrn->bitsPerPixel >> 3)); ++ OUT_RING (chan, ppix->drawable.width); ++ OUT_RING (chan, ppix->drawable.height); ++ OUT_RELOCh(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ OUT_RELOCl(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ ++ BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, ppix->drawable.width); ++ OUT_RING (chan, ppix->drawable.height); ++ BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); ++ OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); ++} ++ ++static void ++nv50_shadow_damage_blit(PixmapPtr ppix, RegionPtr pRegion) ++{ ++ ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; ++ NVPtr pNv = NVPTR(pScrn); ++ struct nouveau_channel *chan = pNv->chan; ++ struct nouveau_grobj *eng2d = pNv->Nv2D; ++ BoxPtr pbox; ++ int nbox; ++ ++ pbox = REGION_RECTS(pRegion); ++ nbox = REGION_NUM_RECTS(pRegion); ++ if (!nbox) ++ return; ++ ++ pNv->pspix = ppix; ++ chan->flush_notify = nv50_shadow_damage_blit_state_emit; ++ chan->flush_notify(chan); ++ while (nbox--) { ++ WAIT_RING (chan, 13); ++ BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12); ++ OUT_RING (chan, pbox->x1); ++ OUT_RING (chan, pbox->y1); ++ OUT_RING (chan, pbox->x2 - pbox->x1); ++ OUT_RING (chan, pbox->y2 - pbox->y1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, pbox->x1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, pbox->y1); ++ ++ pbox++; ++ } ++ chan->flush_notify = NULL; ++} ++ ++/* For frontbuffer fallbacks. */ ++static void ++nv50_shadow_damage_blit_back_state_emit(struct nouveau_channel *chan) ++{ ++ ScrnInfoPtr pScrn = chan->user_private; ++ NVPtr pNv = NVPTR(pScrn); ++ PixmapPtr ppix = pNv->pdpix; ++ struct nouveau_grobj *eng2d = pNv->Nv2D; ++ struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); ++ unsigned delta = nouveau_pixmap_offset(ppix), fmt; ++ ++ WAIT_RING (chan, 27 + 13); ++ ++ switch (ppix->drawable.depth) { ++ case 8 : fmt = NV50_2D_SRC_FORMAT_8BPP; break; ++ case 15: fmt = NV50_2D_SRC_FORMAT_15BPP; break; ++ case 16: fmt = NV50_2D_SRC_FORMAT_16BPP; break; ++ case 24: fmt = NV50_2D_SRC_FORMAT_24BPP; break; ++ case 32: fmt = NV50_2D_SRC_FORMAT_32BPP; break; ++ default: ++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, ++ "Unknown surface format for bpp=%d\n", ++ ppix->drawable.depth); ++ return; ++ } ++ ++ /* untiled source */ ++ BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2); ++ OUT_RING (chan, fmt); ++ OUT_RING (chan, 1); ++ BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5); ++ OUT_RING (chan, NOUVEAU_ALIGN(pScrn->virtualX, 64) * ++ (pScrn->bitsPerPixel >> 3)); ++ OUT_RING (chan, ppix->drawable.width); ++ OUT_RING (chan, ppix->drawable.height); ++ OUT_RELOCh(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ OUT_RELOCl(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ ++ /* tiled destination */ ++ BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 5); ++ OUT_RING (chan, fmt); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ ++ BEGIN_RING(chan, eng2d, NV50_2D_DST_WIDTH, 4); ++ OUT_RING (chan, ppix->drawable.width); ++ OUT_RING (chan, ppix->drawable.height); ++ OUT_RELOCh(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ OUT_RELOCl(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); ++ ++ BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, ppix->drawable.width); ++ OUT_RING (chan, ppix->drawable.height); ++ BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); ++ OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); ++} ++ ++static void ++nv50_shadow_damage_blit_back(PixmapPtr ppix, RegionPtr pRegion) ++{ ++ ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; ++ NVPtr pNv = NVPTR(pScrn); ++ struct nouveau_channel *chan = pNv->chan; ++ struct nouveau_grobj *eng2d = pNv->Nv2D; ++ BoxPtr pbox; ++ int nbox; ++ ++ pbox = REGION_RECTS(pRegion); ++ nbox = REGION_NUM_RECTS(pRegion); ++ if (!nbox) ++ return; ++ ++ pNv->pdpix = ppix; ++ chan->flush_notify = nv50_shadow_damage_blit_back_state_emit; ++ chan->flush_notify(chan); ++ while (nbox--) { ++ WAIT_RING (chan, 13); ++ BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12); ++ OUT_RING (chan, pbox->x1); ++ OUT_RING (chan, pbox->y1); ++ OUT_RING (chan, pbox->x2 - pbox->x1); ++ OUT_RING (chan, pbox->y2 - pbox->y1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, pbox->x1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, pbox->y1); ++ ++ pbox++; ++ } ++ chan->flush_notify = NULL; ++} ++ ++static void ++nv50_shadow_damage_report(DamagePtr pDamage, RegionPtr pRegion, void *closure) ++{ ++ PixmapPtr ppix = closure; ++ ++ nv50_shadow_damage_blit(ppix, pRegion); ++} ++ ++void ++nv50_shadow_damage_frontbuffer_fallback(ScrnInfoPtr pScrn) ++{ ++ NVPtr pNv = NVPTR(pScrn); ++ ScreenPtr pScreen = pScrn->pScreen; ++ PixmapPtr ppix = NULL; ++ DamagePtr pDamage = pNv->screen_damage; ++ ++ if (pNv->Architecture < NV_ARCH_50) ++ return; ++ ++ ppix = pScreen->GetScreenPixmap(pScreen); ++ if (!ppix) { ++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, ++ "No screen pixmap.\n"); ++ return; ++ } ++ ++ /* Pending damage reflects the rendering currently being done. */ ++ /* When exa calls finish access, damage hasn't flushed it yet. */ ++ nv50_shadow_damage_blit_back(ppix, &pDamage->pendingDamage); ++} ++ ++static void ++nv50_shadow_damage_destroy(DamagePtr pDamage, void *closure) ++{ ++ PixmapPtr ppix = closure; ++ ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; ++ NVPtr pNv = NVPTR(pScrn); ++ ++ pNv->screen_damage = NULL; ++} ++ ++bool ++nv50_shadow_damage_create(ScrnInfoPtr pScrn) ++{ ++ NVPtr pNv = NVPTR(pScrn); ++ ScreenPtr pScreen = pScrn->pScreen; ++ PixmapPtr ppix = NULL; ++ ++ if (pNv->Architecture < NV_ARCH_50) ++ return false; ++ ++ ppix = pScreen->GetScreenPixmap(pScreen); ++ if (!ppix) { ++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, ++ "No screen pixmap.\n"); ++ return false; ++ } ++ ++ pNv->screen_damage = DamageCreate(nv50_shadow_damage_report, nv50_shadow_damage_destroy, DamageReportRawRegion, true, pScreen, ppix); ++ if (!pNv->screen_damage) { ++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, ++ "No screen damage\n"); ++ return false; ++ } ++ ++ /* We want the notification after submission. */ ++ DamageSetReportAfterOp(pNv->screen_damage, true); ++ ++ DamageRegister(&ppix->drawable, pNv->screen_damage); ++ ++ return true; ++} +diff --git a/src/nv_dri.c b/src/nv_dri.c +index bd3e5a9..dca6a40 100644 +--- a/src/nv_dri.c ++++ b/src/nv_dri.c +@@ -337,7 +337,7 @@ Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn) + pNOUVEAUDRI->depth = pScrn->depth; + pNOUVEAUDRI->bpp = pScrn->bitsPerPixel; + +- ret = nouveau_bo_handle_get(pNv->FB, &pNOUVEAUDRI->front_offset); ++ ret = nouveau_bo_handle_get(pNv->scanout, &pNOUVEAUDRI->front_offset); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[dri] unable to reference front buffer: %d\n", ret); +diff --git a/src/nv_driver.c b/src/nv_driver.c +index 9f4c96f..a280257 100644 +--- a/src/nv_driver.c ++++ b/src/nv_driver.c +@@ -686,10 +686,11 @@ NVEnterVT(int scrnIndex, int flags) + /* Clear the framebuffer, we don't want to see garbage + * on-screen up until X decides to draw something + */ +- nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR); +- memset(pNv->FB->map, 0, NOUVEAU_ALIGN(pScrn->virtualX, 64) * +- pScrn->virtualY * (pScrn->bitsPerPixel >> 3)); +- nouveau_bo_unmap(pNv->FB); ++ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR); ++ memset(pNv->scanout->map, 0, ++ NOUVEAU_ALIGN(pScrn->virtualX, 64) * pScrn->virtualY * ++ (pScrn->bitsPerPixel >> 3)); ++ nouveau_bo_unmap(pNv->scanout); + + if (pNv->Architecture == NV_ARCH_50) { + if (!NV50AcquireDisplay(pScrn)) +@@ -1609,6 +1610,8 @@ NVMapMemSW(ScrnInfoPtr pScrn) + return FALSE; + pNv->GART = NULL; + ++ nouveau_bo_ref(pNv->FB, &pNv->scanout); ++ + ret = nouveau_bo_fake(&dev, Cursor0Offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, + 64 * 64 * 4, pNv->VRAMMap + Cursor0Offset, +@@ -1760,6 +1763,23 @@ skip_fb: + "at offset 0x%X\n", + (uint32_t)(pNv->FB->size >> 20), (uint32_t) pNv->FB->offset); + ++ /* Allocate linear scanout. */ ++ if (!pNv->NoAccel && pNv->Architecture >= NV_ARCH_50) { ++ unsigned scanout_size; ++ ++ scanout_size = NOUVEAU_ALIGN(pScrn->virtualX, 64); ++ scanout_size *= (pScrn->bitsPerPixel >> 3); ++ scanout_size *= pScrn->virtualY; ++ ++ if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, ++ 0, scanout_size, &pNv->scanout)) { ++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, ++ "Failed to allocate scanout buffer\n"); ++ return FALSE; ++ } ++ } else { ++ nouveau_bo_ref(pNv->FB, &pNv->scanout); ++ } + + /* We don't need to allocate cursors / lut here if we're using + * kernel modesetting +@@ -1832,6 +1852,7 @@ NVUnmapMem(ScrnInfoPtr pScrn) + } + + nouveau_bo_ref(NULL, &pNv->FB); ++ nouveau_bo_ref(NULL, &pNv->scanout); + nouveau_bo_ref(NULL, &pNv->GART); + nouveau_bo_ref(NULL, &pNv->Cursor); + nouveau_bo_ref(NULL, &pNv->Cursor2); +@@ -2347,6 +2368,15 @@ NVSaveScreen(ScreenPtr pScreen, int mode) + bool on = xf86IsUnblank(mode); + int i; + ++ /* This might seem strange, but we need an entry point after CreateScreenResources. ++ * This happens to one of the few, if not the only place. ++ * When we move to driver allocated pixmaps, we can move this. ++ */ ++ if (mode == SCREEN_SAVER_FORCER && pNv->Architecture == NV_ARCH_50 && ++ !pNv->NoAccel && !pNv->screen_damage && ++ !nv50_shadow_damage_create(pScrn)) ++ return FALSE; ++ + if (!pNv->randr12_enable) + return vgaHWSaveScreen(pScreen, mode); + +diff --git a/src/nv_proto.h b/src/nv_proto.h +index 072c7c4..4e9b65c 100644 +--- a/src/nv_proto.h ++++ b/src/nv_proto.h +@@ -267,6 +267,10 @@ void nv50_xv_video_stop(ScrnInfoPtr, pointer, Bool); + int nv50_xv_port_attribute_set(ScrnInfoPtr, Atom, INT32, pointer); + int nv50_xv_port_attribute_get(ScrnInfoPtr, Atom, INT32 *, pointer); + ++/* nv50_shadow_damage.c */ ++bool nv50_shadow_damage_create(ScrnInfoPtr pScrn); ++void nv50_shadow_damage_frontbuffer_fallback(ScrnInfoPtr pScrn); ++ + /* To support EXA 2.0, 2.1 has this in the header */ + #ifndef exaMoveInPixmap + extern void exaMoveInPixmap(PixmapPtr pPixmap); +diff --git a/src/nv_shadow.c b/src/nv_shadow.c +index ea1ba35..e15051c 100644 +--- a/src/nv_shadow.c ++++ b/src/nv_shadow.c +@@ -38,9 +38,9 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) + + cpp = pScrn->bitsPerPixel >> 3; + FBPitch = pScrn->displayWidth * cpp; +- max_height = pNv->FB->size/FBPitch; ++ max_height = pNv->scanout->size/FBPitch; + +- nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR); ++ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR); + while(num--) { + x1 = MAX(pbox->x1, 0); + y1 = MAX(pbox->y1, 0); +@@ -51,7 +51,7 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) + + if (width > 0 && height > 0) { + src = pNv->ShadowPtr + (y1 * pNv->ShadowPitch) + (x1 * cpp); +- dst = pNv->FB->map + (y1 * FBPitch) + (x1 * cpp); ++ dst = pNv->scanout->map + (y1 * FBPitch) + (x1 * cpp); + + while(height--) { + memcpy(dst, src, width); +@@ -62,5 +62,5 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) + + pbox++; + } +- nouveau_bo_unmap(pNv->FB); ++ nouveau_bo_unmap(pNv->scanout); + } +diff --git a/src/nv_type.h b/src/nv_type.h +index 2ec4fba..5396cc8 100644 +--- a/src/nv_type.h ++++ b/src/nv_type.h +@@ -270,6 +270,7 @@ typedef struct _NVRec { + /* Various pinned memory regions */ + struct nouveau_bo * FB; + void * FBMap; ++ struct nouveau_bo * scanout; + //struct nouveau_bo * FB_old; /* for KMS */ + struct nouveau_bo * shadow[2]; /* for easy acces by exa */ + struct nouveau_bo * Cursor; +@@ -278,6 +279,9 @@ typedef struct _NVRec { + + struct nvbios VBIOS; + struct nouveau_bios_info *vbios; ++ ++ DamagePtr screen_damage; /* for NV50+ */ ++ + Bool NoAccel; + Bool HWCursor; + Bool FpScale; +-- +1.6.2.2 + diff --git a/packages/x11/driver/xf86-video-nouveau/patches/25_nouveau-nv50-fb-accel.diff b/packages/x11/driver/xf86-video-nouveau/patches/25_nouveau-nv50-fb-accel.diff new file mode 100644 index 0000000000..c8452cfa70 --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/patches/25_nouveau-nv50-fb-accel.diff @@ -0,0 +1,31 @@ +From 7460d8ebca84bd5e7c26e88143f14f4909598b68 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Mon, 13 Apr 2009 20:20:39 +1000 +Subject: [PATCH 5/6] nv50/f11: disable acceleration on NVAx chipsets + +--- + src/nv_driver.c | 8 ++++++++ + 1 files changed, 8 insertions(+), 0 deletions(-) + +diff --git a/src/nv_driver.c b/src/nv_driver.c +index a280257..f097fb9 100644 +--- a/src/nv_driver.c ++++ b/src/nv_driver.c +@@ -1144,6 +1144,14 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) + pNv->ShadowFB = TRUE; + } + ++ if ((pNv->NVArch & 0xf0) == 0xa0) { ++ xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, ++ "Acceleration disabled, currently non-functional " ++ "on this chipset\n"); ++ pNv->NoAccel = TRUE; ++ pNv->ShadowFB = TRUE; ++ } ++ + /* Save current console video mode */ + if (pNv->Architecture >= NV_ARCH_50 && pNv->pInt10 && !pNv->kms_enable) { + const xf86Int10InfoPtr pInt10 = pNv->pInt10; +-- +1.6.2.2 + diff --git a/packages/x11/driver/xf86-video-nouveau/patches/26_dcbconf_7_4_ignore.diff b/packages/x11/driver/xf86-video-nouveau/patches/26_dcbconf_7_4_ignore.diff new file mode 100644 index 0000000000..f6e6e1b10d --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/patches/26_dcbconf_7_4_ignore.diff @@ -0,0 +1,13 @@ +diff --git a/src/nv_bios.c b/src/nv_bios.c +index fe6368e..7b56148 100644 +--- a/src/nv_bios.c ++++ b/src/nv_bios.c +@@ -4104,6 +4104,8 @@ parse_dcb20_entry(ScrnInfoPtr pScrn, struct bios_parsed_dcb *bdcb, + mask = ~0x5; + if (conf & 0x4) + entry->lvdsconf.use_power_scripts = true; ++ if ((conf & 0xf0) == 0x60) ++ mask &= ~0xf0; + } + if (conf & mask) { + /* I'm bored of getting this reported; left as a reminder for someone to fix it */ diff --git a/packages/x11/driver/xf86-video-nouveau/patches/27_nouveau-fb-resize.diff b/packages/x11/driver/xf86-video-nouveau/patches/27_nouveau-fb-resize.diff new file mode 100644 index 0000000000..58903d52cf --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/patches/27_nouveau-fb-resize.diff @@ -0,0 +1,395 @@ +From 7e4b7775589cff4433de1f3dfa1416c66cdfe060 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Tue, 14 Apr 2009 09:23:07 +1000 +Subject: [PATCH 6/6] f11: support framebuffer resize without driver pixmaps + +--- + src/drmmode_display.c | 75 +++++++++++++++++++++++++++++++-- + src/nouveau_exa.c | 17 ++++---- + src/nv50_randr.c | 6 +++ + src/nv_crtc.c | 16 ++++++- + src/nv_driver.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++--- + src/nv_type.h | 9 ++++- + 6 files changed, 209 insertions(+), 22 deletions(-) + +diff --git a/src/drmmode_display.c b/src/drmmode_display.c +index ca1a60b..c666c9f 100644 +--- a/src/drmmode_display.c ++++ b/src/drmmode_display.c +@@ -1069,6 +1069,59 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) + } + + static Bool ++nv_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height) ++{ ++ ScreenPtr pScreen = pScrn->pScreen; ++ NVPtr pNv = NVPTR(pScrn); ++ const int cpp = pScrn->bitsPerPixel >> 3; ++ int pitch = NOUVEAU_ALIGN(width * cpp, 256); ++ int ret = 0; ++ PixmapPtr ppix; ++ ++ if (pScrn->virtualX == width && pScrn->virtualY == height && ++ (pNv->NoAccel || pNv->exa_onscreen)) ++ return TRUE; ++ ++ if (!pNv->dev) ++ goto out_done; ++ ++ nouveau_fb_free(pScrn); ++ ++ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp); ++ if (ret) { ++ width = pScrn->virtualX; ++ height = pScrn->virtualY; ++ pitch = (*pScreen->GetScreenPixmap)(pScreen)->devKind; ++ ++ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp); ++ /* famous last words: "this should never happen!" */ ++ if (ret) ++ FatalError("couldn't allocate framebuffer!\n"); ++ ++ ret = -ENOMEM; ++ } ++ ++out_done: ++ if (!ret && pNv->ShadowFB) { ++ xfree(pNv->ShadowPtr); ++ pNv->ShadowPtr = xalloc(pitch * height); ++ pNv->ShadowPitch = pitch; ++ } ++ ++ ppix = (*pScreen->GetScreenPixmap)(pScreen); ++ ++ (*pScreen->ModifyPixmapHeader)(ppix, width, height, -1, -1, pitch, ++ (!pNv->NoAccel || pNv->ShadowFB) ? ++ pNv->ShadowPtr : pNv->FBMap); ++ pScrn->pixmapPrivate.ptr = ppix->devPrivate.ptr; ++ ++ pScrn->virtualX = width; ++ pScrn->virtualY = height; ++ pScrn->displayWidth = pitch / cpp; ++ return ret == 0; ++} ++ ++static Bool + drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) + { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); +@@ -1083,10 +1136,23 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) + ErrorF("resize called %d %d\n", width, height); + + if (!pNv->exa_driver_pixmaps) { +- if (width > scrn->virtualX || height > scrn->virtualY) ++ if (!nv_xf86crtc_resize(scrn, width, height)) + return FALSE; + +- scrn->displayWidth = NOUVEAU_ALIGN(width, 64); ++ if (drmmode->fb_id) ++ drmModeRmFB(drmmode->fd, drmmode->fb_id); ++ drmmode->fb_id = 0; ++ ++ for (i = 0; i < config->num_crtc; i++) { ++ xf86CrtcPtr crtc = config->crtc[i]; ++ ++ if (!crtc->enabled) ++ continue; ++ ++ xf86CrtcSetMode(crtc, &crtc->mode, crtc->rotation, ++ crtc->x, crtc->y); ++ } ++ + return TRUE; + } + +@@ -1149,7 +1215,7 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { + + Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp) + { +- xf86CrtcConfigPtr xf86_config; ++ xf86CrtcConfigPtr xf86_config; + drmmode_ptr drmmode; + int i; + +@@ -1173,8 +1239,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp) + for (i = 0; i < drmmode->mode_res->count_connectors; i++) + drmmode_output_init(pScrn, drmmode, i); + +- xf86InitialConfiguration(pScrn, NVPTR(pScrn)->exa_driver_pixmaps); +- ++ xf86InitialConfiguration(pScrn, TRUE); + return TRUE; + } + +diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c +index aee2794..41e3f85 100644 +--- a/src/nouveau_exa.c ++++ b/src/nouveau_exa.c +@@ -279,7 +279,10 @@ nouveau_exa_prepare_access(PixmapPtr ppix, int index) + } else + if (ppix == pScreen->GetScreenPixmap(pScreen)) { + nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR); +- ppix->devPrivate.ptr = pNv->scanout->map; ++ if (pNv->scanout != pNv->FB) ++ ppix->devPrivate.ptr = pNv->scanout->map; ++ else ++ ppix->devPrivate.ptr = pNv->FB->map + pNv->exa_onscreen->offset; + } else { + /* force migration */ + return FALSE; +@@ -301,7 +304,8 @@ nouveau_exa_finish_access(PixmapPtr ppix, int index) + if (ppix == pScreen->GetScreenPixmap(pScreen)) { + ppix->devPrivate.ptr = NULL; + nouveau_bo_unmap(pNv->scanout); +- nv50_shadow_damage_frontbuffer_fallback(pScrn); ++ if (pNv->Architecture == NV_ARCH_50) ++ nv50_shadow_damage_frontbuffer_fallback(pScrn); + } + } + +@@ -543,10 +547,9 @@ Bool + nouveau_exa_pixmap_is_onscreen(PixmapPtr ppix) + { + ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; +- NVPtr pNv = NVPTR(pScrn); + unsigned long offset = exaGetPixmapOffset(ppix); + +- if (offset < pNv->EXADriverPtr->offScreenBase) ++ if (offset == 0) + return TRUE; + + return FALSE; +@@ -630,10 +633,8 @@ nouveau_exa_init(ScreenPtr pScreen) + } + + /* Needed for frontbuffer fallbacks (to ensure it accesses the linear fb). */ +- if (pNv->Architecture >= NV_ARCH_50) { +- exa->PrepareAccess = nouveau_exa_prepare_access; +- exa->FinishAccess = nouveau_exa_finish_access; +- } ++ exa->PrepareAccess = nouveau_exa_prepare_access; ++ exa->FinishAccess = nouveau_exa_finish_access; + + exa->MarkSync = nouveau_exa_mark_sync; + exa->WaitMarker = nouveau_exa_wait_marker; +diff --git a/src/nv50_randr.c b/src/nv50_randr.c +index 538c883..c451ba3 100644 +--- a/src/nv50_randr.c ++++ b/src/nv50_randr.c +@@ -289,8 +289,14 @@ nv50_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) + { + ScrnInfoPtr pScrn = crtc->scrn; + NV50CrtcPrivatePtr nv_crtc = crtc->driver_private; ++ NVPtr pNv = NVPTR(pScrn); + + nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, x, y); ++ if (nv_crtc->crtc->front_buffer && ++ nv_crtc->crtc->front_buffer != pNv->scanout) { ++ nv_crtc->crtc->SetFB(nv_crtc->crtc, pNv->scanout); ++ nv_crtc->crtc->ModeSet(nv_crtc->crtc, &crtc->mode); ++ } + + NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0); + } +diff --git a/src/nv_crtc.c b/src/nv_crtc.c +index 1d50874..cfa06e1 100644 +--- a/src/nv_crtc.c ++++ b/src/nv_crtc.c +@@ -1154,7 +1154,10 @@ void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y) + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); +- uint32_t start = (y * pScrn->displayWidth + x) * pScrn->bitsPerPixel / 8; ++ uint32_t cpp = pScrn->bitsPerPixel / 8; ++ uint32_t start = (y * pScrn->displayWidth + x) * cpp; ++ uint32_t pitch = pScrn->displayWidth * cpp; ++ NVCrtcRegPtr regp = &pNv->ModeReg.crtc_reg[nv_crtc->head]; + + if (crtc->rotatedData != NULL) /* we do not exist on the real framebuffer */ + #if NOUVEAU_EXA_PIXMAPS +@@ -1162,8 +1165,17 @@ void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y) + #else + start = pNv->FB->offset + nv_crtc->shadow->offset; /* We do exist relative to the framebuffer */ + #endif +- else ++ else { ++ if (pNv->exa_onscreen) ++ start += pNv->exa_onscreen->offset; + start += pNv->FB->offset; ++ } ++ ++ regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = pitch >> 3; ++ regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = ++ XLATE(pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX); ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX); + + start &= ~3; + pNv->ModeReg.crtc_reg[nv_crtc->head].fb_start = start; +diff --git a/src/nv_driver.c b/src/nv_driver.c +index f097fb9..0cc81ae 100644 +--- a/src/nv_driver.c ++++ b/src/nv_driver.c +@@ -900,16 +900,112 @@ Bool NVI2CInit(ScrnInfoPtr pScrn) + return TRUE; + } + ++void ++nouveau_fb_free(ScrnInfoPtr pScrn) ++{ ++ ScreenPtr pScreen = pScrn->pScreen; ++ NVPtr pNv = NVPTR(pScrn); ++ ++ if (!pNv->NoAccel && pNv->exa_onscreen) { ++ exaOffscreenFree(pScreen, pNv->exa_onscreen); ++ pNv->exa_onscreen = NULL; ++ } ++ ++ if (pNv->scanout && pNv->FB != pNv->scanout) ++ nouveau_bo_ref(NULL, &pNv->scanout); ++} ++ ++int ++nouveau_fb_alloc(ScrnInfoPtr pScrn, int pitch, int height, int cpp) ++{ ++ ScreenPtr pScreen = pScrn->pScreen; ++ NVPtr pNv = NVPTR(pScrn); ++ int ret; ++ ++ if (!pNv->NoAccel) { ++ pNv->exa_onscreen = exaOffscreenAlloc(pScreen, pitch * height, ++ 256, TRUE, NULL, NULL); ++ if (!pNv->exa_onscreen) ++ return -ENOMEM; ++ } ++ ++ if (!pNv->scanout) { ++ ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, ++ 256, pitch * height, &pNv->scanout); ++ if (ret) { ++ nouveau_fb_free(pScrn); ++ return ret; ++ } ++ } ++ ++ ++ return 0; ++} ++ + static Bool + nv_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height) + { +-#if 0 +- do not change virtual* for now, as it breaks multihead server regeneration +- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_xf86crtc_resize is called with %dx%d resolution.\n", width, height); ++ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); ++ ScreenPtr pScreen = pScrn->pScreen; ++ NVPtr pNv = NVPTR(pScrn); ++ const int cpp = pScrn->bitsPerPixel >> 3; ++ int pitch = NOUVEAU_ALIGN(width * cpp, 256); ++ int ret = 0, i; ++ PixmapPtr ppix; ++ ++ if (pScrn->virtualX == width && pScrn->virtualY == height && ++ (pNv->NoAccel || pNv->exa_onscreen)) ++ return TRUE; ++ ++ if (!pNv->dev) ++ goto out_done; ++ ++ nouveau_fb_free(pScrn); ++ ++ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp); ++ if (ret) { ++ width = pScrn->virtualX; ++ height = pScrn->virtualY; ++ pitch = (*pScreen->GetScreenPixmap)(pScreen)->devKind; ++ ++ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp); ++ /* famous last words: "this should never happen!" */ ++ if (ret) ++ FatalError("couldn't allocate framebuffer!\n"); ++ ++ ret = -ENOMEM; ++ } ++ ++out_done: ++ ++ if (!ret && pNv->ShadowFB) { ++ xfree(pNv->ShadowPtr); ++ pNv->ShadowPtr = xalloc(pitch * height); ++ pNv->ShadowPitch = pitch; ++ } ++ ++ ppix = pScreen->GetScreenPixmap(pScreen); ++ ++ (*pScreen->ModifyPixmapHeader)(ppix, width, height, -1, -1, pitch, ++ (!pNv->NoAccel || pNv->ShadowFB) ? ++ pNv->ShadowPtr : pNv->FBMap); ++ pScrn->pixmapPrivate.ptr = ppix->devPrivate.ptr; ++ + pScrn->virtualX = width; + pScrn->virtualY = height; +-#endif +- return TRUE; ++ pScrn->displayWidth = pitch / cpp; ++ ++ for (i = 0; i < config->num_crtc; i++) { ++ xf86CrtcPtr crtc = config->crtc[i]; ++ ++ if (!crtc->enabled) ++ continue; ++ ++ xf86CrtcSetMode(crtc, &crtc->mode, crtc->rotation, ++ crtc->x, crtc->y); ++ } ++ ++ return ret == 0; + } + + static const xf86CrtcConfigFuncsRec nv_xf86crtc_config_funcs = { +@@ -1423,7 +1519,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) + } else + nv50_output_create(pScrn); /* create randr-1.2 "outputs". */ + +- if (!xf86InitialConfiguration(pScrn, FALSE)) ++ if (!xf86InitialConfiguration(pScrn, TRUE)) + NVPreInitFail("No valid modes.\n"); + } + +diff --git a/src/nv_type.h b/src/nv_type.h +index 5396cc8..1a9b9ed 100644 +--- a/src/nv_type.h ++++ b/src/nv_type.h +@@ -304,8 +304,11 @@ typedef struct _NVRec { + volatile CARD8 *PDIO1; + + uint8_t cur_head; ++ + ExaDriverPtr EXADriverPtr; + Bool exa_driver_pixmaps; ++ ExaOffscreenArea * exa_onscreen; ++ + ScreenBlockHandlerProcPtr BlockHandler; + CloseScreenProcPtr CloseScreen; + /* Cursor */ +@@ -494,11 +497,15 @@ nouveau_pixmap_offset(PixmapPtr ppix) + { + ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; + NVPtr pNv = NVPTR(pScrn); ++ unsigned offset; + + if (pNv->exa_driver_pixmaps) + return 0; + +- return exaGetPixmapOffset(ppix); ++ offset = exaGetPixmapOffset(ppix); ++ if (offset == 0) ++ offset = pNv->exa_onscreen->offset; ++ return offset; + } + + #endif /* __NV_STRUCT_H__ */ +-- +1.6.2.2 + diff --git a/packages/x11/driver/xf86-video-nouveau/url b/packages/x11/driver/xf86-video-nouveau/url new file mode 100644 index 0000000000..fa23ce43bb --- /dev/null +++ b/packages/x11/driver/xf86-video-nouveau/url @@ -0,0 +1 @@ +http://sources.openelec.tv/svn/xf86-video-nouveau-master-20090425.tar.bz2