Resent-Date: Wed, 23 Sep 1998 00:32:15 +0200 (MET DST)
Sender: bharries@vossnet.de
Date: Wed, 23 Sep 1998 00:27:57 +0200
From: Bernd Harries <bha@gmx.de>
Organization: BHA Industries
To: linux-m68k@lists.linux-m68k.org
Subject: atyfb.c 2.1.120 summary diff
References: <199809211322.JAA11190@hades.dmi.stevens-tech.edu>
Resent-From: linux-m68k@phil.uni-sb.de

Hi!

For those who have not yet applyes the first big atyfb 2.1.120 
patch from 2 weeks ago, here is the big diff, containing #1 and #2


--- drivers/video/atyfb.c_21120	Wed Sep  9 18:45:35 1998
+++ drivers/video/atyfb.c	Wed Sep 23 00:12:56 1998
@@ -85,8 +85,24 @@
  */
 #undef PLL_DEBUG
 
+/* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */
 
-#define GUI_RESERVE	0x00001000
+#define REF_FREQ_2595       1432  /*  14.33 MHz  (exact   14.31818) */
+#define REF_DIV_2595          46  /* really 43 on ICS 2595 !!!  */
+                                  /* ohne Prescaler */
+#define MAX_FREQ_2595      15938  /* 159.38 MHz  (really 170.486) */
+#define MIN_FREQ_2595       8000  /*  80.00 MHz  (        85.565) */
+                                  /* mit Prescaler 2, 4, 8 */
+#define ABS_MIN_FREQ_2595   1000  /*  10.00 MHz  (really  10.697) */
+#define N_ADJ_2595           257
+
+#define STOP_BITS_2595     0x1800
+
+
+/* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
+/*  - must be large enough to catch all GUI-Regs   */
+/*  - must be aligned to a PAGE boundary           */
+#define GUI_RESERVE	(1 * PAGE_SIZE)
 
 
 #ifndef __powerpc__
@@ -122,6 +138,14 @@
     u8 n;
 };
 
+struct pll_18818
+{
+  u32  program_bits;
+  u32  locationAddr;
+  u32  period_in_ps;
+  u32  post_divider;
+};
+
 struct pll_ct {
     u8 pll_ref_div;
     u8 pll_gen_cntl;
@@ -144,6 +168,7 @@
     union {
 	struct pll_gx gx;
 	struct pll_ct ct;
+        struct pll_18818 ics2595;
     } pll;
     u32 accel_flags;
 };
@@ -189,6 +214,7 @@
     unsigned long ati_regbase;
     unsigned long frame_buffer_phys;
     unsigned long frame_buffer;
+    unsigned long clk_wr_offset;
     struct pci_mmap_map *mmap_map;
     struct aty_cursor *cursor;
     struct aty_cmap_regs *aty_cmap_regs;
@@ -335,7 +361,28 @@
 			   struct fb_var_screeninfo *var);
 static void aty_set_pll_gx(const struct fb_info_aty *info,
 			   const struct pll_gx *pll);
