All of lore.kernel.org
 help / color / mirror / Atom feed
* RANDR1.2 and LVDS
@ 2007-07-05  2:57 Matthew Garrett
  0 siblings, 0 replies; only message in thread
From: Matthew Garrett @ 2007-07-05  2:57 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Hi!

I've written a small amount of code that gets the randr 1.2 branch much 
closer to working for me on a laptop. Most of the changes are fairly 
obvious, but a couple of comments:

1) The changes to nv_crtc.c are clearly bogus, but I'm not sure what on 
earth these registers do. I need to set them to get a moderately 
sane-looking picture

2) The fp registers poked in nv_output.c don't seem to do anything on 
lvds. No matter what I set them to, the picture is identical

3) This doesn't /quite/ work for me yet. I have a solid and recognisable 
picture, but it's only about the left two thirds of my screen, centred 
on the display with black borders. Clearly the panel programming isn't 
/quite/ right yet...

Signed-off-by: Matthew Garrett <mjg59-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org>

diff --git a/src/nv_crtc.c b/src/nv_crtc.c
index 5b646d0..3388a3a 100644
--- a/src/nv_crtc.c
+++ b/src/nv_crtc.c
@@ -945,8 +945,9 @@ nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode)
     } else
        regp->cursorConfig |= 0x02000000;
 
-    regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = 0;
-    regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = 0;
+    // FIXME: Figure out what these actually do
+    regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = 0xa;
+    regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = 0x2;
 
     regp->unk830 = mode->CrtcVDisplay - 3;
     regp->unk834 = mode->CrtcVDisplay - 1;
diff --git a/src/nv_output.c b/src/nv_output.c
index 9f72fd3..558aa5c 100644
--- a/src/nv_output.c
+++ b/src/nv_output.c
@@ -287,6 +287,23 @@ nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
     return MODE_OK;
 }
 
+static int
+nv_output_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+{
+    NVOutputPrivatePtr nv_output = output->driver_private;
+
+    if (pMode->Flags & V_DBLSCAN)
+	return MODE_NO_DBLESCAN;
+  
+    if (pMode->Clock > 400000 || pMode->Clock < 25000)
+	return MODE_CLOCK_RANGE;
+
+    if (pMode->HDisplay > nv_output->fpWidth
+	|| pMode->VDisplay > nv_output->fpHeight)
+      return MODE_PANEL;
+
+    return MODE_OK;
+}
 
 static Bool
 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
@@ -351,27 +368,28 @@ nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
     {
 	is_fp = TRUE;
 
-	for (i = 0; i < 7; i++) {
+	if (nv_output->type == OUTPUT_DIGITAL) {
+	  for (i = 0; i < 7; i++) {
 	    regp->fp_horiz_regs[i] = savep->fp_horiz_regs[i];
 	    regp->fp_vert_regs[i] = savep->fp_vert_regs[i];
+	  }
+	  
+	  regp->fp_horiz_regs[REG_DISP_END] = mode->CrtcHDisplay - 1;
+	  regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->CrtcHTotal - 1;
+	  regp->fp_horiz_regs[REG_DISP_CRTC] = mode->CrtcHDisplay;
+	  regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->CrtcHSyncStart - 1;
+	  regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->CrtcHSyncEnd - 1;
+	  regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->CrtcHSkew;
+	  regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->CrtcHDisplay - 1;
+	  
+	  regp->fp_vert_regs[REG_DISP_END] = mode->CrtcVDisplay - 1;
+	  regp->fp_vert_regs[REG_DISP_TOTAL] = mode->CrtcVTotal - 1;
+	  regp->fp_vert_regs[REG_DISP_CRTC] = mode->CrtcVDisplay;
+	  regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->CrtcVSyncStart - 1;
+	  regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->CrtcVSyncEnd - 1;
+	  regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
+	  regp->fp_vert_regs[REG_DISP_VALID_END] = mode->CrtcVDisplay - 1;
 	}
-
-	regp->fp_horiz_regs[REG_DISP_END] = mode->CrtcHDisplay - 1;
-	regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->CrtcHTotal - 1;
-	regp->fp_horiz_regs[REG_DISP_CRTC] = mode->CrtcHDisplay;
-	regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->CrtcHSyncStart - 1;
-	regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->CrtcHSyncEnd - 1;
-	regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->CrtcHSkew;
-	regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->CrtcHDisplay - 1;
-	
-	regp->fp_vert_regs[REG_DISP_END] = mode->CrtcVDisplay - 1;
-	regp->fp_vert_regs[REG_DISP_TOTAL] = mode->CrtcVTotal - 1;
-	regp->fp_vert_regs[REG_DISP_CRTC] = mode->CrtcVDisplay;
-	regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->CrtcVSyncStart - 1;
-	regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->CrtcVSyncEnd - 1;
-	regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
-	regp->fp_vert_regs[REG_DISP_VALID_END] = mode->CrtcVDisplay - 1;
-    
     }
 
     if (pNv->Architecture >= NV_ARCH_10) 
@@ -650,11 +668,11 @@ nv_output_lvds_get_modes(xf86OutputPtr output)
     ScrnInfoPtr	pScrn = output->scrn;
     NVOutputPrivatePtr nv_output = output->driver_private;
 
-    //    nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
-    //    nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
+    nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
+    nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
     nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
-    //    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
-    //	       nv_output->fpWidth, nv_output->fpHeight);
+    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
+    	       nv_output->fpWidth, nv_output->fpHeight);
 
     return NULL;
 
