diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2008-10-27 00:04:37 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2008-10-27 00:04:37 +1100 |
commit | 37dc9426ebab81262c1da725c10ac824d89429f7 (patch) | |
tree | ab8f7d3b6d2692dad197ee5374c967375f5e1362 | |
parent | bc2c2728b030cb91661af36a2406d1999cf8d632 (diff) | |
parent | bb20175001748e5d2fab1b9cb2075bbe5d94e5ed (diff) | |
download | xorg-driver-xf86-video-nouveau-37dc9426ebab81262c1da725c10ac824d89429f7.tar.gz |
Merge remote branch 'origin/master' into ng
Conflicts:
src/nouveau_channel.c
src/nouveau_device.c
src/nouveau_xv.c
src/nv30_shaders.c
src/nv_crtc.c
src/nv_driver.c
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/nouveau_xv.c | 2 | ||||
-rw-r--r-- | src/nv30_exa.c | 29 | ||||
-rw-r--r-- | src/nv30_shaders.c | 124 | ||||
-rw-r--r-- | src/nv30_shaders.h | 2 | ||||
-rw-r--r-- | src/nv30_xv_tex.c | 13 | ||||
-rw-r--r-- | src/nv40_exa.c | 32 | ||||
-rw-r--r-- | src/nv40_xv_tex.c | 13 | ||||
-rw-r--r-- | src/nv_accel_common.c | 28 | ||||
-rw-r--r-- | src/nv_bios.c | 527 | ||||
-rw-r--r-- | src/nv_crtc.c | 546 | ||||
-rw-r--r-- | src/nv_cursor.c | 27 | ||||
-rw-r--r-- | src/nv_dac.c | 2 | ||||
-rw-r--r-- | src/nv_dri.c | 26 | ||||
-rw-r--r-- | src/nv_driver.c | 166 | ||||
-rw-r--r-- | src/nv_hw.c | 1271 | ||||
-rw-r--r-- | src/nv_output.c | 942 | ||||
-rw-r--r-- | src/nv_pcicompat.h | 4 | ||||
-rw-r--r-- | src/nv_proto.h | 40 | ||||
-rw-r--r-- | src/nv_setup.c | 170 | ||||
-rw-r--r-- | src/nv_type.h | 19 | ||||
-rw-r--r-- | src/nvreg.h | 217 |
23 files changed, 1942 insertions, 2262 deletions
diff --git a/Makefile.am b/Makefile.am index 3a02f4e..4d17fd0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,5 +26,5 @@ EXTRA_DIST = README.NV1 ChangeLog # Always regenerate the changelog CLEANFILES = ChangeLog ChangeLog: FORCE - git-log > ChangeLog + git log > ChangeLog FORCE: diff --git a/configure.ac b/configure.ac index be5c46c..d9e7310 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,7 @@ AC_DEFINE_UNQUOTED([NV_PATCHLEVEL], [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]\.[[0-9]]\.\([[0-9]]\)/\1/')], [Patch version]) AC_DEFINE_UNQUOTED([NV_DRIVER_DATE], - [$(echo -n \";git-log |head -3|tail -1|tr -d '\n';echo -n \")], + [$(echo -n \";git log |head -3|tail -1|tr -d '\n';echo -n \")], [Driver date]) AC_CONFIG_SRCDIR([Makefile.am]) diff --git a/src/nouveau_xv.c b/src/nouveau_xv.c index faf411e..ac43d61 100644 --- a/src/nouveau_xv.c +++ b/src/nouveau_xv.c @@ -278,7 +278,7 @@ nouveau_xv_bo_realloc(ScrnInfoPtr pScrn, unsigned flags, unsigned size, * @param pScrn screen whose port wants to free memory * @param pPriv port to free memory of */ -static void +void NVFreePortMemory(ScrnInfoPtr pScrn, NVPortPrivPtr pPriv) { nouveau_bo_ref(NULL, &pPriv->video_mem); diff --git a/src/nv30_exa.c b/src/nv30_exa.c index 63a2e06..1da5bc7 100644 --- a/src/nv30_exa.c +++ b/src/nv30_exa.c @@ -607,9 +607,10 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn) struct nouveau_channel *chan = pNv->chan; struct nouveau_grobj *rankine; uint32_t class = 0, chipset; - int i; + int next_hw_offset = 0, i; - NV30EXAHackupA8Shaders(pScrn); + if (!nv40_fp_map_a8[0]) + NV30EXAHackupA8Shaders(pScrn); #define NV30TCL_CHIPSET_3X_MASK 0x00000003 #define NV35TCL_CHIPSET_3X_MASK 0x000001e0 @@ -639,6 +640,22 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn) } rankine = pNv->Nv3D; + if (!pNv->shader_mem) { + if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, + 0, 0x1000, &pNv->shader_mem)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't alloc fragprog buffer!\n"); + nouveau_grobj_free(&pNv->Nv3D); + return FALSE; + } + if (nouveau_bo_map(pNv->shader_mem, NOUVEAU_BO_RDWR)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't map fragprog buffer!\n"); + nouveau_grobj_free(&pNv->Nv3D); + return FALSE; + } + } + BEGIN_RING(chan, rankine, NV34TCL_DMA_TEXTURE0, 3); OUT_RING (chan, chan->vram->handle); OUT_RING (chan, chan->gart->handle); @@ -832,6 +849,12 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn) OUT_RING (chan, 4096<<16); OUT_RING (chan, 4096<<16); + for (i = 0; i < NV30EXA_FPID_MAX; i++) { + NV30_UploadFragProg(pNv, nv40_fp_map[i], &next_hw_offset); + NV30_UploadFragProg(pNv, nv40_fp_map_a8[i], &next_hw_offset); + } + NV30_UploadFragProg(pNv, &nv30_fp_yv12_bicubic, &next_hw_offset); + NV30_UploadFragProg(pNv, &nv30_fp_yv12_bilinear, &next_hw_offset); + return TRUE; } - diff --git a/src/nv30_shaders.c b/src/nv30_shaders.c index b74b851..173accb 100644 --- a/src/nv30_shaders.c +++ b/src/nv30_shaders.c @@ -23,48 +23,54 @@ #include "nv30_shaders.h" -void -NV30_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader) +void NV30_UploadFragProg(NVPtr pNv, nv_shader_t *shader, int *hw_offset) { - NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - struct nouveau_grobj *rankine = pNv->Nv3D; - static struct nouveau_bo *fp_mem = NULL; - static int next_hw_id_offset = 0; - - if (!fp_mem) { - if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, - 0, 0x1000, &fp_mem)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't alloc fragprog buffer!\n"); - return; - } - } - - if (!shader->hw_id) { - uint32_t *map; - int i; + uint32_t *map = pNv->shader_mem->map + *hw_offset; + uint32_t data, i; - nouveau_bo_map(fp_mem, NOUVEAU_BO_WR); - map = fp_mem->map + next_hw_id_offset; + shader->hw_id = *hw_offset; - for (i = 0; i < shader->size; i++) { - uint32_t data = shader->data[i]; + for (i = 0; i < shader->size; i++) { + data = shader->data[i]; #if (X_BYTE_ORDER != X_LITTLE_ENDIAN) - data = ((data >> 16) | ((data & 0xffff) << 16)); + data = ((data >> 16) | ((data & 0xffff) << 16)); #endif - map[i] = data; - } + map[i] = data; + } - nouveau_bo_unmap(fp_mem); + *hw_offset += (shader->size * sizeof(uint32_t)); + *hw_offset = (*hw_offset + 63) & ~63; +} - shader->hw_id += next_hw_id_offset; - next_hw_id_offset += (shader->size * sizeof(uint32_t)); - next_hw_id_offset = (next_hw_id_offset + 63) & ~63; +void NV40_UploadVtxProg(NVPtr pNv, nv_shader_t *shader, int *hw_id) +{ + struct nouveau_channel *chan = pNv->chan; + struct nouveau_grobj *curie = pNv->Nv3D; + int i; + + shader->hw_id = *hw_id; + + BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_FROM_ID, 1); + OUT_RING (chan, (shader->hw_id)); + for (i=0; i<shader->size; i+=4) { + BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_INST(0), 4); + OUT_RING (chan, shader->data[i + 0]); + OUT_RING (chan, shader->data[i + 1]); + OUT_RING (chan, shader->data[i + 2]); + OUT_RING (chan, shader->data[i + 3]); + (*hw_id)++; } +} + +void +NV30_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader) +{ + NVPtr pNv = NVPTR(pScrn); + struct nouveau_channel *chan = pNv->chan; + struct nouveau_grobj *rankine = pNv->Nv3D; BEGIN_RING(chan, rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1); - OUT_RELOC (chan, fp_mem, shader->hw_id, NOUVEAU_BO_VRAM | + OUT_RELOC (chan, pNv->shader_mem, shader->hw_id, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0, NV34TCL_FP_ACTIVE_PROGRAM_DMA1); @@ -78,31 +84,12 @@ NV30_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader) OUT_RING (chan, (shader->card_priv.NV30FP.num_regs-1)/2); } - - void NV40_LoadVtxProg(ScrnInfoPtr pScrn, nv_shader_t *shader) { NVPtr pNv = NVPTR(pScrn); struct nouveau_channel *chan = pNv->chan; struct nouveau_grobj *curie = pNv->Nv3D; - static int next_hw_id = 0; - int i; - - if (!shader->hw_id) { - shader->hw_id = next_hw_id; - - BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_FROM_ID, 1); - OUT_RING (chan, (shader->hw_id)); - for (i=0; i<shader->size; i+=4) { - BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_INST(0), 4); - OUT_RING (chan, shader->data[i + 0]); - OUT_RING (chan, shader->data[i + 1]); - OUT_RING (chan, shader->data[i + 2]); - OUT_RING (chan, shader->data[i + 3]); - next_hw_id++; - } - } BEGIN_RING(chan, curie, NV40TCL_VP_START_FROM_ID, 1); OUT_RING (chan, (shader->hw_id)); @@ -118,42 +105,9 @@ NV40_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader) NVPtr pNv = NVPTR(pScrn); struct nouveau_channel *chan = pNv->chan; struct nouveau_grobj *curie = pNv->Nv3D; - static struct nouveau_bo *fp_mem = NULL; - static int next_hw_id_offset = 0; - - if (!fp_mem) { - if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, - 0, 0x1000, &fp_mem)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't alloc fragprog buffer!\n"); - return; - } - } - - if (!shader->hw_id) { - uint32_t *map; - int i; - - nouveau_bo_map(fp_mem, NOUVEAU_BO_WR); - map = fp_mem->map + next_hw_id_offset; - - for (i = 0; i < shader->size; i++) { - uint32_t data = shader->data[i]; -#if (X_BYTE_ORDER != X_LITTLE_ENDIAN) - data = ((data >> 16) | ((data & 0xffff) << 16)); -#endif - map[i] = data; - } - - nouveau_bo_unmap(fp_mem); - - shader->hw_id = next_hw_id_offset; - next_hw_id_offset += (shader->size * sizeof(uint32_t)); - next_hw_id_offset = (next_hw_id_offset + 63) & ~63; - } BEGIN_RING(chan, curie, NV40TCL_FP_ADDRESS, 1); - OUT_RELOC (chan, fp_mem, shader->hw_id, NOUVEAU_BO_VRAM | + OUT_RELOC (chan, pNv->shader_mem, shader->hw_id, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1); diff --git a/src/nv30_shaders.h b/src/nv30_shaders.h index d51fe3f..10639ce 100644 --- a/src/nv30_shaders.h +++ b/src/nv30_shaders.h @@ -42,6 +42,8 @@ typedef struct nv_shader { uint32_t data[NV_SHADER_MAX_PROGRAM_LENGTH]; } nv_shader_t; +void NV30_UploadFragProg(NVPtr pNv, nv_shader_t *shader, int *hw_offset); +void NV40_UploadVtxProg(NVPtr pNv, nv_shader_t *shader, int *hw_id); void NV40_LoadVtxProg(ScrnInfoPtr pScrn, nv_shader_t *shader); void NV40_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader); void NV30_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader); diff --git a/src/nv30_xv_tex.c b/src/nv30_xv_tex.c index 569cefd..c4cb72e 100644 --- a/src/nv30_xv_tex.c +++ b/src/nv30_xv_tex.c @@ -86,30 +86,29 @@ static void compute_filter_table(int8_t *t) { } } -static struct nouveau_bo *table_mem = NULL; static void NV30_LoadFilterTable(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - if (!table_mem) { + if (!pNv->xv_filtertable_mem) { if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, - 0, TABLE_SIZE*sizeof(float)*4, &table_mem)) { + 0, TABLE_SIZE*sizeof(float)*4, &pNv->xv_filtertable_mem)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't alloc filter table!\n"); return; } - if (nouveau_bo_map(table_mem, NOUVEAU_BO_RDWR)) { + if (nouveau_bo_map(pNv->xv_filtertable_mem, NOUVEAU_BO_RDWR)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't map filter table!\n"); return; } - int8_t *t=table_mem->map; + int8_t *t=pNv->xv_filtertable_mem->map; compute_filter_table(t); - nouveau_bo_unmap(table_mem); + nouveau_bo_unmap(pNv->xv_filtertable_mem); } } @@ -315,7 +314,7 @@ NV30PutTextureImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, OUT_RING (chan, NV34TCL_TX_UNITS_ENABLE_TX0 | NV34TCL_TX_UNITS_ENABLE_TX1); - NV30VideoTexture(pScrn, table_mem, 0, TABLE_SIZE, 1, 0 , 0); + NV30VideoTexture(pScrn, pNv->xv_filtertable_mem, 0, TABLE_SIZE, 1, 0 , 0); NV30VideoTexture(pScrn, src, src_offset, src_w, src_h, src_pitch, 1); /* We've got NV12 format, which means half width and half height texture of chroma channels. */ NV30VideoTexture(pScrn, src, src_offset2, src_w/2, src_h/2, src_pitch, 2); diff --git a/src/nv40_exa.c b/src/nv40_exa.c index 1cbfc69..fcb79aa 100644 --- a/src/nv40_exa.c +++ b/src/nv40_exa.c @@ -556,9 +556,10 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn) struct nouveau_channel *chan = pNv->chan; struct nouveau_grobj *curie; uint32_t class = 0, chipset; - int i; + int next_hw_id = 0, next_hw_offset = 0, i; - NV40EXAHackupA8Shaders(pScrn); + if (!nv40_fp_map_a8[0]) + NV40EXAHackupA8Shaders(pScrn); chipset = (nvReadMC(pNv, NV_PMC_BOOT_0) >> 20) & 0xff; @@ -584,6 +585,22 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn) } curie = pNv->Nv3D; + if (!pNv->shader_mem) { + if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, + 0, 0x1000, &pNv->shader_mem)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't alloc fragprog buffer!\n"); + nouveau_grobj_free(&pNv->Nv3D); + return FALSE; + } + if (nouveau_bo_map(pNv->shader_mem, NOUVEAU_BO_RDWR)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't map fragprog buffer!\n"); + nouveau_grobj_free(&pNv->Nv3D); + return FALSE; + } + } + BEGIN_RING(chan, curie, NV40TCL_DMA_NOTIFY, 1); OUT_RING (chan, pNv->notify0->handle); BEGIN_RING(chan, curie, NV40TCL_DMA_TEXTURE0, 2); @@ -687,6 +704,15 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn) OUT_RING (chan, (4095 << 16)); OUT_RING (chan, (4095 << 16)); + NV40_UploadVtxProg(pNv, &nv40_vp_exa_render, &next_hw_id); + for (i = 0; i < NV40EXA_FPID_MAX; i++) { + NV30_UploadFragProg(pNv, nv40_fp_map[i], &next_hw_offset); + NV30_UploadFragProg(pNv, nv40_fp_map_a8[i], &next_hw_offset); + } + + NV40_UploadVtxProg(pNv, &nv40_vp_video, &next_hw_id); + NV30_UploadFragProg(pNv, &nv40_fp_yv12_bicubic, &next_hw_offset); + NV30_UploadFragProg(pNv, &nv30_fp_yv12_bilinear, &next_hw_offset); + return TRUE; } - diff --git a/src/nv40_xv_tex.c b/src/nv40_xv_tex.c index 040b2b2..328b9e6 100644 --- a/src/nv40_xv_tex.c +++ b/src/nv40_xv_tex.c @@ -88,30 +88,29 @@ static void compute_filter_table(int8_t *t) { } } -static struct nouveau_bo *table_mem = NULL; static void NV40_LoadFilterTable(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - if (!table_mem) { + if (!pNv->xv_filtertable_mem) { if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, - 0, TABLE_SIZE*sizeof(float)*4, &table_mem)) { + 0, TABLE_SIZE*sizeof(float)*4, &pNv->xv_filtertable_mem)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't alloc filter table!\n"); return; } - if (nouveau_bo_map(table_mem, NOUVEAU_BO_RDWR)) { + if (nouveau_bo_map(pNv->xv_filtertable_mem, NOUVEAU_BO_RDWR)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't map filter table!\n"); return; } - int8_t *t=table_mem->map; + int8_t *t=pNv->xv_filtertable_mem->map; compute_filter_table(t); - nouveau_bo_unmap(table_mem); + nouveau_bo_unmap(pNv->xv_filtertable_mem); } } @@ -293,7 +292,7 @@ NV40PutTextureImage(ScrnInfoPtr pScrn, NV40_LoadFilterTable(pScrn); - NV40VideoTexture(pScrn, table_mem, 0, TABLE_SIZE, 1, 0 , 0); + NV40VideoTexture(pScrn, pNv->xv_filtertable_mem, 0, TABLE_SIZE, 1, 0 , 0); NV40VideoTexture(pScrn, src, src_offset, src_w, src_h, src_pitch, 1); /* We've got NV12 format, which means half width and half height texture of chroma channels. */ NV40VideoTexture(pScrn, src, src_offset2, src_w/2, src_h/2, src_pitch, 2); diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c index 2dd464b..bc42ae2 100644 --- a/src/nv_accel_common.c +++ b/src/nv_accel_common.c @@ -534,3 +534,31 @@ NVAccelCommonInit(ScrnInfoPtr pScrn) return TRUE; } +void NVAccelFree(NVPtr pNv) +{ + if (pNv->NoAccel) + return; + + nouveau_notifier_free(&pNv->notify0); + if (pNv->Architecture < NV_ARCH_50) { + nouveau_grobj_free(&pNv->NvContextSurfaces); + nouveau_grobj_free(&pNv->NvContextBeta1); + nouveau_grobj_free(&pNv->NvContextBeta4); + nouveau_grobj_free(&pNv->NvImagePattern); + nouveau_grobj_free(&pNv->NvRop); + nouveau_grobj_free(&pNv->NvRectangle); + nouveau_grobj_free(&pNv->NvImageBlit); + nouveau_grobj_free(&pNv->NvScaledImage); + nouveau_grobj_free(&pNv->NvClipRectangle); + nouveau_grobj_free(&pNv->NvImageFromCpu); + } else + nouveau_grobj_free(&pNv->Nv2D); + nouveau_grobj_free(&pNv->NvMemFormat); + + nouveau_grobj_free(&pNv->Nv3D); + + if (pNv->tesla_scratch) + nouveau_bo_ref(NULL, &pNv->tesla_scratch); + if (pNv->shader_mem) + nouveau_bo_ref(NULL, &pNv->shader_mem); +} diff --git a/src/nv_bios.c b/src/nv_bios.c index 09a9c45..dd9aa0e 100644 --- a/src/nv_bios.c +++ b/src/nv_bios.c @@ -33,13 +33,17 @@ #endif -/* FIXME: put these somewhere */ -#define SEQ_INDEX VGA_SEQ_INDEX -#define NV_VGA_CRTCX_OWNER_HEADA 0x0 -#define NV_VGA_CRTCX_OWNER_HEADB 0x3 +/* these defines are made up */ +#define NV_CIO_CRE_44_HEADA 0x0 +#define NV_CIO_CRE_44_HEADB 0x3 #define FEATURE_MOBILE 0x10 -#define DEBUGLEVEL 6 +//#define BIOSLOG(sip, fmt, arg...) xf86DrvMsg(sip->scrnIndex, X_INFO, fmt, ##arg) +//#define LOG_OLD_VALUE(x) x +#define BIOSLOG(sip, fmt, arg...) +#define LOG_OLD_VALUE(x) + +#define BIOS_USLEEP(n) usleep(n) static int crtchead = 0; @@ -86,18 +90,13 @@ static bool nv_cksum(const uint8_t *data, unsigned int length) static int score_vbios(ScrnInfoPtr pScrn, const uint8_t *data) { - /* check for BIOS signature */ if (!(data[0] == 0x55 && data[1] == 0xAA)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "... BIOS signature not found\n"); + xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, "... BIOS signature not found\n"); return 0; } if (nv_cksum(data, data[2] * 512)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "... BIOS checksum invalid\n"); - /* probably ought to set a do_not_execute flag for table parsing here, - * assuming most BIOSen are valid */ + xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, "... BIOS checksum invalid\n"); return 1; } else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "... appears to be valid\n"); @@ -188,6 +187,8 @@ static bool NVShadowVBIOS(ScrnInfoPtr pScrn, uint8_t *data) return true; } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid BIOS image found\n"); + return false; } @@ -217,7 +218,7 @@ static void parse_init_table(ScrnInfoPtr pScrn, bios_t *bios, unsigned int offse static void still_alive(void) { // sync(); -// usleep(2000); +// BIOS_USLEEP(2000); } static int nv_valid_reg(ScrnInfoPtr pScrn, uint32_t reg) @@ -239,8 +240,6 @@ static int nv_valid_reg(ScrnInfoPtr pScrn, uint32_t reg) return 1; if (WITHIN(reg,NV_PFIFO_OFFSET,NV_PFIFO_SIZE)) return 1; - if (pNv->VBIOS.chip_version >= 0x80 && WITHIN(reg, NV50_DISPLAY_OFFSET, NV50_DISPLAY_SIZE)) - return 1; /* maybe a little large, but it will do for the moment. */ if (pNv->VBIOS.chip_version >= 0x80 && WITHIN(reg, 0x1000, 0xEFFF)) return 1; @@ -262,6 +261,8 @@ static int nv_valid_reg(ScrnInfoPtr pScrn, uint32_t reg) return 1; if (WITHIN(reg,NV_PCRTC0_OFFSET,NV_PCRTC0_SIZE * 2)) return 1; + if (pNv->VBIOS.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 (pNv->VBIOS.chip_version >= 0x17 && reg == 0x0070fff0) @@ -279,12 +280,12 @@ static int nv_valid_reg(ScrnInfoPtr pScrn, uint32_t reg) static bool nv_valid_idx_port(ScrnInfoPtr pScrn, uint16_t port) { /* if adding more ports here, the read/write functions below will need - * updating so that the correct mmio range (PCIO, PDIO, PVIO) is used - * for the port in question + * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is + * used for the port in question */ - if (port == CRTC_INDEX_COLOR) + if (port == NV_CIO_CRX__COLOR) return true; - if (port == SEQ_INDEX) + if (port == NV_VIO_SRX) return true; xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -296,10 +297,10 @@ static bool nv_valid_idx_port(ScrnInfoPtr pScrn, uint16_t port) static bool nv_valid_port(ScrnInfoPtr pScrn, uint16_t port) { /* if adding more ports here, the read/write functions below will need - * updating so that the correct mmio range (PCIO, PDIO, PVIO) is used - * for the port in question + * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is + * used for the port in question */ - if (port == VGA_ENABLE) + if (port == NV_VIO_VSE2) return true; xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -331,9 +332,7 @@ static uint32_t nv32_rd(ScrnInfoPtr pScrn, uint32_t reg) data = NV_RD32(pNv->REGS, reg); - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " Read: Reg: 0x%08X, Data: 0x%08X\n", reg, data); + BIOSLOG(pScrn, " Read: Reg: 0x%08X, Data: 0x%08X\n", reg, data); return data; } @@ -349,11 +348,8 @@ static void nv32_wr(ScrnInfoPtr pScrn, uint32_t reg, uint32_t data) if (reg & 0x1) reg &= 0xfffffffe; - if (DEBUGLEVEL >= 8) - nv32_rd(pScrn, reg); - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data); + LOG_OLD_VALUE(nv32_rd(pScrn, reg)); + BIOSLOG(pScrn, " Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data); if (pNv->VBIOS.execute) { still_alive(); @@ -369,15 +365,13 @@ static uint8_t nv_idx_port_rd(ScrnInfoPtr pScrn, uint16_t port, uint8_t index) if (!nv_valid_idx_port(pScrn, port)) return 0; - if (port == SEQ_INDEX) + if (port == NV_VIO_SRX) data = NVReadVgaSeq(pNv, crtchead, index); - else /* assume CRTC_INDEX_COLOR */ + else /* assume NV_CIO_CRX__COLOR */ data = NVReadVgaCrtc(pNv, crtchead, index); - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " Indexed IO read: Port: 0x%04X, Index: 0x%02X, Head: 0x%02X, Data: 0x%02X\n", - port, index, crtchead, data); + BIOSLOG(pScrn, " Indexed IO read: Port: 0x%04X, Index: 0x%02X, Head: 0x%02X, Data: 0x%02X\n", + port, index, crtchead, data); return data; } @@ -390,30 +384,27 @@ static void nv_idx_port_wr(ScrnInfoPtr pScrn, uint16_t port, uint8_t index, uint return; /* The current head is maintained in a file scope variable crtchead. - * We trap changes to CRTCX_OWNER and update the head variable - * and hence the register set written. - * As CRTCX_OWNER only exists on CRTC0, we update crtchead to head0 - * in advance of the write, and to head1 after the write + * 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 == CRTC_INDEX_COLOR && index == NV_VGA_CRTCX_OWNER && data != NV_VGA_CRTCX_OWNER_HEADB) + if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 && data != NV_CIO_CRE_44_HEADB) crtchead = 0; - if (DEBUGLEVEL >= 8) - nv_idx_port_rd(pScrn, port, index); - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " Indexed IO write: Port: 0x%04X, Index: 0x%02X, Head: 0x%02X, Data: 0x%02X\n", - port, index, crtchead, data); + LOG_OLD_VALUE(nv_idx_port_rd(pScrn, port, index)); + BIOSLOG(pScrn, " Indexed IO write: Port: 0x%04X, Index: 0x%02X, Head: 0x%02X, Data: 0x%02X\n", + port, index, crtchead, data); if (pNv->VBIOS.execute) { still_alive(); - if (port == SEQ_INDEX) + if (port == NV_VIO_SRX) NVWriteVgaSeq(pNv, crtchead, index, data); - else /* assume CRTC_INDEX_COLOR */ + else /* assume NV_CIO_CRX__COLOR */ NVWriteVgaCrtc(pNv, crtchead, index, data); } - if (port == CRTC_INDEX_COLOR && index == NV_VGA_CRTCX_OWNER && data == NV_VGA_CRTCX_OWNER_HEADB) + if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 && data == NV_CIO_CRE_44_HEADB) crtchead = 1; } @@ -425,12 +416,10 @@ static uint8_t nv_port_rd(ScrnInfoPtr pScrn, uint16_t port) if (!nv_valid_port(pScrn, port)) return 0; - data = NVReadPVIO(pNv, crtchead, port); + data = NVReadPRMVIO(pNv, crtchead, NV_PRMVIO0_OFFSET + port); - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " IO read: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", - port, crtchead, data); + BIOSLOG(pScrn, " IO read: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", + port, crtchead, data); return data; } @@ -442,32 +431,13 @@ static void nv_port_wr(ScrnInfoPtr pScrn, uint16_t port, uint8_t data) if (!nv_valid_port(pScrn, port)) return; - if (DEBUGLEVEL >= 8) - nv_port_rd(pScrn, port); - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " IO write: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", - port, crtchead, data); + LOG_OLD_VALUE(nv_port_rd(pScrn, port)); + BIOSLOG(pScrn, " IO write: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", + port, crtchead, data); if (pNv->VBIOS.execute) { still_alive(); - NVWritePVIO(pNv, crtchead, port, data); - } -} - -#define ACCESS_UNLOCK 0 -#define ACCESS_LOCK 1 -static void crtc_access(ScrnInfoPtr pScrn, bool lock) -{ - NVPtr pNv = NVPTR(pScrn); - - if (pNv->twoHeads) - NVSetOwner(pScrn, 0); - NVLockVgaCrtc(pNv, 0, lock); - if (pNv->twoHeads) { - NVSetOwner(pScrn, 1); - NVLockVgaCrtc(pNv, 1, lock); - NVSetOwner(pScrn, crtchead); + NVWritePRMVIO(pNv, crtchead, NV_PRMVIO0_OFFSET + port, data); } } @@ -492,20 +462,15 @@ static bool io_flag_condition(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, uint8_t cmpval = bios->data[condptr + 8]; uint8_t data; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "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); + BIOSLOG(pScrn, "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 = nv_idx_port_rd(pScrn, crtcport, crtcindex); data = bios->data[flagarray + ((data & mask) >> shift)]; data &= flagarraymask; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Checking if 0x%02X equals 0x%02X\n", - offset, data, cmpval); + BIOSLOG(pScrn, "0x%04X: Checking if 0x%02X equals 0x%02X\n", offset, data, cmpval); if (data == cmpval) return true; @@ -734,7 +699,7 @@ static void setPLL_single(ScrnInfoPtr pScrn, uint32_t reg, int NM, int log2P) nv32_wr(pScrn, reg, (oldpll & 0xffff0000) | NM); /* wait a bit */ - usleep(64000); + BIOS_USLEEP(64000); nv32_rd(pScrn, reg); /* then write P as well */ @@ -896,7 +861,7 @@ static void setPLL(ScrnInfoPtr pScrn, bios_t *bios, uint32_t reg, uint32_t clk) getMNP_double(pScrn, &pll_lim, clk, &NM1, &NM2, &log2P); if (NM2 == 0xdead) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Could not find a suitable set of coefficients, giving up\n"); + "Could not find a suitable set of PLL coefficients, giving up\n"); return; } if (reg > 0x405c) @@ -999,10 +964,8 @@ static bool init_io_restrict_prog(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offs if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "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); + BIOSLOG(pScrn, "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 = (nv_idx_port_rd(pScrn, crtcport, crtcindex) & mask) >> shift; if (config > count) { @@ -1014,9 +977,7 @@ static bool init_io_restrict_prog(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offs configval = le32_to_cpu(*((uint32_t *)(&bios->data[offset + 11 + config * 4]))); - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Writing config %02X\n", offset, config); + BIOSLOG(pScrn, "0x%04X: Writing config %02X\n", offset, config); nv32_wr(pScrn, reg, configval); @@ -1039,9 +1000,7 @@ static bool init_repeat(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_e /* no iexec->execute check by design */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: REPEATING FOLLOWING SEGMENT %d TIMES\n", - offset, count); + BIOSLOG(pScrn, "0x%04X: Repeating following segment %d times\n", offset, count); iexec->repeat = true; @@ -1094,10 +1053,8 @@ static bool init_io_restrict_pll(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offse if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "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); + BIOSLOG(pScrn, "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 = (nv_idx_port_rd(pScrn, crtcport, crtcindex) & mask) >> shift; if (config > count) { @@ -1111,18 +1068,14 @@ static bool init_io_restrict_pll(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offse if (io_flag_condition_idx > 0) { if (io_flag_condition(pScrn, bios, offset, io_flag_condition_idx)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: CONDITION FULFILLED - FREQ DOUBLED\n", offset); + BIOSLOG(pScrn, "0x%04X: Condition fulfilled -- frequency doubled\n", offset); freq *= 2; } else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: CONDITION IS NOT FULFILLED. FREQ UNCHANGED\n", offset); + BIOSLOG(pScrn, "0x%04X: Condition not fulfilled -- frequency unchanged\n", offset); } - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n", - offset, reg, config, freq); + BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n", + offset, reg, config, freq); setPLL(pScrn, bios, reg, freq * 10); @@ -1177,10 +1130,8 @@ static bool init_copy(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exe if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "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); + BIOSLOG(pScrn, "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 = nv32_rd(pScrn, reg); @@ -1206,11 +1157,9 @@ static bool init_not(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exec * Invert the current execute / no-execute condition (i.e. "else") */ if (iexec->execute) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: ------ SKIPPING FOLLOWING COMMANDS ------\n", offset); + BIOSLOG(pScrn, "0x%04X: ------ Skipping following commands ------\n", offset); else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: ------ EXECUTING FOLLOWING COMMANDS ------\n", offset); + BIOSLOG(pScrn, "0x%04X: ------ Executing following commands ------\n", offset); iexec->execute = !iexec->execute; return true; @@ -1234,13 +1183,9 @@ static bool init_io_flag_condition(ScrnInfoPtr pScrn, bios_t *bios, uint16_t off return true; if (io_flag_condition(pScrn, bios, offset, cond)) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: CONDITION FULFILLED - CONTINUING TO EXECUTE\n", offset); + BIOSLOG(pScrn, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: CONDITION IS NOT FULFILLED\n", offset); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: ------ SKIPPING FOLLOWING COMMANDS ------\n", offset); + BIOSLOG(pScrn, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); iexec->execute = false; } @@ -1277,18 +1222,14 @@ static bool init_idx_addr_latched(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offs if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n", - offset, controlreg, datareg, mask, data, count); + BIOSLOG(pScrn, "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]; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Address: 0x%02X, Data: 0x%02X\n", offset, instaddress, instdata); + BIOSLOG(pScrn, "0x%04X: Address: 0x%02X, Data: 0x%02X\n", offset, instaddress, instdata); nv32_wr(pScrn, datareg, instdata); value = (nv32_rd(pScrn, controlreg) & mask) | data | instaddress; @@ -1330,10 +1271,8 @@ static bool init_io_restrict_pll2(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offs if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "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); + BIOSLOG(pScrn, "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; @@ -1348,10 +1287,8 @@ static bool init_io_restrict_pll2(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offs freq = le32_to_cpu(*((uint32_t *)(&bios->data[offset + 11 + config * 4]))); - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n", - offset, reg, config, freq); + BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n", + offset, reg, config, freq); setPLL(pScrn, bios, reg, freq); @@ -1375,10 +1312,8 @@ static bool init_pll2(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exe if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Reg: 0x%04X, Freq: %dkHz\n", - offset, reg, freq); + BIOSLOG(pScrn, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n", + offset, reg, freq); setPLL(pScrn, bios, reg, freq); @@ -1400,11 +1335,9 @@ static uint32_t get_tmds_index_reg(ScrnInfoPtr pScrn, uint8_t mlv) if (mlv >= 0x80) { /* here we assume that the DCB table has already been parsed */ - uint8_t dcb_entry; + uint8_t dcb_entry = NVReadVgaCrtc5758(NVPTR(pScrn), crtchead, 0); int dacoffset; - /* This register needs to be written to set index for reading CR58 */ - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, NV_VGA_CRTCX_57, 0); - dcb_entry = nv_idx_port_rd(pScrn, CRTC_INDEX_COLOR, NV_VGA_CRTCX_58); + if (dcb_entry > pNv->dcb_table.entries) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "CR58 doesn't have a valid DCB entry currently (%02X)\n", dcb_entry); @@ -1449,15 +1382,13 @@ static bool init_tmds(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exe if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", - offset, mlv, tmdsaddr, mask, data); + BIOSLOG(pScrn, "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(pScrn, mlv))) return false; - nv32_wr(pScrn, reg, tmdsaddr | 0x10000); + nv32_wr(pScrn, reg, tmdsaddr | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); value = (nv32_rd(pScrn, reg + 4) & mask) | data; nv32_wr(pScrn, reg + 4, value); nv32_wr(pScrn, reg, tmdsaddr); @@ -1489,10 +1420,8 @@ static bool init_zm_tmds_group(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n", - offset, mlv, count); + BIOSLOG(pScrn, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n", + offset, mlv, count); if (!(reg = get_tmds_index_reg(pScrn, mlv))) return false; @@ -1534,21 +1463,19 @@ static bool init_cr_idx_adr_latch(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offs if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Index1: 0x%02X, Index2: 0x%02X, BaseAddr: 0x%02X, Count: 0x%02X\n", - offset, crtcindex1, crtcindex2, baseaddr, count); + BIOSLOG(pScrn, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, BaseAddr: 0x%02X, Count: 0x%02X\n", + offset, crtcindex1, crtcindex2, baseaddr, count); - oldaddr = nv_idx_port_rd(pScrn, CRTC_INDEX_COLOR, crtcindex1); + oldaddr = nv_idx_port_rd(pScrn, NV_CIO_CRX__COLOR, crtcindex1); for (i = 0; i < count; i++) { - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, crtcindex1, baseaddr + i); + nv_idx_port_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex1, baseaddr + i); data = bios->data[offset + 5 + i]; - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, crtcindex2, data); + nv_idx_port_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex2, data); } - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, crtcindex1, oldaddr); + nv_idx_port_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex1, oldaddr); return true; } @@ -1574,13 +1501,11 @@ static bool init_cr(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exec_ if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", - offset, crtcindex, mask, data); + BIOSLOG(pScrn, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", + offset, crtcindex, mask, data); - value = (nv_idx_port_rd(pScrn, CRTC_INDEX_COLOR, crtcindex) & mask) | data; - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, crtcindex, value); + value = (nv_idx_port_rd(pScrn, NV_CIO_CRX__COLOR, crtcindex) & mask) | data; + nv_idx_port_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex, value); return true; } @@ -1602,7 +1527,7 @@ static bool init_zm_cr(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_ex if (!iexec->execute) return true; - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, crtcindex, data); + nv_idx_port_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex, data); return true; } @@ -1660,35 +1585,24 @@ static bool init_condition_time(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset retries *= 50; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Cond: 0x%02X, Retries: 0x%02X\n", offset, cond, retries); + BIOSLOG(pScrn, "0x%04X: Cond: 0x%02X, Retries: 0x%02X\n", offset, cond, retries); for (; retries > 0; retries--) { data = nv32_rd(pScrn, reg) & mask; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Checking if 0x%08X equals 0x%08X\n", - offset, data, cmpval); + BIOSLOG(pScrn, "0x%04X: Checking if 0x%08X equals 0x%08X\n", offset, data, cmpval); if (data != cmpval) { - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Condition not met, sleeping for 2ms\n", offset); - usleep(2000); + BIOSLOG(pScrn, "0x%04X: Condition not met, sleeping for 2ms\n", offset); + BIOS_USLEEP(2000); } else { - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Condition met, continuing\n", offset); + BIOSLOG(pScrn, "0x%04X: Condition met, continuing\n", offset); break; } } if (data != cmpval) { - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Condition still not met, skiping following opcodes\n", offset); + BIOSLOG(pScrn, "0x%04X: Condition still not met, skiping following opcodes\n", offset); iexec->execute = false; } @@ -1717,10 +1631,7 @@ static bool init_zm_reg_sequence(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offse if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n", - offset, basereg, count); + BIOSLOG(pScrn, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n", offset, basereg, count); for (i = 0; i < count; i++) { uint32_t reg = basereg + i * 4; @@ -1780,13 +1691,11 @@ static bool init_sub_direct(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, in if (!iexec->execute) return true; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%04X: EXECUTING SUB-ROUTINE AT 0x%04X\n", - offset, sub_offset); + BIOSLOG(pScrn, "0x%04X: Executing subroutine at 0x%04X\n", offset, sub_offset); parse_init_table(pScrn, bios, sub_offset, iexec); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%04X: END OF SUB-ROUTINE AT 0x%04X\n", - offset, sub_offset); + BIOSLOG(pScrn, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset); return true; } @@ -1819,10 +1728,8 @@ static bool init_copy_nv_reg(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, i if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "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); + BIOSLOG(pScrn, "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 = nv32_rd(pScrn, srcreg); @@ -1902,12 +1809,12 @@ static bool init_compute_mem(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, i /* 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 = nv_idx_port_rd(pScrn, SEQ_INDEX, 0x01); - nv_idx_port_wr(pScrn, SEQ_INDEX, 0x01, crdata | 0x20); + uint8_t crdata = nv_idx_port_rd(pScrn, NV_VIO_SRX, 0x01); + nv_idx_port_wr(pScrn, 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 SEQ_INDEX write) + * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write) */ nv32_wr(pScrn, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1); @@ -1940,7 +1847,7 @@ static bool init_reset(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_ex nv32_wr(pScrn, NV_PBUS_PCI_NV_19, 0); nv32_wr(pScrn, reg, value1); - usleep(10); + BIOS_USLEEP(10); nv32_wr(pScrn, reg, value2); nv32_wr(pScrn, NV_PBUS_PCI_NV_19, pci_nv_19); @@ -1965,14 +1872,15 @@ static bool init_configure_mem(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, /* no iexec->execute check by design */ - uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (nv_idx_port_rd(pScrn, CRTC_INDEX_COLOR, NV_VGA_CRTCX_SCRATCH4) >> 4); + uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (nv_idx_port_rd(pScrn, 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; - nv_idx_port_wr(pScrn, SEQ_INDEX, 0x01, nv_idx_port_rd(pScrn, SEQ_INDEX, 0x01) | 0x20); + nv_idx_port_wr(pScrn, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, + nv_idx_port_rd(pScrn, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); if (bios->data[meminitoffs] & 1) seqtbloffs = bios->legacy.ddr_seq_tbl_ptr; @@ -2017,7 +1925,7 @@ static bool init_configure_clk(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, /* no iexec->execute check by design */ - uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (nv_idx_port_rd(pScrn, CRTC_INDEX_COLOR, NV_VGA_CRTCX_SCRATCH4) >> 4); + uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (nv_idx_port_rd(pScrn, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4); int clock; if (bios->major_version > 2) @@ -2053,7 +1961,7 @@ static bool init_configure_preinit(ScrnInfoPtr pScrn, bios_t *bios, uint16_t off if (bios->major_version > 2) return false; - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, NV_VGA_CRTCX_SCRATCH4, cr3c); + nv_idx_port_wr(pScrn, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX, cr3c); return true; } @@ -2077,10 +1985,8 @@ static bool init_io(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exec_ if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n", - offset, crtcport, mask, data); + BIOSLOG(pScrn, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n", + offset, crtcport, mask, data); nv_port_wr(pScrn, crtcport, (nv_port_rd(pScrn, crtcport) & mask) | data); @@ -2102,15 +2008,13 @@ static bool init_sub(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exec if (!iexec->execute) return true; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: EXECUTING SUB-SCRIPT %d\n", offset, sub); + BIOSLOG(pScrn, "0x%04X: Calling script %d\n", offset, sub); parse_init_table(pScrn, bios, le16_to_cpu(*((uint16_t *)(&bios->data[bios->init_script_tbls_ptr + sub * 2]))), iexec); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: END OF SUB-SCRIPT %d\n", offset, sub); + BIOSLOG(pScrn, "0x%04X: End of script %d\n", offset, sub); return true; } @@ -2137,16 +2041,12 @@ static bool init_ram_condition(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, data = nv32_rd(pScrn, NV_PFB_BOOT_0) & mask; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Checking if 0x%08X equals 0x%08X\n", offset, data, cmpval); + BIOSLOG(pScrn, "0x%04X: Checking if 0x%08X equals 0x%08X\n", offset, data, cmpval); if (data == cmpval) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: CONDITION FULFILLED - CONTINUING TO EXECUTE\n", offset); + BIOSLOG(pScrn, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%04X: CONDITION IS NOT FULFILLED\n", offset); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: ------ SKIPPING FOLLOWING COMMANDS ------\n", offset); + BIOSLOG(pScrn, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); iexec->execute = false; } @@ -2172,10 +2072,7 @@ static bool init_nv_reg(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_e if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n", - offset, reg, mask, data); + BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n", offset, reg, mask, data); nv32_wr(pScrn, reg, (nv32_rd(pScrn, reg) & mask) | data); @@ -2206,10 +2103,8 @@ static bool init_macro(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_ex if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, Count: 0x%02X\n", - offset, macro_index_tbl_idx, macro_tbl_idx, count); + BIOSLOG(pScrn, "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; @@ -2249,8 +2144,7 @@ static bool init_resume(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_e return true; iexec->execute = true; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: ---- EXECUTING FOLLOWING COMMANDS ----\n", offset); + BIOSLOG(pScrn, "0x%04X: ---- Executing following commands ----\n", offset); return true; } @@ -2308,11 +2202,9 @@ static bool init_time(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exe if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Sleeping for 0x%04X microseconds\n", offset, time); + BIOSLOG(pScrn, "0x%04X: Sleeping for 0x%04X microseconds\n", offset, time); - usleep(time); + BIOS_USLEEP(time); return true; } @@ -2341,28 +2233,17 @@ static bool init_condition(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, ini if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Cond: 0x%02X, Reg: 0x%08X, Mask: 0x%08X, Cmpval: 0x%08X\n", - offset, cond, reg, mask, cmpval); + BIOSLOG(pScrn, "0x%04X: Cond: 0x%02X, Reg: 0x%08X, Mask: 0x%08X, Cmpval: 0x%08X\n", + offset, cond, reg, mask, cmpval); data = nv32_rd(pScrn, reg) & mask; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Checking if 0x%08X equals 0x%08X\n", - offset, data, cmpval); + BIOSLOG(pScrn, "0x%04X: Checking if 0x%08X equals 0x%08X\n", offset, data, cmpval); - if (data == cmpval) { - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: CONDITION FULFILLED - CONTINUING TO EXECUTE\n", offset); - } else { - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: CONDITION IS NOT FULFILLED\n", offset); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: ------ SKIPPING FOLLOWING COMMANDS ------\n", offset); + if (data == cmpval) + BIOSLOG(pScrn, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); + else { + BIOSLOG(pScrn, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); iexec->execute = false; } @@ -2391,10 +2272,8 @@ static bool init_index_io(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", - offset, crtcport, crtcindex, mask, data); + BIOSLOG(pScrn, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", + offset, crtcport, crtcindex, mask, data); value = (nv_idx_port_rd(pScrn, crtcport, crtcindex) & mask) | data; nv_idx_port_wr(pScrn, crtcport, crtcindex, value); @@ -2419,10 +2298,7 @@ static bool init_pll(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exec if (!iexec->execute) return true; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", - offset, reg, freq); + BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq); setPLL(pScrn, bios, reg, freq * 10); @@ -2512,10 +2388,8 @@ static bool init_8e(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exec_ data = (entry >> 19); data = ((data & 3) ^ 2) << shift; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Entry: 0x%08X, Reg: 0x%08X, Shift: 0x%02X, Mask: 0x%08X, Data: 0x%08X\n", - offset, entry, reg, shift, mask, data); + BIOSLOG(pScrn, "0x%04X: Entry: 0x%08X, Reg: 0x%08X, Shift: 0x%02X, Mask: 0x%08X, Data: 0x%08X\n", + offset, entry, reg, shift, mask, data); nv32_wr(pScrn, reg, (nv32_rd(pScrn, reg) & mask) | data); @@ -2531,10 +2405,8 @@ static bool init_8e(ScrnInfoPtr pScrn, bios_t *bios, uint16_t offset, init_exec_ data |= 0x10000; data <<= shift; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Entry: 0x%08X, Reg: 0x%08X, Shift: 0x%02X, Mask: 0x%08X, Data: 0x%08X\n", - offset, entry, reg, shift, mask, data); + BIOSLOG(pScrn, "0x%04X: Entry: 0x%08X, Reg: 0x%08X, Shift: 0x%02X, Mask: 0x%08X, Data: 0x%08X\n", + offset, entry, reg, shift, mask, data); nv32_wr(pScrn, reg, (nv32_rd(pScrn, reg) & mask) | data); } @@ -2587,10 +2459,8 @@ static bool init_ram_restrict_zm_reg_group(ScrnInfoPtr pScrn, bios_t *bios, uint strap_ramcfg = (nv32_rd(pScrn, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg]; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "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); + BIOSLOG(pScrn, "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 = le32_to_cpu(*((uint32_t *)(&bios->data[offset + 7 + index * 4 + blocklen * i]))); @@ -2752,8 +2622,8 @@ static void parse_init_table(ScrnInfoPtr pScrn, bios_t *bios, unsigned int offse ; if (itbl_entry[i].name) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%04X: [ (0x%02X) - %s ]\n", - offset, itbl_entry[i].id, itbl_entry[i].name); + BIOSLOG(pScrn, "0x%04X: [ (0x%02X) - %s ]\n", + offset, itbl_entry[i].id, itbl_entry[i].name); /* execute eventual command handler */ if (itbl_entry[i].handler) @@ -2782,10 +2652,9 @@ static void parse_init_tables(ScrnInfoPtr pScrn, bios_t *bios) init_exec_t iexec = {true, false}; while ((table = le16_to_cpu(*((uint16_t *)(&bios->data[bios->init_script_tbls_ptr + i]))))) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: Parsing init table %d\n", table, i / 2); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "0x%04X: ------ EXECUTING FOLLOWING COMMANDS ------\n", table); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Parsing VBIOS init table %d at offset 0x%04X\n", i / 2, table); + BIOSLOG(pScrn, "0x%04X: ------ Executing following commands ------\n", table); parse_init_table(pScrn, bios, table, &iexec); i += 2; @@ -2849,10 +2718,9 @@ static void rundigitaloutscript(ScrnInfoPtr pScrn, uint16_t scriptptr, struct dc init_exec_t iexec = {true, false}; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%04X: Parsing digital output script table\n", scriptptr); - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, NV_VGA_CRTCX_OWNER, - head ? NV_VGA_CRTCX_OWNER_HEADB : NV_VGA_CRTCX_OWNER_HEADA); - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, NV_VGA_CRTCX_57, 0); - nv_idx_port_wr(pScrn, CRTC_INDEX_COLOR, NV_VGA_CRTCX_58, dcbent->index); + nv_idx_port_wr(pScrn, NV_CIO_CRX__COLOR, NV_CIO_CRE_44, + head ? NV_CIO_CRE_44_HEADB : NV_CIO_CRE_44_HEADA); + NVWriteVgaCrtc5758(NVPTR(pScrn), head, 0, dcbent->index); parse_init_table(pScrn, bios, scriptptr, &iexec); link_head_and_output(pScrn, dcbent, head); @@ -2872,7 +2740,7 @@ static void call_lvds_manufacturer_script(ScrnInfoPtr pScrn, struct dcb_entry *d if (script == LVDS_PANEL_OFF) /* off-on delay in ms */ - usleep(le16_to_cpu(*(uint16_t *)&bios->data[bios->fp.xlated_entry + 7])); + BIOS_USLEEP(le16_to_cpu(*(uint16_t *)&bios->data[bios->fp.xlated_entry + 7])); #ifdef __powerpc__ /* Powerbook specific quirks */ if (script == LVDS_RESET && ((pNv->Chipset & 0xffff) == 0x0179 || (pNv->Chipset & 0xffff) == 0x0329)) @@ -3197,7 +3065,6 @@ static void parse_fp_mode_table(ScrnInfoPtr pScrn, bios_t *bios, struct fppointe * bytes 38-39 relate to spread spectrum settings * bytes 40-43 are something to do with PWM */ - mode->prev = mode->next = NULL; mode->status = MODE_OK; mode->type = M_T_DRIVER | M_T_PREFERRED; xf86SetModeDefaultName(mode); @@ -3438,14 +3305,9 @@ bool get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pl xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pointer to PLL limits table invalid\n"); return false; } - } else { + } else pll_lim_ver = bios->data[bios->pll_limit_tbl_ptr]; - if (DEBUGLEVEL >= 7) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Found PLL limits table version 0x%X\n", pll_lim_ver); - } - crystal_strap_mask = 1 << 6; /* open coded pNv->twoHeads test */ if (bios->chip_version > 0x10 && bios->chip_version != 0x15 && @@ -3473,7 +3335,7 @@ bool get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pl break; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "PLL limits table revision not currently supported\n"); + "PLL limits table revision 0x%X not currently supported\n", pll_lim_ver); return false; } @@ -3545,9 +3407,7 @@ bool get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pl plloffs += recordlen * pllindex; - if (DEBUGLEVEL >= 6) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Loading PLL limits for reg 0x%08x\n", - pllindex ? reg : 0); + BIOSLOG(pScrn, "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 */ @@ -3591,7 +3451,7 @@ bool get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pl if (((limit_match == NV_RAMDAC_VPLL || limit_match == VPLL1) && sel_clk & 0x20) || ((limit_match == NV_RAMDAC_VPLL2 || limit_match == VPLL2) && sel_clk & 0x80)) { - if (nv_idx_port_rd(pScrn, CRTC_INDEX_COLOR, NV_VGA_CRTCX_REVISION) < 0xa3) + if (nv_idx_port_rd(pScrn, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3) pll_lim->refclk = 200000; else pll_lim->refclk = 25000; @@ -3695,14 +3555,13 @@ static int parse_bit_display_tbl_entry(ScrnInfoPtr pScrn, bios_t *bios, bit_entr * offset + 2 (16 bits): mode table pointer */ - struct fppointers fpp; + struct fppointers fpp = { 0 }; if (bitentry->length != 4) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Do not understand BIT display table\n"); return 0; } - memset(&fpp, 0, sizeof(struct fppointers)); fpp.fptablepointer = le16_to_cpu(*((uint16_t *)(&bios->data[bitentry->offset + 2]))); parse_fp_mode_table(pScrn, bios, &fpp); @@ -3756,7 +3615,7 @@ static int parse_bit_i_tbl_entry(ScrnInfoPtr pScrn, bios_t *bios, bit_entry_t *b uint8_t dacversion, dacheaderlen; if (bitentry->length < 6) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "BIT i table not long enough for BIOS version and feature byte\n"); return 0; } @@ -3790,9 +3649,7 @@ static int parse_bit_i_tbl_entry(ScrnInfoPtr pScrn, bios_t *bios, bit_entry_t *b "DAC load detection comparison table version %d.%d not known\n", dacversion >> 4, dacversion & 0xf); return 0; - } else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "DAC load detection comparison table version %x found\n", dacversion); + } bios->dactestval = le32_to_cpu(*((uint32_t *)(&bios->data[daccmpoffset + dacheaderlen]))); @@ -3884,8 +3741,12 @@ static int parse_bit_tmds_tbl_entry(ScrnInfoPtr pScrn, bios_t *bios, bit_entry_t return 0; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found TMDS table revision %d.%d\n", - bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); + /* nv50+ has v2.0, but we don't parse it atm */ + if (bios->data[tmdstableptr] != 0x11) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "TMDS table revision %d.%d not currently supported\n", + bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); + return 0; + } /* These two scripts are odd: they don't seem to get run even when they are not stubbed */ script1 = le16_to_cpu(*((uint16_t *)&bios->data[tmdstableptr + 7])); @@ -3987,16 +3848,14 @@ static void parse_bmp_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int of NVPtr pNv = NVPTR(pScrn); uint8_t bmp_version_major, bmp_version_minor; uint16_t bmplength; - struct fppointers fpp; + struct fppointers fpp = { 0 }; uint16_t legacy_scripts_offset, legacy_i2c_offset; - memset(&fpp, 0, sizeof(struct fppointers)); - /* load needed defaults in case we can't parse this info */ - pNv->dcb_table.i2c_write[0] = 0x3f; - pNv->dcb_table.i2c_read[0] = 0x3e; - pNv->dcb_table.i2c_write[1] = 0x37; - pNv->dcb_table.i2c_read[1] = 0x36; + pNv->dcb_table.i2c_write[0] = NV_CIO_CRE_DDC_WR__INDEX; + pNv->dcb_table.i2c_read[0] = NV_CIO_CRE_DDC_STATUS__INDEX; + pNv->dcb_table.i2c_write[1] = NV_CIO_CRE_DDC0_WR__INDEX; + pNv->dcb_table.i2c_read[1] = NV_CIO_CRE_DDC0_STATUS__INDEX; bios->digital_min_front_porch = 0x4b; bios->fmaxvco = 256000; bios->fminvco = 128000; @@ -4050,7 +3909,7 @@ static void parse_bmp_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int of /* checksum */ if (nv_cksum(bios->data + offset, 8)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Bad BMP checksum\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad BMP checksum\n"); return; } @@ -4327,8 +4186,8 @@ parse_dcb_entry(ScrnInfoPtr pScrn, int index, uint8_t dcb_version, uint16_t i2ct memcpy(&entry[1], &entry[0], sizeof(struct dcb_entry)); entry[1].index = ++index; entry[1].type = OUTPUT_ANALOG; - ErrorF("Concocting additional DCB entry for analogue " - "encoder on DVI output\n"); + xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, + "Concocting additional DCB entry for analogue encoder on DVI output\n"); pNv->dcb_table.entries++; } read_dcb_i2c_entry(pScrn, dcb_version, i2ctabptr, entry->i2c_index); @@ -4341,7 +4200,7 @@ parse_dcb_entry(ScrnInfoPtr pScrn, int index, uint8_t dcb_version, uint16_t i2ct */ entry->i2c_index = pNv->VBIOS.legacy.i2c_indices.crt; } else { /* pre DCB / v1.1 - use the safe defaults for a crt */ - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, "No information in BIOS output table; assuming a CRT output exists\n"); entry->i2c_index = pNv->VBIOS.legacy.i2c_indices.crt; } @@ -4424,7 +4283,7 @@ static unsigned int parse_dcb_table(ScrnInfoPtr pScrn, bios_t *bios) /* get DCB version */ dcb_version = dcbtable[0]; xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Display Configuration Block version %d.%d found\n", + "Found Display Configuration Block version %d.%d\n", dcb_version >> 4, dcb_version & 0xf); if (dcb_version >= 0x20) { /* NV17+ */ @@ -4436,10 +4295,6 @@ static unsigned int parse_dcb_table(ScrnInfoPtr pScrn, bios_t *bios) recordlength = dcbtable[3]; i2ctabptr = le16_to_cpu(*(uint16_t *)&dcbtable[4]); sig = le32_to_cpu(*(uint32_t *)&dcbtable[6]); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "DCB header length %d, with %d possible entries\n", - headerlen, entries); } else { i2ctabptr = le16_to_cpu(*(uint16_t *)&dcbtable[2]); sig = le32_to_cpu(*(uint32_t *)&dcbtable[4]); @@ -4452,9 +4307,8 @@ static unsigned int parse_dcb_table(ScrnInfoPtr pScrn, bios_t *bios) return 0; } } else if (dcb_version >= 0x14) { /* some NV15/16, and NV11+ */ - char sig[8]; + char sig[8] = { 0 }; - memset(sig, 0, 8); strncpy(sig, (char *)&dcbtable[-7], 7); i2ctabptr = le16_to_cpu(*(uint16_t *)&dcbtable[2]); recordlength = 10; @@ -4490,8 +4344,9 @@ static unsigned int parse_dcb_table(ScrnInfoPtr pScrn, bios_t *bios) if (connection == 0x00000000) /* seen on an NV11 with DCB v1.5 */ break; - ErrorF("Raw DCB entry %d: %08x %08x\n", - pNv->dcb_table.entries, connection, config); + xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, "Raw DCB entry %d: %08x %08x\n", + pNv->dcb_table.entries, connection, config); + if (!parse_dcb_entry(pScrn, pNv->dcb_table.entries, dcb_version, i2ctabptr, connection, config)) break; } @@ -4569,7 +4424,8 @@ static void read_bios_edid(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found EDID in BIOS\n"); - bios->fp.edid = xalloc(EDID1_LEN); + if (!(bios->fp.edid = xalloc(EDID1_LEN))) + return; for (i = 0; i < EDID1_LEN; i++) bios->fp.edid[i] = bios->data[offset + i]; } @@ -4579,11 +4435,10 @@ bool NVInitVBIOS(ScrnInfoPtr pScrn) NVPtr pNv = NVPTR(pScrn); memset(&pNv->VBIOS, 0, sizeof(bios_t)); - pNv->VBIOS.data = xalloc(NV_PROM_SIZE); + if (!(pNv->VBIOS.data = xalloc(NV_PROM_SIZE))) + return false; if (!NVShadowVBIOS(pScrn, pNv->VBIOS.data)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid BIOS image found\n"); xfree(pNv->VBIOS.data); return false; } @@ -4602,7 +4457,9 @@ bool NVRunVBIOSInit(ScrnInfoPtr pScrn) const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' }; int offset, ret = 0; - crtc_access(pScrn, ACCESS_UNLOCK); + NVLockVgaCrtcs(pNv, false); + if (pNv->twoHeads) + NVSetOwner(pNv, crtchead); if ((offset = findstr(pNv->VBIOS.data, pNv->VBIOS.length, bit_signature, sizeof(bit_signature)))) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIT BIOS found\n"); @@ -4623,7 +4480,9 @@ bool NVRunVBIOSInit(ScrnInfoPtr pScrn) ret = 1; } - crtc_access(pScrn, ACCESS_LOCK); + NVLockVgaCrtcs(pNv, true); + if (pNv->twoHeads) + NVSetOwner(pNv, crtchead); if (ret) return false; @@ -4652,9 +4511,7 @@ unsigned int NVParseBios(ScrnInfoPtr pScrn) if (!NVRunVBIOSInit(pScrn)) return 0; - if (parse_dcb_table(pScrn, &pNv->VBIOS)) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Found %d entries in DCB\n", pNv->dcb_table.entries); + parse_dcb_table(pScrn, &pNv->VBIOS); for (i = 0 ; i < pNv->dcb_table.entries; i++) if (pNv->dcb_table.entry[i].type == OUTPUT_LVDS) diff --git a/src/nv_crtc.c b/src/nv_crtc.c index f561a13..bca091e 100644 --- a/src/nv_crtc.c +++ b/src/nv_crtc.c @@ -23,28 +23,10 @@ * DEALINGS IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <assert.h> -#include "xf86.h" -#include "os.h" -#include "mibank.h" -#include "globals.h" -#include "xf86.h" -#include "xf86Priv.h" -#include "xf86DDC.h" -#include "mipointer.h" -#include "windowstr.h" -#include <randrstr.h> -#include <X11/extensions/render.h> - -#include "xf86Crtc.h" #include "nv_include.h" static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state); -static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state, Bool override); +static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state); static void nv_crtc_load_state_ramdac(xf86CrtcPtr crtc, RIVA_HW_STATE *state); static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state); static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state); @@ -88,14 +70,11 @@ static void NVCrtcWriteRAMDAC(xf86CrtcPtr crtc, uint32_t reg, uint32_t val) NVWriteRAMDAC(pNv, nv_crtc->head, reg, val); } -void NVCrtcLockUnlock(xf86CrtcPtr crtc, Bool lock) +void NVCrtcLockUnlock(xf86CrtcPtr crtc, bool lock) { struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); - ScrnInfoPtr pScrn = crtc->scrn; - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(crtc->scrn); - if (pNv->twoHeads) - NVSetOwner(pScrn, nv_crtc->head); NVLockVgaCrtc(pNv, nv_crtc->head, lock); } @@ -159,10 +138,8 @@ static void nv_crtc_load_state_pll(xf86CrtcPtr crtc, RIVA_HW_STATE *state) /* This sequence is important, the NV28 is very sensitive in this area. */ /* Keep pllsel last and sel_clk first. */ - if (pNv->twoHeads) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Writing NV_RAMDAC_SEL_CLK %08X\n", state->sel_clk); + if (pNv->twoHeads) NVWriteRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK, state->sel_clk); - } if (pNv->Architecture == NV_ARCH_40) { savedc040 = nvReadMC(pNv, 0xc040); @@ -173,23 +150,16 @@ static void nv_crtc_load_state_pll(xf86CrtcPtr crtc, RIVA_HW_STATE *state) } if (nv_crtc->head) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Writing NV_RAMDAC_VPLL2 %08X\n", regp->vpll_a); NVWriteRAMDAC(pNv, 0, NV_RAMDAC_VPLL2, regp->vpll_a); - if (pNv->twoStagePLL) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Writing NV_RAMDAC_VPLL2_B %08X\n", regp->vpll_b); + if (pNv->twoStagePLL) NVWriteRAMDAC(pNv, 0, NV_RAMDAC_VPLL2_B, regp->vpll_b); - } } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Writing NV_RAMDAC_VPLL %08X\n", regp->vpll_a); NVWriteRAMDAC(pNv, 0, NV_RAMDAC_VPLL, regp->vpll_a); - if (pNv->twoStagePLL) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Writing NV_RAMDAC_VPLL_B %08X\n", regp->vpll_b); + if (pNv->twoStagePLL) NVWriteRAMDAC(pNv, 0, NV_RAMDAC_VPLL_B, regp->vpll_b); - } } if (pNv->Architecture == NV_ARCH_40) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Writing NV_RAMDAC_580 %08X\n", state->reg580); NVWriteRAMDAC(pNv, 0, NV_RAMDAC_580, state->reg580); /* We need to wait a while */ @@ -201,7 +171,33 @@ static void nv_crtc_load_state_pll(xf86CrtcPtr crtc, RIVA_HW_STATE *state) NVWriteRAMDAC(pNv, 0, NV_RAMDAC_PLL_SELECT, state->pllsel); } -/* Calculate extended mode parameters (SVGA) and save in a mode state structure */ +static void nv_crtc_cursor_set(xf86CrtcPtr crtc) +{ + NVPtr pNv = NVPTR(crtc->scrn); + struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); + uint32_t cursor_start; + uint8_t *CRTC = pNv->ModeReg.crtc_reg[nv_crtc->head].CRTC; + + if (pNv->Architecture == NV_ARCH_04) + cursor_start = 0x5E00 << 2; + else + cursor_start = nv_crtc->head ? pNv->Cursor2->offset : pNv->Cursor->offset; + + CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] = cursor_start >> 17; + if (pNv->Architecture != NV_ARCH_04) + CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] |= NV_CIO_CRE_HCUR_ASI; + CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] = (cursor_start >> 11) << 2; + if (crtc->mode.Flags & V_DBLSCAN) + CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] |= NV_CIO_CRE_HCUR_ADDR1_CUR_DBL; + CRTC[NV_CIO_CRE_HCUR_ADDR2_INDEX] = cursor_start >> 24; + + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HCUR_ADDR0_INDEX, CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HCUR_ADDR1_INDEX, CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HCUR_ADDR2_INDEX, CRTC[NV_CIO_CRE_HCUR_ADDR2_INDEX]); + if (pNv->Architecture == NV_ARCH_40) + nv_fix_nv40_hw_cursor(pNv, nv_crtc->head); +} + static void nv_crtc_calc_state_ext(xf86CrtcPtr crtc, DisplayModePtr mode, int dot_clock) { ScrnInfoPtr pScrn = crtc->scrn; @@ -212,15 +208,16 @@ static void nv_crtc_calc_state_ext(xf86CrtcPtr crtc, DisplayModePtr mode, int do struct pll_lims pll_lim; int NM1 = 0xbeef, NM2 = 0, log2P = 0, VClk = 0; uint32_t g70_pll_special_bits = 0; - Bool nv4x_single_stage_pll_mode = FALSE; - uint32_t arbitration0, arbitration1; + bool nv4x_single_stage_pll_mode = false; + uint8_t arbitration0; + uint16_t arbitration1; if (!get_pll_limits(pScrn, nv_crtc->head ? VPLL2 : VPLL1, &pll_lim)) return; if (pNv->twoStagePLL || pNv->NVArch == 0x30 || pNv->NVArch == 0x35) { if (dot_clock < pll_lim.vco1.maxfreq && pNv->NVArch > 0x40) { /* use a single VCO */ - nv4x_single_stage_pll_mode = TRUE; + nv4x_single_stage_pll_mode = true; /* Turn the second set of divider and multiplier off */ /* Bogus data, the same nvidia uses */ NM2 = 0x11f; @@ -286,45 +283,21 @@ static void nv_crtc_calc_state_ext(xf86CrtcPtr crtc, DisplayModePtr mode, int do else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n", NM1 >> 8, NM2 >> 8, NM1 & 0xff, NM2 & 0xff, log2P); - if (pNv->Architecture == NV_ARCH_04) { - nv4UpdateArbitrationSettings(VClk, pScrn->bitsPerPixel, - &arbitration0, &arbitration1, pNv); - - regp->CRTC[NV_VGA_CRTCX_CURCTL0] = 0x00; - regp->CRTC[NV_VGA_CRTCX_CURCTL1] = 0xbC; - regp->CRTC[NV_VGA_CRTCX_CURCTL2] = 0x00000000; - } else { - uint32_t CursorStart = nv_crtc->head ? pNv->Cursor2->offset : pNv->Cursor->offset; - - if (((pNv->Chipset & 0xfff0) == CHIPSET_C51) || - ((pNv->Chipset & 0xfff0) == CHIPSET_C512)) { - arbitration0 = 128; - arbitration1 = 0x0480; - } else if (((pNv->Chipset & 0xffff) == CHIPSET_NFORCE) || - ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE2)) - nForceUpdateArbitrationSettings(VClk, pScrn->bitsPerPixel, - &arbitration0, - &arbitration1, pNv); - else if (pNv->Architecture < NV_ARCH_30) - nv10UpdateArbitrationSettings(VClk, pScrn->bitsPerPixel, - &arbitration0, - &arbitration1, pNv); - else - nv30UpdateArbitrationSettings(pNv, &arbitration0, - &arbitration1); - - regp->CRTC[NV_VGA_CRTCX_CURCTL0] = 0x80 | (CursorStart >> 17); - regp->CRTC[NV_VGA_CRTCX_CURCTL1] = (CursorStart >> 11) << 2; - regp->CRTC[NV_VGA_CRTCX_CURCTL2] = CursorStart >> 24; - } - - if (mode->Flags & V_DBLSCAN) - regp->CRTC[NV_VGA_CRTCX_CURCTL1] |= 2; + if (pNv->Architecture < NV_ARCH_30) + nv4_10UpdateArbitrationSettings(pScrn, VClk, pScrn->bitsPerPixel, &arbitration0, &arbitration1); + else if ((pNv->Chipset & 0xfff0) == CHIPSET_C51 || + (pNv->Chipset & 0xfff0) == CHIPSET_C512) { + arbitration0 = 128; + arbitration1 = 0x0480; + } else + nv30UpdateArbitrationSettings(&arbitration0, &arbitration1); - regp->CRTC[NV_VGA_CRTCX_FIFO0] = arbitration0; - regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = arbitration1 & 0xff; + regp->CRTC[NV_CIO_CRE_FF_INDEX] = arbitration0; + regp->CRTC[NV_CIO_CRE_FFLWM__INDEX] = arbitration1 & 0xff; if (pNv->Architecture >= NV_ARCH_30) - regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = arbitration1 >> 8; + regp->CRTC[NV_CIO_CRE_47] = arbitration1 >> 8; + + nv_crtc_cursor_set(crtc); } static void @@ -336,7 +309,7 @@ nv_crtc_dpms(xf86CrtcPtr crtc, int mode) unsigned char seq1 = 0, crtc17 = 0; unsigned char crtc1A; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_crtc_dpms is called for CRTC %d with mode %d.\n", nv_crtc->head, mode); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting dpms mode %d on CRTC %d\n", mode, nv_crtc->head); if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */ return; @@ -344,9 +317,9 @@ nv_crtc_dpms(xf86CrtcPtr crtc, int mode) nv_crtc->last_dpms = mode; if (pNv->twoHeads) - NVSetOwner(pScrn, nv_crtc->head); + NVSetOwner(pNv, nv_crtc->head); - crtc1A = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_REPAINT1) & ~0xC0; + crtc1A = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RPC1_INDEX) & ~0xC0; switch(mode) { case DPMSModeStandby: /* Screen: Off; HSync: Off, VSync: On -- Not Supported */ @@ -376,14 +349,14 @@ nv_crtc_dpms(xf86CrtcPtr crtc, int mode) NVVgaSeqReset(pNv, nv_crtc->head, true); /* Each head has it's own sequencer, so we can turn it off when we want */ - seq1 |= (NVReadVgaSeq(pNv, nv_crtc->head, 0x01) & ~0x20); - NVWriteVgaSeq(pNv, nv_crtc->head, 0x1, seq1); - crtc17 |= (NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_MODECTL) & ~0x80); + seq1 |= (NVReadVgaSeq(pNv, nv_crtc->head, NV_VIO_SR_CLOCK_INDEX) & ~0x20); + NVWriteVgaSeq(pNv, nv_crtc->head, NV_VIO_SR_CLOCK_INDEX, seq1); + crtc17 |= (NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CR_MODE_INDEX) & ~0x80); usleep(10000); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_MODECTL, crtc17); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CR_MODE_INDEX, crtc17); NVVgaSeqReset(pNv, nv_crtc->head, false); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_REPAINT1, crtc1A); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RPC1_INDEX, crtc1A); } static Bool @@ -428,9 +401,6 @@ nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjus fp_output = true; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode clock: %d\n", mode->Clock); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Adjusted mode clock: %d\n", adjusted_mode->Clock); - if (fp_output) { vertStart = vertTotal - 3; vertEnd = vertTotal - 2; @@ -491,29 +461,29 @@ nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjus /* * Time Sequencer */ - regp->Sequencer[0] = 0x00; + regp->Sequencer[NV_VIO_SR_RESET_INDEX] = 0x00; /* 0x20 disables the sequencer */ if (mode->Flags & V_CLKDIV2) - regp->Sequencer[1] = 0x29; + regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x29; else - regp->Sequencer[1] = 0x21; - regp->Sequencer[2] = 0x0F; - regp->Sequencer[3] = 0x00; /* Font select */ - regp->Sequencer[4] = 0x0E; /* Misc */ + regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x21; + regp->Sequencer[NV_VIO_SR_PLANE_MASK_INDEX] = 0x0F; + regp->Sequencer[NV_VIO_SR_CHAR_MAP_INDEX] = 0x00; + regp->Sequencer[NV_VIO_SR_MEM_MODE_INDEX] = 0x0E; /* * CRTC Controller */ - regp->CRTC[NV_VGA_CRTCX_HTOTAL] = Set8Bits(horizTotal); - regp->CRTC[NV_VGA_CRTCX_HDISPE] = Set8Bits(horizDisplay); - regp->CRTC[NV_VGA_CRTCX_HBLANKS] = Set8Bits(horizBlankStart); - regp->CRTC[NV_VGA_CRTCX_HBLANKE] = SetBitField(horizBlankEnd,4:0,4:0) + regp->CRTC[NV_CIO_CR_HDT_INDEX] = Set8Bits(horizTotal); + regp->CRTC[NV_CIO_CR_HDE_INDEX] = Set8Bits(horizDisplay); + regp->CRTC[NV_CIO_CR_HBS_INDEX] = Set8Bits(horizBlankStart); + regp->CRTC[NV_CIO_CR_HBE_INDEX] = SetBitField(horizBlankEnd,4:0,4:0) | SetBit(7); - regp->CRTC[NV_VGA_CRTCX_HSYNCS] = Set8Bits(horizStart); - regp->CRTC[NV_VGA_CRTCX_HSYNCE] = SetBitField(horizBlankEnd,5:5,7:7) + regp->CRTC[NV_CIO_CR_HRS_INDEX] = Set8Bits(horizStart); + regp->CRTC[NV_CIO_CR_HRE_INDEX] = SetBitField(horizBlankEnd,5:5,7:7) | SetBitField(horizEnd,4:0,4:0); - regp->CRTC[NV_VGA_CRTCX_VTOTAL] = SetBitField(vertTotal,7:0,7:0); - regp->CRTC[NV_VGA_CRTCX_OVERFLOW] = SetBitField(vertTotal,8:8,0:0) + regp->CRTC[NV_CIO_CR_VDT_INDEX] = SetBitField(vertTotal,7:0,7:0); + regp->CRTC[NV_CIO_CR_OVL_INDEX] = SetBitField(vertTotal,8:8,0:0) | SetBitField(vertDisplay,8:8,1:1) | SetBitField(vertStart,8:8,2:2) | SetBitField(vertBlankStart,8:8,3:3) @@ -521,71 +491,70 @@ nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjus | SetBitField(vertTotal,9:9,5:5) | SetBitField(vertDisplay,9:9,6:6) | SetBitField(vertStart,9:9,7:7); - regp->CRTC[NV_VGA_CRTCX_PRROWSCN] = 0x00; - regp->CRTC[NV_VGA_CRTCX_MAXSCLIN] = SetBitField(vertBlankStart,9:9,5:5) + regp->CRTC[NV_CIO_CR_RSAL_INDEX] = 0x00; + regp->CRTC[NV_CIO_CR_CELL_HT_INDEX] = SetBitField(vertBlankStart,9:9,5:5) | SetBit(6) - | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00); - regp->CRTC[NV_VGA_CRTCX_VGACURSTART] = 0x00; - regp->CRTC[NV_VGA_CRTCX_VGACUREND] = 0x00; - regp->CRTC[NV_VGA_CRTCX_FBSTADDH] = 0x00; - regp->CRTC[NV_VGA_CRTCX_FBSTADDL] = 0x00; - regp->CRTC[0xe] = 0x00; - regp->CRTC[0xf] = 0x00; - regp->CRTC[NV_VGA_CRTCX_VSYNCS] = Set8Bits(vertStart); + | (mode->Flags & V_DBLSCAN) * NV_CIO_CR_CELL_HT_SCANDBL; + regp->CRTC[NV_CIO_CR_CURS_ST_INDEX] = 0x00; + regp->CRTC[NV_CIO_CR_CURS_END_INDEX] = 0x00; + regp->CRTC[NV_CIO_CR_SA_HI_INDEX] = 0x00; + regp->CRTC[NV_CIO_CR_SA_LO_INDEX] = 0x00; + regp->CRTC[NV_CIO_CR_TCOFF_HI_INDEX] = 0x00; + regp->CRTC[NV_CIO_CR_TCOFF_LO_INDEX] = 0x00; + regp->CRTC[NV_CIO_CR_VRS_INDEX] = Set8Bits(vertStart); /* What is the meaning of bit5, it is empty in the vga spec. */ - regp->CRTC[NV_VGA_CRTCX_VSYNCE] = SetBitField(vertEnd,3:0,3:0) | SetBit(5); - regp->CRTC[NV_VGA_CRTCX_VDISPE] = Set8Bits(vertDisplay); + regp->CRTC[NV_CIO_CR_VRE_INDEX] = SetBitField(vertEnd,3:0,3:0) | SetBit(5); + regp->CRTC[NV_CIO_CR_VDE_INDEX] = Set8Bits(vertDisplay); /* framebuffer can be larger than crtc scanout area. */ - regp->CRTC[NV_VGA_CRTCX_PITCHL] = pScrn->displayWidth / 8 * pScrn->bitsPerPixel / 8; - regp->CRTC[NV_VGA_CRTCX_UNDERLINE] = 0x00; - regp->CRTC[NV_VGA_CRTCX_VBLANKS] = Set8Bits(vertBlankStart); - regp->CRTC[NV_VGA_CRTCX_VBLANKE] = Set8Bits(vertBlankEnd); - /* 0x80 enables the sequencer, we don't want that */ - regp->CRTC[NV_VGA_CRTCX_MODECTL] = 0xC3 & ~0x80; - regp->CRTC[NV_VGA_CRTCX_LINECOMP] = 0xff; + regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = pScrn->displayWidth / 8 * pScrn->bitsPerPixel / 8; + regp->CRTC[NV_CIO_CR_ULINE_INDEX] = 0x00; + regp->CRTC[NV_CIO_CR_VBS_INDEX] = Set8Bits(vertBlankStart); + regp->CRTC[NV_CIO_CR_VBE_INDEX] = Set8Bits(vertBlankEnd); + regp->CRTC[NV_CIO_CR_MODE_INDEX] = 0x43; + regp->CRTC[NV_CIO_CR_LCOMP_INDEX] = 0xff; /* * Some extended CRTC registers (they are not saved with the rest of the vga regs). */ /* framebuffer can be larger than crtc scanout area. */ - regp->CRTC[NV_VGA_CRTCX_REPAINT0] = ((pScrn->displayWidth / 8 * pScrn->bitsPerPixel / 8) & 0x700) >> 3; - regp->CRTC[NV_VGA_CRTCX_REPAINT1] = mode->CrtcHDisplay < 1280 ? 0x04 : 0x00; - regp->CRTC[NV_VGA_CRTCX_LSR] = SetBitField(horizBlankEnd,6:6,4:4) + regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = ((pScrn->displayWidth / 8 * pScrn->bitsPerPixel / 8) & 0x700) >> 3; + regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->CrtcHDisplay < 1280 ? 0x04 : 0x00; + regp->CRTC[NV_CIO_CRE_LSR_INDEX] = SetBitField(horizBlankEnd,6:6,4:4) | SetBitField(vertBlankStart,10:10,3:3) | SetBitField(vertStart,10:10,2:2) | SetBitField(vertDisplay,10:10,1:1) | SetBitField(vertTotal,10:10,0:0); - regp->CRTC[NV_VGA_CRTCX_HEB] = SetBitField(horizTotal,8:8,0:0) + regp->CRTC[NV_CIO_CRE_HEB__INDEX] = SetBitField(horizTotal,8:8,0:0) | SetBitField(horizDisplay,8:8,1:1) | SetBitField(horizBlankStart,8:8,2:2) | SetBitField(horizStart,8:8,3:3); - regp->CRTC[NV_VGA_CRTCX_EXTRA] = SetBitField(vertTotal,11:11,0:0) + regp->CRTC[NV_CIO_CRE_EBR_INDEX] = SetBitField(vertTotal,11:11,0:0) | SetBitField(vertDisplay,11:11,2:2) | SetBitField(vertStart,11:11,4:4) | SetBitField(vertBlankStart,11:11,6:6); if(mode->Flags & V_INTERLACE) { horizTotal = (horizTotal >> 1) & ~1; - regp->CRTC[NV_VGA_CRTCX_INTERLACE] = Set8Bits(horizTotal); - regp->CRTC[NV_VGA_CRTCX_HEB] |= SetBitField(horizTotal,8:8,4:4); + regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = Set8Bits(horizTotal); + regp->CRTC[NV_CIO_CRE_HEB__INDEX] |= SetBitField(horizTotal,8:8,4:4); } else - regp->CRTC[NV_VGA_CRTCX_INTERLACE] = 0xff; /* interlace off */ + regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = 0xff; /* interlace off */ /* * Graphics Display Controller */ - regp->Graphics[0] = 0x00; - regp->Graphics[1] = 0x00; - regp->Graphics[2] = 0x00; - regp->Graphics[3] = 0x00; - regp->Graphics[4] = 0x00; - regp->Graphics[5] = 0x40; /* 256 color mode */ - regp->Graphics[6] = 0x05; /* map 64k mem + graphic mode */ - regp->Graphics[7] = 0x0F; - regp->Graphics[8] = 0xFF; + regp->Graphics[NV_VIO_GX_SR_INDEX] = 0x00; + regp->Graphics[NV_VIO_GX_SREN_INDEX] = 0x00; + regp->Graphics[NV_VIO_GX_CCOMP_INDEX] = 0x00; + regp->Graphics[NV_VIO_GX_ROP_INDEX] = 0x00; + regp->Graphics[NV_VIO_GX_READ_MAP_INDEX] = 0x00; + regp->Graphics[NV_VIO_GX_MODE_INDEX] = 0x40; /* 256 color mode */ + regp->Graphics[NV_VIO_GX_MISC_INDEX] = 0x05; /* map 64k mem + graphic mode */ + regp->Graphics[NV_VIO_GX_DONT_CARE_INDEX] = 0x0F; + regp->Graphics[NV_VIO_GX_BIT_MASK_INDEX] = 0xFF; regp->Attribute[0] = 0x00; /* standard colormap translation */ regp->Attribute[1] = 0x01; @@ -603,12 +572,12 @@ nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjus regp->Attribute[13] = 0x0D; regp->Attribute[14] = 0x0E; regp->Attribute[15] = 0x0F; - regp->Attribute[16] = 0x01; /* Enable graphic mode */ + regp->Attribute[NV_CIO_AR_MODE_INDEX] = 0x01; /* Enable graphic mode */ /* Non-vga */ - regp->Attribute[17] = 0x00; - regp->Attribute[18] = 0x0F; /* enable all color planes */ - regp->Attribute[19] = 0x00; - regp->Attribute[20] = 0x00; + regp->Attribute[NV_CIO_AR_OSCAN_INDEX] = 0x00; + regp->Attribute[NV_CIO_AR_PLANE_INDEX] = 0x0F; /* enable all color planes */ + regp->Attribute[NV_CIO_AR_HPP_INDEX] = 0x00; + regp->Attribute[NV_CIO_AR_CSEL_INDEX] = 0x00; } /** @@ -645,17 +614,17 @@ nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode) /* bit2 = 0 -> fine pitched crtc granularity */ /* The rest disables double buffering on CRTC access */ - regp->CRTC[NV_VGA_CRTCX_BUFFER] = 0xfa; + regp->CRTC[NV_CIO_CRE_21] = 0xfa; /* the blob sometimes sets |= 0x10 (which is the same as setting |= * 1 << 30 on 0x60.830), for no apparent reason */ - regp->CRTC[NV_VGA_CRTCX_59] = 0x0; + regp->CRTC[NV_CIO_CRE_59] = 0x0; if (tmds_output && pNv->Architecture < NV_ARCH_40) - regp->CRTC[NV_VGA_CRTCX_59] |= 0x1; + regp->CRTC[NV_CIO_CRE_59] |= 0x1; /* What is the meaning of this register? */ /* A few popular values are 0x18, 0x1c, 0x38, 0x3c */ - regp->CRTC[NV_VGA_CRTCX_FIFO1] = savep->CRTC[NV_VGA_CRTCX_FIFO1] & ~(1<<5); + regp->CRTC[NV_CIO_CRE_ENH_INDEX] = savep->CRTC[NV_CIO_CRE_ENH_INDEX] & ~(1<<5); regp->head = 0; /* Except for rare conditions I2C is enabled on the primary crtc */ @@ -682,26 +651,22 @@ nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode) regp->cursorConfig |= NV_CRTC_CURSOR_CONFIG_32LINES; /* Unblock some timings */ - regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = 0; - regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = 0; - - /* What is the purpose of this register? */ - /* 0x14 may be disabled? */ - regp->CRTC[NV_VGA_CRTCX_26] = 0x20; + regp->CRTC[NV_CIO_CRE_53] = 0; + regp->CRTC[NV_CIO_CRE_54] = 0; /* 0x00 is disabled, 0x11 is lvds, 0x22 crt and 0x88 tmds */ if (lvds_output) - regp->CRTC[NV_VGA_CRTCX_3B] = 0x11; + regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x11; else if (tmds_output) - regp->CRTC[NV_VGA_CRTCX_3B] = 0x88; + regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x88; else - regp->CRTC[NV_VGA_CRTCX_3B] = 0x22; + regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x22; /* These values seem to vary */ /* This register seems to be used by the bios to make certain decisions on some G70 cards? */ - regp->CRTC[NV_VGA_CRTCX_SCRATCH4] = savep->CRTC[NV_VGA_CRTCX_SCRATCH4]; + regp->CRTC[NV_CIO_CRE_SCRATCH4__INDEX] = savep->CRTC[NV_CIO_CRE_SCRATCH4__INDEX]; - regp->CRTC[NV_VGA_CRTCX_45] = 0x80; + regp->CRTC[NV_CIO_CRE_CSB] = 0x80; /* What does this do?: * bit0: crtc0 @@ -709,18 +674,18 @@ nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode) * bit7: (only in X) */ if (nv_crtc->head == 0) - regp->CRTC[NV_VGA_CRTCX_4B] = 0x81; + regp->CRTC[NV_CIO_CRE_4B] = 0x81; else - regp->CRTC[NV_VGA_CRTCX_4B] = 0x80; + regp->CRTC[NV_CIO_CRE_4B] = 0x80; if (lvds_output) - regp->CRTC[NV_VGA_CRTCX_4B] |= 0x40; + regp->CRTC[NV_CIO_CRE_4B] |= 0x40; /* The blob seems to take the current value from crtc 0, add 4 to that * and reuse the old value for crtc 1 */ - regp->CRTC[NV_VGA_CRTCX_52] = pNv->SavedReg.crtc_reg[0].CRTC[NV_VGA_CRTCX_52]; + regp->CRTC[NV_CIO_CRE_52] = pNv->SavedReg.crtc_reg[0].CRTC[NV_CIO_CRE_52]; if (!nv_crtc->head) - regp->CRTC[NV_VGA_CRTCX_52] += 4; + regp->CRTC[NV_CIO_CRE_52] += 4; regp->unk830 = mode->CrtcVDisplay - 3; regp->unk834 = mode->CrtcVDisplay - 1; @@ -735,18 +700,18 @@ nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode) if (pNv->twoHeads) regp->gpio_ext = NVReadCRTC(pNv, 0, NV_CRTC_GPIO_EXT); - regp->config = 0x2; /* HSYNC mode */ + regp->config = NV_PCRTC_CONFIG_START_ADDRESS_HSYNC; /* Some misc regs */ if (pNv->Architecture == NV_ARCH_40) { - regp->CRTC[NV_VGA_CRTCX_85] = 0xFF; - regp->CRTC[NV_VGA_CRTCX_86] = 0x1; + regp->CRTC[NV_CIO_CRE_85] = 0xFF; + regp->CRTC[NV_CIO_CRE_86] = 0x1; } - regp->CRTC[NV_VGA_CRTCX_PIXEL] = (pScrn->depth + 1) / 8; + regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (pScrn->depth + 1) / 8; /* Enable slaved mode */ if (lvds_output || tmds_output) - regp->CRTC[NV_VGA_CRTCX_PIXEL] |= (1 << 7); + regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7); /* Generic PRAMDAC regs */ @@ -955,27 +920,23 @@ nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); NVPtr pNv = NVPTR(pScrn); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_crtc_mode_set is called for CRTC %d.\n", nv_crtc->head); - - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode on CRTC %d\n", nv_crtc->head); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CTRC mode on CRTC %d:\n", nv_crtc->head); xf86PrintModeline(pScrn->scrnIndex, mode); - if (pNv->twoHeads) - NVSetOwner(pScrn, nv_crtc->head); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output mode on CRTC %d:\n", nv_crtc->head); + xf86PrintModeline(pScrn->scrnIndex, adjusted_mode); nv_crtc_mode_set_vga(crtc, mode, adjusted_mode); /* calculated in output_prepare, nv40 needs it written before calculating PLLs */ - if (pNv->Architecture == NV_ARCH_40) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Writing NV_RAMDAC_SEL_CLK %08X\n", pNv->ModeReg.sel_clk); + if (pNv->Architecture == NV_ARCH_40) NVWriteRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK, pNv->ModeReg.sel_clk); - } nv_crtc_mode_set_regs(crtc, mode); nv_crtc_mode_set_fp_regs(crtc, mode, adjusted_mode); nv_crtc_calc_state_ext(crtc, mode, adjusted_mode->Clock); NVVgaProtect(pNv, nv_crtc->head, true); nv_crtc_load_state_ramdac(crtc, &pNv->ModeReg); - nv_crtc_load_state_ext(crtc, &pNv->ModeReg, FALSE); + nv_crtc_load_state_ext(crtc, &pNv->ModeReg); nv_crtc_load_state_palette(crtc, &pNv->ModeReg); nv_crtc_load_state_vga(crtc, &pNv->ModeReg); nv_crtc_load_state_pll(crtc, &pNv->ModeReg); @@ -987,25 +948,23 @@ nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, #if X_BYTE_ORDER == X_BIG_ENDIAN /* turn on LFB swapping */ { - unsigned char tmp; - - tmp = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_SWAPPING); - tmp |= (1 << 7); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_SWAPPING, tmp); + uint8_t tmp = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RCR); + tmp |= NV_CIO_CRE_RCR_ENDIAN_BIG; + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RCR, tmp); } #endif } static void nv_crtc_save(xf86CrtcPtr crtc) { - ScrnInfoPtr pScrn = crtc->scrn; struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(crtc->scrn); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_crtc_save is called for CRTC %d.\n", nv_crtc->head); + if (pNv->twoHeads) + NVSetOwner(pNv, nv_crtc->head); /* We just came back from terminal, so unlock */ - NVCrtcLockUnlock(crtc, FALSE); + NVCrtcLockUnlock(crtc, false); nv_crtc_save_state_ramdac(crtc, &pNv->SavedReg); nv_crtc_save_state_vga(crtc, &pNv->SavedReg); @@ -1016,28 +975,23 @@ static void nv_crtc_save(xf86CrtcPtr crtc) /* init some state to saved value */ pNv->ModeReg.reg580 = pNv->SavedReg.reg580; pNv->ModeReg.sel_clk = pNv->SavedReg.sel_clk & ~(0x5 << 16); - pNv->ModeReg.crtc_reg[nv_crtc->head].CRTC[NV_VGA_CRTCX_LCD] = pNv->SavedReg.crtc_reg[nv_crtc->head].CRTC[NV_VGA_CRTCX_LCD]; + pNv->ModeReg.crtc_reg[nv_crtc->head].CRTC[NV_CIO_CRE_LCD__INDEX] = pNv->SavedReg.crtc_reg[nv_crtc->head].CRTC[NV_CIO_CRE_LCD__INDEX]; } static void nv_crtc_restore(xf86CrtcPtr crtc) { - ScrnInfoPtr pScrn = crtc->scrn; struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); - NVPtr pNv = NVPTR(pScrn); - RIVA_HW_STATE *state; - NVCrtcRegPtr savep; - - state = &pNv->SavedReg; - savep = &pNv->SavedReg.crtc_reg[nv_crtc->head]; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_crtc_restore is called for CRTC %d.\n", nv_crtc->head); + NVPtr pNv = NVPTR(crtc->scrn); /* Just to be safe */ - NVCrtcLockUnlock(crtc, FALSE); + NVCrtcLockUnlock(crtc, false); + + if (pNv->twoHeads) + NVSetOwner(pNv, nv_crtc->head); NVVgaProtect(pNv, nv_crtc->head, true); nv_crtc_load_state_ramdac(crtc, &pNv->SavedReg); - nv_crtc_load_state_ext(crtc, &pNv->SavedReg, TRUE); + nv_crtc_load_state_ext(crtc, &pNv->SavedReg); nv_crtc_load_state_palette(crtc, &pNv->SavedReg); nv_crtc_load_state_vga(crtc, &pNv->SavedReg); nv_crtc_load_state_pll(crtc, &pNv->SavedReg); @@ -1052,7 +1006,8 @@ static void nv_crtc_prepare(xf86CrtcPtr crtc) NVPtr pNv = NVPTR(pScrn); struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_crtc_prepare is called for CRTC %d.\n", nv_crtc->head); + if (pNv->twoHeads) + NVSetOwner(pNv, nv_crtc->head); /* Just in case */ NVCrtcLockUnlock(crtc, 0); @@ -1065,10 +1020,10 @@ static void nv_crtc_prepare(xf86CrtcPtr crtc) exaWaitSync(pScrn->pScreen); } - NVBlankScreen(pScrn, nv_crtc->head, true); + NVBlankScreen(pNv, nv_crtc->head, true); /* Some more preperation. */ - NVCrtcWriteCRTC(crtc, NV_CRTC_CONFIG, 0x1); /* Go to non-vga mode/out of enhanced mode */ + NVCrtcWriteCRTC(crtc, NV_CRTC_CONFIG, NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA); if (pNv->Architecture == NV_ARCH_40) { uint32_t reg900 = NVCrtcReadRAMDAC(crtc, NV_RAMDAC_900); NVCrtcWriteRAMDAC(crtc, NV_RAMDAC_900, reg900 & ~0x10000); @@ -1077,10 +1032,6 @@ static void nv_crtc_prepare(xf86CrtcPtr crtc) static void nv_crtc_commit(xf86CrtcPtr crtc) { - struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); - ScrnInfoPtr pScrn = crtc->scrn; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_crtc_commit for CRTC %d.\n", nv_crtc->head); - crtc->funcs->dpms (crtc, DPMSModeOn); if (crtc->scrn->pScreen != NULL) { @@ -1176,8 +1127,6 @@ nv_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) unsigned long rotate_pitch; int size, align = 64; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_crtc_shadow_allocate is called.\n"); - rotate_pitch = pScrn->displayWidth * (pScrn->bitsPerPixel/8); size = rotate_pitch * height; @@ -1211,8 +1160,6 @@ nv_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) PixmapPtr rotate_pixmap; struct nouveau_pixmap *nvpix; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_crtc_shadow_create is called.\n"); - if (!data) data = crtc->funcs->shadow_allocate (crtc, width, height); @@ -1265,8 +1212,6 @@ nv_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); ScreenPtr pScreen = pScrn->pScreen; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_crtc_shadow_destroy is called.\n"); - if (rotate_pixmap) { /* This should also unmap the buffer object if relevant. */ pScreen->DestroyPixmap(rotate_pixmap); } @@ -1320,11 +1265,14 @@ nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num) crtcfuncs.shadow_destroy = NULL; } - crtc = xf86CrtcCreate(pScrn, &crtcfuncs); - if (crtc == NULL) + if (!(crtc = xf86CrtcCreate(pScrn, &crtcfuncs))) return; - nv_crtc = xnfcalloc (sizeof (struct nouveau_crtc), 1); + if (!(nv_crtc = xcalloc(1, sizeof (struct nouveau_crtc)))) { + xf86CrtcDestroy(crtc); + return; + } + nv_crtc->head = crtc_num; nv_crtc->last_dpms = NV_DPMS_CLEARED; @@ -1337,7 +1285,7 @@ nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num) regp->DAC[(i*3)+2] = i; } - NVCrtcLockUnlock(crtc, FALSE); + NVCrtcLockUnlock(crtc, false); } static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state) @@ -1348,14 +1296,11 @@ static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state) int i; NVCrtcRegPtr regp = &state->crtc_reg[nv_crtc->head]; - NVWritePVIO(pNv, nv_crtc->head, VGA_MISC_OUT_W, regp->MiscOutReg); + NVWritePRMVIO(pNv, nv_crtc->head, NV_PRMVIO_MISC__WRITE, regp->MiscOutReg); for (i = 0; i < 5; i++) NVWriteVgaSeq(pNv, nv_crtc->head, i, regp->Sequencer[i]); - /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */ - NVWriteVgaCrtc(pNv, nv_crtc->head, 17, regp->CRTC[17] & ~0x80); - for (i = 0; i < 25; i++) NVWriteVgaCrtc(pNv, nv_crtc->head, i, regp->CRTC[i]); @@ -1369,7 +1314,7 @@ static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state) NVSetEnablePalette(pNv, nv_crtc->head, false); } -static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state, Bool override) +static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state) { ScrnInfoPtr pScrn = crtc->scrn; NVPtr pNv = NVPTR(pScrn); @@ -1381,7 +1326,7 @@ static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state, Bool if (pNv->Architecture >= NV_ARCH_10) { if (pNv->twoHeads) - /* setting FSEL *must* come before CRTCX_LCD, as writing CRTCX_LCD sets some + /* setting FSEL *must* come before CIO_CRE_LCD, as writing CIO_CRE_LCD sets some * bits (16 & 17) in FSEL that should not be overwritten by writing FSEL */ NVCrtcWriteCRTC(crtc, NV_CRTC_FSEL, regp->head); @@ -1395,7 +1340,7 @@ static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state, Bool nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_LIMIT(1), pNv->VRAMPhysicalSize - 1); nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, 0); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_BUFFER, regp->CRTC[NV_VGA_CRTCX_BUFFER]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_21, regp->CRTC[NV_CIO_CRE_21]); NVCrtcWriteCRTC(crtc, NV_CRTC_CURSOR_CONFIG, regp->cursorConfig); NVCrtcWriteCRTC(crtc, NV_CRTC_0830, regp->unk830); NVCrtcWriteCRTC(crtc, NV_CRTC_0834, regp->unk834); @@ -1406,7 +1351,7 @@ static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state, Bool if (pNv->Architecture == NV_ARCH_40) { uint32_t reg900 = NVCrtcReadRAMDAC(crtc, NV_RAMDAC_900); - if (regp->config == 0x2) /* enhanced "horizontal only" non-vga mode */ + if (regp->config == NV_PCRTC_CONFIG_START_ADDRESS_HSYNC) NVCrtcWriteRAMDAC(crtc, NV_RAMDAC_900, reg900 | 0x10000); else NVCrtcWriteRAMDAC(crtc, NV_RAMDAC_900, reg900 & ~0x10000); @@ -1416,51 +1361,47 @@ static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state, Bool NVCrtcWriteCRTC(crtc, NV_CRTC_CONFIG, regp->config); NVCrtcWriteCRTC(crtc, NV_CRTC_GPIO, regp->gpio); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_REPAINT0, regp->CRTC[NV_VGA_CRTCX_REPAINT0]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_REPAINT1, regp->CRTC[NV_VGA_CRTCX_REPAINT1]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_LSR, regp->CRTC[NV_VGA_CRTCX_LSR]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_PIXEL, regp->CRTC[NV_VGA_CRTCX_PIXEL]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_LCD, regp->CRTC[NV_VGA_CRTCX_LCD]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_HEB, regp->CRTC[NV_VGA_CRTCX_HEB]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FIFO1, regp->CRTC[NV_VGA_CRTCX_FIFO1]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FIFO0, regp->CRTC[NV_VGA_CRTCX_FIFO0]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FIFO_LWM, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RPC0_INDEX, regp->CRTC[NV_CIO_CRE_RPC0_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RPC1_INDEX, regp->CRTC[NV_CIO_CRE_RPC1_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_LSR_INDEX, regp->CRTC[NV_CIO_CRE_LSR_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_PIXEL_INDEX, regp->CRTC[NV_CIO_CRE_PIXEL_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_LCD__INDEX, regp->CRTC[NV_CIO_CRE_LCD__INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HEB__INDEX, regp->CRTC[NV_CIO_CRE_HEB__INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_ENH_INDEX, regp->CRTC[NV_CIO_CRE_ENH_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_FF_INDEX, regp->CRTC[NV_CIO_CRE_FF_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_FFLWM__INDEX, regp->CRTC[NV_CIO_CRE_FFLWM__INDEX]); if (pNv->Architecture >= NV_ARCH_30) - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FIFO_LWM_NV30, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30]); - - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_CURCTL0, regp->CRTC[NV_VGA_CRTCX_CURCTL0]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_CURCTL1, regp->CRTC[NV_VGA_CRTCX_CURCTL1]); - if (pNv->Architecture == NV_ARCH_40) /* HW bug */ - nv_crtc_fix_nv40_hw_cursor(pScrn, nv_crtc->head); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_CURCTL2, regp->CRTC[NV_VGA_CRTCX_CURCTL2]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_INTERLACE, regp->CRTC[NV_VGA_CRTCX_INTERLACE]); - - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_26, regp->CRTC[NV_VGA_CRTCX_26]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_3B, regp->CRTC[NV_VGA_CRTCX_3B]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_SCRATCH4, regp->CRTC[NV_VGA_CRTCX_SCRATCH4]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_47, regp->CRTC[NV_CIO_CRE_47]); + + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HCUR_ADDR0_INDEX, regp->CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HCUR_ADDR1_INDEX, regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HCUR_ADDR2_INDEX, regp->CRTC[NV_CIO_CRE_HCUR_ADDR2_INDEX]); + if (pNv->Architecture == NV_ARCH_40) + nv_fix_nv40_hw_cursor(pNv, nv_crtc->head); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_ILACE__INDEX, regp->CRTC[NV_CIO_CRE_ILACE__INDEX]); + + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_SCRATCH3__INDEX, regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_SCRATCH4__INDEX, regp->CRTC[NV_CIO_CRE_SCRATCH4__INDEX]); if (pNv->Architecture >= NV_ARCH_10) { - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_EXTRA, regp->CRTC[NV_VGA_CRTCX_EXTRA]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_45, regp->CRTC[NV_VGA_CRTCX_45]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_4B, regp->CRTC[NV_VGA_CRTCX_4B]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_52, regp->CRTC[NV_VGA_CRTCX_52]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_EBR_INDEX, regp->CRTC[NV_CIO_CRE_EBR_INDEX]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_CSB, regp->CRTC[NV_CIO_CRE_CSB]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_4B, regp->CRTC[NV_CIO_CRE_4B]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_52, regp->CRTC[NV_CIO_CRE_52]); } /* NV11 and NV20 stop at 0x52. */ if (pNv->NVArch >= 0x17 && pNv->twoHeads) { - if (override) - for (i = 0; i < 0x10; i++) - NVWriteVgaCrtc5758(pNv, nv_crtc->head, i, regp->CR58[i]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_53, regp->CRTC[NV_CIO_CRE_53]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_54, regp->CRTC[NV_CIO_CRE_54]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FP_HTIMING, regp->CRTC[NV_VGA_CRTCX_FP_HTIMING]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FP_VTIMING, regp->CRTC[NV_VGA_CRTCX_FP_VTIMING]); - - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_59, regp->CRTC[NV_VGA_CRTCX_59]); + for (i = 0; i < 0x10; i++) + NVWriteVgaCrtc5758(pNv, nv_crtc->head, i, regp->CR58[i]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_59, regp->CRTC[NV_CIO_CRE_59]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_85, regp->CRTC[NV_VGA_CRTCX_85]); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_86, regp->CRTC[NV_VGA_CRTCX_86]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_85, regp->CRTC[NV_CIO_CRE_85]); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_86, regp->CRTC[NV_CIO_CRE_86]); } - if (override) - NVCrtcWriteCRTC(crtc, NV_CRTC_START, regp->fb_start); + NVCrtcWriteCRTC(crtc, NV_CRTC_START, regp->fb_start); /* Setting 1 on this value gives you interrupts for every vblank period. */ NVCrtcWriteCRTC(crtc, NV_CRTC_INTR_EN_0, 0); @@ -1475,7 +1416,7 @@ static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state) int i; NVCrtcRegPtr regp = &state->crtc_reg[nv_crtc->head]; - regp->MiscOutReg = NVReadPVIO(pNv, nv_crtc->head, VGA_MISC_OUT_R); + regp->MiscOutReg = NVReadPRMVIO(pNv, nv_crtc->head, NV_PRMVIO_MISC__READ); for (i = 0; i < 25; i++) regp->CRTC[i] = NVReadVgaCrtc(pNv, nv_crtc->head, i); @@ -1502,23 +1443,23 @@ static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state) regp = &state->crtc_reg[nv_crtc->head]; - regp->CRTC[NV_VGA_CRTCX_LCD] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_LCD); - regp->CRTC[NV_VGA_CRTCX_REPAINT0] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_REPAINT0); - regp->CRTC[NV_VGA_CRTCX_REPAINT1] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_REPAINT1); - regp->CRTC[NV_VGA_CRTCX_LSR] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_LSR); - regp->CRTC[NV_VGA_CRTCX_PIXEL] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_PIXEL); - regp->CRTC[NV_VGA_CRTCX_HEB] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_HEB); - regp->CRTC[NV_VGA_CRTCX_FIFO1] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FIFO1); - - regp->CRTC[NV_VGA_CRTCX_FIFO0] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FIFO0); - regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FIFO_LWM); - regp->CRTC[NV_VGA_CRTCX_BUFFER] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_BUFFER); + regp->CRTC[NV_CIO_CRE_LCD__INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_LCD__INDEX); + regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RPC0_INDEX); + regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RPC1_INDEX); + regp->CRTC[NV_CIO_CRE_LSR_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_LSR_INDEX); + regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_PIXEL_INDEX); + regp->CRTC[NV_CIO_CRE_HEB__INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HEB__INDEX); + regp->CRTC[NV_CIO_CRE_ENH_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_ENH_INDEX); + + regp->CRTC[NV_CIO_CRE_FF_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_FF_INDEX); + regp->CRTC[NV_CIO_CRE_FFLWM__INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_FFLWM__INDEX); + regp->CRTC[NV_CIO_CRE_21] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_21); if (pNv->Architecture >= NV_ARCH_30) - regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FIFO_LWM_NV30); - regp->CRTC[NV_VGA_CRTCX_CURCTL0] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_CURCTL0); - regp->CRTC[NV_VGA_CRTCX_CURCTL1] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_CURCTL1); - regp->CRTC[NV_VGA_CRTCX_CURCTL2] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_CURCTL2); - regp->CRTC[NV_VGA_CRTCX_INTERLACE] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_INTERLACE); + regp->CRTC[NV_CIO_CRE_47] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_47); + regp->CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HCUR_ADDR0_INDEX); + regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HCUR_ADDR1_INDEX); + regp->CRTC[NV_CIO_CRE_HCUR_ADDR2_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_HCUR_ADDR2_INDEX); + regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_ILACE__INDEX); if (pNv->Architecture >= NV_ARCH_10) { regp->unk830 = NVCrtcReadCRTC(crtc, NV_CRTC_0830); @@ -1527,36 +1468,33 @@ static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state) regp->unk850 = NVCrtcReadCRTC(crtc, NV_CRTC_0850); regp->gpio_ext = NVCrtcReadCRTC(crtc, NV_CRTC_GPIO_EXT); } - if (pNv->twoHeads) { + if (pNv->twoHeads) regp->head = NVCrtcReadCRTC(crtc, NV_CRTC_FSEL); - regp->crtcOwner = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_OWNER); - } regp->cursorConfig = NVCrtcReadCRTC(crtc, NV_CRTC_CURSOR_CONFIG); } regp->gpio = NVCrtcReadCRTC(crtc, NV_CRTC_GPIO); regp->config = NVCrtcReadCRTC(crtc, NV_CRTC_CONFIG); - regp->CRTC[NV_VGA_CRTCX_26] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_26); - regp->CRTC[NV_VGA_CRTCX_3B] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_3B); - regp->CRTC[NV_VGA_CRTCX_SCRATCH4] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_SCRATCH4); + regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_SCRATCH3__INDEX); + regp->CRTC[NV_CIO_CRE_SCRATCH4__INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_SCRATCH4__INDEX); if (pNv->Architecture >= NV_ARCH_10) { - regp->CRTC[NV_VGA_CRTCX_EXTRA] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_EXTRA); - regp->CRTC[NV_VGA_CRTCX_45] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_45); - regp->CRTC[NV_VGA_CRTCX_4B] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_4B); - regp->CRTC[NV_VGA_CRTCX_52] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_52); + regp->CRTC[NV_CIO_CRE_EBR_INDEX] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_EBR_INDEX); + regp->CRTC[NV_CIO_CRE_CSB] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_CSB); + regp->CRTC[NV_CIO_CRE_4B] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_4B); + regp->CRTC[NV_CIO_CRE_52] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_52); } /* NV11 and NV20 don't have this, they stop at 0x52. */ if (pNv->NVArch >= 0x17 && pNv->twoHeads) { for (i = 0; i < 0x10; i++) regp->CR58[i] = NVReadVgaCrtc5758(pNv, nv_crtc->head, i); - regp->CRTC[NV_VGA_CRTCX_59] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_59); - regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FP_HTIMING); - regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_FP_VTIMING); + regp->CRTC[NV_CIO_CRE_59] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_59); + regp->CRTC[NV_CIO_CRE_53] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_53); + regp->CRTC[NV_CIO_CRE_54] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_54); - regp->CRTC[NV_VGA_CRTCX_85] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_85); - regp->CRTC[NV_VGA_CRTCX_86] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_86); + regp->CRTC[NV_CIO_CRE_85] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_85); + regp->CRTC[NV_CIO_CRE_86] = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_86); } regp->fb_start = NVCrtcReadCRTC(crtc, NV_CRTC_START); @@ -1679,7 +1617,9 @@ void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y) start += pNv->FB->offset; /* 30 bits addresses in 32 bits according to haiku */ - NVCrtcWriteCRTC(crtc, NV_CRTC_START, start & 0xfffffffc); + start &= ~3; + pNv->ModeReg.crtc_reg[nv_crtc->head].fb_start = start; + NVCrtcWriteCRTC(crtc, NV_CRTC_START, start); crtc->x = x; crtc->y = y; @@ -1689,15 +1629,14 @@ static void nv_crtc_save_state_palette(xf86CrtcPtr crtc, RIVA_HW_STATE *state) { struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); NVPtr pNv = NVPTR(crtc->scrn); - uint32_t mmiobase = nv_crtc->head ? NV_PDIO1_OFFSET : NV_PDIO0_OFFSET; - int i; + int head_offset = nv_crtc->head * NV_PRMDIO_SIZE, i; - VGA_WR08(pNv->REGS, VGA_DAC_MASK + mmiobase, 0xff); - VGA_WR08(pNv->REGS, VGA_DAC_READ_ADDR + mmiobase, 0x0); + VGA_WR08(pNv->REGS, NV_PRMDIO_PIXEL_MASK + head_offset, NV_PRMDIO_PIXEL_MASK_MASK); + VGA_WR08(pNv->REGS, NV_PRMDIO_READ_MODE_ADDRESS + head_offset, 0x0); for (i = 0; i < 768; i++) { - state->crtc_reg[nv_crtc->head].DAC[i] = NV_RD08(pNv->REGS, VGA_DAC_DATA + mmiobase); - DDXMMIOH("nv_crtc_save_state_palette: head %d reg 0x%04x data 0x%02x\n", nv_crtc->head, VGA_DAC_DATA + mmiobase, state->crtc_reg[nv_crtc->head].DAC[i]); + state->crtc_reg[nv_crtc->head].DAC[i] = NV_RD08(pNv->REGS, NV_PRMDIO_PALETTE_DATA + head_offset); + DDXMMIOH("nv_crtc_save_state_palette: head %d reg 0x%04x data 0x%02x\n", nv_crtc->head, NV_PRMDIO_PALETTE_DATA + head_offset, state->crtc_reg[nv_crtc->head].DAC[i]); } NVSetEnablePalette(pNv, nv_crtc->head, false); @@ -1706,15 +1645,14 @@ static void nv_crtc_load_state_palette(xf86CrtcPtr crtc, RIVA_HW_STATE *state) { struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); NVPtr pNv = NVPTR(crtc->scrn); - uint32_t mmiobase = nv_crtc->head ? NV_PDIO1_OFFSET : NV_PDIO0_OFFSET; - int i; + int head_offset = nv_crtc->head * NV_PRMDIO_SIZE, i; - VGA_WR08(pNv->REGS, VGA_DAC_MASK + mmiobase, 0xff); - VGA_WR08(pNv->REGS, VGA_DAC_WRITE_ADDR + mmiobase, 0x0); + VGA_WR08(pNv->REGS, NV_PRMDIO_PIXEL_MASK + head_offset, NV_PRMDIO_PIXEL_MASK_MASK); + VGA_WR08(pNv->REGS, NV_PRMDIO_WRITE_MODE_ADDRESS + head_offset, 0x0); for (i = 0; i < 768; i++) { - DDXMMIOH("nv_crtc_load_state_palette: head %d reg 0x%04x data 0x%02x\n", nv_crtc->head, VGA_DAC_DATA + mmiobase, state->crtc_reg[nv_crtc->head].DAC[i]); - NV_WR08(pNv->REGS, VGA_DAC_DATA + mmiobase, state->crtc_reg[nv_crtc->head].DAC[i]); + DDXMMIOH("nv_crtc_load_state_palette: head %d reg 0x%04x data 0x%02x\n", nv_crtc->head, NV_PRMDIO_PALETTE_DATA + head_offset, state->crtc_reg[nv_crtc->head].DAC[i]); + NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA + head_offset, state->crtc_reg[nv_crtc->head].DAC[i]); } NVSetEnablePalette(pNv, nv_crtc->head, false); diff --git a/src/nv_cursor.c b/src/nv_cursor.c index 09b0296..e1eaf39 100644 --- a/src/nv_cursor.c +++ b/src/nv_cursor.c @@ -330,41 +330,18 @@ Bool NVCursorInitRandr12(ScreenPtr pScreen) return xf86_cursors_init(pScreen, cursor_size, cursor_size, flags); } -void nv_crtc_fix_nv40_hw_cursor(ScrnInfoPtr pScrn, uint8_t head) -{ - NVPtr pNv = NVPTR(pScrn); - volatile uint32_t curpos = NVReadRAMDAC(pNv, head, NV_RAMDAC_CURSOR_POS); - NVWriteRAMDAC(pNv, head, NV_RAMDAC_CURSOR_POS, curpos); -} - -void nv_crtc_show_hide_cursor(ScrnInfoPtr pScrn, uint8_t head, Bool show) -{ - NVPtr pNv = NVPTR(pScrn); - int curctl1 = NVReadVgaCrtc(pNv, head, NV_VGA_CRTCX_CURCTL1); - - if (show) - NVWriteVgaCrtc(pNv, head, NV_VGA_CRTCX_CURCTL1, curctl1 | 1); - else - NVWriteVgaCrtc(pNv, head, NV_VGA_CRTCX_CURCTL1, curctl1 & ~1); - - if (pNv->Architecture == NV_ARCH_40) /* HW bug */ - nv_crtc_fix_nv40_hw_cursor(pScrn, head); -} - void nv_crtc_show_cursor(xf86CrtcPtr crtc) { struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); - ScrnInfoPtr pScrn = crtc->scrn; - nv_crtc_show_hide_cursor(pScrn, nv_crtc->head, TRUE); + nv_show_cursor(NVPTR(crtc->scrn), nv_crtc->head, true); } void nv_crtc_hide_cursor(xf86CrtcPtr crtc) { struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); - ScrnInfoPtr pScrn = crtc->scrn; - nv_crtc_show_hide_cursor(pScrn, nv_crtc->head, FALSE); + nv_show_cursor(NVPTR(crtc->scrn), nv_crtc->head, false); } void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) diff --git a/src/nv_dac.c b/src/nv_dac.c index 02aa6ec..71545f1 100644 --- a/src/nv_dac.c +++ b/src/nv_dac.c @@ -182,7 +182,7 @@ NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) if(pNv->Architecture >= NV_ARCH_10) pNv->CURSOR = (CARD32 *)pNv->Cursor->map; - NVCalcStateExt(pNv, + NVCalcStateExt(pScrn, nvReg, i, pScrn->displayWidth, diff --git a/src/nv_dri.c b/src/nv_dri.c index 6fc8c15..ce8444d 100644 --- a/src/nv_dri.c +++ b/src/nv_dri.c @@ -248,7 +248,9 @@ Bool NVDRIGetVersion(ScrnInfoPtr pScrn) #ifdef XF86DRM_MODE if (!pNv->drmmode) /* drmmode still needs the file descriptor */ #endif + { drmClose(fd); + } if (pNv->pKernelDRMVersion == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -303,7 +305,7 @@ Bool NVDRIScreenInit(ScrnInfoPtr pScrn) drm_page_size = getpagesize(); if (!(pDRIInfo = DRICreateInfoRec())) return FALSE; - + pNv->pDRIInfo = pDRIInfo; pDRIInfo->drmDriverName = "nouveau"; pDRIInfo->clientDriverName = "nouveau"; @@ -371,8 +373,8 @@ Bool NVDRIScreenInit(ScrnInfoPtr pScrn) return FALSE; } - /* turn on need_close, so we explictly drmClose() on exit */ - if (nouveau_device_open_existing(&pNv->dev, 1, drm_fd, 0)) { + /* need_close = 0, because DRICloseScreen() will handle the closing. */ + if (nouveau_device_open_existing(&pNv->dev, 0, drm_fd, 0)) { xf86DrvMsg(pScreen->myNum, X_ERROR, "Error creating device\n"); xfree(pDRIInfo->devPrivate); pDRIInfo->devPrivate = NULL; @@ -415,7 +417,23 @@ void NVDRICloseScreen(ScrnInfoPtr pScrn) ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; NVPtr pNv = NVPTR(pScrn); - DRICloseScreen(pScreen); nouveau_device_close(&pNv->dev); + + DRICloseScreen(pScreen); + + /* The channel should have been removed from the drm side, that still leaves a memory leak though. */ + if (pNv->chan) { + free(pNv->chan); + pNv->chan = NULL; + } + + if (pNv->pDRIInfo) { + if (pNv->pDRIInfo->devPrivate) { + xfree(pNv->pDRIInfo->devPrivate); + pNv->pDRIInfo->devPrivate = NULL; + } + DRIDestroyInfoRec(pNv->pDRIInfo); + pNv->pDRIInfo = NULL; + } } diff --git a/src/nv_driver.c b/src/nv_driver.c index 7fae7df..1dd16d1 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -264,39 +264,6 @@ static XF86ModuleVersionInfo nouveauVersRec = _X_EXPORT XF86ModuleData nouveauModuleData = { &nouveauVersRec, nouveauSetup, NULL }; -static Bool -NVGetRec(ScrnInfoPtr pScrn) -{ - /* - * Allocate an NVRec, and hook it into pScrn->driverPrivate. - * pScrn->driverPrivate is initialised to NULL, so we can check if - * the allocation has already been done. - */ - if (pScrn->driverPrivate != NULL) - return TRUE; - - pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1); - /* Initialise it */ - - return TRUE; -} - -static void -NVFreeRec(ScrnInfoPtr pScrn) -{ - if (pScrn->driverPrivate == NULL) - return; - NVPtr pNv = NVPTR(pScrn); - if (pNv->Architecture == NV_ARCH_50 && !pNv->kms_enable) { - NV50ConnectorDestroy(pScrn); - NV50OutputDestroy(pScrn); - NV50CrtcDestroy(pScrn); - } - xfree(pScrn->driverPrivate); - pScrn->driverPrivate = NULL; -} - - static pointer nouveauSetup(pointer module, pointer opts, int *errmaj, int *errmin) { @@ -711,10 +678,7 @@ NVEnterVT(int scrnIndex, int flags) } /* Save the current state */ - if (pNv->SaveGeneration != serverGeneration) { - pNv->SaveGeneration = serverGeneration; - NVSave(pScrn); - } + NVSave(pScrn); for (i = 0; i < xf86_config->num_crtc; i++) { NVCrtcLockUnlock(xf86_config->crtc[i], 0); @@ -722,6 +686,8 @@ NVEnterVT(int scrnIndex, int flags) if (!xf86SetDesiredModes(pScrn)) return FALSE; + + NVAccelCommonInit(pScrn); } else { if (!NVModeInit(pScrn, pScrn->currentMode)) return FALSE; @@ -830,12 +796,14 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen) } } - if (pNv->pInt10) - xf86FreeInt10(pNv->pInt10); - + NVAccelFree(pNv); NVUnmapMem(pScrn); + NVXvDMANotifiersRealFree(); + nouveau_channel_free(&pNv->chan); + vgaHWUnmapMem(pScrn); NVDRICloseScreen(pScrn); + xf86_cursors_fini(pScreen); if (pNv->CursorInfoRec) xf86DestroyCursorInfoRec(pNv->CursorInfoRec); if (pNv->ShadowPtr) { @@ -879,10 +847,29 @@ NVFreeScreen(int scrnIndex, int flags) /* * This only gets called when a screen is being deleted. It does not * get called routinely at the end of a server generation. - */ + */ + + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + NVPtr pNv = NVPTR(pScrn); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) vgaHWFreeHWRec(xf86Screens[scrnIndex]); - NVFreeRec(xf86Screens[scrnIndex]); + + if (!pNv) + return; + + if (pNv->Architecture == NV_ARCH_50 && !pNv->kms_enable) { + NV50ConnectorDestroy(pScrn); + NV50OutputDestroy(pScrn); + NV50CrtcDestroy(pScrn); + } + + /* Free this here and not in CloseScreen, as it's needed after the first server generation. */ + if (pNv->pInt10) + xf86FreeInt10(pNv->pInt10); + + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; } @@ -970,9 +957,12 @@ static Bool NVPreInitDRI(ScrnInfoPtr pScrn) 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); pScrn->virtualX = width; pScrn->virtualY = height; +#endif return TRUE; } @@ -982,9 +972,7 @@ static const xf86CrtcConfigFuncsRec nv_xf86crtc_config_funcs = { #define NVPreInitFail(fmt, args...) do { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%d: "fmt, __LINE__, ##args); \ - if (pNv->pInt10) \ - xf86FreeInt10(pNv->pInt10); \ - NVFreeRec(pScrn); \ + NVFreeScreen(pScrn->scrnIndex, 0); \ return FALSE; \ } while(0) @@ -1034,9 +1022,8 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; /* Allocate the NVRec driverPrivate */ - if (!NVGetRec(pScrn)) { + if (!(pScrn->driverPrivate = xnfcalloc(1, sizeof(NVRec)))) return FALSE; - } pNv = NVPTR(pScrn); /* Get the entity, and make sure it is PCI. */ @@ -1664,12 +1651,19 @@ NVUnmapMem(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); + nouveau_bo_ref(NULL, &pNv->xv_filtertable_mem); + if (pNv->blitAdaptor) + NVFreePortMemory(pScrn, GET_BLIT_PRIVATE(pNv)); + if (pNv->textureAdaptor[0]) + NVFreePortMemory(pScrn, pNv->textureAdaptor[0]->pPortPrivates[0].ptr); + if (pNv->textureAdaptor[1]) + NVFreePortMemory(pScrn, pNv->textureAdaptor[1]->pPortPrivates[0].ptr); + nouveau_bo_ref(NULL, &pNv->FB); nouveau_bo_ref(NULL, &pNv->GART); nouveau_bo_ref(NULL, &pNv->Cursor); - if (pNv->randr12_enable) { + if (pNv->randr12_enable) nouveau_bo_ref(NULL, &pNv->Cursor2); - } nouveau_bo_ref(NULL, &pNv->CLUT0); nouveau_bo_ref(NULL, &pNv->CLUT1); @@ -1702,7 +1696,7 @@ NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) NVLockUnlock(pScrn, 0); if(pNv->twoHeads) { - nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, nvReg->crtcOwner); + nvWriteCurVGA(pNv, NV_CIO_CRE_44, nvReg->crtcOwner); NVLockUnlock(pScrn, 0); } @@ -1716,9 +1710,9 @@ NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { unsigned char tmp; - tmp = nvReadCurVGA(pNv, NV_VGA_CRTCX_SWAPPING); + tmp = nvReadCurVGA(pNv, NV_CIO_CRE_RCR); tmp |= (1 << 7); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_SWAPPING, tmp); + nvWriteCurVGA(pNv, NV_CIO_CRE_RCR, tmp); } #endif @@ -1747,9 +1741,11 @@ NVRestore(ScrnInfoPtr pScrn) for (i = 0; i < xf86_config->num_crtc; i++) NVCrtcLockUnlock(xf86_config->crtc[i], 0); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Restoring encoders\n"); for (i = 0; i < pNv->dcb_table.entries; i++) nv_encoder_restore(pScrn, &pNv->encoders[i]); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Restoring crtcs\n"); for (i = 0; i < xf86_config->num_crtc; i++) xf86_config->crtc[i]->funcs->restore(xf86_config->crtc[i]); @@ -1765,7 +1761,7 @@ NVRestore(ScrnInfoPtr pScrn) NVLockUnlock(pScrn, 0); if(pNv->twoHeads) { - nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->crtc_active[1] * 0x3); + nvWriteCurVGA(pNv, NV_CIO_CRE_44, pNv->crtc_active[1] * 0x3); NVLockUnlock(pScrn, 0); } @@ -1776,10 +1772,9 @@ NVRestore(ScrnInfoPtr pScrn) } if (pNv->twoHeads) { - NVSetOwner(pScrn, 0); /* move to head A to set owner */ NVLockVgaCrtc(pNv, 0, false); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Restoring CRTC_OWNER to %d.\n", pNv->vtOWNER); - NVWriteVgaCrtc(pNv, 0, NV_VGA_CRTCX_OWNER, pNv->vtOWNER); + NVSetOwner(pNv, pNv->vtOWNER); NVLockVgaCrtc(pNv, 0, true); } } @@ -1939,22 +1934,14 @@ NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) static Bool NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { - ScrnInfoPtr pScrn; - vgaHWPtr hwp; - NVPtr pNv; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + NVPtr pNv = NVPTR(pScrn); int ret; VisualPtr visual; unsigned char *FBStart; int displayWidth; - /* - * First get the ScrnInfoRec - */ - pScrn = xf86Screens[pScreen->myNum]; - - hwp = VGAHWPTR(pScrn); - pNv = NVPTR(pScrn); - /* Map the VGA memory when the primary video */ if (pNv->Primary) { hwp->MapSize = 0x10000; @@ -2009,6 +1996,15 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) NVSaveScreen(pScreen, SCREEN_SAVER_ON); pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); } else { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + /* need to point to new screen on server regeneration */ + for (i = 0; i < xf86_config->num_crtc; i++) + xf86_config->crtc[i]->scrn = pScrn; + for (i = 0; i < xf86_config->num_output; i++) + xf86_config->output[i]->scrn = pScrn; + pScrn->memPhysBase = pNv->VRAMPhysical; pScrn->fbOffset = 0; @@ -2099,7 +2095,6 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!pNv->NoAccel) { if (!NVExaInit(pScreen)) return FALSE; - NVAccelCommonInit(pScrn); } else if (pNv->VRAMPhysicalSize / 2 < NOUVEAU_ALIGN(pScrn->virtualX, 64) * NOUVEAU_ALIGN(pScrn->virtualY, 64) * (pScrn->bitsPerPixel >> 3)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "The virtual screen size's resolution is too big for the video RAM framebuffer at this colour depth.\n"); return FALSE; @@ -2198,27 +2193,26 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) static Bool NVSaveScreen(ScreenPtr pScreen, int mode) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - NVPtr pNv = NVPTR(pScrn); - int i; - Bool on = xf86IsUnblank(mode); - - if (pNv->randr12_enable) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + NVPtr pNv = NVPTR(pScrn); + bool on = xf86IsUnblank(mode); + int i; + + if (!pNv->randr12_enable) + return vgaHWSaveScreen(pScreen, mode); + if (pScrn->vtSema && pNv->Architecture < NV_ARCH_50) { - for (i = 0; i < xf86_config->num_crtc; i++) { - - if (xf86_config->crtc[i]->enabled) { - struct nouveau_crtc *nv_crtc = to_nouveau_crtc(xf86_config->crtc[i]); - NVBlankScreen(pScrn, nv_crtc->head, !on); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + for (i = 0; i < xf86_config->num_crtc; i++) { + struct nouveau_crtc *nv_crtc = to_nouveau_crtc(xf86_config->crtc[i]); + + if (xf86_config->crtc[i]->enabled) + NVBlankScreen(pNv, nv_crtc->head, !on); } - } - } - return TRUE; - } - return vgaHWSaveScreen(pScreen, mode); + return TRUE; } static void @@ -2233,9 +2227,11 @@ NVSave(ScrnInfoPtr pScrn) nv_save_restore_vga_fonts(pScrn, 1); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Saving crtcs\n"); for (i = 0; i < xf86_config->num_crtc; i++) xf86_config->crtc[i]->funcs->save(xf86_config->crtc[i]); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Saving encoders\n"); for (i = 0; i < pNv->dcb_table.entries; i++) nv_encoder_save(pScrn, &pNv->encoders[i]); } else { @@ -2243,7 +2239,7 @@ NVSave(ScrnInfoPtr pScrn) vgaRegPtr vgaReg = &pVga->SavedReg; NVLockUnlock(pScrn, 0); if (pNv->twoHeads) { - nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->crtc_active[1] * 0x3); + nvWriteCurVGA(pNv, NV_CIO_CRE_44, pNv->crtc_active[1] * 0x3); NVLockUnlock(pScrn, 0); } diff --git a/src/nv_hw.c b/src/nv_hw.c index 3e594e3..6fa621c 100644 --- a/src/nv_hw.c +++ b/src/nv_hw.c @@ -22,8 +22,6 @@ */ #include "nv_include.h" -#include "nv_local.h" -#include "compiler.h" uint32_t NVRead(NVPtr pNv, uint32_t reg) { @@ -100,20 +98,16 @@ void nv_write_tmds(NVPtr pNv, int or, int dl, uint8_t address, uint8_t data) void NVWriteVgaCrtc(NVPtr pNv, int head, uint8_t index, uint8_t value) { - uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET; - DDXMMIOH("NVWriteVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, value); - NV_WR08(pNv->REGS, CRTC_INDEX_COLOR + mmiobase, index); - NV_WR08(pNv->REGS, CRTC_DATA_COLOR + mmiobase, value); + NV_WR08(pNv->REGS, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); + NV_WR08(pNv->REGS, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value); } uint8_t NVReadVgaCrtc(NVPtr pNv, int head, uint8_t index) { - uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET; - - NV_WR08(pNv->REGS, CRTC_INDEX_COLOR + mmiobase, index); - DDXMMIOH("NVReadVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, CRTC_DATA_COLOR + mmiobase)); - return NV_RD08(pNv->REGS, CRTC_DATA_COLOR + mmiobase); + NV_WR08(pNv->REGS, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); + DDXMMIOH("NVReadVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE)); + return NV_RD08(pNv->REGS, 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 @@ -132,165 +126,214 @@ uint8_t NVReadVgaCrtc(NVPtr pNv, int head, uint8_t index) void NVWriteVgaCrtc5758(NVPtr pNv, int head, uint8_t index, uint8_t value) { - NVWriteVgaCrtc(pNv, head, 0x57, index); - NVWriteVgaCrtc(pNv, head, 0x58, value); + NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_57, index); + NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_58, value); } uint8_t NVReadVgaCrtc5758(NVPtr pNv, int head, uint8_t index) { - NVWriteVgaCrtc(pNv, head, 0x57, index); - return NVReadVgaCrtc(pNv, head, 0x58); + NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_57, index); + return NVReadVgaCrtc(pNv, head, NV_CIO_CRE_58); } -uint8_t NVReadPVIO(NVPtr pNv, int head, uint16_t port) +uint8_t NVReadPRMVIO(NVPtr pNv, int head, uint32_t reg) { - /* Only NV4x have two pvio ranges */ - uint32_t mmiobase = (head && pNv->Architecture == NV_ARCH_40) ? NV_PVIO1_OFFSET : NV_PVIO0_OFFSET; + /* Only NV4x have two pvio ranges; other twoHeads cards MUST call + * NVSetOwner for the relevant head to be programmed */ + if (head && pNv->Architecture == NV_ARCH_40) + reg += NV_PRMVIO_SIZE; - DDXMMIOH("NVReadPVIO: head %d reg %08x val %02x\n", head, port + mmiobase, NV_RD08(pNv->REGS, port + mmiobase)); - return NV_RD08(pNv->REGS, port + mmiobase); + DDXMMIOH("NVReadPRMVIO: head %d reg %08x val %02x\n", head, reg, NV_RD08(pNv->REGS, reg)); + return NV_RD08(pNv->REGS, reg); } -void NVWritePVIO(NVPtr pNv, int head, uint16_t port, uint8_t value) +void NVWritePRMVIO(NVPtr pNv, int head, uint32_t reg, uint8_t value) { - /* Only NV4x have two pvio ranges */ - uint32_t mmiobase = (head && pNv->Architecture == NV_ARCH_40) ? NV_PVIO1_OFFSET : NV_PVIO0_OFFSET; + /* Only NV4x have two pvio ranges; other twoHeads cards MUST call + * NVSetOwner for the relevant head to be programmed */ + if (head && pNv->Architecture == NV_ARCH_40) + reg += NV_PRMVIO_SIZE; - DDXMMIOH("NVWritePVIO: head %d reg %08x val %02x\n", head, port + mmiobase, value); - NV_WR08(pNv->REGS, port + mmiobase, value); + DDXMMIOH("NVWritePRMVIO: head %d reg %08x val %02x\n", head, reg, value); + NV_WR08(pNv->REGS, reg, value); } void NVWriteVgaSeq(NVPtr pNv, int head, uint8_t index, uint8_t value) { - NVWritePVIO(pNv, head, VGA_SEQ_INDEX, index); - NVWritePVIO(pNv, head, VGA_SEQ_DATA, value); + NVWritePRMVIO(pNv, head, NV_PRMVIO_SRX, index); + NVWritePRMVIO(pNv, head, NV_PRMVIO_SR, value); } uint8_t NVReadVgaSeq(NVPtr pNv, int head, uint8_t index) { - NVWritePVIO(pNv, head, VGA_SEQ_INDEX, index); - return NVReadPVIO(pNv, head, VGA_SEQ_DATA); + NVWritePRMVIO(pNv, head, NV_PRMVIO_SRX, index); + return NVReadPRMVIO(pNv, head, NV_PRMVIO_SR); } void NVWriteVgaGr(NVPtr pNv, int head, uint8_t index, uint8_t value) { - NVWritePVIO(pNv, head, VGA_GRAPH_INDEX, index); - NVWritePVIO(pNv, head, VGA_GRAPH_DATA, value); + NVWritePRMVIO(pNv, head, NV_PRMVIO_GRX, index); + NVWritePRMVIO(pNv, head, NV_PRMVIO_GX, value); } uint8_t NVReadVgaGr(NVPtr pNv, int head, uint8_t index) { - NVWritePVIO(pNv, head, VGA_GRAPH_INDEX, index); - return NVReadPVIO(pNv, head, VGA_GRAPH_DATA); + NVWritePRMVIO(pNv, head, NV_PRMVIO_GRX, index); + return NVReadPRMVIO(pNv, head, NV_PRMVIO_GX); } -#define CRTC_IN_STAT_1 0x3da - void NVSetEnablePalette(NVPtr pNv, int head, bool enable) { - uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET; - - VGA_RD08(pNv->REGS, CRTC_IN_STAT_1 + mmiobase); - VGA_WR08(pNv->REGS, VGA_ATTR_INDEX + mmiobase, enable ? 0 : 0x20); + VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); + VGA_WR08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20); } static bool NVGetEnablePalette(NVPtr pNv, int head) { - uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET; - - VGA_RD08(pNv->REGS, CRTC_IN_STAT_1 + mmiobase); - return !(VGA_RD08(pNv->REGS, VGA_ATTR_INDEX + mmiobase) & 0x20); + VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); + return !(VGA_RD08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20); } void NVWriteVgaAttr(NVPtr pNv, int head, uint8_t index, uint8_t value) { - uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET; - if (NVGetEnablePalette(pNv, head)) index &= ~0x20; else index |= 0x20; - NV_RD08(pNv->REGS, CRTC_IN_STAT_1 + mmiobase); + NV_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); DDXMMIOH("NVWriteVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, value); - NV_WR08(pNv->REGS, VGA_ATTR_INDEX + mmiobase, index); - NV_WR08(pNv->REGS, VGA_ATTR_DATA_W + mmiobase, value); + NV_WR08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); + NV_WR08(pNv->REGS, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value); } uint8_t NVReadVgaAttr(NVPtr pNv, int head, uint8_t index) { - uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET; - if (NVGetEnablePalette(pNv, head)) index &= ~0x20; else index |= 0x20; - NV_RD08(pNv->REGS, CRTC_IN_STAT_1 + mmiobase); - NV_WR08(pNv->REGS, VGA_ATTR_INDEX + mmiobase, index); - DDXMMIOH("NVReadVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, VGA_ATTR_DATA_R + mmiobase)); - return NV_RD08(pNv->REGS, VGA_ATTR_DATA_R + mmiobase); + NV_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); + NV_WR08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); + DDXMMIOH("NVReadVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE)); + return NV_RD08(pNv->REGS, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE); } void NVVgaSeqReset(NVPtr pNv, int head, bool start) { - NVWriteVgaSeq(pNv, head, 0x0, start ? 0x1 : 0x3); + NVWriteVgaSeq(pNv, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3); } void NVVgaProtect(NVPtr pNv, int head, bool protect) { - uint8_t seq1 = NVReadVgaSeq(pNv, head, 0x1); + uint8_t seq1 = NVReadVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX); if (protect) { NVVgaSeqReset(pNv, head, true); - NVWriteVgaSeq(pNv, head, 0x01, seq1 | 0x20); + NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); } else { /* Reenable sequencer, then turn on screen */ - NVWriteVgaSeq(pNv, head, 0x01, seq1 & ~0x20); /* reenable display */ + NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); /* reenable display */ NVVgaSeqReset(pNv, head, false); } NVSetEnablePalette(pNv, head, protect); } -void NVSetOwner(ScrnInfoPtr pScrn, int head) +/* 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(NVPtr pNv, int owner) { - NVPtr pNv = NVPTR(pScrn); - /* CRTCX_OWNER is always changed on CRTC0 */ - NVWriteVgaCrtc(pNv, 0, NV_VGA_CRTCX_OWNER, head * 0x3); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting owner: 0x%X.\n", head * 0x3); + if (owner == 1) + owner *= 3; + /* CR44 is always changed on CRTC0 */ + NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_44, owner); + if (pNv->NVArch == 0x11) { /* set me harder */ + NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_2E, owner); + NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_2E, owner); + } } void NVLockVgaCrtc(NVPtr pNv, int head, bool lock) { uint8_t cr11; - NVWriteVgaCrtc(pNv, head, NV_VGA_CRTCX_LOCK, lock ? 0x99 : 0x57); + NVWriteVgaCrtc(pNv, head, NV_CIO_SR_LOCK_INDEX, + lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE); - cr11 = NVReadVgaCrtc(pNv, head, NV_VGA_CRTCX_VSYNCE); + cr11 = NVReadVgaCrtc(pNv, head, NV_CIO_CR_VRE_INDEX); if (lock) cr11 |= 0x80; else cr11 &= ~0x80; - NVWriteVgaCrtc(pNv, head, NV_VGA_CRTCX_VSYNCE, cr11); + NVWriteVgaCrtc(pNv, head, NV_CIO_CR_VRE_INDEX, cr11); } -void NVBlankScreen(ScrnInfoPtr pScrn, int head, bool blank) +void NVLockVgaCrtcs(NVPtr pNv, bool lock) +{ + NVLockVgaCrtc(pNv, 0, lock); + /* NV11 has independently lockable crtcs, except when tied */ + if (pNv->NVArch == 0x11 && !(nvReadMC(pNv, NV_PBUS_DEBUG_1) & (1 << 28))) + NVLockVgaCrtc(pNv, 1, lock); +} + +void NVBlankScreen(NVPtr pNv, int head, bool blank) { unsigned char seq1; - NVPtr pNv = NVPTR(pScrn); if (pNv->twoHeads) - NVSetOwner(pScrn, head); + NVSetOwner(pNv, head); - seq1 = NVReadVgaSeq(pNv, head, 0x1); + seq1 = NVReadVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX); - NVVgaSeqReset(pNv, head, TRUE); + NVVgaSeqReset(pNv, head, true); if (blank) - NVWriteVgaSeq(pNv, head, 0x1, seq1 | 0x20); + NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); else - NVWriteVgaSeq(pNv, head, 0x1, seq1 & ~0x20); - NVVgaSeqReset(pNv, head, FALSE); + NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); + NVVgaSeqReset(pNv, head, false); +} + +void nv_fix_nv40_hw_cursor(NVPtr pNv, 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(pNv, head, NV_RAMDAC_CURSOR_POS); + NVWriteRAMDAC(pNv, head, NV_RAMDAC_CURSOR_POS, curpos); +} + +void nv_show_cursor(NVPtr pNv, int head, bool show) +{ + int curctl1 = NVReadVgaCrtc(pNv, head, NV_CIO_CRE_HCUR_ADDR1_INDEX); + + if (show) + NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, + curctl1 | NV_CIO_CRE_HCUR_ADDR1_ENABLE); + else + NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, + curctl1 & ~NV_CIO_CRE_HCUR_ADDR1_ENABLE); + + if (pNv->Architecture == NV_ARCH_40) + nv_fix_nv40_hw_cursor(pNv, head); } int nv_decode_pll_highregs(NVPtr pNv, uint32_t pll1, uint32_t pll2, bool force_single, int refclk) @@ -339,24 +382,30 @@ static int nv_decode_pll_lowregs(uint32_t Pval, uint32_t NMNM, int refclk) return (N1 * N2 * refclk / (M1 * M2)) >> log2P; } - -static int nv_get_clock(NVPtr pNv, enum pll_types plltype) +static int nv_get_clock(ScrnInfoPtr pScrn, enum pll_types plltype) { + NVPtr pNv = NVPTR(pScrn); const uint32_t nv04_regs[MAX_PLL_TYPES] = { NV_RAMDAC_NVPLL, NV_RAMDAC_MPLL, NV_RAMDAC_VPLL, NV_RAMDAC_VPLL2 }; const uint32_t nv40_regs[MAX_PLL_TYPES] = { 0x4000, 0x4020, NV_RAMDAC_VPLL, NV_RAMDAC_VPLL2 }; uint32_t reg1; struct pll_lims pll_lim; + if (plltype == MPLL && (pNv->Chipset & 0x0ff0) == CHIPSET_NFORCE) { + uint32_t mpllP = (PCI_SLOT_READ_LONG(3, 0x6c) >> 8) & 0xf; + + if (!mpllP) + mpllP = 4; + return 400000 / mpllP; + } else if (plltype == MPLL && (pNv->Chipset & 0xff0) == CHIPSET_NFORCE2) + return PCI_SLOT_READ_LONG(5, 0x4c) / 1000; + if (pNv->Architecture < NV_ARCH_40) reg1 = nv04_regs[plltype]; else reg1 = nv40_regs[plltype]; - /* XXX no pScrn. CrystalFreqKHz is good enough for current nv_get_clock users though if (!get_pll_limits(pScrn, plltype, &pll_lim)) return 0; - */ - pll_lim.refclk = pNv->CrystalFreqKHz; if (reg1 <= 0x405c) return nv_decode_pll_lowregs(nvReadMC(pNv, reg1), nvReadMC(pNv, reg1 + 4), pll_lim.refclk); @@ -376,589 +425,363 @@ static int nv_get_clock(NVPtr pNv, enum pll_types plltype) * * \****************************************************************************/ -typedef struct { - int graphics_lwm; - int video_lwm; - int graphics_burst_size; - int video_burst_size; - int valid; -} nv4_fifo_info; - -typedef struct { - int pclk_khz; - int mclk_khz; - int nvclk_khz; - char mem_page_miss; - char mem_latency; - int memory_width; - char enable_video; - char gr_during_vid; - char pix_bpp; - char mem_aligned; - char enable_mp; -} nv4_sim_state; - -typedef struct { - int graphics_lwm; - int video_lwm; - int graphics_burst_size; - int video_burst_size; - int valid; -} nv10_fifo_info; - -typedef struct { - uint32_t pclk_khz; - uint32_t mclk_khz; - uint32_t nvclk_khz; - uint8_t mem_page_miss; - uint8_t mem_latency; - uint32_t memory_type; - uint32_t memory_width; - uint8_t enable_video; - uint8_t gr_during_vid; - uint8_t pix_bpp; - uint8_t mem_aligned; - uint8_t enable_mp; -} nv10_sim_state; - -static void nv4CalcArbitration ( - nv4_fifo_info *fifo, - nv4_sim_state *arb -) +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 data, 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; - - fifo->valid = 1; - 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 = 1; - 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)) - { - fifo->valid = 0; - found = 0; - if (mclk_extra ==0) found = 1; - mclk_extra--; - } - else if (video_enable) - { - if ((clwm > 511) || (vlwm > 255)) - { - fifo->valid = 0; - found = 0; - if (mclk_extra ==0) found = 1; - mclk_extra--; - } - } - else - { - if (clwm > 519) - { - fifo->valid = 0; - found = 0; - if (mclk_extra ==0) found = 1; - mclk_extra--; - } - } - if (clwm < 384) clwm = 384; - if (vlwm < 128) vlwm = 128; - data = (int)(clwm); - fifo->graphics_lwm = data; - fifo->graphics_burst_size = 128; - data = (int)((vlwm+15)); - fifo->video_lwm = data; - fifo->video_burst_size = vbs; - } + 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; + } } -void nv4UpdateArbitrationSettings ( - unsigned VClk, - unsigned pixelDepth, - unsigned *burst, - unsigned *lwm, - NVPtr pNv -) +static void nv10CalcArbitration(struct nv_fifo_info *fifo, struct nv_sim_state *arb) { - nv4_fifo_info fifo_data; - nv4_sim_state sim_data; - unsigned int MClk, NVClk, cfg1; - - MClk = nv_get_clock(pNv, MPLL); - NVClk = nv_get_clock(pNv, NVPLL); - - cfg1 = nvReadFB(pNv, NV_PFB_CFG1); - sim_data.pix_bpp = (char)pixelDepth; - sim_data.enable_video = 0; - sim_data.enable_mp = 0; - sim_data.memory_width = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; - sim_data.mem_latency = (char)cfg1 & 0x0F; - sim_data.mem_aligned = 1; - sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01)); - sim_data.gr_during_vid = 0; - sim_data.pclk_khz = VClk; - sim_data.mclk_khz = MClk; - sim_data.nvclk_khz = NVClk; - nv4CalcArbitration(&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; - } -} + 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; -static void nv10CalcArbitration ( - nv10_fifo_info *fifo, - nv10_sim_state *arb -) -{ - int data, 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; - - fifo->valid = 1; - 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; - } + 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 = 1; - 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 = ((int)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 = 0; - 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 = 0; - found = 0; - if(min_mclk_extra == 0) - found = 1; /* Can't adjust anymore! */ - else - min_mclk_extra--; - } - } + 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; + } + } + } - if(clwm < (1024-cbs+8)) clwm = 1024-cbs+8; - data = (int)(clwm); - /* printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */ - fifo->graphics_lwm = data; fifo->graphics_burst_size = cbs; + /* + * 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--; + } - fifo->video_lwm = 1024; fifo->video_burst_size = 512; - } -} + 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; -void nv10UpdateArbitrationSettings ( - unsigned VClk, - unsigned pixelDepth, - unsigned *burst, - unsigned *lwm, - NVPtr pNv -) -{ - nv10_fifo_info fifo_data; - nv10_sim_state sim_data; - unsigned int MClk, NVClk, cfg1; - - MClk = nv_get_clock(pNv, MPLL); - NVClk = nv_get_clock(pNv, NVPLL); - - cfg1 = nvReadFB(pNv, NV_PFB_CFG1); - sim_data.pix_bpp = (char)pixelDepth; - sim_data.enable_video = 1; - sim_data.enable_mp = 0; - sim_data.memory_type = (nvReadFB(pNv, NV_PFB_CFG0) & 0x01) ? 1 : 0; - sim_data.memory_width = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; - sim_data.mem_latency = (char)cfg1 & 0x0F; - sim_data.mem_aligned = 1; - sim_data.mem_page_miss = (char)(((cfg1>>4) &0x0F) + ((cfg1>>31) & 0x01)); - sim_data.gr_during_vid = 0; - sim_data.pclk_khz = VClk; - sim_data.mclk_khz = MClk; - sim_data.nvclk_khz = NVClk; - 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; - } + fifo->video_lwm = 1024; + fifo->video_burst_size = 512; + } } - -void nv30UpdateArbitrationSettings (NVPtr pNv, - unsigned *burst, - unsigned *lwm) +void nv4_10UpdateArbitrationSettings(ScrnInfoPtr pScrn, int VClk, int bpp, uint8_t *burst, uint16_t *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; -} - -#ifdef XSERVER_LIBPCIACCESS + NVPtr pNv = NVPTR(pScrn); + struct nv_fifo_info fifo_data; + struct nv_sim_state sim_data; + int MClk = nv_get_clock(pScrn, MPLL); + int NVClk = nv_get_clock(pScrn, NVPLL); + uint32_t cfg1 = nvReadFB(pNv, 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 ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE || + (pNv->Chipset & 0xffff) == CHIPSET_NFORCE2) { + sim_data.enable_video = false; + sim_data.memory_type = (PCI_SLOT_READ_LONG(1, 0x7c) >> 12) & 1; + sim_data.memory_width = 64; + sim_data.mem_latency = 3; + sim_data.mem_page_miss = 10; + } else { + sim_data.enable_video = (pNv->Architecture != NV_ARCH_04); + sim_data.memory_type = nvReadFB(pNv, NV_PFB_CFG0) & 0x1; + sim_data.memory_width = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; + sim_data.mem_latency = cfg1 & 0xf; + sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1); + } -struct pci_device GetDeviceByPCITAG(uint32_t bus, uint32_t dev, uint32_t func) -{ - const struct pci_slot_match match[] = { {0, bus, dev, func, 0} }; - struct pci_device_iterator *iterator; - struct pci_device *device; - - /* assume one device to exist */ - iterator = pci_slot_match_iterator_create(match); - device = pci_device_next(iterator); - - return *device; + if (pNv->Architecture == NV_ARCH_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; + } } -#endif /* XSERVER_LIBPCIACCESS */ - -void nForceUpdateArbitrationSettings (unsigned VClk, - unsigned pixelDepth, - unsigned *burst, - unsigned *lwm, - NVPtr pNv -) +void nv30UpdateArbitrationSettings(uint8_t *burst, uint16_t *lwm) { - nv10_fifo_info fifo_data; - nv10_sim_state sim_data; - unsigned int MClk, NVClk, memctrl; - -#ifdef XSERVER_LIBPCIACCESS - struct pci_device tmp; -#endif /* XSERVER_LIBPCIACCESS */ - - if((pNv->Chipset & 0x0FF0) == CHIPSET_NFORCE) { - unsigned int uMClkPostDiv; - -#ifdef XSERVER_LIBPCIACCESS - tmp = GetDeviceByPCITAG(0, 0, 3); - PCI_DEV_READ_LONG(&tmp, 0x6C, &(uMClkPostDiv)); - uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf; -#else - uMClkPostDiv = (pciReadLong(pciTag(0, 0, 3), 0x6C) >> 8) & 0xf; -#endif /* XSERVER_LIBPCIACCESS */ - if(!uMClkPostDiv) uMClkPostDiv = 4; - MClk = 400000 / uMClkPostDiv; - } else { -#ifdef XSERVER_LIBPCIACCESS - tmp = GetDeviceByPCITAG(0, 0, 5); - PCI_DEV_READ_LONG(&tmp, 0x4C, &(MClk)); - MClk /= 1000; -#else - MClk = pciReadLong(pciTag(0, 0, 5), 0x4C) / 1000; -#endif /* XSERVER_LIBPCIACCESS */ - } + unsigned int fifo_size, burst_size, graphics_lwm; - NVClk = nv_get_clock(pNv, NVPLL); - sim_data.pix_bpp = (char)pixelDepth; - sim_data.enable_video = 0; - sim_data.enable_mp = 0; -#ifdef XSERVER_LIBPCIACCESS - tmp = GetDeviceByPCITAG(0, 0, 1); - PCI_DEV_READ_LONG(&tmp, 0x7C, &(sim_data.memory_type)); - sim_data.memory_type = (sim_data.memory_type >> 12) & 1; -#else - sim_data.memory_type = (pciReadLong(pciTag(0, 0, 1), 0x7C) >> 12) & 1; -#endif /* XSERVER_LIBPCIACCESS */ - sim_data.memory_width = 64; - -#ifdef XSERVER_LIBPCIACCESS - /* This offset is 0, is this even usefull? */ - tmp = GetDeviceByPCITAG(0, 0, 3); - PCI_DEV_READ_LONG(&tmp, 0x00, &(memctrl)); - memctrl >>= 16; -#else - memctrl = pciReadLong(pciTag(0, 0, 3), 0x00) >> 16; -#endif /* XSERVER_LIBPCIACCESS */ - - if((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) { - uint32_t dimm[3]; -#ifdef XSERVER_LIBPCIACCESS - tmp = GetDeviceByPCITAG(0, 0, 2); - PCI_DEV_READ_LONG(&tmp, 0x40, &(dimm[0])); - PCI_DEV_READ_LONG(&tmp, 0x44, &(dimm[1])); - PCI_DEV_READ_LONG(&tmp, 0x48, &(dimm[2])); - int i; - for (i = 0; i < 3; i++) { - dimm[i] = (dimm[i] >> 8) & 0x4F; - } -#else - dimm[0] = (pciReadLong(pciTag(0, 0, 2), 0x40) >> 8) & 0x4F; - dimm[1] = (pciReadLong(pciTag(0, 0, 2), 0x44) >> 8) & 0x4F; - dimm[2] = (pciReadLong(pciTag(0, 0, 2), 0x48) >> 8) & 0x4F; -#endif - - if((dimm[0] + dimm[1]) != dimm[2]) { - ErrorF("WARNING: " - "your nForce DIMMs are not arranged in optimal banks!\n"); - } - } + fifo_size = 2048; + burst_size = 512; + graphics_lwm = fifo_size - burst_size; - sim_data.mem_latency = 3; - sim_data.mem_aligned = 1; - sim_data.mem_page_miss = 10; - sim_data.gr_during_vid = 0; - sim_data.pclk_khz = VClk; - sim_data.mclk_khz = MClk; - sim_data.nvclk_khz = NVClk; - 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; - } + *burst = 0; + burst_size >>= 5; + while (burst_size >>= 1) + (*burst)++; + *lwm = graphics_lwm >> 3; } - /****************************************************************************\ * * * RIVA Mode State Routines * @@ -1059,7 +882,7 @@ static void CalcVClock2Stage ( * mode state structure. */ void NVCalcStateExt ( - NVPtr pNv, + ScrnInfoPtr pScrn, RIVA_HW_STATE *state, int bpp, int width, @@ -1069,6 +892,7 @@ void NVCalcStateExt ( int flags ) { + NVPtr pNv = NVPTR(pScrn); int pixelDepth, VClk = 0; CARD32 CursorStart; @@ -1090,11 +914,10 @@ void NVCalcStateExt ( switch (pNv->Architecture) { case NV_ARCH_04: - nv4UpdateArbitrationSettings(VClk, + nv4_10UpdateArbitrationSettings(pScrn, VClk, pixelDepth * 8, &(state->arbitration0), - &(state->arbitration1), - pNv); + &(state->arbitration1)); state->cursor0 = 0x00; state->cursor1 = 0xbC; if (flags & V_DBLSCAN) @@ -1113,24 +936,13 @@ void NVCalcStateExt ( { state->arbitration0 = 128; state->arbitration1 = 0x0480; - } else - if(((pNv->Chipset & 0xffff) == CHIPSET_NFORCE) || - ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE2)) - { - nForceUpdateArbitrationSettings(VClk, - pixelDepth * 8, - &(state->arbitration0), - &(state->arbitration1), - pNv); } else if(pNv->Architecture < NV_ARCH_30) { - nv10UpdateArbitrationSettings(VClk, + nv4_10UpdateArbitrationSettings(pScrn, VClk, pixelDepth * 8, &(state->arbitration0), - &(state->arbitration1), - pNv); + &(state->arbitration1)); } else { - nv30UpdateArbitrationSettings(pNv, - &(state->arbitration0), + nv30UpdateArbitrationSettings(&(state->arbitration0), &(state->arbitration1)); } CursorStart = pNv->Cursor->offset; @@ -1209,34 +1021,34 @@ void NVLoadStateExt ( nvWriteCurRAMDAC(pNv, NV_RAMDAC_FP_DITHER, state->dither); } - nvWriteCurVGA(pNv, NV_VGA_CRTCX_FP_HTIMING, state->timingH); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_FP_VTIMING, state->timingV); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_BUFFER, 0xfa); + nvWriteCurVGA(pNv, NV_CIO_CRE_53, state->timingH); + nvWriteCurVGA(pNv, NV_CIO_CRE_54, state->timingV); + nvWriteCurVGA(pNv, NV_CIO_CRE_21, 0xfa); } - nvWriteCurVGA(pNv, NV_VGA_CRTCX_EXTRA, state->extra); + nvWriteCurVGA(pNv, NV_CIO_CRE_EBR_INDEX, state->extra); } - nvWriteCurVGA(pNv, NV_VGA_CRTCX_REPAINT0, state->repaint0); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_REPAINT1, state->repaint1); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_LSR, state->screen); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_PIXEL, state->pixel); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_HEB, state->horiz); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_FIFO1, state->fifo); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_FIFO0, state->arbitration0); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_FIFO_LWM, state->arbitration1); + nvWriteCurVGA(pNv, NV_CIO_CRE_RPC0_INDEX, state->repaint0); + nvWriteCurVGA(pNv, NV_CIO_CRE_RPC1_INDEX, state->repaint1); + nvWriteCurVGA(pNv, NV_CIO_CRE_LSR_INDEX, state->screen); + nvWriteCurVGA(pNv, NV_CIO_CRE_PIXEL_INDEX, state->pixel); + nvWriteCurVGA(pNv, NV_CIO_CRE_HEB__INDEX, state->horiz); + nvWriteCurVGA(pNv, NV_CIO_CRE_ENH_INDEX, state->fifo); + nvWriteCurVGA(pNv, NV_CIO_CRE_FF_INDEX, state->arbitration0); + nvWriteCurVGA(pNv, NV_CIO_CRE_FFLWM__INDEX, state->arbitration1); if(pNv->Architecture >= NV_ARCH_30) { - nvWriteCurVGA(pNv, NV_VGA_CRTCX_FIFO_LWM_NV30, state->arbitration1 >> 8); + nvWriteCurVGA(pNv, NV_CIO_CRE_47, state->arbitration1 >> 8); } - nvWriteCurVGA(pNv, NV_VGA_CRTCX_CURCTL0, state->cursor0); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_CURCTL1, state->cursor1); + nvWriteCurVGA(pNv, NV_CIO_CRE_HCUR_ADDR0_INDEX, state->cursor0); + nvWriteCurVGA(pNv, NV_CIO_CRE_HCUR_ADDR1_INDEX, state->cursor1); if(pNv->Architecture == NV_ARCH_40) { /* HW bug */ volatile CARD32 curpos = nvReadCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS); nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, curpos); } - nvWriteCurVGA(pNv, NV_VGA_CRTCX_CURCTL2, state->cursor2); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_INTERLACE, state->interlace); + nvWriteCurVGA(pNv, NV_CIO_CRE_HCUR_ADDR2_INDEX, state->cursor2); + nvWriteCurVGA(pNv, NV_CIO_CRE_ILACE__INDEX, state->interlace); if(!pNv->FlatPanel) { NVWriteRAMDAC(pNv, 0, NV_RAMDAC_PLL_SELECT, state->pllsel); @@ -1263,21 +1075,21 @@ void NVUnloadStateExt RIVA_HW_STATE *state ) { - state->repaint0 = nvReadCurVGA(pNv, NV_VGA_CRTCX_REPAINT0); - state->repaint1 = nvReadCurVGA(pNv, NV_VGA_CRTCX_REPAINT1); - state->screen = nvReadCurVGA(pNv, NV_VGA_CRTCX_LSR); - state->pixel = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL); - state->horiz = nvReadCurVGA(pNv, NV_VGA_CRTCX_HEB); - state->fifo = nvReadCurVGA(pNv, NV_VGA_CRTCX_FIFO1); - state->arbitration0 = nvReadCurVGA(pNv, NV_VGA_CRTCX_FIFO0); - state->arbitration1 = nvReadCurVGA(pNv, NV_VGA_CRTCX_FIFO_LWM); + state->repaint0 = nvReadCurVGA(pNv, NV_CIO_CRE_RPC0_INDEX); + state->repaint1 = nvReadCurVGA(pNv, NV_CIO_CRE_RPC1_INDEX); + state->screen = nvReadCurVGA(pNv, NV_CIO_CRE_LSR_INDEX); + state->pixel = nvReadCurVGA(pNv, NV_CIO_CRE_PIXEL_INDEX); + state->horiz = nvReadCurVGA(pNv, NV_CIO_CRE_HEB__INDEX); + state->fifo = nvReadCurVGA(pNv, NV_CIO_CRE_ENH_INDEX); + state->arbitration0 = nvReadCurVGA(pNv, NV_CIO_CRE_FF_INDEX); + state->arbitration1 = nvReadCurVGA(pNv, NV_CIO_CRE_FFLWM__INDEX); if(pNv->Architecture >= NV_ARCH_30) { - state->arbitration1 |= (nvReadCurVGA(pNv, NV_VGA_CRTCX_FIFO_LWM_NV30) & 1) << 8; + state->arbitration1 |= (nvReadCurVGA(pNv, NV_CIO_CRE_47) & 1) << 8; } - state->cursor0 = nvReadCurVGA(pNv, NV_VGA_CRTCX_CURCTL0); - state->cursor1 = nvReadCurVGA(pNv, NV_VGA_CRTCX_CURCTL1); - state->cursor2 = nvReadCurVGA(pNv, NV_VGA_CRTCX_CURCTL2); - state->interlace = nvReadCurVGA(pNv, NV_VGA_CRTCX_INTERLACE); + state->cursor0 = nvReadCurVGA(pNv, NV_CIO_CRE_HCUR_ADDR0_INDEX); + state->cursor1 = nvReadCurVGA(pNv, NV_CIO_CRE_HCUR_ADDR1_INDEX); + state->cursor2 = nvReadCurVGA(pNv, NV_CIO_CRE_HCUR_ADDR2_INDEX); + state->interlace = nvReadCurVGA(pNv, NV_CIO_CRE_ILACE__INDEX); state->vpll = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL); if(pNv->twoHeads) @@ -1294,9 +1106,9 @@ void NVUnloadStateExt if(pNv->twoHeads) { state->head = NVReadCRTC(pNv, 0, NV_CRTC_FSEL); state->head2 = NVReadCRTC(pNv, 1, NV_CRTC_FSEL); - state->crtcOwner = nvReadCurVGA(pNv, NV_VGA_CRTCX_OWNER); + state->crtcOwner = nvReadCurVGA(pNv, NV_CIO_CRE_44); } - state->extra = nvReadCurVGA(pNv, NV_VGA_CRTCX_EXTRA); + state->extra = nvReadCurVGA(pNv, NV_CIO_CRE_EBR_INDEX); state->cursorConfig = nvReadCurCRTC(pNv, NV_CRTC_CURSOR_CONFIG); @@ -1308,8 +1120,8 @@ void NVUnloadStateExt } if(pNv->FlatPanel) { - state->timingH = nvReadCurVGA(pNv, NV_VGA_CRTCX_FP_HTIMING); - state->timingV = nvReadCurVGA(pNv, NV_VGA_CRTCX_FP_VTIMING); + state->timingH = nvReadCurVGA(pNv, NV_CIO_CRE_53); + state->timingV = nvReadCurVGA(pNv, NV_CIO_CRE_54); } } @@ -1344,12 +1156,6 @@ uint32_t nv_pitch_align(NVPtr pNv, uint32_t width, int bpp) return (width + mask) & ~mask; } -#define VGA_SEQ_PLANE_WRITE 0x02 -#define VGA_SEQ_MEMORY_MODE 0x04 -#define VGA_GFX_PLANE_READ 0x04 -#define VGA_GFX_MODE 0x05 -#define VGA_GFX_MISC 0x06 - void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save) { NVPtr pNv = NVPTR(pScrn); @@ -1357,8 +1163,11 @@ void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save) uint8_t misc, gr4, gr5, gr6, seq2, seq4; int i; + if (pNv->twoHeads) + NVSetOwner(pNv, 0); + NVSetEnablePalette(pNv, 0, true); - graphicsmode = NVReadVgaAttr(pNv, 0, 0x10) & 1; + graphicsmode = NVReadVgaAttr(pNv, 0, NV_CIO_AR_MODE_INDEX) & 1; NVSetEnablePalette(pNv, 0, false); if (graphicsmode) /* graphics mode => framebuffer => no need to save */ @@ -1366,25 +1175,25 @@ void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%sing VGA fonts\n", save ? "Sav" : "Restor"); if (pNv->twoHeads) - NVBlankScreen(pScrn, 1, true); - NVBlankScreen(pScrn, 0, true); + NVBlankScreen(pNv, 1, true); + NVBlankScreen(pNv, 0, true); /* save control regs */ - misc = NVReadPVIO(pNv, 0, VGA_MISC_OUT_R); - seq2 = NVReadVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE); - seq4 = NVReadVgaSeq(pNv, 0, VGA_SEQ_MEMORY_MODE); - gr4 = NVReadVgaGr(pNv, 0, VGA_GFX_PLANE_READ); - gr5 = NVReadVgaGr(pNv, 0, VGA_GFX_MODE); - gr6 = NVReadVgaGr(pNv, 0, VGA_GFX_MISC); - - NVWritePVIO(pNv, 0, VGA_MISC_OUT_W, 0x67); - NVWriteVgaSeq(pNv, 0, VGA_SEQ_MEMORY_MODE, 0x6); - NVWriteVgaGr(pNv, 0, VGA_GFX_MODE, 0x0); - NVWriteVgaGr(pNv, 0, VGA_GFX_MISC, 0x5); + misc = NVReadPRMVIO(pNv, 0, NV_PRMVIO_MISC__READ); + seq2 = NVReadVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX); + seq4 = NVReadVgaSeq(pNv, 0, NV_VIO_SR_MEM_MODE_INDEX); + gr4 = NVReadVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX); + gr5 = NVReadVgaGr(pNv, 0, NV_VIO_GX_MODE_INDEX); + gr6 = NVReadVgaGr(pNv, 0, NV_VIO_GX_MISC_INDEX); + + NVWritePRMVIO(pNv, 0, NV_PRMVIO_MISC__WRITE, 0x67); + NVWriteVgaSeq(pNv, 0, NV_VIO_SR_MEM_MODE_INDEX, 0x6); + NVWriteVgaGr(pNv, 0, NV_VIO_GX_MODE_INDEX, 0x0); + NVWriteVgaGr(pNv, 0, NV_VIO_GX_MISC_INDEX, 0x5); /* store font in plane 0 */ - NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, 0x1); - NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, 0x0); + NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x1); + NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, 0x0); for (i = 0; i < 16384; i++) if (save) pNv->saved_vga_font[0][i] = MMIO_IN32(pNv->FB_BAR, i * 4); @@ -1392,8 +1201,8 @@ void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save) MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[0][i]); /* store font in plane 1 */ - NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, 0x2); - NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, 0x1); + NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x2); + NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, 0x1); for (i = 0; i < 16384; i++) if (save) pNv->saved_vga_font[1][i] = MMIO_IN32(pNv->FB_BAR, i * 4); @@ -1401,8 +1210,8 @@ void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save) MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[1][i]); /* store font in plane 2 */ - NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, 0x4); - NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, 0x2); + NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x4); + NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, 0x2); for (i = 0; i < 16384; i++) if (save) pNv->saved_vga_font[2][i] = MMIO_IN32(pNv->FB_BAR, i * 4); @@ -1410,8 +1219,8 @@ void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save) MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[2][i]); /* store font in plane 3 */ - NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, 0x8); - NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, 0x3); + NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x8); + NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, 0x3); for (i = 0; i < 16384; i++) if (save) pNv->saved_vga_font[3][i] = MMIO_IN32(pNv->FB_BAR, i * 4); @@ -1419,14 +1228,14 @@ void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save) MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[3][i]); /* restore control regs */ - NVWritePVIO(pNv, 0, VGA_MISC_OUT_W, misc); - NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, gr4); - NVWriteVgaGr(pNv, 0, VGA_GFX_MODE, gr5); - NVWriteVgaGr(pNv, 0, VGA_GFX_MISC, gr6); - NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, seq2); - NVWriteVgaSeq(pNv, 0, VGA_SEQ_MEMORY_MODE, seq4); + NVWritePRMVIO(pNv, 0, NV_PRMVIO_MISC__WRITE, misc); + NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, gr4); + NVWriteVgaGr(pNv, 0, NV_VIO_GX_MODE_INDEX, gr5); + NVWriteVgaGr(pNv, 0, NV_VIO_GX_MISC_INDEX, gr6); + NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, seq2); + NVWriteVgaSeq(pNv, 0, NV_VIO_SR_MEM_MODE_INDEX, seq4); if (pNv->twoHeads) - NVBlankScreen(pScrn, 1, false); - NVBlankScreen(pScrn, 0, false); + NVBlankScreen(pNv, 1, false); + NVBlankScreen(pNv, 0, false); } diff --git a/src/nv_output.c b/src/nv_output.c index 4803c98..a3c5c71 100644 --- a/src/nv_output.c +++ b/src/nv_output.c @@ -24,24 +24,7 @@ * DEALINGS IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "os.h" -#include "mibank.h" -#include "globals.h" -#include "xf86.h" -#include "xf86Priv.h" -#include "xf86DDC.h" -#include "mipointer.h" -#include "windowstr.h" -#include <randrstr.h> -#include <X11/extensions/render.h> -#include "X11/Xatom.h" - -#include "xf86Crtc.h" +#include <X11/Xatom.h> #include "nv_include.h" #define MULTIPLE_ENCODERS(e) (e & (e - 1)) @@ -49,9 +32,6 @@ if (c->possible_encoders & (1 << i) && \ (e = &pNv->encoders[i])) -static Atom scaling_mode_atom; -static Atom dithering_atom; - static int nv_output_ramdac_offset(struct nouveau_encoder *nv_encoder) { int offset = 0; @@ -64,300 +44,14 @@ static int nv_output_ramdac_offset(struct nouveau_encoder *nv_encoder) return offset; } -static void dpms_update_fp_control(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode) -{ - NVPtr pNv = NVPTR(pScrn); - struct nouveau_crtc *nv_crtc; - NVCrtcRegPtr regp; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - - if (mode == DPMSModeOn) { - nv_crtc = to_nouveau_crtc(crtc); - regp = &pNv->ModeReg.crtc_reg[nv_crtc->head]; - - nv_crtc->fp_users |= 1 << nv_encoder->dcb->index; - NVWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL, regp->fp_control & ~0x20000022); - } else - for (i = 0; i <= pNv->twoHeads; i++) { - nv_crtc = to_nouveau_crtc(xf86_config->crtc[i]); - regp = &pNv->ModeReg.crtc_reg[nv_crtc->head]; - - nv_crtc->fp_users &= ~(1 << nv_encoder->dcb->index); - if (!nv_crtc->fp_users) { - /* cut the FP output */ - regp->fp_control |= 0x20000022; - NVWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL, regp->fp_control); - } - } -} - -static void nv_digital_output_prepare_sel_clk(NVPtr pNv, struct nouveau_encoder *nv_encoder, int head); - -static void -lvds_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode) -{ - NVPtr pNv = NVPTR(pScrn); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "lvds_encoder_dpms is called with mode %d\n", mode); - - if (nv_encoder->last_dpms == mode) - return; - nv_encoder->last_dpms = mode; - - if (nv_encoder->dcb->lvdsconf.use_power_scripts) { - /* when removing an output, crtc may not be set, but PANEL_OFF must still be run */ - int head = nv_get_digital_bound_head(pNv, nv_encoder->dcb->or); - int pclk = nv_encoder->native_mode->Clock; - - if (crtc) - head = to_nouveau_crtc(crtc)->head; - - if (mode == DPMSModeOn) - call_lvds_script(pScrn, nv_encoder->dcb, head, LVDS_PANEL_ON, pclk); - else - call_lvds_script(pScrn, nv_encoder->dcb, head, LVDS_PANEL_OFF, pclk); - } - - dpms_update_fp_control(pScrn, nv_encoder, crtc, mode); - - if (mode == DPMSModeOn) - nv_digital_output_prepare_sel_clk(pNv, nv_encoder, to_nouveau_crtc(crtc)->head); - else { - pNv->ModeReg.sel_clk = NVReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK); - pNv->ModeReg.sel_clk &= ~0xf0; - } - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK, pNv->ModeReg.sel_clk); -} - -static void -vga_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode) -{ - NVPtr pNv = NVPTR(pScrn); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "vga_encoder_dpms is called with mode %d\n", mode); - - if (nv_encoder->last_dpms == mode) - return; - nv_encoder->last_dpms = mode; - - if (pNv->twoHeads) { - uint32_t outputval = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder)); - - if (mode == DPMSModeOff) - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder), - outputval & ~NV_RAMDAC_OUTPUT_DAC_ENABLE); - else if (mode == DPMSModeOn) - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder), - outputval | NV_RAMDAC_OUTPUT_DAC_ENABLE); - } -} - -static void -tmds_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode) -{ - NVPtr pNv = NVPTR(pScrn); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "tmds_encoder_dpms is called with mode %d\n", mode); - - if (nv_encoder->last_dpms == mode) - return; - nv_encoder->last_dpms = mode; - - dpms_update_fp_control(pScrn, nv_encoder, crtc, mode); - - if (nv_encoder->dcb->location != LOC_ON_CHIP) { - struct nouveau_crtc *nv_crtc; - int i; - - if (mode == DPMSModeOn) { - nv_crtc = to_nouveau_crtc(crtc); - NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_LCD, - pNv->ModeReg.crtc_reg[nv_crtc->head].CRTC[NV_VGA_CRTCX_LCD]); - } else - for (i = 0; i <= pNv->twoHeads; i++) - NVWriteVgaCrtc(pNv, i, NV_VGA_CRTCX_LCD, - NVReadVgaCrtc(pNv, i, NV_VGA_CRTCX_LCD) & ~((nv_encoder->dcb->or << 4) & 0x30)); - } -} - -static void nv_output_dpms(xf86OutputPtr output, int mode) -{ - struct nouveau_connector *nv_connector = to_nouveau_connector(output); - struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); - ScrnInfoPtr pScrn = output->scrn; - xf86CrtcPtr crtc = output->crtc; - NVPtr pNv = NVPTR(pScrn); - int i; - void (* const encoder_dpms[4])(ScrnInfoPtr, struct nouveau_encoder *, xf86CrtcPtr, int) = - /* index matches DCB type */ - { vga_encoder_dpms, NULL, tmds_encoder_dpms, lvds_encoder_dpms }; - - struct nouveau_encoder *nv_encoder_i; - FOR_EACH_ENCODER_IN_CONNECTOR(i, nv_connector, nv_encoder_i) - if (nv_encoder_i != nv_encoder) - encoder_dpms[nv_encoder_i->dcb->type](pScrn, nv_encoder_i, crtc, DPMSModeOff); - - if (nv_encoder) /* may be called before encoder is picked, but iteration above solves it */ - encoder_dpms[nv_encoder->dcb->type](pScrn, nv_encoder, crtc, mode); -} - -void nv_encoder_save(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder) -{ - NVPtr pNv = NVPTR(pScrn); - - if (!nv_encoder->dcb) /* uninitialised encoder */ - return; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_encoder_save is called.\n"); - - if (pNv->twoHeads && nv_encoder->dcb->type == OUTPUT_ANALOG) - nv_encoder->restore.output = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder)); - if (nv_encoder->dcb->type == OUTPUT_TMDS || nv_encoder->dcb->type == OUTPUT_LVDS) - nv_encoder->restore.head = nv_get_digital_bound_head(pNv, nv_encoder->dcb->or); -} - -static uint32_t nv_get_clock_from_crtc(ScrnInfoPtr pScrn, RIVA_HW_STATE *state, uint8_t crtc) -{ - NVPtr pNv = NVPTR(pScrn); - struct pll_lims pll_lim; - uint32_t vplla = state->crtc_reg[crtc].vpll_a; - uint32_t vpllb = state->crtc_reg[crtc].vpll_b; - bool nv40_single = pNv->Architecture == 0x40 && - ((!crtc && state->reg580 & NV_RAMDAC_580_VPLL1_ACTIVE) || - (crtc && state->reg580 & NV_RAMDAC_580_VPLL2_ACTIVE)); - - if (!get_pll_limits(pScrn, crtc ? VPLL2 : VPLL1, &pll_lim)) - return 0; - - return nv_decode_pll_highregs(pNv, vplla, vpllb, nv40_single, pll_lim.refclk); -} - -void nv_encoder_restore(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder) -{ - NVPtr pNv = NVPTR(pScrn); - int head = nv_encoder->restore.head; - - if (!nv_encoder->dcb) /* uninitialised encoder */ - return; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_encoder_restore is called.\n"); - - if (pNv->twoHeads && nv_encoder->dcb->type == OUTPUT_ANALOG) - NVWriteRAMDAC(pNv, 0, - NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder), - nv_encoder->restore.output); - if (nv_encoder->dcb->type == OUTPUT_LVDS) - call_lvds_script(pScrn, nv_encoder->dcb, head, LVDS_PANEL_ON, - nv_encoder->native_mode->Clock); - if (nv_encoder->dcb->type == OUTPUT_TMDS) { - int clock = nv_get_clock_from_crtc(pScrn, &pNv->SavedReg, head); - - run_tmds_table(pScrn, nv_encoder->dcb, head, clock); - } - - nv_encoder->last_dpms = NV_DPMS_CLEARED; -} - -static int nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode) -{ - struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); - NVPtr pNv = NVPTR(output->scrn); - - if (!output->doubleScanAllowed && mode->Flags & V_DBLSCAN) - return MODE_NO_DBLESCAN; - if (!output->interlaceAllowed && mode->Flags & V_INTERLACE) - return MODE_NO_INTERLACE; - - if (nv_encoder->dcb->type == OUTPUT_ANALOG) { - if (mode->Clock > (pNv->twoStagePLL ? 400000 : 350000)) - return MODE_CLOCK_HIGH; - if (mode->Clock < 12000) - return MODE_CLOCK_LOW; - } - if (nv_encoder->dcb->type == OUTPUT_LVDS || nv_encoder->dcb->type == OUTPUT_TMDS) - /* No modes > panel's native res */ - if (mode->HDisplay > nv_encoder->native_mode->HDisplay || - mode->VDisplay > nv_encoder->native_mode->VDisplay) - return MODE_PANEL; - if (nv_encoder->dcb->type == OUTPUT_TMDS) { - if (nv_encoder->dcb->duallink_possible) { - if (mode->Clock > 330000) /* 2x165 MHz */ - return MODE_CLOCK_HIGH; - } else { - if (mode->Clock > 165000) /* 165 MHz */ - return MODE_CLOCK_HIGH; - } - } - - return MODE_OK; -} - -static Bool -nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); - ScrnInfoPtr pScrn = output->scrn; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_mode_fixup is called.\n"); - - /* For internal panels and gpu scaling on DVI we need the native mode */ - if (nv_encoder->dcb->type == OUTPUT_LVDS || - (nv_encoder->dcb->type == OUTPUT_TMDS && nv_encoder->scaling_mode != SCALE_PANEL)) { - adjusted_mode->HDisplay = nv_encoder->native_mode->HDisplay; - adjusted_mode->HSkew = nv_encoder->native_mode->HSkew; - adjusted_mode->HSyncStart = nv_encoder->native_mode->HSyncStart; - adjusted_mode->HSyncEnd = nv_encoder->native_mode->HSyncEnd; - adjusted_mode->HTotal = nv_encoder->native_mode->HTotal; - adjusted_mode->VDisplay = nv_encoder->native_mode->VDisplay; - adjusted_mode->VScan = nv_encoder->native_mode->VScan; - adjusted_mode->VSyncStart = nv_encoder->native_mode->VSyncStart; - adjusted_mode->VSyncEnd = nv_encoder->native_mode->VSyncEnd; - adjusted_mode->VTotal = nv_encoder->native_mode->VTotal; - adjusted_mode->Clock = nv_encoder->native_mode->Clock; - adjusted_mode->Flags = nv_encoder->native_mode->Flags; - - xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); - } - - return TRUE; -} - -static void -nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); - ScrnInfoPtr pScrn = output->scrn; - NVPtr pNv = NVPTR(pScrn); - struct nouveau_crtc *nv_crtc = to_nouveau_crtc(output->crtc); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_mode_set is called.\n"); - - if (pNv->twoHeads && nv_encoder->dcb->type == OUTPUT_ANALOG) - /* bit 16-19 are bits that are set on some G70 cards, - * but don't seem to have much effect */ - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder), - nv_crtc->head << 8 | NV_RAMDAC_OUTPUT_DAC_ENABLE); - if (nv_encoder->dcb->type == OUTPUT_TMDS) - run_tmds_table(pScrn, nv_encoder->dcb, nv_crtc->head, adjusted_mode->Clock); - else if (nv_encoder->dcb->type == OUTPUT_LVDS) - call_lvds_script(pScrn, nv_encoder->dcb, nv_crtc->head, LVDS_RESET, adjusted_mode->Clock); - - /* This could use refinement for flatpanels, but it should work this way */ - if (pNv->NVArch < 0x44) - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + nv_output_ramdac_offset(nv_encoder), 0xf0000000); - else - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + nv_output_ramdac_offset(nv_encoder), 0x00100000); -} - -static Bool +static bool nv_load_detect(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder) { NVPtr pNv = NVPTR(pScrn); uint32_t testval, regoffset = nv_output_ramdac_offset(nv_encoder); uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, saved_rtest_ctrl, temp; - int present = 0; + int head, present = 0; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); #define RGB_TEST_DATA(r,g,b) (r << 0 | g << 10 | b << 20) testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */ @@ -365,7 +59,8 @@ nv_load_detect(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder) testval = pNv->VBIOS.dactestval; saved_rtest_ctrl = NVReadRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + regoffset); - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl & ~0x00010000); + NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + regoffset, + saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF); if (pNv->NVArch >= 0x17) { saved_powerctrl_2 = nvReadMC(pNv, NV_PBUS_POWERCTRL_2); @@ -380,26 +75,33 @@ nv_load_detect(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder) usleep(4000); saved_routput = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset); - /* nv driver and nv31 use 0xfffffeee - * nv34 and 6600 use 0xfffffece */ - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset, saved_routput & 0xfffffece); + head = (saved_routput & 0x100) >> 8; + /* if there's a spare crtc, using it will minimise flicker for the case + * where the in-use crtc is in use by an off-chip tmds encoder */ + if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled) + head ^= 1; + /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ + NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset, + (saved_routput & 0xfffffece) | head << 8); usleep(1000); temp = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset); NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset, temp | 1); - /* no regoffset on purpose */ - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_DATA, 1 << 31 | testval); - temp = NVReadRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL); - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL, temp | 0x1000); + NVWriteRAMDAC(pNv, head, NV_RAMDAC_TEST_DATA, + NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK | testval); + temp = NVReadRAMDAC(pNv, head, NV_RAMDAC_TEST_CONTROL); + NVWriteRAMDAC(pNv, head, NV_RAMDAC_TEST_CONTROL, + temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); usleep(1000); - present = NVReadRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + regoffset) & (1 << 28); + present = NVReadRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + regoffset) & + NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI; - /* no regoffset on purpose */ - temp = NVReadRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL); - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL, temp & 0xffffefff); - NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_DATA, 0); + temp = NVReadRAMDAC(pNv, head, NV_RAMDAC_TEST_CONTROL); + NVWriteRAMDAC(pNv, head, NV_RAMDAC_TEST_CONTROL, + temp & ~NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); + NVWriteRAMDAC(pNv, head, NV_RAMDAC_TEST_DATA, 0); /* bios does something more complex for restoring, but I think this is good enough */ NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset, saved_routput); @@ -412,24 +114,24 @@ nv_load_detect(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder) if (present) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Load detected on output %c\n", '@' + ffs(nv_encoder->dcb->or)); - return TRUE; + return true; } - return FALSE; + return false; } static void -update_output_fields(xf86OutputPtr output, struct nouveau_encoder *nv_encoder) +update_output_fields(xf86OutputPtr output, struct nouveau_encoder *det_encoder) { struct nouveau_connector *nv_connector = to_nouveau_connector(output); NVPtr pNv = NVPTR(output->scrn); - if (nv_connector->nv_encoder == nv_encoder) + if (nv_connector->detected_encoder == det_encoder) return; - nv_connector->nv_encoder = nv_encoder; - output->possible_crtcs = nv_encoder->dcb->heads; - if (nv_encoder->dcb->type == OUTPUT_LVDS || nv_encoder->dcb->type == OUTPUT_TMDS) { + nv_connector->detected_encoder = det_encoder; + output->possible_crtcs = det_encoder->dcb->heads; + if (det_encoder->dcb->type == OUTPUT_LVDS || det_encoder->dcb->type == OUTPUT_TMDS) { output->doubleScanAllowed = false; output->interlaceAllowed = false; } else { @@ -443,12 +145,6 @@ update_output_fields(xf86OutputPtr output, struct nouveau_encoder *nv_encoder) else output->interlaceAllowed = true; } - - if (output->randr_output) { - RRDeleteOutputProperty(output->randr_output, dithering_atom); - RRDeleteOutputProperty(output->randr_output, scaling_mode_atom); - output->funcs->create_resources(output); - } } static xf86OutputStatus @@ -457,7 +153,7 @@ nv_output_detect(xf86OutputPtr output) struct nouveau_connector *nv_connector = to_nouveau_connector(output); ScrnInfoPtr pScrn = output->scrn; NVPtr pNv = NVPTR(pScrn); - struct nouveau_encoder *nv_encoder; + struct nouveau_encoder *det_encoder; xf86OutputStatus ret = XF86OutputStatusDisconnected; struct nouveau_encoder *find_encoder_by_type(NVOutputType type) @@ -470,41 +166,36 @@ nv_output_detect(xf86OutputPtr output) return NULL; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_detect is called.\n"); - if (nv_connector->pDDCBus && (nv_connector->edid = xf86OutputGetEDID(output, nv_connector->pDDCBus), xf86OutputSetEDID(output, nv_connector->edid), nv_connector->edid)) { if (MULTIPLE_ENCODERS(nv_connector->possible_encoders)) { if (nv_connector->edid->features.input_type) - nv_encoder = find_encoder_by_type(OUTPUT_TMDS); + det_encoder = find_encoder_by_type(OUTPUT_TMDS); else - nv_encoder = find_encoder_by_type(OUTPUT_ANALOG); + det_encoder = find_encoder_by_type(OUTPUT_ANALOG); } else - nv_encoder = find_encoder_by_type(OUTPUT_ANY); + det_encoder = find_encoder_by_type(OUTPUT_ANY); ret = XF86OutputStatusConnected; - } else if ((nv_encoder = find_encoder_by_type(OUTPUT_ANALOG))) { + } else if ((det_encoder = find_encoder_by_type(OUTPUT_ANALOG))) { /* we don't have a load det function for early cards */ if (!pNv->twoHeads || pNv->NVArch == 0x11) ret = XF86OutputStatusUnknown; - else if (pNv->twoHeads && nv_load_detect(pScrn, nv_encoder)) + else if (pNv->twoHeads && nv_load_detect(pScrn, det_encoder)) ret = XF86OutputStatusConnected; - } else if ((nv_encoder = find_encoder_by_type(OUTPUT_LVDS))) { - if (nv_encoder->dcb->lvdsconf.use_straps_for_mode && + } else if ((det_encoder = find_encoder_by_type(OUTPUT_LVDS))) { + if (det_encoder->dcb->lvdsconf.use_straps_for_mode && pNv->VBIOS.fp.native_mode) ret = XF86OutputStatusConnected; if (pNv->VBIOS.fp.edid) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Will use hardcoded BIOS FP EDID\n"); - nv_connector->edid = xf86InterpretEDID(pScrn->scrnIndex, - pNv->VBIOS.fp.edid); + nv_connector->edid = xf86InterpretEDID(pScrn->scrnIndex, pNv->VBIOS.fp.edid); xf86OutputSetEDID(output, nv_connector->edid); ret = XF86OutputStatusConnected; } } if (ret != XF86OutputStatusDisconnected) - update_output_fields(output, nv_encoder); + update_output_fields(output, det_encoder); return ret; } @@ -513,7 +204,7 @@ static DisplayModePtr get_native_mode_from_edid(xf86OutputPtr output, DisplayModePtr edid_modes) { struct nouveau_connector *nv_connector = to_nouveau_connector(output); - struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); + struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; ScrnInfoPtr pScrn = output->scrn; int max_h_active = 0, max_v_active = 0; int i; @@ -530,7 +221,8 @@ get_native_mode_from_edid(xf86OutputPtr output, DisplayModePtr edid_modes) } } if (!(max_h_active && max_v_active)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No EDID detailed timings available, bailing out.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No EDID detailed timings available for finding native mode\n"); return NULL; } @@ -563,12 +255,11 @@ get_native_mode_from_edid(xf86OutputPtr output, DisplayModePtr edid_modes) static DisplayModePtr nv_output_get_edid_modes(xf86OutputPtr output) { - struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); + struct nouveau_connector *nv_connector = to_nouveau_connector(output); + struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; ScrnInfoPtr pScrn = output->scrn; DisplayModePtr edid_modes; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_get_edid_modes is called.\n"); - if (!(edid_modes = xf86OutputGetEDIDModes(output))) return edid_modes; @@ -576,131 +267,92 @@ nv_output_get_edid_modes(xf86OutputPtr output) if (!get_native_mode_from_edid(output, edid_modes)) return NULL; - if (nv_encoder->dcb->type == OUTPUT_LVDS) { - static bool dual_link_correction_done = false; - - if (!dual_link_correction_done) { - parse_lvds_manufacturer_table(pScrn, &NVPTR(pScrn)->VBIOS, nv_encoder->native_mode->Clock); - dual_link_correction_done = true; - } - } + if (nv_encoder->dcb->type == OUTPUT_LVDS) + parse_lvds_manufacturer_table(pScrn, &NVPTR(pScrn)->VBIOS, nv_encoder->native_mode->Clock); return edid_modes; } -static void -nv_output_destroy (xf86OutputPtr output) +static DisplayModePtr +nv_lvds_output_get_modes(xf86OutputPtr output) { struct nouveau_connector *nv_connector = to_nouveau_connector(output); - struct nouveau_encoder *nv_encoder; + struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; ScrnInfoPtr pScrn = output->scrn; - NVPtr pNv = NVPTR(output->scrn); - int i; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_destroy is called.\n"); - - if (!nv_connector) - return; - - if (nv_connector->edid) - xfree(nv_connector->edid); - FOR_EACH_ENCODER_IN_CONNECTOR(i, nv_connector, nv_encoder) - if (nv_encoder->native_mode) - xfree(nv_encoder->native_mode); - xfree(nv_connector); -} + NVPtr pNv = NVPTR(pScrn); + DisplayModePtr modes; -static void nv_digital_output_prepare_sel_clk(NVPtr pNv, struct nouveau_encoder *nv_encoder, int head) -{ - NVRegPtr state = &pNv->ModeReg; - uint32_t bits1618 = nv_encoder->dcb->or & OUTPUT_A ? 0x10000 : 0x40000; + /* panels only have one mode, and it doesn't change */ + if (nv_encoder->native_mode) + return xf86DuplicateMode(nv_encoder->native_mode); - if (nv_encoder->dcb->location != LOC_ON_CHIP) - return; + if ((modes = nv_output_get_edid_modes(output))) + return modes; - /* SEL_CLK is only used on the primary ramdac - * It toggles spread spectrum PLL output and sets the bindings of PLLs - * to heads on digital outputs - */ - if (head) - state->sel_clk |= bits1618; - else - state->sel_clk &= ~bits1618; + if (!nv_encoder->dcb->lvdsconf.use_straps_for_mode || pNv->VBIOS.fp.native_mode == NULL) + return NULL; - /* nv30: - * bit 0 NVClk spread spectrum on/off - * bit 2 MemClk spread spectrum on/off - * bit 4 PixClk1 spread spectrum on/off toggle - * bit 6 PixClk2 spread spectrum on/off toggle - * - * nv40 (observations from bios behaviour and mmio traces): - * bits 4&6 as for nv30 - * bits 5&7 head dependent as for bits 4&6, but do not appear with 4&6; - * maybe a different spread mode - * bits 8&10 seen on dual-link dvi outputs, purpose unknown (set by POST scripts) - * The logic behind turning spread spectrum on/off in the first place, - * and which bit-pair to use, is unclear on nv40 (for earlier cards, the fp table - * entry has the necessary info) - */ - if (nv_encoder->dcb->type == OUTPUT_LVDS && pNv->SavedReg.sel_clk & 0xf0) { - int shift = (pNv->SavedReg.sel_clk & 0x50) ? 0 : 1; + nv_encoder->native_mode = xf86DuplicateMode(pNv->VBIOS.fp.native_mode); - state->sel_clk &= ~0xf0; - state->sel_clk |= (head ? 0x40 : 0x10) << shift; - } + return xf86DuplicateMode(pNv->VBIOS.fp.native_mode); } -static void -nv_output_prepare(xf86OutputPtr output) +static int nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode) { - struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); - ScrnInfoPtr pScrn = output->scrn; + struct nouveau_encoder *nv_encoder = to_nouveau_connector(output)->detected_encoder; NVPtr pNv = NVPTR(output->scrn); - struct nouveau_crtc *nv_crtc = to_nouveau_crtc(output->crtc); - NVCrtcRegPtr regp = &pNv->ModeReg.crtc_reg[nv_crtc->head]; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_prepare is called.\n"); - output->funcs->dpms(output, DPMSModeOff); + if (!output->doubleScanAllowed && mode->Flags & V_DBLSCAN) + return MODE_NO_DBLESCAN; + if (!output->interlaceAllowed && mode->Flags & V_INTERLACE) + return MODE_NO_INTERLACE; - /* calculate some output specific CRTC regs now, so that they can be written in nv_crtc_set_mode */ + if (nv_encoder->dcb->type == OUTPUT_ANALOG) { + if (mode->Clock > (pNv->twoStagePLL ? 400000 : 350000)) + return MODE_CLOCK_HIGH; + if (mode->Clock < 12000) + return MODE_CLOCK_LOW; + } if (nv_encoder->dcb->type == OUTPUT_LVDS || nv_encoder->dcb->type == OUTPUT_TMDS) - nv_digital_output_prepare_sel_clk(pNv, nv_encoder, nv_crtc->head); - - /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f etc.) which we don't alter */ - if (!(regp->CRTC[NV_VGA_CRTCX_LCD] & 0x44)) { - if (nv_encoder->dcb->type == OUTPUT_LVDS || nv_encoder->dcb->type == OUTPUT_TMDS) { - regp->CRTC[NV_VGA_CRTCX_LCD] &= ~0x30; - regp->CRTC[NV_VGA_CRTCX_LCD] |= 0x3; - if (nv_crtc->head == 0) - regp->CRTC[NV_VGA_CRTCX_LCD] |= 0x8; - else - regp->CRTC[NV_VGA_CRTCX_LCD] &= ~0x8; - if (nv_encoder->dcb->location != LOC_ON_CHIP) - regp->CRTC[NV_VGA_CRTCX_LCD] |= (nv_encoder->dcb->or << 4) & 0x30; + /* No modes > panel's native res */ + if (mode->HDisplay > nv_encoder->native_mode->HDisplay || + mode->VDisplay > nv_encoder->native_mode->VDisplay) + return MODE_PANEL; + if (nv_encoder->dcb->type == OUTPUT_TMDS) { + if (nv_encoder->dcb->duallink_possible) { + if (mode->Clock > 330000) /* 2x165 MHz */ + return MODE_CLOCK_HIGH; } else - regp->CRTC[NV_VGA_CRTCX_LCD] = 0; + if (mode->Clock > 165000) /* 165 MHz */ + return MODE_CLOCK_HIGH; } + + return MODE_OK; } static void -nv_output_commit(xf86OutputPtr output) +nv_output_destroy(xf86OutputPtr output) { - struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); + struct nouveau_connector *nv_connector = to_nouveau_connector(output); + struct nouveau_encoder *nv_encoder; ScrnInfoPtr pScrn = output->scrn; - xf86CrtcPtr crtc = output->crtc; - struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc); + NVPtr pNv = NVPTR(output->scrn); + int i; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_commit is called.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s called\n", __func__); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %s is running on CRTC %d using output %c\n", output->name, nv_crtc->head, '@' + ffs(nv_encoder->dcb->or)); + if (!nv_connector) + return; - output->funcs->dpms(output, DPMSModeOn); + if (nv_connector->edid) + xfree(nv_connector->edid); + FOR_EACH_ENCODER_IN_CONNECTOR(i, nv_connector, nv_encoder) + if (nv_encoder->native_mode) + xfree(nv_encoder->native_mode); + xfree(nv_connector); } -/* - * Several scaling modes exist, let the user choose. - */ +static Atom scaling_mode_atom; #define SCALING_MODE_NAME "SCALING_MODE" static const struct { char *name; @@ -713,6 +365,7 @@ static const struct { { NULL, SCALE_INVALID} }; +static Atom dithering_atom; #define DITHERING_MODE_NAME "DITHERING" static void @@ -830,6 +483,362 @@ nv_output_set_property(xf86OutputPtr output, Atom property, return TRUE; } +static Bool +nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + struct nouveau_connector *nv_connector = to_nouveau_connector(output); + + if (nv_connector->nv_encoder != nv_connector->detected_encoder) { + nv_connector->nv_encoder = nv_connector->detected_encoder; + if (output->randr_output) { + RRDeleteOutputProperty(output->randr_output, dithering_atom); + RRDeleteOutputProperty(output->randr_output, scaling_mode_atom); + output->funcs->create_resources(output); + } + } + + struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); + + /* For internal panels and gpu scaling on DVI we need the native mode */ + if (nv_encoder->dcb->type == OUTPUT_LVDS || + (nv_encoder->dcb->type == OUTPUT_TMDS && nv_encoder->scaling_mode != SCALE_PANEL)) { + adjusted_mode->HDisplay = nv_encoder->native_mode->HDisplay; + adjusted_mode->HSkew = nv_encoder->native_mode->HSkew; + adjusted_mode->HSyncStart = nv_encoder->native_mode->HSyncStart; + adjusted_mode->HSyncEnd = nv_encoder->native_mode->HSyncEnd; + adjusted_mode->HTotal = nv_encoder->native_mode->HTotal; + adjusted_mode->VDisplay = nv_encoder->native_mode->VDisplay; + adjusted_mode->VScan = nv_encoder->native_mode->VScan; + adjusted_mode->VSyncStart = nv_encoder->native_mode->VSyncStart; + adjusted_mode->VSyncEnd = nv_encoder->native_mode->VSyncEnd; + adjusted_mode->VTotal = nv_encoder->native_mode->VTotal; + adjusted_mode->Clock = nv_encoder->native_mode->Clock; + adjusted_mode->Flags = nv_encoder->native_mode->Flags; + + xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); + } + + return TRUE; +} + +static void nv_digital_output_prepare_sel_clk(NVPtr pNv, struct nouveau_encoder *nv_encoder, int head) +{ + NVRegPtr state = &pNv->ModeReg; + uint32_t bits1618 = nv_encoder->dcb->or & OUTPUT_A ? 0x10000 : 0x40000; + + if (nv_encoder->dcb->location != LOC_ON_CHIP) + return; + + /* SEL_CLK is only used on the primary ramdac + * It toggles spread spectrum PLL output and sets the bindings of PLLs + * to heads on digital outputs + */ + if (head) + state->sel_clk |= bits1618; + else + state->sel_clk &= ~bits1618; + + /* nv30: + * bit 0 NVClk spread spectrum on/off + * bit 2 MemClk spread spectrum on/off + * bit 4 PixClk1 spread spectrum on/off toggle + * bit 6 PixClk2 spread spectrum on/off toggle + * + * nv40 (observations from bios behaviour and mmio traces): + * bits 4&6 as for nv30 + * bits 5&7 head dependent as for bits 4&6, but do not appear with 4&6; + * maybe a different spread mode + * bits 8&10 seen on dual-link dvi outputs, purpose unknown (set by POST scripts) + * The logic behind turning spread spectrum on/off in the first place, + * and which bit-pair to use, is unclear on nv40 (for earlier cards, the fp table + * entry has the necessary info) + */ + if (nv_encoder->dcb->type == OUTPUT_LVDS && pNv->SavedReg.sel_clk & 0xf0) { + int shift = (pNv->SavedReg.sel_clk & 0x50) ? 0 : 1; + + state->sel_clk &= ~0xf0; + state->sel_clk |= (head ? 0x40 : 0x10) << shift; + } +} + +static void +nv_output_prepare(xf86OutputPtr output) +{ + struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); + NVPtr pNv = NVPTR(output->scrn); + struct nouveau_crtc *nv_crtc = to_nouveau_crtc(output->crtc); + NVCrtcRegPtr regp = &pNv->ModeReg.crtc_reg[nv_crtc->head]; + + output->funcs->dpms(output, DPMSModeOff); + + /* calculate some output specific CRTC regs now, so that they can be written in nv_crtc_set_mode */ + if (nv_encoder->dcb->type == OUTPUT_LVDS || nv_encoder->dcb->type == OUTPUT_TMDS) + nv_digital_output_prepare_sel_clk(pNv, nv_encoder, nv_crtc->head); + + /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f etc.) which we don't alter */ + if (!(regp->CRTC[NV_CIO_CRE_LCD__INDEX] & 0x44)) { + if (nv_encoder->dcb->type == OUTPUT_LVDS || nv_encoder->dcb->type == OUTPUT_TMDS) { + regp->CRTC[NV_CIO_CRE_LCD__INDEX] &= ~0x30; + regp->CRTC[NV_CIO_CRE_LCD__INDEX] |= 0x3; + if (nv_crtc->head == 0) + regp->CRTC[NV_CIO_CRE_LCD__INDEX] |= 0x8; + else + regp->CRTC[NV_CIO_CRE_LCD__INDEX] &= ~0x8; + if (nv_encoder->dcb->location != LOC_ON_CHIP) + regp->CRTC[NV_CIO_CRE_LCD__INDEX] |= (nv_encoder->dcb->or << 4) & 0x30; + } else + regp->CRTC[NV_CIO_CRE_LCD__INDEX] = 0; + } +} + +static void +nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) +{ + struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + struct nouveau_crtc *nv_crtc = to_nouveau_crtc(output->crtc); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%s called for encoder %d\n", __func__, nv_encoder->dcb->index); + + if (pNv->twoHeads && nv_encoder->dcb->type == OUTPUT_ANALOG) { + uint32_t dac_offset = nv_output_ramdac_offset(nv_encoder); + uint32_t otherdac; + int i; + + /* bit 16-19 are bits that are set on some G70 cards, + * but don't seem to have much effect */ + NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + dac_offset, + nv_crtc->head << 8 | NV_RAMDAC_OUTPUT_DAC_ENABLE); + /* force any other vga encoders to bind to the other crtc */ + for (i = 0; i < pNv->dcb_table.entries; i++) + if (i != nv_encoder->dcb->index && pNv->encoders[i].dcb && + pNv->encoders[i].dcb->type == OUTPUT_ANALOG) { + dac_offset = nv_output_ramdac_offset(&pNv->encoders[i]); + otherdac = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + dac_offset); + NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + dac_offset, + (otherdac & ~0x100) | (nv_crtc->head ^ 1) << 8); + } + } + if (nv_encoder->dcb->type == OUTPUT_TMDS) + run_tmds_table(pScrn, nv_encoder->dcb, nv_crtc->head, adjusted_mode->Clock); + else if (nv_encoder->dcb->type == OUTPUT_LVDS) + call_lvds_script(pScrn, nv_encoder->dcb, nv_crtc->head, LVDS_RESET, adjusted_mode->Clock); + + /* This could use refinement for flatpanels, but it should work this way */ + if (pNv->NVArch < 0x44) + NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + nv_output_ramdac_offset(nv_encoder), 0xf0000000); + else + NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + nv_output_ramdac_offset(nv_encoder), 0x00100000); +} + +static void +nv_output_commit(xf86OutputPtr output) +{ + struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); + ScrnInfoPtr pScrn = output->scrn; + struct nouveau_crtc *nv_crtc = to_nouveau_crtc(output->crtc); + + output->funcs->dpms(output, DPMSModeOn); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %s is running on CRTC %d using output %c\n", output->name, nv_crtc->head, '@' + ffs(nv_encoder->dcb->or)); +} + +static void dpms_update_fp_control(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode) +{ + NVPtr pNv = NVPTR(pScrn); + struct nouveau_crtc *nv_crtc; + NVCrtcRegPtr regp; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + if (mode == DPMSModeOn) { + nv_crtc = to_nouveau_crtc(crtc); + regp = &pNv->ModeReg.crtc_reg[nv_crtc->head]; + + nv_crtc->fp_users |= 1 << nv_encoder->dcb->index; + NVWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL, + regp->fp_control & ~NV_PRAMDAC_FP_TG_CONTROL_OFF); + } else + for (i = 0; i < xf86_config->num_crtc; i++) { + nv_crtc = to_nouveau_crtc(xf86_config->crtc[i]); + regp = &pNv->ModeReg.crtc_reg[nv_crtc->head]; + + nv_crtc->fp_users &= ~(1 << nv_encoder->dcb->index); + if (!nv_crtc->fp_users) { + /* cut the FP output */ + regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_OFF; + NVWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL, regp->fp_control); + } + } +} + +static void +lvds_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode) +{ + NVPtr pNv = NVPTR(pScrn); + + if (nv_encoder->last_dpms == mode) + return; + nv_encoder->last_dpms = mode; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Setting dpms mode %d on lvds encoder (output %d)\n", mode, nv_encoder->dcb->index); + + if (nv_encoder->dcb->lvdsconf.use_power_scripts) { + /* when removing an output, crtc may not be set, but PANEL_OFF must still be run */ + int head = nv_get_digital_bound_head(pNv, nv_encoder->dcb->or); + int pclk = nv_encoder->native_mode->Clock; + + if (crtc) + head = to_nouveau_crtc(crtc)->head; + + if (mode == DPMSModeOn) + call_lvds_script(pScrn, nv_encoder->dcb, head, LVDS_PANEL_ON, pclk); + else + call_lvds_script(pScrn, nv_encoder->dcb, head, LVDS_PANEL_OFF, pclk); + } + + dpms_update_fp_control(pScrn, nv_encoder, crtc, mode); + + if (mode == DPMSModeOn) + nv_digital_output_prepare_sel_clk(pNv, nv_encoder, to_nouveau_crtc(crtc)->head); + else { + pNv->ModeReg.sel_clk = NVReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK); + pNv->ModeReg.sel_clk &= ~0xf0; + } + NVWriteRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK, pNv->ModeReg.sel_clk); +} + +static void +vga_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode) +{ + NVPtr pNv = NVPTR(pScrn); + + if (nv_encoder->last_dpms == mode) + return; + nv_encoder->last_dpms = mode; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Setting dpms mode %d on vga encoder (output %d)\n", mode, nv_encoder->dcb->index); + + if (pNv->twoHeads) { + uint32_t outputval = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder)); + + if (mode == DPMSModeOff) + NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder), + outputval & ~NV_RAMDAC_OUTPUT_DAC_ENABLE); + else if (mode == DPMSModeOn) + NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder), + outputval | NV_RAMDAC_OUTPUT_DAC_ENABLE); + } +} + +static void +tmds_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode) +{ + NVPtr pNv = NVPTR(pScrn); + + if (nv_encoder->last_dpms == mode) + return; + nv_encoder->last_dpms = mode; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Setting dpms mode %d on tmds encoder (output %d)\n", mode, nv_encoder->dcb->index); + + dpms_update_fp_control(pScrn, nv_encoder, crtc, mode); + + if (nv_encoder->dcb->location != LOC_ON_CHIP) { + struct nouveau_crtc *nv_crtc; + int i; + + if (mode == DPMSModeOn) { + nv_crtc = to_nouveau_crtc(crtc); + NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_LCD__INDEX, + pNv->ModeReg.crtc_reg[nv_crtc->head].CRTC[NV_CIO_CRE_LCD__INDEX]); + } else + for (i = 0; i <= pNv->twoHeads; i++) + NVWriteVgaCrtc(pNv, i, NV_CIO_CRE_LCD__INDEX, + NVReadVgaCrtc(pNv, i, NV_CIO_CRE_LCD__INDEX) & ~((nv_encoder->dcb->or << 4) & 0x30)); + } +} + +static void nv_output_dpms(xf86OutputPtr output, int mode) +{ + struct nouveau_connector *nv_connector = to_nouveau_connector(output); + struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); + ScrnInfoPtr pScrn = output->scrn; + xf86CrtcPtr crtc = output->crtc; + NVPtr pNv = NVPTR(pScrn); + int i; + void (* const encoder_dpms[4])(ScrnInfoPtr, struct nouveau_encoder *, xf86CrtcPtr, int) = + /* index matches DCB type */ + { vga_encoder_dpms, NULL, tmds_encoder_dpms, lvds_encoder_dpms }; + + struct nouveau_encoder *nv_encoder_i; + FOR_EACH_ENCODER_IN_CONNECTOR(i, nv_connector, nv_encoder_i) + if (nv_encoder_i != nv_encoder) + encoder_dpms[nv_encoder_i->dcb->type](pScrn, nv_encoder_i, crtc, DPMSModeOff); + + if (nv_encoder) /* may be called before encoder is picked, but iteration above solves it */ + encoder_dpms[nv_encoder->dcb->type](pScrn, nv_encoder, crtc, mode); +} + +static uint32_t nv_get_clock_from_crtc(ScrnInfoPtr pScrn, RIVA_HW_STATE *state, uint8_t crtc) +{ + NVPtr pNv = NVPTR(pScrn); + struct pll_lims pll_lim; + uint32_t vplla = state->crtc_reg[crtc].vpll_a; + uint32_t vpllb = state->crtc_reg[crtc].vpll_b; + bool nv40_single = pNv->Architecture == 0x40 && + ((!crtc && state->reg580 & NV_RAMDAC_580_VPLL1_ACTIVE) || + (crtc && state->reg580 & NV_RAMDAC_580_VPLL2_ACTIVE)); + + if (!get_pll_limits(pScrn, crtc ? VPLL2 : VPLL1, &pll_lim)) + return 0; + + return nv_decode_pll_highregs(pNv, vplla, vpllb, nv40_single, pll_lim.refclk); +} + +void nv_encoder_save(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder) +{ + NVPtr pNv = NVPTR(pScrn); + + if (!nv_encoder->dcb) /* uninitialised encoder */ + return; + + if (pNv->twoHeads && nv_encoder->dcb->type == OUTPUT_ANALOG) + nv_encoder->restore.output = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder)); + if (nv_encoder->dcb->type == OUTPUT_TMDS || nv_encoder->dcb->type == OUTPUT_LVDS) + nv_encoder->restore.head = nv_get_digital_bound_head(pNv, nv_encoder->dcb->or); +} + +void nv_encoder_restore(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder) +{ + NVPtr pNv = NVPTR(pScrn); + int head = nv_encoder->restore.head; + + if (!nv_encoder->dcb) /* uninitialised encoder */ + return; + + if (pNv->twoHeads && nv_encoder->dcb->type == OUTPUT_ANALOG) + NVWriteRAMDAC(pNv, 0, + NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(nv_encoder), + nv_encoder->restore.output); + if (nv_encoder->dcb->type == OUTPUT_LVDS) + call_lvds_script(pScrn, nv_encoder->dcb, head, LVDS_PANEL_ON, + nv_encoder->native_mode->Clock); + if (nv_encoder->dcb->type == OUTPUT_TMDS) { + int clock = nv_get_clock_from_crtc(pScrn, &pNv->SavedReg, head); + + run_tmds_table(pScrn, nv_encoder->dcb, head, clock); + } + + nv_encoder->last_dpms = NV_DPMS_CLEARED; +} + static const xf86OutputFuncsRec nv_output_funcs = { .dpms = nv_output_dpms, .mode_valid = nv_output_mode_valid, @@ -844,29 +853,6 @@ static const xf86OutputFuncsRec nv_output_funcs = { .set_property = nv_output_set_property, }; -static DisplayModePtr -nv_lvds_output_get_modes(xf86OutputPtr output) -{ - struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output); - ScrnInfoPtr pScrn = output->scrn; - NVPtr pNv = NVPTR(pScrn); - DisplayModePtr modes; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_lvds_output_get_modes is called.\n"); - - if ((modes = nv_output_get_edid_modes(output))) - return modes; - - if (!nv_encoder->dcb->lvdsconf.use_straps_for_mode || pNv->VBIOS.fp.native_mode == NULL) - return NULL; - - if (nv_encoder->native_mode) - xfree(nv_encoder->native_mode); - nv_encoder->native_mode = xf86DuplicateMode(pNv->VBIOS.fp.native_mode); - - return xf86DuplicateMode(pNv->VBIOS.fp.native_mode); -} - static const xf86OutputFuncsRec nv_lvds_output_funcs = { .dpms = nv_output_dpms, .mode_valid = nv_output_mode_valid, @@ -912,8 +898,10 @@ nv_add_connector(ScrnInfoPtr pScrn, int i2c_index, int encoders, const xf86Outpu if (!(output = xf86OutputCreate(pScrn, output_funcs, outputname))) return; - if (!(nv_connector = xnfcalloc(sizeof (struct nouveau_connector), 1))) + if (!(nv_connector = xcalloc(1, sizeof (struct nouveau_connector)))) { + xf86OutputDestroy(output); return; + } output->driver_private = nv_connector; @@ -925,15 +913,13 @@ nv_add_connector(ScrnInfoPtr pScrn, int i2c_index, int encoders, const xf86Outpu void NvSetupOutputs(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - uint16_t connectors[0x10]; + uint16_t connectors[0x10] = { 0 }; struct dcb_entry *dcbent; int i, vga_count = 0, dvid_count = 0, dvii_count = 0, lvds_count = 0; - if (!(pNv->encoders = xnfcalloc(pNv->dcb_table.entries, sizeof (struct nouveau_encoder)))) + if (!(pNv->encoders = xcalloc(pNv->dcb_table.entries, sizeof (struct nouveau_encoder)))) return; - memset(connectors, 0, sizeof (connectors)); - for (i = 0; i < pNv->dcb_table.entries; i++) { dcbent = &pNv->dcb_table.entry[i]; diff --git a/src/nv_pcicompat.h b/src/nv_pcicompat.h index 4ead510..5e52437 100644 --- a/src/nv_pcicompat.h +++ b/src/nv_pcicompat.h @@ -23,6 +23,8 @@ #define PCI_DEV_READ_LONG(_device, _offset, _dest_ptr) (pci_device_cfg_read_u32(_device, _dest_ptr, _offset)) #define PCI_DEV_WRITE_LONG(_device, _offset, _src) (pci_device_cfg_write_u32(_device, _src, _offset)) +#define PCI_SLOT_READ_LONG(_slot, _offset) __extension__ ({ uint32_t _pci_slot_read_ret; pci_device_cfg_read_u32(pci_device_find_by_slot(0, 0, 0, _slot), &_pci_slot_read_ret, _offset); _pci_slot_read_ret; }) + #else /* PRE_PCIACCESS */ #define PCI_DEV_VENDOR_ID(_device) ((_device)->vendor) @@ -41,6 +43,8 @@ #define PCI_DEV_READ_LONG(_device, _offset, _dest_ptr) (*(_dest_ptr) = pciReadLong(PCI_DEV_TAG(_device), _offset)) #define PCI_DEV_WRITE_LONG(_device, _offset, _src) (pciWriteLong(PCI_DEV_TAG(_device), _offset, _src)) +#define PCI_SLOT_READ_LONG(_slot, _offset) (pciReadLong(pciTag(0, 0, _slot), _offset)) + #endif /* XSERVER_LIBPCIACCESS */ #define PCI_DEV_PCI_ID(_device) ((PCI_DEV_VENDOR_ID(_device) << 16) | PCI_DEV_DEVICE_ID(_device)) diff --git a/src/nv_proto.h b/src/nv_proto.h index 450c824..aefc0ce 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -8,6 +8,7 @@ Bool NVAccelCommonInit(ScrnInfoPtr pScrn); Bool NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret); Bool NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPix, int *fmt_ret); PixmapPtr NVGetDrawablePixmap(DrawablePtr pDraw); +void NVAccelFree(NVPtr pNv); /* in nv_driver.c */ Bool NVI2CInit(ScrnInfoPtr pScrn); @@ -29,11 +30,13 @@ void NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual ); Bool NVDACi2cInit(ScrnInfoPtr pScrn); -/* in nv_video.c */ +/* in nouveau_xv.c */ void NVInitVideo(ScreenPtr); void NVWaitVSync(ScrnInfoPtr pScrn, int crtc); void NVSetPortDefaults (ScrnInfoPtr pScrn, NVPortPrivPtr pPriv); unsigned int nv_window_belongs_to_crtc(ScrnInfoPtr, int, int, int, int); +void NVXvDMANotifiersRealFree(void); +void NVFreePortMemory(ScrnInfoPtr pScrn, NVPortPrivPtr pPriv); /* in nv_setup.c */ void RivaEnterLeave(ScrnInfoPtr pScrn, Bool enter); @@ -48,8 +51,6 @@ void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y); void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg); void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image); void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image); -void nv_crtc_fix_nv40_hw_cursor(ScrnInfoPtr pScrn, uint8_t head); -void nv_crtc_show_hide_cursor(ScrnInfoPtr pScrn, uint8_t head, Bool show); /* in nv_dma.c */ void NVSync(ScrnInfoPtr pScrn); @@ -60,7 +61,7 @@ Bool NVExaInit(ScreenPtr pScreen); Bool NVExaPixmapIsOnscreen(PixmapPtr pPixmap); /* in nv_hw.c */ -void NVCalcStateExt(NVPtr,struct _riva_hw_state *,int,int,int,int,int,int); +void NVCalcStateExt(ScrnInfoPtr,struct _riva_hw_state *,int,int,int,int,int,int); void NVLoadStateExt(ScrnInfoPtr pScrn,struct _riva_hw_state *); void NVUnloadStateExt(NVPtr,struct _riva_hw_state *); void NVSetStartAddress(NVPtr,CARD32); @@ -80,7 +81,7 @@ bool get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pl /* nv_crtc.c */ void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y); void nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num); -void NVCrtcLockUnlock(xf86CrtcPtr crtc, Bool lock); +void NVCrtcLockUnlock(xf86CrtcPtr crtc, bool lock); /* nv_output.c */ void nv_encoder_restore(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder); @@ -101,8 +102,8 @@ void NVWriteVgaCrtc(NVPtr pNv, int head, uint8_t index, uint8_t value); uint8_t NVReadVgaCrtc(NVPtr pNv, int head, uint8_t index); void NVWriteVgaCrtc5758(NVPtr pNv, int head, uint8_t index, uint8_t value); uint8_t NVReadVgaCrtc5758(NVPtr pNv, int head, uint8_t index); -uint8_t NVReadPVIO(NVPtr pNv, int head, uint16_t port); -void NVWritePVIO(NVPtr pNv, int head, uint16_t port, uint8_t value); +uint8_t NVReadPRMVIO(NVPtr pNv, int head, uint32_t reg); +void NVWritePRMVIO(NVPtr pNv, int head, uint32_t reg, uint8_t value); void NVWriteVgaSeq(NVPtr pNv, int head, uint8_t index, uint8_t value); uint8_t NVReadVgaSeq(NVPtr pNv, int head, uint8_t index); void NVWriteVgaGr(NVPtr pNv, int head, uint8_t index, uint8_t value); @@ -112,26 +113,15 @@ void NVWriteVgaAttr(NVPtr pNv, int head, uint8_t index, uint8_t value); uint8_t NVReadVgaAttr(NVPtr pNv, int head, uint8_t index); void NVVgaSeqReset(NVPtr pNv, int head, bool start); void NVVgaProtect(NVPtr pNv, int head, bool protect); -void NVSetOwner(ScrnInfoPtr pScrn, int head); +void NVSetOwner(NVPtr pNv, int owner); void NVLockVgaCrtc(NVPtr pNv, int head, bool lock); -void NVBlankScreen(ScrnInfoPtr pScrn, int head, bool blank); +void NVLockVgaCrtcs(NVPtr pNv, bool lock); +void NVBlankScreen(NVPtr pNv, int head, bool blank); +void nv_fix_nv40_hw_cursor(NVPtr pNv, int head); +void nv_show_cursor(NVPtr pNv, int head, bool show); int nv_decode_pll_highregs(NVPtr pNv, uint32_t pll1, uint32_t pll2, bool force_single, int refclk); -void nForceUpdateArbitrationSettings (unsigned VClk, unsigned pixelDepth, - unsigned *burst, unsigned *lwm, - NVPtr pNv); -void nv30UpdateArbitrationSettings (NVPtr pNv, - unsigned *burst, - unsigned *lwm); -void nv10UpdateArbitrationSettings (unsigned VClk, - unsigned pixelDepth, - unsigned *burst, - unsigned *lwm, - NVPtr pNv); -void nv4UpdateArbitrationSettings (unsigned VClk, - unsigned pixelDepth, - unsigned *burst, - unsigned *lwm, - NVPtr pNv); +void nv4_10UpdateArbitrationSettings(ScrnInfoPtr pScrn, int VClk, int bpp, uint8_t *burst, uint16_t *lwm); +void nv30UpdateArbitrationSettings(uint8_t *burst, uint16_t *lwm); uint32_t nv_pitch_align(NVPtr pNv, uint32_t width, int bpp); void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save); diff --git a/src/nv_setup.c b/src/nv_setup.c index 71a20b1..84b3c37 100644 --- a/src/nv_setup.c +++ b/src/nv_setup.c @@ -21,7 +21,6 @@ */ #include "nv_include.h" -#include "nvreg.h" /* * Override VGA I/O routines. @@ -237,6 +236,55 @@ NVProbeDDC (ScrnInfoPtr pScrn, int bus) return MonInfo; } +static void store_initial_head_owner(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + + if (pNv->NVArch != 0x11) { + pNv->vtOWNER = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_44); + goto ownerknown; + } + + /* reading CR44 is broken on nv11, so we attempt to infer it */ + if (nvReadMC(pNv, NV_PBUS_DEBUG_1) & (1 << 28)) /* heads tied, restore both */ + pNv->vtOWNER = 0x4; + else { + uint8_t slaved_on_A, slaved_on_B; + bool tvA, tvB = false; + + NVLockVgaCrtcs(pNv, false); + + slaved_on_B = NVReadVgaCrtc(pNv, 1, NV_CIO_CRE_PIXEL_INDEX) & 0x80; + if (slaved_on_B) + tvB = !(NVReadVgaCrtc(pNv, 1, NV_CIO_CRE_LCD__INDEX) & NV_CIO_CRE_LCD_LCD_SELECT); + + slaved_on_A = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX) & 0x80; + if (slaved_on_A) + tvA = !(NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_LCD__INDEX) & NV_CIO_CRE_LCD_LCD_SELECT); + + NVLockVgaCrtcs(pNv, true); + + if (slaved_on_A && !tvA) + pNv->vtOWNER = 0x0; + else if (slaved_on_B && !tvB) + pNv->vtOWNER = 0x3; + else if (slaved_on_A) + pNv->vtOWNER = 0x0; + else if (slaved_on_B) + pNv->vtOWNER = 0x3; + else + pNv->vtOWNER = 0x0; + } + +ownerknown: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initial CRTC_OWNER is %d\n", pNv->vtOWNER); + + /* we need to ensure the heads are not tied henceforth, or reading any + * 8 bit reg on head B will fail + * setting a single arbitrary head solves that */ + NVSetOwner(pNv, 0); +} + static void nv4GetConfig (NVPtr pNv) { uint32_t reg_FB0 = nvReadFB(pNv, NV_PFB_BOOT_0); @@ -266,39 +314,40 @@ static void nv4GetConfig (NVPtr pNv) pNv->MaxVClockFreqKHz = 350000; } -static void nv10GetConfig (NVPtr pNv) +static void nForce_check_dimms(ScrnInfoPtr pScrn) { + uint16_t mem_ctrlr_pciid = PCI_SLOT_READ_LONG(3, 0x00) >> 16; + + if ((mem_ctrlr_pciid == 0x1a9) || (mem_ctrlr_pciid == 0x1ab) || (mem_ctrlr_pciid == 0x1ed)) { + uint32_t dimm[3]; + + dimm[0] = (PCI_SLOT_READ_LONG(2, 0x40) >> 8) & 0x4f; + dimm[1] = (PCI_SLOT_READ_LONG(2, 0x44) >> 8) & 0x4f; + dimm[2] = (PCI_SLOT_READ_LONG(2, 0x48) >> 8) & 0x4f; + + if (dimm[0] + dimm[1] != dimm[2]) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Your nForce DIMMs are not arranged in optimal banks!\n"); + } +} + +static void nv10GetConfig(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); uint32_t implementation = pNv->Chipset & 0x0ff0; #if X_BYTE_ORDER == X_BIG_ENDIAN if (!(nvReadMC(pNv, 0x0004) & 0x01000001)) - xf86DrvMsg(0, X_ERROR, "Card is in big endian mode, something is very wrong !\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Card is in big endian mode, something is very wrong !\n"); #endif if (implementation == CHIPSET_NFORCE) { - uint32_t amt; -#ifdef XSERVER_LIBPCIACCESS - const struct pci_slot_match match[] = { {0, 0, 0, 1, 0} }; - struct pci_device_iterator *iterator = pci_slot_match_iterator_create(match); - /* assume one device to exist */ - struct pci_device *device = pci_device_next(iterator); - PCI_DEV_READ_LONG(device, 0x7c, &amt); -#else - amt = pciReadLong(pciTag(0, 0, 1), 0x7C); -#endif /* XSERVER_LIBPCIACCESS */ - pNv->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024; + pNv->RamAmountKBytes = (((PCI_SLOT_READ_LONG(1, 0x7c) >> 6) & 31) + 1) * 1024; + nForce_check_dimms(pScrn); } else if (implementation == CHIPSET_NFORCE2) { - uint32_t amt; -#ifdef XSERVER_LIBPCIACCESS - const struct pci_slot_match match[] = { {0, 0, 0, 1, 0} }; - struct pci_device_iterator *iterator = pci_slot_match_iterator_create(match); - /* assume one device to exist */ - struct pci_device *device = pci_device_next(iterator); - PCI_DEV_READ_LONG(device, 0x84, &amt); -#else - amt = pciReadLong(pciTag(0, 0, 1), 0x84); -#endif /* XSERVER_LIBPCIACCESS */ - pNv->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024; + pNv->RamAmountKBytes = (((PCI_SLOT_READ_LONG(1, 0x84) >> 4) & 127) + 1) * 1024; + nForce_check_dimms(pScrn); } else pNv->RamAmountKBytes = (nvReadFB(pNv, NV_PFB_020C) & 0xFFF00000) >> 10; @@ -372,12 +421,12 @@ NVCommonSetup(ScrnInfoPtr pScrn) pNv->PGRAPH = pNv->REGS + (NV_PGRAPH_OFFSET/4); /* 8 bit registers */ - pNv->PCIO0 = (uint8_t *)pNv->REGS + NV_PCIO0_OFFSET; - pNv->PDIO0 = (uint8_t *)pNv->REGS + NV_PDIO0_OFFSET; - pNv->PVIO0 = (uint8_t *)pNv->REGS + NV_PVIO0_OFFSET; - pNv->PCIO1 = pNv->PCIO0 + NV_PCIO_SIZE; - pNv->PDIO1 = pNv->PDIO0 + NV_PDIO_SIZE; - pNv->PVIO1 = pNv->PVIO0 + NV_PVIO_SIZE; + pNv->PCIO0 = (uint8_t *)pNv->REGS + NV_PRMCIO0_OFFSET; + pNv->PDIO0 = (uint8_t *)pNv->REGS + NV_PRMDIO0_OFFSET; + pNv->PVIO0 = (uint8_t *)pNv->REGS + NV_PRMVIO0_OFFSET; + pNv->PCIO1 = pNv->PCIO0 + NV_PRMCIO_SIZE; + pNv->PDIO1 = pNv->PDIO0 + NV_PRMDIO_SIZE; + pNv->PVIO1 = pNv->PVIO0 + NV_PRMVIO_SIZE; pNv->alphaCursor = (pNv->NVArch >= 0x11); @@ -471,43 +520,8 @@ NVCommonSetup(ScrnInfoPtr pScrn) pNv->Television = FALSE; - if (pNv->twoHeads) { - pNv->vtOWNER = NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_OWNER); - if (pNv->NVArch == 0x11) { /* reading OWNER is broken on nv11 */ - if (nvReadMC(pNv, NV_PBUS_DEBUG_1) & (1 << 28)) /* heads tied, restore both */ - pNv->vtOWNER = 0x04; - else { - uint8_t slaved_on_A, slaved_on_B; - - NVSetOwner(pScrn, 1); - NVLockVgaCrtc(pNv, 1, false); - - slaved_on_B = NVReadVgaCrtc(pNv, 1, NV_VGA_CRTCX_PIXEL) & 0x80; - if (slaved_on_B) - tvB = !(NVReadVgaCrtc(pNv, 1, NV_VGA_CRTCX_LCD) & 0x01); - - NVSetOwner(pScrn, 0); - NVLockVgaCrtc(pNv, 0, false); - - slaved_on_A = NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_PIXEL) & 0x80; - if (slaved_on_A) - tvA = !(NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_LCD) & 0x01); - - if (slaved_on_A && !tvA) - pNv->vtOWNER = 0x0; - else if (slaved_on_B && !tvB) - pNv->vtOWNER = 0x3; - else if (slaved_on_A) - pNv->vtOWNER = 0x0; - else if (slaved_on_B) - pNv->vtOWNER = 0x3; - else - pNv->vtOWNER = 0x0; - } - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initial CRTC_OWNER is %d\n", pNv->vtOWNER); - } + if (pNv->twoHeads) + store_initial_head_owner(pScrn); /* Parse the bios to initialize the card */ NVParseBios(pScrn); @@ -515,7 +529,7 @@ NVCommonSetup(ScrnInfoPtr pScrn) if (pNv->Architecture == NV_ARCH_04) nv4GetConfig(pNv); else - nv10GetConfig(pNv); + nv10GetConfig(pScrn); if (!pNv->randr12_enable) { @@ -536,8 +550,8 @@ NVCommonSetup(ScrnInfoPtr pScrn) if((pNv->Chipset & 0x0fff) <= CHIPSET_NV04) FlatPanel = 0; } else { - if(nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) { - if(!(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01)) + if(nvReadCurVGA(pNv, NV_CIO_CRE_PIXEL_INDEX) & 0x80) { + if(!(nvReadCurVGA(pNv, NV_CIO_CRE_LCD__INDEX) & 0x01)) Television = TRUE; FlatPanel = 1; } else { @@ -585,22 +599,22 @@ NVCommonSetup(ScrnInfoPtr pScrn) cr44 = pNv->vtOWNER; - nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, 3); + nvWriteCurVGA(pNv, NV_CIO_CRE_44, 3); NVSelectHeadRegisters(pScrn, 1); NVLockUnlock(pScrn, 0); - slaved_on_B = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80; + slaved_on_B = nvReadCurVGA(pNv, NV_CIO_CRE_PIXEL_INDEX) & 0x80; if(slaved_on_B) { - tvB = !(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01); + tvB = !(nvReadCurVGA(pNv, NV_CIO_CRE_LCD__INDEX) & 0x01); } - nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, 0); + nvWriteCurVGA(pNv, NV_CIO_CRE_44, 0); NVSelectHeadRegisters(pScrn, 0); NVLockUnlock(pScrn, 0); - slaved_on_A = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80; + slaved_on_A = nvReadCurVGA(pNv, NV_CIO_CRE_PIXEL_INDEX) & 0x80; if(slaved_on_A) { - tvA = !(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01); + tvA = !(nvReadCurVGA(pNv, NV_CIO_CRE_LCD__INDEX) & 0x01); } oldhead = NVReadCRTC(pNv, 0, NV_CRTC_FSEL); @@ -719,7 +733,7 @@ NVCommonSetup(ScrnInfoPtr pScrn) NVWriteCRTC(pNv, 0, NV_CRTC_FSEL, oldhead); - nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, cr44); + nvWriteCurVGA(pNv, NV_CIO_CRE_44, cr44); NVSelectHeadRegisters(pScrn, pNv->crtc_active[1]); } diff --git a/src/nv_type.h b/src/nv_type.h index 639dc9c..5666afd 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -147,7 +147,6 @@ typedef struct _nv_crtc_reg uint8_t Attribute[21]; unsigned char DAC[768]; /* Internal Colorlookuptable */ uint32_t cursorConfig; - uint32_t crtcOwner; uint32_t gpio; uint32_t gpio_ext; uint32_t unk830; @@ -197,10 +196,10 @@ typedef struct _riva_hw_state uint32_t fifo; uint32_t pixel; uint32_t horiz; - uint32_t arbitration0; - uint32_t arbitration1; - uint32_t pll; - uint32_t pllB; + uint8_t arbitration0; + uint16_t arbitration1; + CARD32 pll; + CARD32 pllB; uint32_t vpll; uint32_t vpll2; uint32_t vpllB; @@ -250,6 +249,7 @@ struct nouveau_connector { xf86MonPtr edid; I2CBusPtr pDDCBus; uint16_t possible_encoders; + struct nouveau_encoder *detected_encoder; struct nouveau_encoder *nv_encoder; }; @@ -428,7 +428,6 @@ typedef struct _NVRec { volatile CARD8 *PDIO0; volatile CARD8 *PDIO1; - unsigned int SaveGeneration; uint8_t cur_head; ExaDriverPtr EXADriverPtr; xf86CursorInfoPtr CursorInfoRec; @@ -526,15 +525,13 @@ typedef struct _NVRec { struct nouveau_grobj *Nv2D; struct nouveau_grobj *Nv3D; struct nouveau_bo *tesla_scratch; + struct nouveau_bo *shader_mem; + struct nouveau_bo *xv_filtertable_mem; } NVRec; #define NVPTR(p) ((NVPtr)((p)->driverPrivate)) -#define NVShowHideCursor(pScrn, show) do { \ - NVPtr pNv = NVPTR(pScrn); \ - nv_crtc_show_hide_cursor(pScrn, pNv->cur_head, show); \ -} while(0) - +#define NVShowHideCursor(pScrn, show) nv_show_cursor(NVPTR(pScrn), NVPTR(pScrn)->cur_head, show) #define NVLockUnlock(pScrn, lock) NVLockVgaCrtc(NVPTR(pScrn), NVPTR(pScrn)->cur_head, lock) #define nvReadCurVGA(pNv, reg) NVReadVgaCrtc(pNv, pNv->cur_head, reg) diff --git a/src/nvreg.h b/src/nvreg.h index f1c90c6..f41bc55 100644 --- a/src/nvreg.h +++ b/src/nvreg.h @@ -50,12 +50,12 @@ #define NV_PPM_OFFSET 0x0000A000 #define NV_PPM_SIZE 0x00001000 -#define NV_PVGA_OFFSET 0x000A0000 -#define NV_PVGA_SIZE 0x00020000 +#define NV_PRMVGA_OFFSET 0x000A0000 +#define NV_PRMVGA_SIZE 0x00020000 -#define NV_PVIO0_OFFSET 0x000C0000 -#define NV_PVIO_SIZE 0x00002000 -#define NV_PVIO1_OFFSET 0x000C2000 +#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 @@ -75,9 +75,9 @@ #define NV_PCRTC0_OFFSET 0x00600000 #define NV_PCRTC0_SIZE 0x00002000 /* empirical */ -#define NV_PCIO0_OFFSET 0x00601000 -#define NV_PCIO_SIZE 0x00002000 -#define NV_PCIO1_OFFSET 0x00603000 +#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 @@ -85,9 +85,9 @@ #define NV_PRAMDAC0_OFFSET 0x00680000 #define NV_PRAMDAC0_SIZE 0x00002000 -#define NV_PDIO0_OFFSET 0x00681000 -#define NV_PDIO_SIZE 0x00002000 -#define NV_PDIO1_OFFSET 0x00683000 +#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 @@ -95,75 +95,15 @@ #define NV_FIFO_OFFSET 0x00800000 #define NV_FIFO_SIZE 0x00800000 -#define CRTC_INDEX_COLOR 0x3d4 -#define CRTC_DATA_COLOR 0x3d5 - -/* Nvidia CRTC indexed registers */ -/* VGA standard registers: - from Haiku */ -#define NV_VGA_CRTCX_HTOTAL 0x00 -#define NV_VGA_CRTCX_HDISPE 0x01 -#define NV_VGA_CRTCX_HBLANKS 0x02 -#define NV_VGA_CRTCX_HBLANKE 0x03 -#define NV_VGA_CRTCX_HSYNCS 0x04 -#define NV_VGA_CRTCX_HSYNCE 0x05 -#define NV_VGA_CRTCX_VTOTAL 0x06 -#define NV_VGA_CRTCX_OVERFLOW 0x07 -#define NV_VGA_CRTCX_PRROWSCN 0x08 -#define NV_VGA_CRTCX_MAXSCLIN 0x09 -#define NV_VGA_CRTCX_VGACURSTART 0x0a -#define NV_VGA_CRTCX_VGACUREND 0x0b -#define NV_VGA_CRTCX_FBSTADDH 0x0c -#define NV_VGA_CRTCX_FBSTADDL 0x0d -#define NV_VGA_CRTCX_VSYNCS 0x10 -#define NV_VGA_CRTCX_VSYNCE 0x11 -#define NV_VGA_CRTCX_VDISPE 0x12 -#define NV_VGA_CRTCX_PITCHL 0x13 -#define NV_VGA_CRTCX_UNDERLINE 0x14 -#define NV_VGA_CRTCX_VBLANKS 0x15 -#define NV_VGA_CRTCX_VBLANKE 0x16 -#define NV_VGA_CRTCX_MODECTL 0x17 -#define NV_VGA_CRTCX_LINECOMP 0x18 -/* Extended VGA CRTC registers */ -#define NV_VGA_CRTCX_REPAINT0 0x19 -#define NV_VGA_CRTCX_REPAINT1 0x1a -#define NV_VGA_CRTCX_FIFO0 0x1b -#define NV_VGA_CRTCX_FIFO1 0x1c -#define NV_VGA_CRTCX_LOCK 0x1f -#define NV_VGA_CRTCX_FIFO_LWM 0x20 -#define NV_VGA_CRTCX_BUFFER 0x21 -#define NV_VGA_CRTCX_LSR 0x25 -#define NV_VGA_CRTCX_26 0x26 -#define NV_VGA_CRTCX_REVISION 0x27 -#define NV_VGA_CRTCX_PIXEL 0x28 -#define NV_VGA_CRTCX_HEB 0x2d -#define NV_VGA_CRTCX_2E 0x2e -#define NV_VGA_CRTCX_CURCTL2 0x2f -#define NV_VGA_CRTCX_CURCTL0 0x30 -#define NV_VGA_CRTCX_CURCTL1 0x31 -#define NV_VGA_CRTCX_LCD 0x33 -#define NV_VGA_CRTCX_INTERLACE 0x39 -#define NV_VGA_CRTCX_3B 0x3b -#define NV_VGA_CRTCX_SCRATCH4 0x3c -#define NV_VGA_CRTCX_EXTRA 0x41 -#define NV_VGA_CRTCX_OWNER 0x44 -#define NV_VGA_CRTCX_45 0x45 -#define NV_VGA_CRTCX_SWAPPING 0x46 -#define NV_VGA_CRTCX_FIFO_LWM_NV30 0x47 -#define NV_VGA_CRTCX_4B 0x4b -#define NV_VGA_CRTCX_FP_HTIMING 0x53 -#define NV_VGA_CRTCX_FP_VTIMING 0x54 -#define NV_VGA_CRTCX_52 0x52 -#define NV_VGA_CRTCX_55 0x55 -#define NV_VGA_CRTCX_56 0x56 -#define NV_VGA_CRTCX_57 0x57 -#define NV_VGA_CRTCX_58 0x58 -#define NV_VGA_CRTCX_59 0x59 -#define NV_VGA_CRTCX_85 0x85 -#define NV_VGA_CRTCX_86 0x86 - #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 @@ -177,6 +117,27 @@ #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 @@ -204,6 +165,8 @@ #define NV_CRTC_INTR_EN_0 0x00600140 #define NV_CRTC_START 0x00600800 #define NV_CRTC_CONFIG 0x00600804 + #define NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA 1 + #define NV_PCRTC_CONFIG_START_ADDRESS_HSYNC 2 #define NV_CRTC_CURSOR_ADDRESS 0x0060080C #define NV_CRTC_CURSOR_CONFIG 0x00600810 # define NV_CRTC_CURSOR_CONFIG_ENABLE (1 << 0) @@ -225,6 +188,91 @@ # define NV_CRTC_FSEL_TVOUT2 (2<<8) # 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_HRS_INDEX 0x04 /* horizontal retrace start */ + #define NV_CIO_CR_HRE_INDEX 0x05 /* horizontal retrace end */ + #define NV_CIO_CR_VDT_INDEX 0x06 /* vertical display total */ + #define NV_CIO_CR_OVL_INDEX 0x07 /* overflow bits */ + #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_SCANDBL 0x80 + #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_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_RPC1_INDEX 0x1a /* repaint control 1 */ + #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_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_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_ASI 0x80 + #define NV_CIO_CRE_HCUR_ADDR1_INDEX 0x31 /* address */ + #define NV_CIO_CRE_HCUR_ADDR1_CUR_DBL 0x02 + #define NV_CIO_CRE_HCUR_ADDR1_ENABLE 0x01 + #define NV_CIO_CRE_LCD__INDEX 0x33 + #define NV_CIO_CRE_LCD_LCD_SELECT 0x01 + #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_44 0x44 /* head control */ + #define NV_CIO_CRE_CSB 0x45 + #define NV_CIO_CRE_RCR 0x46 + #define NV_CIO_CRE_RCR_ENDIAN_BIG 0x80; + #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_52 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_85 0x85 + #define NV_CIO_CRE_86 0x86 +#define NV_PRMCIO_INP0__COLOR 0x006013da + #define NV_RAMDAC_CURSOR_POS 0x00680300 #define NV_RAMDAC_CURSOR_CTRL 0x00680320 #define NV_RAMDAC_CURSOR_DATA_LO 0x00680324 @@ -291,7 +339,11 @@ #define NV_RAMDAC_594 0x00680594 #define NV_RAMDAC_GENERAL_CONTROL 0x00680600 #define NV_RAMDAC_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_RAMDAC_TEST_DATA 0x00680610 + #define NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK (1 << 31) #define NV_RAMDAC_630 0x00680630 /* This register is similar to TEST_CONTROL in the style of values */ #define NV_RAMDAC_670 0x00680670 @@ -349,6 +401,9 @@ # define NV_RAMDAC_FP_CONTROL_WIDTH_12 (1 << 24) # define NV_RAMDAC_FP_CONTROL_DISPEN_POS (1 << 28) # define NV_RAMDAC_FP_CONTROL_DISPEN_DISABLE (2 << 28) + #define NV_PRAMDAC_FP_TG_CONTROL_OFF (NV_RAMDAC_FP_CONTROL_DISPEN_DISABLE | \ + NV_RAMDAC_FP_CONTROL_HSYNC_DISABLE | \ + NV_RAMDAC_FP_CONTROL_VSYNC_DISABLE) #define NV_RAMDAC_FP_850 0x00680850 #define NV_RAMDAC_FP_85C 0x0068085c @@ -369,6 +424,7 @@ #define NV30_RAMDAC_894 0x00680894 #define NV30_RAMDAC_89C 0x0068089C +/* see NV_PRAMDAC_INDIR_TMDS in rules.xml */ #define NV_RAMDAC_FP_TMDS_CONTROL 0x006808b0 # define NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE (1<<16) #define NV_RAMDAC_FP_TMDS_DATA 0x006808b4 @@ -382,6 +438,13 @@ #define NV_RAMDAC_A24 0x00680A24 #define NV_RAMDAC_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 |