-static int aty_var_to_pll_18818(u32 vclk_per, struct pll_gx *pll);
+
+static void
+aty_set_dac_DAC_ATI68860_B(const struct fb_info_aty *info,
+  u32 bpp,
+  u32 AccelMode);
+
+static int
+aty_var_to_pll_18818(u32 period_in_ps, struct pll_18818 *pll);
+
+static int
+aty_pll_18818_to_var(const struct pll_18818 *pll, u32 *period_in_ps);
+
+static void
+aty_set_pll18818(const struct fb_info_aty *info, const struct pll_18818 *pll);
+
+static void 
+aty_StrobeClock(const struct fb_info_aty *info);
+
+static void
+aty_ICS2595_put1bit(u8 data, const struct fb_info_aty *info);
+
+
 static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll);
 static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per);
 static void aty_set_pll_ct(const struct fb_info_aty *info,
@@ -418,7 +465,7 @@
     const char *name;
 } aty_features[] __initdata = {
     /* mach64GX family */
-    { 0x4758, 0x00d7, "mach64GX (ATI888GX00)" },
+    { 0x4758, 0x00D7, "mach64GX (ATI888GX00)" },
     { 0x4358, 0x0057, "mach64CX (ATI888CX00)" },
 
     /* mach64CT family */
@@ -946,7 +993,7 @@
 #else
 #ifdef __BIG_ENDIAN
 	addr = fb->frame_buffer_phys - 0x800000 + cursor->offset;
-	cursor->ram = (u8 *)ioremap(addr, 1024);
+/*	cursor->ram = (u8 *)ioremap(addr, 1024);  */
 #else
 	addr = fb->frame_buffer + cursor->offset;
 	cursor->ram = (u8 *)addr;
@@ -1142,6 +1189,89 @@
     return 0;
 }
 
