xf86-video-intel: Branch 'intel-batchbuffer' - 12 commits - configure.ac src/dri_bufmgr.c src/fix.5c src/i830_debug.c src/i830_display.c src/i830_driver.c src/i830_exa.c src/i830_memory.c src/i830_tv.c src/intel_batchbuffer.c src/scripts/clock.5c src/scripts/clock-graph.5c src/scripts/fix.5c src/scripts/tv.5c src/tv.5c
Dave Airlie
airlied at kemper.freedesktop.org
Wed Oct 31 17:03:36 PDT 2007
configure.ac | 2
src/dri_bufmgr.c | 5 -
src/fix.5c | 14 ---
src/i830_debug.c | 29 +++++++
src/i830_display.c | 12 ++-
src/i830_driver.c | 18 +++-
src/i830_exa.c | 2
src/i830_memory.c | 33 +++++++-
src/i830_tv.c | 3
src/intel_batchbuffer.c | 2
src/scripts/clock-graph.5c | 174 +++++++++++++++++++++++++++++++++++++++++++++
src/scripts/clock.5c | 40 ++++++++++
src/scripts/fix.5c | 14 +++
src/scripts/tv.5c | 128 +++++++++++++++++++++++++++++++++
src/tv.5c | 128 ---------------------------------
15 files changed, 445 insertions(+), 159 deletions(-)
New commits:
commit 13cc4cfb03a3d79e1acd7a8bdb950fe2aec18dd7
Author: Dave Airlie <airlied at redhat.com>
Date: Thu Nov 1 10:43:10 2007 +1100
intel: add support for unsnooped cached mappings to batchbuffer code
diff --git a/src/dri_bufmgr.c b/src/dri_bufmgr.c
index 8f1d432..3c20789 100644
--- a/src/dri_bufmgr.c
+++ b/src/dri_bufmgr.c
@@ -39,9 +39,8 @@ dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size,
assert((location_mask & ~(DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT |
DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_PRIV0 |
DRM_BO_FLAG_MEM_PRIV1 | DRM_BO_FLAG_MEM_PRIV2 |
- DRM_BO_FLAG_MEM_PRIV3 |
- DRM_BO_FLAG_MEM_PRIV4)) == 0);
-
+ DRM_BO_FLAG_MEM_PRIV3 | DRM_BO_FLAG_MEM_PRIV4 |
+ DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED)) == 0);
return bufmgr->bo_alloc(bufmgr, name, size, alignment, location_mask);
}
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 3106db9..069df40 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -400,7 +400,7 @@ static void *I830EXACreatePixmap(ScreenPtr pScreen, int size, int align)
return new_priv;
new_priv->bo = dri_bo_alloc(pI830->bufmgr, "pixmap",
- size, 4096, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_LOCAL);
+ size, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED);
return new_priv;
}
diff --git a/src/intel_batchbuffer.c b/src/intel_batchbuffer.c
index 24e4866..fdb7b51 100644
--- a/src/intel_batchbuffer.c
+++ b/src/intel_batchbuffer.c
@@ -88,7 +88,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch)
batch->buf = dri_bo_alloc(pI830->bufmgr, "batchbuffer",
pI830->maxBatchSize, 4096,
- DRM_BO_FLAG_MEM_TT);
+ DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED);
dri_bo_map(batch->buf, TRUE);
batch->map = batch->buf->virtual;
batch->size = pI830->maxBatchSize;
commit 59f6c2912a39fe7dfc687f0a0cc5a79a9623177f
Merge: cc25171... ecd995d...
Author: Dave Airlie <airlied at redhat.com>
Date: Wed Oct 31 12:38:19 2007 +1100
Merge branch 'master' into intel-batchbuffer
commit ecd995d533d28b622afc71a20504d47c33ff5b8d
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date: Tue Oct 30 18:20:49 2007 -0700
Fix builds without DRI
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 0ab7e8f..488232d 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -172,6 +172,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
+#include <errno.h>
#include "xf86.h"
#include "xf86_OSproc.h"
@@ -202,7 +203,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef XF86DRI
#include "dri.h"
#include <sys/ioctl.h>
-#include <errno.h>
#ifdef XF86DRI_MM
#include "xf86mm.h"
#endif
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 91d7beb..d9f8a26 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -313,12 +313,14 @@ i830_reset_allocations(ScrnInfoPtr pScrn)
while (pI830->memory_list->next->next != NULL) {
i830_memory *mem = pI830->memory_list->next;
+#ifdef XF86DRI
/* Don't reset BO allocator, which we set up at init. */
if (pI830->memory_manager == mem) {
mem = mem->next;
if (mem->next == NULL)
break;
}
+#endif
i830_free_memory(pScrn, pI830->memory_list->next);
}
@@ -825,11 +827,14 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
I830Ptr pI830 = I830PTR(pScrn);
i830_memory *mem;
+#ifdef XF86DRI_MM
if (pI830->memory_manager && !(flags & NEED_PHYSICAL_ADDR) &&
!(flags & NEED_LIFETIME_FIXED))
{
return i830_allocate_memory_bo(pScrn, name, size, alignment, flags);
- } else {
+ } else
+#endif
+ {
mem = i830_allocate_aperture(pScrn, name, size, alignment, flags);
if (mem == NULL)
return NULL;
commit 7c88b58a93fce9fda59b6344acb87af16336e287
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date: Tue Oct 30 18:20:15 2007 -0700
Clear compiler error: "void functions cannot return values"
diff --git a/src/i830_display.c b/src/i830_display.c
index 292814c..a99b4a5 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -224,9 +224,9 @@ static void i9xx_clock(int refclk, intel_clock_t *clock)
static void intel_clock(I830Ptr pI830, int refclk, intel_clock_t *clock)
{
if (IS_I9XX(pI830))
- return i9xx_clock (refclk, clock);
+ i9xx_clock (refclk, clock);
else
- return i8xx_clock (refclk, clock);
+ i8xx_clock (refclk, clock);
}
static void
commit d2c78f82c20f33fc9c22cab8a7ca161e57a34bf8
Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Date: Wed Oct 24 19:34:12 2007 +0200
Adapt to DRM Lockfree and setStatus changes.
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 4407241..0ab7e8f 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3004,8 +3004,8 @@ I830LeaveVT(int scrnIndex, int flags)
*/
#ifdef XF86DRI_MM
if (pI830->directRenderingOpen) {
- if (pI830->memory_manager != NULL) {
- drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT);
+ if (pI830->memory_manager != NULL && pScrn->vtSema) {
+ drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT, 1, 0);
}
}
#endif /* XF86DRI_MM */
@@ -3043,8 +3043,8 @@ I830EnterVT(int scrnIndex, int flags)
/* Unlock the memory manager first of all so that we can pin our
* buffer objects
*/
- if (pI830->memory_manager != NULL) {
- drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT);
+ if (pI830->memory_manager != NULL && pScrn->vtSema) {
+ drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT, 1);
}
}
#endif /* XF86DRI_MM */
@@ -3157,6 +3157,14 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
if (pScrn->vtSema == TRUE) {
I830LeaveVT(scrnIndex, 0);
+#ifdef XF86DRI_MM
+ if (pI830->directRenderingEnabled) {
+ if (pI830->memory_manager != NULL) {
+ drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT, 1);
+ }
+ }
+#endif /* XF86DRI_MM */
+
}
if (pI830->devicesTimer)
diff --git a/src/i830_memory.c b/src/i830_memory.c
index bdfbba6..91d7beb 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -165,7 +165,17 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
I830Ptr pI830 = I830PTR(pScrn);
int ret;
- ret = drmBOSetPin(pI830->drmSubFD, &mem->bo, 1);
+ ret = drmBOSetStatus(pI830->drmSubFD, &mem->bo,
+ DRM_BO_FLAG_MEM_VRAM |
+ DRM_BO_FLAG_MEM_TT |
+ DRM_BO_FLAG_READ |
+ DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_NO_EVICT,
+ DRM_BO_MASK_MEM |
+ DRM_BO_FLAG_READ |
+ DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_NO_EVICT,
+ 0, 0, 0);
if (ret != 0)
return FALSE;
@@ -226,7 +236,10 @@ i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
I830Ptr pI830 = I830PTR(pScrn);
int ret;
- ret = drmBOSetPin(pI830->drmSubFD, &mem->bo, 0);
+ ret = drmBOSetStatus(pI830->drmSubFD, &mem->bo,
+ 0, DRM_BO_FLAG_NO_EVICT,
+ 0, 0, 0);
+
if (ret == 0) {
mem->bound = FALSE;
/* Give buffer obviously wrong offset/end until it's re-pinned. */
@@ -739,8 +752,15 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
return NULL;
}
+ /*
+ * Create buffers in local memory to avoid having the creation order
+ * determine the TT offset. Driver acceleration
+ * cannot handle changed front buffer TT offsets yet ,
+ * so let's keep our fingers crossed.
+ */
+
mask = DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE |
- DRM_BO_FLAG_MEM_TT;
+ DRM_BO_FLAG_MEM_LOCAL;
if (flags & ALLOW_SHARING)
mask |= DRM_BO_FLAG_SHAREABLE;
commit 78aaec0ffc711742bf8ad77757ed8c15cc3f7a9f
Author: Eric Anholt <eric at anholt.net>
Date: Wed Oct 24 11:50:54 2007 -0700
Fix typo in my hand-application of rglowery's patch.
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 678d510..ee2538a 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1453,7 +1453,7 @@ i830_tv_get_modes(xf86OutputPtr output)
mode_ptr->next = ret;
mode_ptr->prev = NULL;
if (ret != NULL)
- reg->prev = mode_ptr;
+ ret->prev = mode_ptr;
ret = mode_ptr;
}
commit 021265fbec9fd4ee31bdc9767c0c0453479ea22c
Author: Rob <rglowery at exemail.com.au>
Date: Wed Oct 24 11:06:53 2007 -0700
Fix a crash in TV mode handling by initializing the prev field of modes.
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 940250e..678d510 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1451,6 +1451,9 @@ i830_tv_get_modes(xf86OutputPtr output)
mode_ptr->type = M_T_DRIVER;
mode_ptr->next = ret;
+ mode_ptr->prev = NULL;
+ if (ret != NULL)
+ reg->prev = mode_ptr;
ret = mode_ptr;
}
commit 87345e820d20f1a98216c52e156c2e18c15ffa44
Author: Jesse Barnes <jesse.barnes at intel.com>
Date: Mon Oct 22 14:22:37 2007 -0700
intel_reg_dumper - dump VGA AR registers too
Add a VGA AR dumping function so we can debug text mode problems too.
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 8b4b76f..54dff29 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -560,6 +560,34 @@ static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int
}
}
+static void i830DumpAR(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ int i;
+ uint16_t st01, palette_enable = 0;
+ unsigned char orig_arx, msr;
+
+ msr = INREG8(0x3cc);
+ if (msr & 1)
+ st01 = 0x3da;
+ else
+ st01 = 0x3ba;
+
+ INREG8(st01); /* make sure index/write register is in index mode */
+ orig_arx = INREG8(0x3c0);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%19.19sX: 0x%02x\n",
+ "AR", orig_arx);
+
+ for (i = 0; i <= 0x14; i++) {
+ INREG8(st01);
+ OUTREG8(0x3c0, i);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%18.18s%02x: 0x%02x\n",
+ "AR", i, INREG8(0x3c1));
+ }
+ INREG8(st01);
+ OUTREG8(0x3c0, orig_arx);
+}
+
void i830DumpRegs (ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
@@ -594,6 +622,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%02x\n",
"MSR", (unsigned int) msr);
+ i830DumpAR (pScrn);
if (msr & 1)
crt = 0x3d0;
else
commit 78e251db671e21bc859c9b505d391b70babee2dc
Author: Eric Anholt <eric at anholt.net>
Date: Fri Oct 19 15:04:10 2007 -0700
In the clock graph, draw the VCO as erasures in the lines representing clocks.
This shows one of the reasons for the gaps: with the other settings, the VCO
is too low inside the gap. However, it also points out another issue: we
aren't using the high end of the VCO range due to some other limits being hit.
diff --git a/src/scripts/clock-graph.5c b/src/scripts/clock-graph.5c
index 98500e1..e39e559 100644
--- a/src/scripts/clock-graph.5c
+++ b/src/scripts/clock-graph.5c
@@ -4,12 +4,14 @@ library "examples/sort.5c";
import Sort;
int width = 1000, height = 200;
-
+int min_vco = 1400000000;
+int max_vco = 2800000000;
int min = 0xffffffff;
int max = 0;
int max_clocks = 1000;
int[4][max_clocks] clocks;
+int[4][max_clocks] vcos;
int[4] clock_count = {0...};
int[4] p2vals = {5,10,7,14};
@@ -49,8 +51,7 @@ void calc_p2(int p2i)
continue;
if (m2 > m1)
continue; /* won't happen */
- if (vco < 1400000000 ||
- vco > 2800000000)
+ if (vco < min_vco || vco > max_vco)
continue;
/*
@@ -61,6 +62,7 @@ void calc_p2(int p2i)
*/
clocks[p2i][clock_count[p2i]] = clock;
+ vcos[p2i][clock_count[p2i]] = vco;
clock_count[p2i]++;
}
}
@@ -88,6 +90,9 @@ real scale_x(real clock)
for (p2i = 0; p2i < dim(p2vals); p2i++) {
int p2 = p2vals[p2i];
calc_p2(p2i);
+ real row_y1 = (p2i + 1) / (dim(p2vals) + 1) * height;
+ real row_y2 = p2i / (dim(p2vals) + 1) * height;
+
/*qsort(&p2vals[p2i], sort_p2);*/
switch (p2) {
@@ -104,6 +109,8 @@ for (p2i = 0; p2i < dim(p2vals); p2i++) {
set_source_rgb(cr, 0,0,0);
break;
}
+
+ /* draw the line for the clock */
for (int i = 0; i < clock_count[p2i]; i++) {
int clock = clocks[p2i][i];
real xpos;
@@ -112,8 +119,27 @@ for (p2i = 0; p2i < dim(p2vals); p2i++) {
continue;
xpos = scale_x(clock);
- move_to(cr, xpos, p2i / (dim(p2vals) + 1) * height);
- line_to(cr, xpos, (p2i + 1) / (dim(p2vals) + 1) * height);
+ move_to(cr, xpos, row_y1);
+ line_to(cr, xpos, row_y2);
+ stroke(cr);
+ }
+
+ set_source_rgb(cr, 1, 1, 1);
+ /* add a mark for the vco value of the clocks at each location */
+ for (int i = 0; i < clock_count[p2i]; i++) {
+ int clock = clocks[p2i][i];
+ int vco = vcos[p2i][i];
+ real mark_center;
+
+ if (clock < min_rate || clock > max_rate)
+ continue;
+
+ real xpos = scale_x(clock);
+ real vcofrac = (vco - min_vco) / (max_vco - min_vco);
+ real mark_height = (row_y1 + vcofrac * (row_y2 - row_y1));
+
+ move_to(cr, xpos, mark_height - 1);
+ line_to(cr, xpos, mark_height + 1);
stroke(cr);
}
commit 9f9b888525b274036d301d6e06351583d0415f9e
Author: Eric Anholt <eric at anholt.net>
Date: Thu Oct 18 11:25:24 2007 -0700
Warn in the log if we choose a PLL clock that's way out of line.
diff --git a/src/i830_display.c b/src/i830_display.c
index 92e52ed..292814c 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1025,6 +1025,14 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
if (!ok)
FatalError("Couldn't find PLL settings for mode!\n");
+ if (fabs(adjusted_mode->Clock - clock.dot) / clock.dot > .02) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Chosen PLL clock of %.1f Mhz more than 2%% away from "
+ "desired %.1f Mhz\n",
+ (float)clock.dot / 1000,
+ (float)adjusted_mode->Clock / 1000);
+ }
+
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
dpll = DPLL_VGA_MODE_DIS;
commit 1f8bf110394cc1df66aae9acf5c818145ae19b52
Author: Eric Anholt <eric at anholt.net>
Date: Thu Oct 18 11:17:38 2007 -0700
Add some nickle scripts for looking at PLL issues.
While here, move similar nickle scripts under src/scripts/
diff --git a/src/fix.5c b/src/fix.5c
deleted file mode 100644
index b758a43..0000000
--- a/src/fix.5c
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Convert CSC fix point values to floats
- */
-
-real fixval (int fix)
-{
- int exp = fix >> 9;
- int mant = fix & ((1 << 9) - 1);
- real ret;
- if (exp == 0x7)
- return 1.0;
- ret = (2 ** -exp) * mant / (1 << 9);
- return ret;
-}
diff --git a/src/scripts/clock-graph.5c b/src/scripts/clock-graph.5c
new file mode 100644
index 0000000..98500e1
--- /dev/null
+++ b/src/scripts/clock-graph.5c
@@ -0,0 +1,148 @@
+autoload Cairo;
+import Cairo;
+library "examples/sort.5c";
+import Sort;
+
+int width = 1000, height = 200;
+
+int min = 0xffffffff;
+int max = 0;
+
+int max_clocks = 1000;
+int[4][max_clocks] clocks;
+int[4] clock_count = {0...};
+
+int[4] p2vals = {5,10,7,14};
+
+cairo_t cr = Cairo::new(width, height);
+
+void calc_p2(int p2i)
+{
+ int p2 = p2vals[p2i];
+ int min_p, max_p;
+
+ clocks[p2i] = (int [max_clocks]){0...};
+
+ if (p2 == 7 || p2 == 14) {
+ /* LVDS */
+ min_p = 7;
+ max_p = 98;
+ } else {
+ /* SDVO/DAC */
+ min_p = 5;
+ max_p = 80;
+ }
+
+ for (int m1 = 10; m1 <= 20; m1++) {
+ for (int m2 = 5; m2 <= 9; m2++) {
+ for (int n = 3; n <= 8; n++) {
+ for (int p1 = 1; p1 <= 8; p1++) {
+ int ref = 96000000;
+ int m = 5 * (m1 + 2) + (m2 + 2);
+ int p = p1 * p2;
+ int vco = floor(ref * m / (n + 2));
+ int clock = floor(vco / p);
+
+ if (p < min_p || p > max_p)
+ continue;
+ if (m < 70 || m > 120)
+ continue;
+ if (m2 > m1)
+ continue; /* won't happen */
+ if (vco < 1400000000 ||
+ vco > 2800000000)
+ continue;
+
+/*
+ printf("clock: %d (%d,%d), %d, "
+ "(%d,%d)\n",
+ floor(clock / 1000),
+ m1, m2, n, p1, p2);
+*/
+
+ clocks[p2i][clock_count[p2i]] = clock;
+ clock_count[p2i]++;
+ }
+ }
+ }
+ }
+}
+
+bool sort_p2(poly a, poly b)
+{
+ return a > b;
+}
+
+int min_rate = 25000 * 1000;
+int max_rate = 200000 * 1000;
+
+real scale_x(real clock)
+{
+ int min_x = 75, max_x = width - 50;
+
+ real frac = (clock - min_rate) / (max_rate - min_rate);
+
+ return min_x + frac * (max_x - min_x);
+}
+
+for (p2i = 0; p2i < dim(p2vals); p2i++) {
+ int p2 = p2vals[p2i];
+ calc_p2(p2i);
+ /*qsort(&p2vals[p2i], sort_p2);*/
+
+ switch (p2) {
+ case 5:
+ set_source_rgb(cr, 1,0,0);
+ break;
+ case 10:
+ set_source_rgb(cr, 0,1,0);
+ break;
+ case 7:
+ set_source_rgb(cr, 0,0,1);
+ break;
+ case 14:
+ set_source_rgb(cr, 0,0,0);
+ break;
+ }
+ for (int i = 0; i < clock_count[p2i]; i++) {
+ int clock = clocks[p2i][i];
+ real xpos;
+
+ if (clock < min_rate || clock > max_rate)
+ continue;
+
+ xpos = scale_x(clock);
+ move_to(cr, xpos, p2i / (dim(p2vals) + 1) * height);
+ line_to(cr, xpos, (p2i + 1) / (dim(p2vals) + 1) * height);
+ stroke(cr);
+ }
+
+ set_source_rgb(cr, 0, 0, 0);
+ string p2label = sprintf("p2 = %d", p2);
+ move_to(cr, 5, (p2i + .5) / (dim(p2vals) + 1) * height + 4);
+ show_text(cr, p2label);
+}
+
+void label_clock(real clock) {
+ real center_x = scale_x(clock);
+ string label = sprintf("%d", floor((clock + 500) / 1000000));
+ text_extents_t e = text_extents(cr, label);
+ real left_x = center_x - e.x_advance / 2;
+ save(cr);
+ move_to(cr, left_x, height - 20);
+ show_text(cr, label);
+ restore(cr);
+}
+
+label_clock(min_rate);
+label_clock(max_rate);
+label_clock(140 * 1000 * 1000);
+label_clock(115 * 1000 * 1000);
+label_clock(100 * 1000 * 1000);
+label_clock(82 * 1000 * 1000);
+
+string xlabel = "Clock in Mhz";
+text_extents_t e = text_extents(cr, xlabel);
+move_to(cr, width / 2 - e.x_advance / 2, height - 5);
+show_text(cr, xlabel);
+sleep(10);
diff --git a/src/scripts/clock.5c b/src/scripts/clock.5c
new file mode 100644
index 0000000..8ee9d90
--- /dev/null
+++ b/src/scripts/clock.5c
@@ -0,0 +1,40 @@
+int p2 = 14;
+int min_p, max_p;
+
+if (p2 == 7 || p2 == 14) {
+ /* LVDS */
+ min_p = 7;
+ max_p = 98;
+} else {
+ /* SDVO/DAC */
+ min_p = 5;
+ max_p = 80;
+}
+
+for (int m1 = 10; m1 <= 20; m1++) {
+ for (int m2 = 5; m2 <= 9; m2++) {
+ for (int n = 3; n <= 8; n++) {
+ for (int p1 = 1; p1 <= 8; p1++) {
+ int ref = 96000000;
+ int m = 5 * (m1 + 2) + (m2 + 2);
+ int p = p1 * p2;
+ int vco = floor(ref * m / (n + 2));
+ int clock = floor(vco / p);
+
+ if (p < min_p || p > max_p)
+ continue;
+ if (m < 70 || m > 120)
+ continue;
+ if (m2 > m1)
+ continue; /* won't happen */
+ if (vco < 1400000000 ||
+ vco > 2800000000)
+ continue;
+
+ printf("clock: %d (%d,%d),%d,(%d,%d)\n",
+ floor(clock / 1000),
+ m1, m2, n, p1, p2);
+ }
+ }
+ }
+}
diff --git a/src/scripts/fix.5c b/src/scripts/fix.5c
new file mode 100644
index 0000000..b758a43
--- /dev/null
+++ b/src/scripts/fix.5c
@@ -0,0 +1,14 @@
+/*
+ * Convert CSC fix point values to floats
+ */
+
+real fixval (int fix)
+{
+ int exp = fix >> 9;
+ int mant = fix & ((1 << 9) - 1);
+ real ret;
+ if (exp == 0x7)
+ return 1.0;
+ ret = (2 ** -exp) * mant / (1 << 9);
+ return ret;
+}
diff --git a/src/scripts/tv.5c b/src/scripts/tv.5c
new file mode 100644
index 0000000..b4a2ba6
--- /dev/null
+++ b/src/scripts/tv.5c
@@ -0,0 +1,128 @@
+/*
+ * tv.5c
+ *
+ * Compute tv encoder subcarrier dda constants
+ *
+ * The TV encoder subcarrier must be set precisely to the
+ * required frequency or the cumulative phase errors will be
+ * quite visible in the output. To accomplish this, the TV encoder
+ * has a complex circuit that takes a fixed clock, generated by the PLL
+ * and generates a precise subcarrier clock from that using the following
+ * formula:
+ *
+ * subcarrier = pixel_clock * (S1 + (S2 + (S3/Z3)) / Z2) / 4096
+ *
+ * Careful selection of the constants will provide the necessarily
+ * precise clock.
+ *
+ * In the code below, S1 is represented by dda1, S2/Z2 by dda2 and S3/Z3
+ * by dda3.
+ */
+
+typedef struct {
+ int step;
+ int size;
+} term_t;
+
+/*
+ * Find the approximation closest, but no larger than 'v', where
+ * 0 <= v < 1, and the result denominator must be less than 30000.
+ */
+term_t approx (rational v)
+{
+ rational best_dist = 1.0;
+ term_t best;
+
+ for (int den = 20000; den < 30000; den++)
+ {
+ int num = floor (v * den);
+ term_t approx = { step = num, size = den };
+ rational dist = v - approx.step/approx.size;
+ if (dist >= 0 && dist < best_dist)
+ {
+ best_dist = dist;
+ best = approx;
+ }
+ }
+ return best;
+}
+
+typedef struct {
+ rational subcarrier;
+ rational pixel;
+ rational result;
+ term_t dda1;
+ term_t dda2;
+ term_t dda3;
+} dda;
+
+/*
+ * Compute the dda constants for the given pixel clock and
+ * desired subcarrier frequency
+ */
+
+dda find_dda (rational pixel, rational subcarrier)
+{
+ dda d;
+
+ d.subcarrier = subcarrier;
+ d.pixel = pixel;
+
+ rational dda1 = subcarrier / pixel * 4096;
+ d.dda1 = (term_t) { step = floor (dda1), size = 4096 };
+
+ rational dda2 = dda1 - d.dda1.step;
+ d.dda2 = approx (dda2);
+
+ rational dda3 = dda2 * d.dda2.size - d.dda2.step;
+ d.dda3 = approx (dda3);
+
+ /* Compute the resulting pixel clock to compare */
+ d.result = d.pixel * (d.dda1.step +
+ (d.dda2.step + d.dda3.step/d.dda3.size) /
+ d.dda2.size) / d.dda1.size;
+ return d;
+}
+
+/*
+ * Print out the computed constants
+ */
+void print_dda (dda d)
+{
+ printf ("\t/* desired %9.7f actual %9.7f clock %g */\n",
+ d.subcarrier, d.result, d.pixel);
+ printf ("\t.dda1_inc\t= %6d,\n", d.dda1.step);
+ printf ("\t.dda2_inc\t= %6d,\t.dda2_size\t= %6d,\n",
+ d.dda2.step, d.dda2.step != 0 ? d.dda2.size : 0);
+ printf ("\t.dda3_inc\t= %6d,\t.dda3_size\t= %6d,\n",
+ d.dda3.step, d.dda3.step != 0 ? d.dda3.size : 0);
+}
+
+/*
+ * These are all of the required subcarrier frequencies
+ */
+rational[] subcarriers = {
+ /* these are the values we use; for some reason, this generates
+ * a more stable image (at least for NTSC) */
+ 3.580, 4.434, 3.582, 3.576, 4.430,
+
+ /* these are the values pulled out of the various specs */
+ 3.579545, 4.433618, 3.582056, 3.575611, 4.433618
+};
+
+/*
+ * We fix the pixel clock to a value which the hardware can
+ * generate exactly
+ */
+rational pixel = 107.520;
+
+void main ()
+{
+ for (int i = 0; i < dim(subcarriers); i++)
+ {
+ dda d = find_dda (pixel, subcarriers[i]);
+ print_dda (d);
+ }
+}
+
+main ();
diff --git a/src/tv.5c b/src/tv.5c
deleted file mode 100644
index b4a2ba6..0000000
--- a/src/tv.5c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * tv.5c
- *
- * Compute tv encoder subcarrier dda constants
- *
- * The TV encoder subcarrier must be set precisely to the
- * required frequency or the cumulative phase errors will be
- * quite visible in the output. To accomplish this, the TV encoder
- * has a complex circuit that takes a fixed clock, generated by the PLL
- * and generates a precise subcarrier clock from that using the following
- * formula:
- *
- * subcarrier = pixel_clock * (S1 + (S2 + (S3/Z3)) / Z2) / 4096
- *
- * Careful selection of the constants will provide the necessarily
- * precise clock.
- *
- * In the code below, S1 is represented by dda1, S2/Z2 by dda2 and S3/Z3
- * by dda3.
- */
-
-typedef struct {
- int step;
- int size;
-} term_t;
-
-/*
- * Find the approximation closest, but no larger than 'v', where
- * 0 <= v < 1, and the result denominator must be less than 30000.
- */
-term_t approx (rational v)
-{
- rational best_dist = 1.0;
- term_t best;
-
- for (int den = 20000; den < 30000; den++)
- {
- int num = floor (v * den);
- term_t approx = { step = num, size = den };
- rational dist = v - approx.step/approx.size;
- if (dist >= 0 && dist < best_dist)
- {
- best_dist = dist;
- best = approx;
- }
- }
- return best;
-}
-
-typedef struct {
- rational subcarrier;
- rational pixel;
- rational result;
- term_t dda1;
- term_t dda2;
- term_t dda3;
-} dda;
-
-/*
- * Compute the dda constants for the given pixel clock and
- * desired subcarrier frequency
- */
-
-dda find_dda (rational pixel, rational subcarrier)
-{
- dda d;
-
- d.subcarrier = subcarrier;
- d.pixel = pixel;
-
- rational dda1 = subcarrier / pixel * 4096;
- d.dda1 = (term_t) { step = floor (dda1), size = 4096 };
-
- rational dda2 = dda1 - d.dda1.step;
- d.dda2 = approx (dda2);
-
- rational dda3 = dda2 * d.dda2.size - d.dda2.step;
- d.dda3 = approx (dda3);
-
- /* Compute the resulting pixel clock to compare */
- d.result = d.pixel * (d.dda1.step +
- (d.dda2.step + d.dda3.step/d.dda3.size) /
- d.dda2.size) / d.dda1.size;
- return d;
-}
-
-/*
- * Print out the computed constants
- */
-void print_dda (dda d)
-{
- printf ("\t/* desired %9.7f actual %9.7f clock %g */\n",
- d.subcarrier, d.result, d.pixel);
- printf ("\t.dda1_inc\t= %6d,\n", d.dda1.step);
- printf ("\t.dda2_inc\t= %6d,\t.dda2_size\t= %6d,\n",
- d.dda2.step, d.dda2.step != 0 ? d.dda2.size : 0);
- printf ("\t.dda3_inc\t= %6d,\t.dda3_size\t= %6d,\n",
- d.dda3.step, d.dda3.step != 0 ? d.dda3.size : 0);
-}
-
-/*
- * These are all of the required subcarrier frequencies
- */
-rational[] subcarriers = {
- /* these are the values we use; for some reason, this generates
- * a more stable image (at least for NTSC) */
- 3.580, 4.434, 3.582, 3.576, 4.430,
-
- /* these are the values pulled out of the various specs */
- 3.579545, 4.433618, 3.582056, 3.575611, 4.433618
-};
-
-/*
- * We fix the pixel clock to a value which the hardware can
- * generate exactly
- */
-rational pixel = 107.520;
-
-void main ()
-{
- for (int i = 0; i < dim(subcarriers); i++)
- {
- dda d = find_dda (pixel, subcarriers[i]);
- print_dda (d);
- }
-}
-
-main ();
commit 79636b8c776ae024518103c9fa137c8498c21d48
Author: Eric Anholt <eric at anholt.net>
Date: Wed Oct 17 17:10:24 2007 -0700
Bump pciaccess version requirement for new API usage.
diff --git a/configure.ac b/configure.ac
index e5a7cf6..1e6ffe0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -115,7 +115,7 @@ AC_CHECK_DECL(XSERVER_LIBPCIACCESS,
CFLAGS="$save_CFLAGS"
if test x$XSERVER_LIBPCIACCESS = xyes; then
- PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0])
+ PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.10.0])
else
PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.5.0],
have_libpciaccess=yes,
More information about the xorg-commit
mailing list