@@ -664,7 +682,7 @@ static const xf86OutputFuncsRec nv_lvds_output_funcs = {
     .dpms = nv_panel_output_dpms,
     .save = nv_output_save,
     .restore = nv_output_restore,
-    .mode_valid = nv_output_mode_valid,
+    .mode_valid = nv_output_lvds_mode_valid,
     .mode_fixup = nv_output_mode_fixup,
     .mode_set = nv_output_mode_set,
     .detect = nv_output_lvds_detect,
@@ -707,6 +725,37 @@ static void nv_add_analog_output(ScrnInfoPtr pScrn, int i2c_index)
   pNv->analog_count++;
 }
 
+static void nv_add_lvds_output(ScrnInfoPtr pScrn, int i2c_index)
+{
+  NVPtr pNv = NVPTR(pScrn);
+  xf86OutputPtr	    output;
+  NVOutputPrivatePtr    nv_output;
+  char outputname[20];
+  int   crtc_mask = (1<<0) | (1<<1);
+
+  sprintf(outputname, "LVDS-%d", pNv->lvds_count);
+  output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
+  if (!output)
+    return;
+  nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
+  if (!nv_output)
+  {
+    xf86OutputDestroy (output);
+    return;
+  }
+  
+  output->driver_private = nv_output;
+  nv_output->type = OUTPUT_PANEL;
+  
+  nv_output->ramdac = pNv->lvds_count;
+  
+  nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
+  
+  output->possible_crtcs = crtc_mask;
+  xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
+
+  pNv->lvds_count++;
+}
 
 static void nv_add_digital_output(ScrnInfoPtr pScrn, int i2c_index)
 {
@@ -784,6 +833,9 @@ void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
 	case 0: /* analog */
 	  nv_add_analog_output(pScrn, port);
 	  break;
+	case 1: /* panel */
+	  nv_add_lvds_output(pScrn, port);
+	  break;
 	case 2:
 	  nv_add_digital_output(pScrn, port);
 	default:
diff --git a/src/nv_type.h b/src/nv_type.h
index fd5054f..fe18e38 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -309,6 +309,7 @@ typedef struct _NVRec {
     int dcb_entries;
 
     int analog_count;
+    int lvds_count;
     int digital_count;
     CARD32 dcb_table[NV40_NUM_DCB_ENTRIES]; /* 10 is a good limit */
 } NVRec;

-- 
Matthew Garrett | mjg59-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2007-07-05  2:57 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-05  2:57 RANDR1.2 and LVDS Matthew Garrett

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.