+
+
+/*-------------------------------------------------------------------------*/
+
+static void
+aty_set_dac_DAC_ATI68860_B(const struct fb_info_aty *info,
+  u32 bpp,
+  u32 AccelMode)
+
+/*-------------------------------------------------------------------------*/
+{
+  u32 gmr, dsra, temp, mask;
+
+  /*-------------------------------------------------------------------------*/
+  printk(" aty_set_dac_DAC_ATI68860_B() bpp=$%02X \n", bpp);
+
+  return;
+  
+  gmr = 0;
+  dsra = 0;
+  
+  switch(bpp)
+  {
+    case CRTC_PIX_WIDTH_8BPP:
+	gmr = 0x83;
+	dsra = 0x60 | 0x00  /*(info->mach64DAC8Bit ? 0x00 : 0x01) */ ;
+	break;
+    case CRTC_PIX_WIDTH_15BPP:
+	gmr = 0xA0;
+	dsra = 0x60;
+	break;
+    case CRTC_PIX_WIDTH_16BPP:
+	gmr = 0xA1;
+	dsra = 0x60;
+	break;
+    case CRTC_PIX_WIDTH_24BPP:
+	gmr = 0xC0;
+	dsra = 0x60;
+	break;
+    case CRTC_PIX_WIDTH_32BPP:
+	gmr = 0xE3;
+	dsra = 0x60;
+	break;
+  }
+
+  if(!AccelMode)
+  {
+    gmr = 0x80;
+    dsra = 0x61;
+  }
+
+  temp = aty_ld_8(DAC_CNTL, info);
+  aty_st_8(DAC_CNTL, (temp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3, info);
+
+  aty_st_8(DAC_REGS + 2, 0x1D, info);
+  aty_st_8(DAC_REGS + 3, gmr, info);
+  aty_st_8(DAC_REGS, 0x02, info);
+
+  temp = aty_ld_8(DAC_CNTL, info);
+  aty_st_8(DAC_CNTL, temp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, info);
+
+  if (info->total_vram < MEM_SIZE_1M)
+    mask = 0x04;
+  else if (info->total_vram == MEM_SIZE_1M)
+    mask = 0x08;
+  else
+    mask = 0x0c;
+
+  /* The following assumes that the BIOS has correctly set R7 of the
+   * Device Setup Register A at boot time.
+   */
+#define A860_DELAY_L	0x80
+
+  temp = aty_ld_8(DAC_REGS, info);
+  aty_st_8(DAC_REGS, (dsra | mask) | (temp & A860_DELAY_L), info);
+  temp = aty_ld_8(DAC_CNTL, info);
+  aty_st_8(DAC_CNTL, (temp & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3)), info);
+
+  return;
+}
+
+/*-------------------------------------------------------------------------*/
+
 static void aty_set_dac_514(const struct fb_info_aty *info, u32 bpp)
 {
     static struct {
@@ -1323,9 +1453,6 @@
 			   const struct pll_gx *pll)
 {
     switch (info->clk_type) {
-	case CLK_ATI18818_1:
-	    aty_st_8(CLOCK_CNTL, pll->m, info);
-	    break;
 	case CLK_IBMRGB514:
 	    aty_st_514(0x06, 0x02, info);	/* DAC Operation */
 	    aty_st_514(0x10, 0x01, info);	/* PLL Control 1 */
@@ -1339,13 +1466,20 @@
     }
 }
 
-static int aty_var_to_pll_18818(u32 vclk_per, struct pll_gx *pll)
+#ifdef BHA_NEVER
+/*-------------------------------------------------------------------------*/
+
+static int
+aty_select_pll_18818(u32 vclk_period, struct pll_gx *pll) /* in Picosec */
+
+/*-------------------------------------------------------------------------*/
 {
     /*
      *  FIXME: use real calculations instead of using fixed values from the old
      *	       driver
      */
-    static struct {
+    static struct
+    {
 	u32 ps_lim;	/* pixclock period rounding limit (arbitrary) */
 	u8 mode;	/* (prescsaler << 4) | Select */
 	u8 prog;	/* ref_div_count */
@@ -1383,16 +1517,187 @@
     };
     int set;
 
+  /*-------------------------------------------------------------------------*/
+
+    printk("aty_select_pll_18818() $%08X\n", vclk_period);
+    pll->m = 0x0B;
+    pll->n = 1;
     for (set = 0; set < sizeof(ATI18818_clocks)/sizeof(*ATI18818_clocks);
 	 set++)
-	if (vclk_per <= ATI18818_clocks[set].ps_lim) {
+	if (vclk_period <= ATI18818_clocks[set].ps_lim) {
 	    pll->m = ATI18818_clocks[set].mode;
 	    pll->n = ATI18818_clocks[set].prog;
+            printk(" m=$%02X n=%X \n", pll->m, pll->n);
 	    return 0;
 	}
+
+  return -EINVAL;
+}
+#endif  /* BHA_NEVER */
+
+/*-------------------------------------------------------------------------*/
+
+static int
+aty_var_to_pll_18818(u32 period_in_ps, struct pll_18818 *pll) /* in Picosec */
+
+/*-------------------------------------------------------------------------*/
+{
+  u32     MHz100;                 /* in 0.01 MHz */
+  u32     program_bits;
+  u32     post_divider;
+
+  /*-------------------------------------------------------------------------*/
+  /* printk("aty_var_to_pll_18818() $%08X\n", period_in_ps); */
+
+  /* Calculate the programming word */
+  MHz100 = 100000000 / period_in_ps;
+  
+  program_bits = -1;
+  post_divider = 1;
+
+  if(MHz100 > MAX_FREQ_2595)
+  {
+    MHz100 = MAX_FREQ_2595;
+    return -EINVAL;
+  }
+  else if (MHz100 < ABS_MIN_FREQ_2595)
+  {
+    program_bits = 0;  /* MHz100 = 257 */
     return -EINVAL;
+  }
+  else
+  {
+    while (MHz100 < MIN_FREQ_2595)
+    {
+      MHz100 *= 2;
+      post_divider *= 2;
+    }
+  }
+  /*endif*/
+  MHz100 *= 1000;
+  MHz100 = (REF_DIV_2595 * MHz100) / REF_FREQ_2595;
+
+  MHz100 += 500;    /* + 0.5 round */
+  MHz100 /= 1000;
+
+  if(program_bits == -1)
+  {
+    program_bits = MHz100 - N_ADJ_2595;
+    switch(post_divider)
+    {
+      case 1:
+        program_bits |= 0x0600;
+        break;
+      case 2:
+        program_bits |= 0x0400;
+        break;
+      case 4:
+        program_bits |= 0x0200;
+        break;
+      case 8:
+      default:
+      {
+        break;
+      }
+    }
+    /*endswitch(post_divider)*/
+  }
+
+  program_bits |= STOP_BITS_2595;
+
+
+  pll->program_bits = program_bits;
+  pll->locationAddr = 0;
+  pll->post_divider = post_divider;
+  pll->period_in_ps = period_in_ps;
+
+  return 0;
+}
+
+
+static int
+aty_pll_18818_to_var(const struct pll_18818 *pll, u32 *period_in_ps)
+{
+
+  /*-------------------------------------------------------------------------*/
+
+  *period_in_ps = pll->period_in_ps;  /* default for now */
+    
+  return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void
+aty_set_pll18818(const struct fb_info_aty *info, const struct pll_18818 *pll)
+
+/*-------------------------------------------------------------------------*/
+{
+  u32     program_bits;
+  u32     locationAddr;
+
+  u32     i;
+
+  u8      old_clock_cntl;
+  u8      old_crtc_ext_disp;
+
+  /*-------------------------------------------------------------------------*/
+  /* printk("aty_set_pll18818(): program_bits=$%08X locationAddr=$%08X\n",
+    pll->program_bits, pll->locationAddr); */
+
+  old_clock_cntl = aty_ld_8(CLOCK_CNTL, info);
+  /* printk(" old_clock_cntl=$%08X\n", old_clock_cntl); */
+  aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
+
+  old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
+  aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24), info);
+
+  udelay(15000); /* delay for 50 (15) ms */
+
+  program_bits = pll->program_bits;
+  locationAddr = pll->locationAddr;
+
+  /* Turn off interrupts */
+  /*(void)xf86DisableInterrupts(); */
+
+  /* Program the clock chip */
+  aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);  /* Strobe = 0 */
+  aty_StrobeClock(info);
+  aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 1, info);  /* Strobe = 0 */
+  aty_StrobeClock(info);
+
+  aty_ICS2595_put1bit(1, info);    /* Send start bits */
+  aty_ICS2595_put1bit(0, info);    /* Start bit */
+  aty_ICS2595_put1bit(0, info);    /* Read / ~Write */
+
+  for(i = 0; i < 5; i++)    /* Location 0..4 */
+  {
+    aty_ICS2595_put1bit(locationAddr & 1, info);
+    locationAddr >>= 1;
+  }
+
+  for (i = 0; i < 8 + 1 + 2 + 2; i++)
+  {
+    aty_ICS2595_put1bit(program_bits & 1, info);
+    program_bits >>= 1;
+  }
+
+  /* Enable interrupts */
+  /*(void)xf86EnableInterrupts();*/
+
+  udelay(1000); /* delay for 1 ms */
+
+  (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
+  aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
+  aty_st_8(CLOCK_CNTL + info->clk_wr_offset, old_clock_cntl | CLOCK_STROBE, info);
+
+  udelay(50000); /* delay for 50 (15) ms */
+  aty_st_8(CLOCK_CNTL + info->clk_wr_offset, ((pll->locationAddr & 0x0F) | CLOCK_STROBE), info);
+ 
+  return;
 }
 
+
 static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll)
 {
     /*
@@ -1423,7 +1728,50 @@
     return -EINVAL;
 }
 
-    /* FIXME: ATI18818?? */
+/*-------------------------------------------------------------------------*/
+
+static void 
+aty_StrobeClock(const struct fb_info_aty *info)
+
+/*-------------------------------------------------------------------------*/
+{
+  u8 tmp;
+
+  /*-------------------------------------------------------------------------*/
+  udelay(26);
+
+  tmp = aty_ld_8(CLOCK_CNTL, info);
+  aty_st_8(CLOCK_CNTL + info->clk_wr_offset, tmp | CLOCK_STROBE, info);
+
+  return;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void
+aty_ICS2595_put1bit(u8 data, const struct fb_info_aty *info)
+
+{
+  u8 tmp;
+
+  /*-------------------------------------------------------------------------*/
+  data &= 0x01;
+  tmp = aty_ld_8(CLOCK_CNTL, info);
+  aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x04) | (data << 2), info);
+
+  tmp = aty_ld_8(CLOCK_CNTL, info);
+  aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (0 << 3), info);
+
+  aty_StrobeClock(info);
+
+  tmp = aty_ld_8(CLOCK_CNTL, info);
+  aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (1 << 3), info);
+
+  aty_StrobeClock(info);
+
+  return;
+}
+
 
 static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per)
 {
@@ -1673,19 +2021,43 @@
     info->current_par = *par;
 
     aty_set_crtc(info, &par->crtc);
-    aty_st_8(CLOCK_CNTL, 0, info);
-    aty_st_8(CLOCK_CNTL, CLOCK_STROBE, info);
+    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);  /* better call aty_StrobeClock ?? */
+    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, CLOCK_STROBE, info);
+
+    if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
+    {
+      switch (info->dac_type)
+      {
+	case DAC_IBMRGB514:
+	    aty_set_dac_514(info, par->crtc.bpp);
+	    break;
+        case DAC_ATI68860_B:
+        {
+          aty_set_dac_DAC_ATI68860_B(info, par->crtc.bpp, par->accel_flags);
+          break;
+        }
+        default:
+        {
+          printk(" atyfb_set_par: DAC type not implemented yet!");
+          break;
+        }
+      }
+      /*endswitch*/
+      switch(info->clk_type)
+      {
+        case CLK_ATI18818_1:
+          aty_set_pll18818(info, &par->pll.ics2595);
+          break;
+        case CLK_IBMRGB514:
+          aty_set_pll_gx(info, &par->pll.gx);
+          break;
+        default:
+        {
+          printk(" atyfb_set_par: CLK type not implemented yet!");
+          break;
+        }
+      }
 
-    if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
-	switch (info->dac_type) {
-	    case DAC_IBMRGB514:
-		aty_set_dac_514(info, par->crtc.bpp);
-		break;
-	    case DAC_ATI68860_B:
-		/* FIXME */
-		break;
-	}
-	aty_set_pll_gx(info, &par->pll.gx);
 	aty_st_le32(BUS_CNTL, 0x890e20f1, info);
 	aty_st_le32(DAC_CNTL, 0x47052100, info);
     } else {
@@ -1755,21 +2127,41 @@
     int err;
 
     if ((err = aty_var_to_crtc(info, var, &par->crtc)))
-	return err;
-    if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
-	switch (info->clk_type) {
-	    case CLK_ATI18818_1:
-		err = aty_var_to_pll_18818(var->pixclock, &par->pll.gx);
-		break;
-	    case CLK_IBMRGB514:
-		err = aty_var_to_pll_514(var->pixclock, &par->pll.gx);
-		break;
-	}
-    else
-	err = aty_var_to_pll_ct(info, var->pixclock, par->crtc.bpp,
-				&par->pll.ct);
-    if (err)
-	return err;
+  {
+    printk(" aty_var_to_crtc failed! \n");
+    return err;
+  }
+
+  if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))  /* why was here *_PCI_ID ?? */
+  {
+    /* printk(" GX / CX \n"); */
+    switch (info->clk_type)
+    {
+      case CLK_ATI18818_1:
+        err = aty_var_to_pll_18818(var->pixclock, &par->pll.ics2595);
+        break;
+      case CLK_IBMRGB514:
+	err = aty_var_to_pll_514(var->pixclock, &par->pll.gx);
+	break;
+    }
+  }
+  else if (Gx == CT_CHIP_ID) 
+  {
+    printk(" CT \n");
+    err = aty_var_to_pll_ct(info, var->pixclock, par->crtc.bpp, &par->pll.ct);
+  }
+  else
+  {
+    printk(" chip_type=$%04X ?????\n", Gx);
+
+    err = aty_var_to_pll_ct(info, var->pixclock, par->crtc.bpp, &par->pll.ct);
+  }
+
+  if (err)
+  {
+    printk(" aty_var_to_pll failed! \n");
+    return err;
+  }
 
     if (var->accel_flags & FB_ACCELF_TEXT)
 	par->accel_flags = FB_ACCELF_TEXT;
