summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-17 18:58:45 -0300
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-17 18:58:45 -0300
commit8b7ce66e26113ec5859566e7f3d0fd15d3e29eaa (patch)
treec81701397e2a26d63712eefc09568143f4d6178f
parentde1b633f916f4fcaaa95b226a8622d37041c86d4 (diff)
Update sm502 pll3 programming.
Also print the value of sm502 registers (should be a noop on sm501). Added the frequency field to the MSOCRegRec's misc_ctl, as it is a read/write registers, and changing bit 24 may change the logic of pll3 programming (needs clarification with SMI).
-rw-r--r--src/smi501_crtc.c9
-rw-r--r--src/smi_501.c20
-rw-r--r--src/smi_501.h5
3 files changed, 25 insertions, 9 deletions
diff --git a/src/smi501_crtc.c b/src/smi501_crtc.c
index 87aaec0..18fa764 100644
--- a/src/smi501_crtc.c
+++ b/src/smi501_crtc.c
@@ -177,10 +177,11 @@ SMI501_CrtcModeSet_lcd(xf86CrtcPtr crtc,
pll_diff = SMI501_FindPLLClock(xf86mode->Clock, &m, &n, &xclck);
if (pll_diff < p2_diff) {
- /* FIXME Need to clarify. This is required for the GDIUM,
- * but based on the sample smi source code, it is not
- * always required to set this field to 1. */
- mode->clock.f.p2_1xclck = 1;
+ /* Zero the pre 502 bitfield */
+ mode->clock.f.p2_select = 0;
+ mode->clock.f.p2_divider = 0;
+ mode->clock.f.p2_shift = 0;
+ mode->clock.f.p2_1xclck = 0;
mode->clock.f.pll_select = 1;
mode->pll_ctl.f.m = m;
diff --git a/src/smi_501.c b/src/smi_501.c
index 99bbcdb..1816423 100644
--- a/src/smi_501.c
+++ b/src/smi_501.c
@@ -428,14 +428,24 @@ SMI501_FindPLLClock(double clock, int32_t *m, int32_t *n, int32_t *xclck)
*
* K is a divisor, used by setting bit 15 of the PLL_CTL
* (PLL Output Divided by 2).
+ *
+ * So, it should be requested_clock = input_frequency * M / N / K
+ */
+
+ /* That said, use what actually works, that is:
+ * requested_clock = input_frequency * K * M / N
+ *
+ * where requested_clock is modeline pixel clock,
+ * input_frequency is 12, K is either 1 or 2 (and sets bit15 accordingly),
+ * M is a non zero 7 bits unsigned integer, and N is a value from 2 to 24.
*/
best = 0x7fffffff;
- frequency = 24 * 1000;
+ frequency = 12 * 1000.0;
for (N = 2; N <= 24; N++) {
for (K = 1; K <= 2; K++) {
- M = (clock * K) / frequency * N;
- diff = ((int32_t)(frequency * M) / N) - (clock * K);
+ M = clock / frequency * K * N;
+ diff = ((int32_t)(frequency / K * M) / N) - clock;
/* Ensure M is larger then 0 and fits in 7 bits */
if (M > 0 && M < 0x80 && fabs(diff) < best) {
*m = M;
@@ -450,7 +460,7 @@ SMI501_FindPLLClock(double clock, int32_t *m, int32_t *n, int32_t *xclck)
xf86ErrorFVerb(VERBLEV,
"\tMatching alternate clock %5.2f, diff %5.2f (%d/%d/%d)\n",
- frequency * *m / *n / (*xclck ? 1 : 2), best,
+ frequency / (*xclck ? 1 : 2) * *m / *n, best,
*m, *n, *xclck);
return (best);
@@ -463,7 +473,7 @@ SMI501_PrintRegs(ScrnInfoPtr pScrn)
SMIPtr pSmi = SMIPTR(pScrn);
xf86ErrorFVerb(VERBLEV, " SMI501 System Setup:\n");
- for (i = 0x00; i < 0x6c; i += 4)
+ for (i = 0x00; i <= 0x74; i += 4)
xf86ErrorFVerb(VERBLEV, "\t%08x: %s\n", i,
format_integer_base2(READ_SCR(pSmi, i)));
xf86ErrorFVerb(VERBLEV, " SMI501 Display Setup:\n");
diff --git a/src/smi_501.h b/src/smi_501.h
index a3c1549..77eaa13 100644
--- a/src/smi_501.h
+++ b/src/smi_501.h
@@ -208,11 +208,16 @@ typedef struct _MSOCRegRec {
* 12:12 DAC Power Control.
* 0: Enable.
* 1: Disable.
+ * 24:24 Crystal Frequency Select.
+ * 0: 24MHz.
+ * 1: 12MHz
*/
union {
struct {
int32_t u0 : bits( 0, 11);
int32_t dac : bits(12, 12);
+ int32_t u1 : bits(13, 23);
+ int32_t frequency : bits(24, 24);
} f;
int32_t value;
} misc_ctl;