+ return nv50_screen(pscreen)->fence.map[0];
+}
+
+static int
+nv50_screen_init_hwctx(struct nv50_screen *screen, unsigned tls_space)
+{
+ struct nouveau_pushbuf *push = screen->base.pushbuf;
+ struct nv04_fifo *fifo;
+ unsigned i;
+
+ fifo = (struct nv04_fifo *)screen->base.channel->data;
+
+ BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
+ PUSH_DATA (push, screen->m2mf->handle);
+ BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3);
+ PUSH_DATA (push, screen->sync->handle);
+ PUSH_DATA (push, fifo->vram);
+ PUSH_DATA (push, fifo->vram);
+
+ BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
+ PUSH_DATA (push, screen->eng2d->handle);
+ BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4);
+ PUSH_DATA (push, screen->sync->handle);
+ PUSH_DATA (push, fifo->vram);
+ PUSH_DATA (push, fifo->vram);
+ PUSH_DATA (push, fifo->vram);
+ BEGIN_NV04(push, NV50_2D(OPERATION), 1);
+ PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
+ BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, SUBC_2D(0x0888), 1);
+ PUSH_DATA (push, 1);
+
+ BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
+ PUSH_DATA (push, screen->tesla->handle);
+
+ BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
+ PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
+
+ BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1);
+ PUSH_DATA (push, screen->sync->handle);
+ BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11);
+ for (i = 0; i < 11; ++i)
+ PUSH_DATA(push, fifo->vram);
+ BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
+ for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
+ PUSH_DATA(push, fifo->vram);
+
+ BEGIN_NV04(push, NV50_3D(REG_MODE), 1);
+ PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED);
+ BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1);
+ PUSH_DATA (push, 0xf);
+
+ BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
+ PUSH_DATA (push, 1);
+
+ BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
+ PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1);
+ PUSH_DATA (push, 1);
+
+ if (screen->tesla->oclass >= NVA0_3D_CLASS) {
+ BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1);
+ PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
+ }
+
+ BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1);
+ PUSH_DATA (push, 0x3f);
+
+ BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2);
+ PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
+ PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
+
+ BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2);
+ PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
+ PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
+
+ BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2);
+ PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
+ PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
+
+ BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->tls_bo->offset);
+ PUSH_DATA (push, screen->tls_bo->offset);
+ PUSH_DATA (push, util_logbase2(tls_space / 8));
+
+ BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->stack_bo->offset);
+ PUSH_DATA (push, screen->stack_bo->offset);
+ PUSH_DATA (push, 4);
+
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->uniforms->offset + (0 << 16));
+ PUSH_DATA (push, screen->uniforms->offset + (0 << 16));
+ PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000);
+
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->uniforms->offset + (1 << 16));
+ PUSH_DATA (push, screen->uniforms->offset + (1 << 16));
+ PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000);
+
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->uniforms->offset + (2 << 16));
+ PUSH_DATA (push, screen->uniforms->offset + (2 << 16));
+ PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000);
+
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->uniforms->offset + (3 << 16));
+ PUSH_DATA (push, screen->uniforms->offset + (3 << 16));
+ PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200);
+
+ BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 6);
+ PUSH_DATA (push, (NV50_CB_PVP << 12) | 0x001);
+ PUSH_DATA (push, (NV50_CB_PGP << 12) | 0x021);
+ PUSH_DATA (push, (NV50_CB_PFP << 12) | 0x031);
+ PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01);
+ PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21);
+ PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31);
+
+ /* max TIC (bits 4:8) & TSC bindings, per program type */
+ for (i = 0; i < 3; ++i) {
+ BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1);
+ PUSH_DATA (push, 0x54);
+ }
+
+ BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->txc->offset);
+ PUSH_DATA (push, screen->txc->offset);
+ PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1);
+
+ BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->txc->offset + 65536);
+ PUSH_DATA (push, screen->txc->offset + 65536);
+ PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1);
+
+ BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1);
+ PUSH_DATA (push, 0);
+
+ BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1);
+ PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
+ BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
+ for (i = 0; i < 8 * 2; ++i)
+ PUSH_DATA(push, 0);
+ BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1);
+ PUSH_DATA (push, 0);
+
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
+ PUSH_DATAf(push, 0.0f);
+ PUSH_DATAf(push, 1.0f);
+
+ BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
+#ifdef NV50_SCISSORS_CLIPPING
+ PUSH_DATA (push, 0x0000);
+#else
+ PUSH_DATA (push, 0x1080);
+#endif
+
+ BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1);
+ PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
+
+ /* We use scissors instead of exact view volume clipping,
+ * so they're always enabled.
+ */
+ BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 8192 << 16);
+ PUSH_DATA (push, 8192 << 16);
+
+ BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1);
+ PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL);
+ BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
+ PUSH_DATA (push, 0x11111111);
+ BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
+ PUSH_DATA (push, 1);
+
+ PUSH_KICK (push);
+
+ return 0;