@@ -1794,8 +2186,18 @@
 
     if ((err = aty_crtc_to_var(&par->crtc, var)))
 	return err;
-    if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
+  if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
+  {
+    switch (info->clk_type)
+    {
+      case CLK_ATI18818_1:
+	  err = aty_pll_18818_to_var(&par->pll.ics2595, &var->pixclock);
+	  break;
+      case CLK_IBMRGB514:
 	err = aty_pll_gx_to_var(&par->pll.gx, &var->pixclock);
+	  break;
+    }
+  }
     else
 	err = aty_pll_ct_to_var(&par->pll.ct, &var->pixclock);
     if (err)
@@ -2285,7 +2687,9 @@
      *  Initialisation
      */
 
-__initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
+__initfunc(
+static int
+aty_init(struct fb_info_aty *info, const char *name))
 {
     u32 chip_id;
     u32 i;
@@ -2303,21 +2707,27 @@
     Gx = chip_id & CFG_CHIP_TYPE;
     Rev = (chip_id & CFG_CHIP_REV)>>24;
     for (j = 0; j < (sizeof(aty_features)/sizeof(*aty_features)); j++)
+    {
 	if (aty_features[j].chip_type == Gx) {
 	    chipname = aty_features[j].name;
+      info->dac_type = (aty_ld_le32(DAC_CNTL, info) >> 16) & 0x07;
 	    break;
 	}
+    }
+
     if (!chipname) {
-	printk("atyfb: Unknown mach64 0x%04x\n", Gx);
+	printk("atyfb: Unknown mach64 0x%04X\n", Gx);
 	return 0;
     } else
-	printk("atyfb: %s [0x%04x rev 0x%02x] ", chipname, Gx, Rev);
+	printk("atyfb: %s [0x%04X rev 0x%02X] ", chipname, Gx, Rev);
+
     if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
 	info->bus_type = (aty_ld_le32(CONFIG_STAT0, info) >> 0) & 0x07;
 	info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) >> 3) & 0x07;
 	/* FIXME: clockchip/RAMDAC probing? */
 #ifdef CONFIG_ATARI
-	info->dac_type = DAC_ATI68860_B;
+	info->dac_type = (aty_ld_le32(DAC_CNTL, info) >> 16) & 0x07;
+        /* was: DAC_ATI68860_B; */
 	info->clk_type = CLK_ATI18818_1;
 #else
 	info->dac_type = DAC_IBMRGB514;
@@ -2415,7 +2825,7 @@
 	    default:
 		info->total_vram = 0x80000;
 	}
-    else
+    else   /* not GT-chip */
 	switch (i & MEM_SIZE_ALIAS) {
 	    case MEM_SIZE_512K:
 		info->total_vram = 0x80000;
@@ -2438,6 +2848,7 @@
 	    default:
 		info->total_vram = 0x80000;
 	}
+  /*endif(GT-chip)*/
 
     if (Gx == GI_CHIP_ID) {
 	if (aty_ld_le32(CONFIG_STAT1, info) & 0x40000000)
@@ -2449,10 +2860,25 @@
     	   info->total_vram == 0x80000 ? 'K' : 'M', pll, mclk);
     
     if (info->bus_type == ISA)
+    {
 	if ((info->total_vram == 0x400000) || (info->total_vram == 0x800000)) {
 	    /* protect GUI-regs if complete Aperture is VRAM */
 	    info->total_vram -= GUI_RESERVE;
 	}
+#if 1
+  printk(" aty_init: regbase=$%08lX, frame_buffer=$%08lX, total_vram=$%08X\n",
+    info->ati_regbase,
+    info->frame_buffer,
+    info->total_vram);
+  printk(" types: bus=$%02X dac=$%02X ram=$%02X clk=$%02X? wr_offset=$%02lX \n",
+    info->bus_type,
+    info->dac_type,
+    info->ram_type,
+    info->clk_type,
+    info->clk_wr_offset);
+#endif
+
+    }
 
 #if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
     if (default_vmode == VMODE_NVRAM) {
@@ -2533,16 +2959,21 @@
 	   GET_FB_IDX(info->fb_info.node), atyfb_name, name);
     return 1;
 }
+/*endproc aty_init()*/
+
 
 __initfunc(void atyfb_init(void))
 {
+
 #if defined(CONFIG_FB_OF)
     /* We don't want to be called like this. */
     /* We rely on Open Firmware (offb) instead. */
+
 #elif defined(CONFIG_PCI)
     struct pci_dev *pdev;
     struct fb_info_aty *info;
     unsigned long addr;
+
 #ifdef __sparc__
     extern int con_is_present(void);
     struct pcidev_cookie *pcp;
@@ -2769,9 +3200,11 @@
 #endif /* __sparc__ */
 	}
     }
+
 #elif defined(CONFIG_ATARI)
-    int m64_num;
-    struct fb_info_aty *info;
+  u32   clock_r;
+  int   m64_num;
+  struct fb_info_aty *info;
 
     for (m64_num = 0; m64_num < mach64_count; m64_num++) {
 	if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
@@ -2795,10 +3228,38 @@
 	info->frame_buffer = kernel_map(phys_vmembase[m64_num],
 					phys_size[m64_num],
 					KERNELMAP_NOCACHE_SER, NULL);
-	info->frame_buffer_phys = info->frame_buffer;
+	info->frame_buffer_phys = info->frame_buffer;  /* Fake! */
 	info->ati_regbase = kernel_map(phys_guiregbase[m64_num], 0x10000,
 				       KERNELMAP_NOCACHE_SER, NULL)+0xFC00ul;
-	info->ati_regbase_phys = info->ati_regbase;
+	info->ati_regbase_phys = info->ati_regbase;  /* Fake! */
+
+        aty_st_le32(CLOCK_CNTL, 0x12345678, info);
+        clock_r = aty_ld_le32(CLOCK_CNTL, info);
+
+        switch(clock_r & 0x003F)
+        {
+          case 0x12:
+          {
+            info->clk_wr_offset = 3;  /*  */
+            break;
+          }
+          case 0x34:
+          {
+            info->clk_wr_offset = 2;  /* Medusa ST-IO ISA Adapter etc. */
+            break;
+          }
+          case 0x16:
+          {
+            info->clk_wr_offset = 1;  /*  */
+            break;
+          }
+          case 0x38:
+          {
+            info->clk_wr_offset = 0;  /* Panther 1 ISA Adapter (Gerald) */
+            break;
+          }
+        }
+        /*endswitch*/
 
 	if (!aty_init(info, "ISA bus")) {
 	    kfree(info);
@@ -2806,8 +3267,10 @@
 	    return;
 	}
     }
-#endif
+#endif  /* defined(CONFIG_ATARI) */
+
 }
+/*endproc atyfb_init()*/
 
 #ifdef CONFIG_FB_OF
 __initfunc(void atyfb_of_init(struct device_node *dp))

-- 
Bernd Harries

bha@gmx.de            http://www.freeyellow.com/members/bharries
bharries@vossnet.de    Tel. +49 421 809 7351 priv.  | MSB First!
harries@stn-atlas.de        +49 421 457 3966 offi.  | Linux-m68k
bernd@linux-m68k.org                                | Medusa T40
           <>_<>      _______                _____
       .---|'"`|---. |  |_|  |_|_|_|_|_|_|_ (_____)  .-----.
______`o"O-OO-OO-O"o'`-o---o-'`-oo-----oo-'`-o---o-'`-o---o-'___

