Esempio n. 1
0
static long nv_tco_ioctl(struct file *file, unsigned int cmd,
			 unsigned long arg)
{
	int new_options, retval = -EINVAL;
	int new_heartbeat;
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	static const struct watchdog_info ident = {
		.options =		WDIOF_SETTIMEOUT |
					WDIOF_KEEPALIVEPING |
					WDIOF_MAGICCLOSE,
		.firmware_version =	0,
		.identity =		TCO_MODULE_NAME,
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);
	case WDIOC_SETOPTIONS:
		if (get_user(new_options, p))
			return -EFAULT;
		if (new_options & WDIOS_DISABLECARD) {
			tco_timer_stop();
			retval = 0;
		}
		if (new_options & WDIOS_ENABLECARD) {
			tco_timer_keepalive();
			tco_timer_start();
			retval = 0;
		}
		return retval;
	case WDIOC_KEEPALIVE:
		tco_timer_keepalive();
		return 0;
	case WDIOC_SETTIMEOUT:
		if (get_user(new_heartbeat, p))
			return -EFAULT;
		if (tco_timer_set_heartbeat(new_heartbeat))
			return -EINVAL;
		tco_timer_keepalive();
		/* Fall through */
	case WDIOC_GETTIMEOUT:
		return put_user(heartbeat, p);
	default:
		return -ENOTTY;
	}
}

/*
 *	Kernel Interfaces
 */

static const struct file_operations nv_tco_fops = {
	.owner =		THIS_MODULE,
	.llseek =		no_llseek,
	.write =		nv_tco_write,
	.unlocked_ioctl =	nv_tco_ioctl,
	.open =			nv_tco_open,
	.release =		nv_tco_release,
};

static struct miscdevice nv_tco_miscdev = {
	.minor =	WATCHDOG_MINOR,
	.name =		"watchdog",
	.fops =		&nv_tco_fops,
};

/*
 * Data for PCI driver interface
 *
 * This data only exists for exporting the supported
 * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
 * register a pci_driver, because someone else might one day
 * want to register another driver on the same PCI id.
 */
static DEFINE_PCI_DEVICE_TABLE(tco_pci_tbl) = {
	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS,
	  PCI_ANY_ID, PCI_ANY_ID, },
	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS,
	  PCI_ANY_ID, PCI_ANY_ID, },
	{ 0, },			/* End of list */
};
MODULE_DEVICE_TABLE(pci, tco_pci_tbl);

/*
 *	Init & exit routines
 */

static unsigned char __devinit nv_tco_getdevice(void)
{
	struct pci_dev *dev = NULL;
	u32 val;

	/* Find the PCI device */
	for_each_pci_dev(dev) {
		if (pci_match_id(tco_pci_tbl, dev) != NULL) {
			tco_pci = dev;
			break;
		}
	}

	if (!tco_pci)
		return 0;

	/* Find the base io port */
	pci_read_config_dword(tco_pci, 0x64, &val);
	val &= 0xffff;
	if (val == 0x0001 || val == 0x0000) {
		/* Something is wrong here, bar isn't setup */
		printk(KERN_ERR PFX "failed to get tcobase address\n");
		return 0;
	}
	val &= 0xff00;
	tcobase = val + 0x40;

	if (!request_region(tcobase, 0x10, "NV TCO")) {
		printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
		       tcobase);
		return 0;
	}

	/* Set a reasonable heartbeat before we stop the timer */
	tco_timer_set_heartbeat(30);

	/*
	 * Stop the TCO before we change anything so we don't race with
	 * a zeroed timer.
	 */
	tco_timer_keepalive();
	tco_timer_stop();

	/* Disable SMI caused by TCO */
	if (!request_region(MCP51_SMI_EN(tcobase), 4, "NV TCO")) {
		printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
		       MCP51_SMI_EN(tcobase));
		goto out;
	}
	val = inl(MCP51_SMI_EN(tcobase));
	val &= ~MCP51_SMI_EN_TCO;
	outl(val, MCP51_SMI_EN(tcobase));
	val = inl(MCP51_SMI_EN(tcobase));
	release_region(MCP51_SMI_EN(tcobase), 4);
	if (val & MCP51_SMI_EN_TCO) {
		printk(KERN_ERR PFX "Could not disable SMI caused by TCO\n");
		goto out;
	}

	/* Check chipset's NO_REBOOT bit */
	pci_read_config_dword(tco_pci, MCP51_SMBUS_SETUP_B, &val);
	val |= MCP51_SMBUS_SETUP_B_TCO_REBOOT;
	pci_write_config_dword(tco_pci, MCP51_SMBUS_SETUP_B, val);
	pci_read_config_dword(tco_pci, MCP51_SMBUS_SETUP_B, &val);
	if (!(val & MCP51_SMBUS_SETUP_B_TCO_REBOOT)) {
		printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot "
		       "disabled by hardware\n");
		goto out;
	}

	return 1;
out:
	release_region(tcobase, 0x10);
	return 0;
}

static int __devinit nv_tco_init(struct platform_device *dev)
{
	int ret;

	/* Check whether or not the hardware watchdog is there */
	if (!nv_tco_getdevice())
		return -ENODEV;

	/* Check to see if last reboot was due to watchdog timeout */
	printk(KERN_INFO PFX "Watchdog reboot %sdetected.\n",
	       inl(TCO_STS(tcobase)) & TCO_STS_TCO2TO_STS ? "" : "not ");

	/* Clear out the old status */
	outl(TCO_STS_RESET, TCO_STS(tcobase));

	/*
	 * Check that the heartbeat value is within it's range.
	 * If not, reset to the default.
	 */
	if (tco_timer_set_heartbeat(heartbeat)) {
		heartbeat = WATCHDOG_HEARTBEAT;
		tco_timer_set_heartbeat(heartbeat);
		printk(KERN_INFO PFX "heartbeat value must be 2<heartbeat<39, "
		       "using %d\n", heartbeat);
	}

	ret = misc_register(&nv_tco_miscdev);
	if (ret != 0) {
		printk(KERN_ERR PFX "cannot register miscdev on minor=%d "
		       "(err=%d)\n", WATCHDOG_MINOR, ret);
		goto unreg_region;
	}

	clear_bit(0, &timer_alive);

	tco_timer_stop();

	printk(KERN_INFO PFX "initialized (0x%04x). heartbeat=%d sec "
	       "(nowayout=%d)\n", tcobase, heartbeat, nowayout);

	return 0;

unreg_region:
	release_region(tcobase, 0x10);
	return ret;
}

static void __devexit nv_tco_cleanup(void)
{
	u32 val;

	/* Stop the timer before we leave */
	if (!nowayout)
		tco_timer_stop();

	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
	pci_read_config_dword(tco_pci, MCP51_SMBUS_SETUP_B, &val);
	val &= ~MCP51_SMBUS_SETUP_B_TCO_REBOOT;
	pci_write_config_dword(tco_pci, MCP51_SMBUS_SETUP_B, val);
	pci_read_config_dword(tco_pci, MCP51_SMBUS_SETUP_B, &val);
	if (val & MCP51_SMBUS_SETUP_B_TCO_REBOOT) {
		printk(KERN_CRIT PFX "Couldn't unset REBOOT bit.  Machine may "
		       "soon reset\n");
	}

	/* Deregister */
	misc_deregister(&nv_tco_miscdev);
	release_region(tcobase, 0x10);
}
Esempio n. 2
0
void  io_int_set(unsigned int u32addr, unsigned int u32data)
{
	ioperm(u32addr,4, 1); // ioperm(address from, byte num, enable or disable);
	outl(u32data, u32addr );
}
Esempio n. 3
0
static void execute_release_code(pci_list* x)
{
  int pos;
  u8* releasecode;

  if (!x->releasecode)
    return;
  pos=0;
  releasecode=x->releasecode;

  cli();
  while (1) {
    int basenum=releasecode[pos];
    int type=releasecode[pos+2];
    unsigned int base=x->dev->resource[basenum].start;
    int io=(x->dev->resource[basenum].flags&1);
    unsigned int offset;
    unsigned int val;
    int len;
    unsigned int i;
    int op=releasecode[pos+1];

    pos+=2; /* skip base/op */
    if (type&0x40) {
      offset=((u32)releasecode[pos+2]<<8)|
	((u32)releasecode[pos+3]<<0);
      pos+=2;
    }
    else {
      offset=releasecode[pos+1];
    }      
    pos+=2; /* skip type/offset */
    switch(type) {
    case 0x80:
    case 0xc0: len=4; break;
    case 0x90:
    case 0xd0: len=2; break;
    case 0xa0:
    case 0xe0: len=1; break;
    default:
      sti();
      return;
    }
    val=0;
    for (i=0;i<len;i++)
      val=(val<<8)+releasecode[pos+i];

    printk("op %d: base %x, offset %x, val %x, io=%d, len=%d\n",op,base,offset,val,io,len);

    switch(op) {
    case 0x00: 
      {/* write */
	if (io) {
	  switch(len) {
	  case 4: outl(val,base+offset); break;
	  case 2: outw(val,base+offset); break;
	  case 1: outb(val,base+offset); break;
	  }
	}
	else { /* memory */
	  unsigned long paddr=(unsigned long)bus_to_virt(base+offset);
	  void* addr=ioremap(paddr,4);

	  switch(len) {
	  case 4: *((u32*)addr)=val; break;
	  case 2: *((u16*)addr)=val; break;
	  case 1: *((u8*)addr)=val; break;
	  }
	  iounmap(addr);
	}
      }
      break;

    case 0x01: 
      { /* read */
	if (io) {
	  switch(len) {
	  case 4: dummy+=inl(base+offset); break;
	  case 2: dummy+=inw(base+offset); break;
	  case 1: dummy+=inb(base+offset); break;
	  }
	}
	else { /* memory */
	  unsigned long paddr=(unsigned long)bus_to_virt(base+offset);
	  void* addr=ioremap(paddr,4);

	  switch(len) {
	  case 4: dummy+=*((u32*)addr); break;
	  case 2: dummy+=*((u16*)addr); break;
	  case 1: dummy+=*((u8*)addr); break;
	  }
	  iounmap(addr);
	}
      }
      break;

    case 0x02: 
      { /* sleep */
	for (i=0;i<val;i++)
	  outb(0,0x80);
      }
      break;

    default:
      break;
    }
    
    if (len==1)
      pos+=2;
    else
      pos+=len;
  }
  sti();
}
static void w55fa93fb_stop_device(void)
{
	outl((inl(REG_LCM_LCDCCtl)& 0xFFFEFFFE), REG_LCM_LCDCCtl);
}
Esempio n. 5
0
static AROS_UFH3(void, Enumerator,
    AROS_UFHA(struct Hook *,    hook,   A0),
    AROS_UFHA(OOP_Object *,     device, A2),
    AROS_UFHA(APTR,             msg,    A1))
{
    AROS_USERFUNC_INIT

    ULONG VendorID,ProductID;
    int i;

    OOP_GetAttr(device, aHidd_PCIDevice_ProductID, &ProductID);
    OOP_GetAttr(device, aHidd_PCIDevice_VendorID, &VendorID);

    D(bug("[ac97] Found audio device %04x:%04x\n", VendorID, ProductID));

    for (i=0; support[i].VendorID; i++)
    {
	if (VendorID == support[i].VendorID && ProductID == support[i].ProductID)
	{
	    struct TagItem attrs[] = {
		{ aHidd_PCIDevice_isIO,	    TRUE },
		{ aHidd_PCIDevice_isMEM,    FALSE },
		{ aHidd_PCIDevice_isMaster, TRUE },
		{ TAG_DONE, 0UL },	
	    };
	    
	    D(bug("[ac97] Found supported '%s' card\n", support[i].Model));
	    ac97Base->cardfound = TRUE;
	    ac97Base->mixer_set_reg = i8x0_set_reg;
	    ac97Base->mixer_get_reg = i8x0_get_reg;

	    OOP_SetAttrs(device, (struct TagItem *)&attrs);

	    OOP_GetAttr(device, aHidd_PCIDevice_Base0, &ac97Base->mixerbase);
	    OOP_GetAttr(device, aHidd_PCIDevice_Base1, &ac97Base->dmabase);
	    OOP_GetAttr(device, aHidd_PCIDevice_INTLine, &ac97Base->irq_num);

	    D(bug("[ac97] Mixer IO base %x\n", ac97Base->mixerbase));
    	    D(bug("[ac97] DMA IO base %x\n", ac97Base->dmabase));

	    outl(2, ac97Base->dmabase + GLOB_CNT);
	    
	    ac97Base->mixer_set_reg(ac97Base, AC97_RESET, 0);
	    ac97Base->mixer_set_reg(ac97Base, AC97_POWERDOWN, 0);

	    /* Set master volume to no attenuation, mute off */
	    ac97Base->mixer_set_reg(ac97Base, AC97_MASTER_VOL,	    0x0000);
	    ac97Base->mixer_set_reg(ac97Base, AC97_HEADPHONE_VOL,   0x0000);
	    ac97Base->mixer_set_reg(ac97Base, AC97_TONE,	    0x0f0f);

	    D(bug("[ac97] Powerdown = %02x\n", ac97Base->mixer_get_reg(ac97Base, AC97_POWERDOWN)));
	    D(bug("[ac97] GLOB_CNT = %08x\n", inl(ac97Base->dmabase + GLOB_CNT)));
	    D(bug("[ac97] GLOB_STA = %08x\n", inl(ac97Base->dmabase + GLOB_STA)));
	    
/*
	    int i;
	    for (i=0; i < 64; i+=2)
	    {
		D(bug("[ac97] reg %02x = %04x\n", i, ac97Base->mixer_get_reg(ac97Base, i)));
	    }
*/
	    outl(ac97Base->PCM_out, ac97Base->dmabase + PO_BDBAR);
	    
	    D(bug("[ac97] PO_BDBAR=%08x\n", inl(ac97Base->dmabase + PO_BDBAR)));
	    D(bug("[ac97] PO_REGS=%08x\n", inl(ac97Base->dmabase + PO_CIV)));
	    D(bug("[ac97] PO_PICB=%04x\n", inw(ac97Base->dmabase + PO_PICB)));
	    D(bug("[ac97] PO_PIV=%02x\n", inb(ac97Base->dmabase + PO_PIV)));
	    D(bug("[ac97] PO_CR=%02x\n", inb(ac97Base->dmabase + PO_CR)));
	}
    }

    AROS_USERFUNC_EXIT
}
Esempio n. 6
0
void hd64461_outsl(unsigned long port, const void *buffer, unsigned long count)
{
	const unsigned long *buf=buffer;
	while(count--) outl(*buf++, port);
}
static int w55fa93fb_init_device(struct w55fa93fb_info *fbi)
{
	unsigned int clock_div;
	

	// enable VPOST clock 	
	outl(inl(REG_AHBCLK) | VPOST_CKE | HCLK4_CKE , REG_AHBCLK);   // 27 MHz source
	
  	// Reset IP
	outl(inl(REG_AHBIPRST) | VPOSTRST, REG_AHBIPRST);
	outl(inl(REG_AHBIPRST) & ~VPOSTRST, REG_AHBIPRST);	

//	printk("w55fa93_upll_clock = 0x%x\n", w55fa93_upll_clock);		   	

//	w55fa93_upll_clock = 192000;
	clock_div = w55fa93_upll_clock / 28000;
	clock_div /= 2;
	clock_div &= 0xFF;
	
	// given clock divider for VPOST 
	outl((inl(REG_CLKDIV1) & ~VPOST_N0) | 1, REG_CLKDIV1);					// divider 2 in VPOST_N0
	outl((inl(REG_CLKDIV1) & ~VPOST_N1) | (clock_div << 8), REG_CLKDIV1);	
	
//	outl((inl(REG_CLKDIV1) & ~VPOST_S), REG_CLKDIV1);				// VPOST clock from UPLL
	outl((inl(REG_CLKDIV1) & ~VPOST_S) | (3<<3), REG_CLKDIV1);		// VPOST clock from UPLL

	// enable VPOST function pins
   	outl(inl(REG_GPBFUN) | MF_GPB15, REG_GPBFUN);						// enable LPCLK pin
   	outl(inl(REG_GPCFUN) | 0x0000FFFF, REG_GPCFUN);						// enable LVDATA[7:0] pins
   	outl(inl(REG_GPDFUN) | (MF_GPD10+MF_GPD9), REG_GPDFUN);	// enable HSYNC/VSYNC pins	   			
   	
	// configure LCD interface  // enable sync with TV, LCD type select 
   	outl(inl(REG_LCM_LCDCPrm)& ~LCDCPrm_LCDSynTv, REG_LCM_LCDCPrm);	// async with TV
   	outl((inl(REG_LCM_LCDCPrm)& ~LCDCPrm_LCDTYPE) | 0x01, REG_LCM_LCDCPrm);	// Sync-type TFT LCD
	/*
	0x0  // High Resolution mode
	0x1  // Sync-type TFT LCD
	0x2  // Sync-type Color STN LCD
	0x3  // MPU-type LCD
	*/
	outl((inl(REG_LCM_LCDCPrm)& ~LCDCPrm_LCDDataSel) | 0x0C, REG_LCM_LCDCPrm);	// RGB ThroughMode	

	GOWORLD_GWMTF9360A_Init();

	// configure LCD parallel data bus 
   	outl( (inl(REG_LCM_LCDCCtl)& ~LCDCCtl_PRDB_SEL) | (0x00 << 20), REG_LCM_LCDCCtl);	// 16-bit mode 
   	//outl( (inl(REG_LCM_LCDCCtl)& ~LCDCCtl_PRDB_SEL) | (0x01 << 20), REG_LCM_LCDCCtl);	// 18-bit mode 
	/*
	0x0  // 16-bit mode (RGB565 output)
	0x1  // 18-bit mode (RGB666 output)
	0x2  // 24-bit mode (RGB888 output)		
	*/
	
	// LCDSrc, TVSrc: Frame buffer; NotchE; enable TV encoder; NTSC; Frame Buffer Size:320x240; 
  	outl((inl(REG_LCM_TVCtl)& (~TVCtl_LCDSrc))|(0x00000400), REG_LCM_TVCtl);  

		  
	///outl((inl(REG_LCM_TVDisCtl)& 0xFE000000)|(0x00F016A0), REG_LCM_TVDisCtl);

   	// set Horizontal scanning line timing for Syn type LCD 
//	outl((inl(REG_LCM_TCON1)& 0xFF000000)|(0x00035555), REG_LCM_TCON1);
//	outl((inl(REG_LCM_TCON1)& 0xFF000000)|(0x000941D1), REG_LCM_TCON1);
	outl((inl(REG_LCM_TCON1)& 0xFF000000)|(0x0001C93B), REG_LCM_TCON1);	
	
	// set Vertical scanning line timing for Syn type LCD   
	outl((inl(REG_LCM_TCON2)& 0xFF000000)|(0x00001203), REG_LCM_TCON2);

	// set both "active pixel per line" and "active lines per screen" for Syn type LCD   
   	outl(0x03BF00F0, REG_LCM_TCON3);	// 320x240
   	
   	outl(0x01400102, REG_LCM_TCON4);	// signal polarity

	// set TV control register and LCD from frame buffer source
   	outl((inl(REG_LCM_TVCtl)& 0xFFFFF0DA)|(0x00000410), REG_LCM_TVCtl);   // DAC disable	
   	
	// enable LCD controller
	outl((inl(REG_LCM_LCDCCtl)& 0xFFFEFFF0)|(0x10003), REG_LCM_LCDCCtl);
	return 0;
}
Esempio n. 8
0
static int tulip_rx(struct net_device *dev)
{
	struct tulip_private *tp = (struct tulip_private *)dev->priv;
	int entry = tp->cur_rx % RX_RING_SIZE;
	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
	int received = 0;

#ifdef CONFIG_NET_HW_FLOWCONTROL
        int drop = 0, mit_sel = 0;

/* that one buffer is needed for mit activation; or might be a
   bug in the ring buffer code; check later -- JHS*/

        if (rx_work_limit >=RX_RING_SIZE) rx_work_limit--;
#endif

	if (tulip_debug > 4)
		printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
			   tp->rx_ring[entry].status);
	/* If we own the next entry, it is a new packet. Send it up. */
	while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
		s32 status = le32_to_cpu(tp->rx_ring[entry].status);

		if (tulip_debug > 5)
			printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
				   dev->name, entry, status);
		if (--rx_work_limit < 0)
			break;
		if ((status & 0x38008300) != 0x0300) {
			if ((status & 0x38000300) != 0x0300) {
				/* Ingore earlier buffers. */
				if ((status & 0xffff) != 0x7fff) {
					if (tulip_debug > 1)
						printk(KERN_WARNING "%s: Oversized Ethernet frame "
							   "spanned multiple buffers, status %8.8x!\n",
							   dev->name, status);
					tp->stats.rx_length_errors++;
				}
			} else if (status & RxDescFatalErr) {
				/* There was a fatal error. */
				if (tulip_debug > 2)
					printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
						   dev->name, status);
				tp->stats.rx_errors++; /* end of a packet.*/
				if (status & 0x0890) tp->stats.rx_length_errors++;
				if (status & 0x0004) tp->stats.rx_frame_errors++;
				if (status & 0x0002) tp->stats.rx_crc_errors++;
				if (status & 0x0001) tp->stats.rx_fifo_errors++;
			}
		} else {
			/* Omit the four octet CRC from the length. */
			short pkt_len = ((status >> 16) & 0x7ff) - 4;
			struct sk_buff *skb;

#ifndef final_version
			if (pkt_len > 1518) {
				printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
					   dev->name, pkt_len, pkt_len);
				pkt_len = 1518;
				tp->stats.rx_length_errors++;
			}
#endif

#ifdef CONFIG_NET_HW_FLOWCONTROL
                        drop = atomic_read(&netdev_dropping);
                        if (drop)
                                goto throttle;
#endif
			/* Check if the packet is long enough to accept without copying
			   to a minimally-sized skbuff. */
			if (pkt_len < tulip_rx_copybreak
				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
				skb->dev = dev;
				skb_reserve(skb, 2);	/* 16 byte align the IP header */
				pci_dma_sync_single(tp->pdev,
						    tp->rx_buffers[entry].mapping,
						    pkt_len, PCI_DMA_FROMDEVICE);
#if ! defined(__alpha__)
				eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
						 pkt_len, 0);
				skb_put(skb, pkt_len);
#else
				memcpy(skb_put(skb, pkt_len),
				       tp->rx_buffers[entry].skb->tail,
				       pkt_len);
#endif
			} else { 	/* Pass up the skb already on the Rx ring. */
				char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
						     pkt_len);

#ifndef final_version
				if (tp->rx_buffers[entry].mapping !=
				    le32_to_cpu(tp->rx_ring[entry].buffer1)) {
					printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
					       "do not match in tulip_rx: %08x vs. %Lx %p / %p.\n",
					       dev->name,
					       le32_to_cpu(tp->rx_ring[entry].buffer1),
					       (long long)tp->rx_buffers[entry].mapping,
					       skb->head, temp);
				}
#endif

				pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
						 PKT_BUF_SZ, PCI_DMA_FROMDEVICE);

				tp->rx_buffers[entry].skb = NULL;
				tp->rx_buffers[entry].mapping = 0;
			}
			skb->protocol = eth_type_trans(skb, dev);
#ifdef CONFIG_NET_HW_FLOWCONTROL
                        mit_sel =
#endif
			netif_rx(skb);

#ifdef CONFIG_NET_HW_FLOWCONTROL
                        switch (mit_sel) {
                        case NET_RX_SUCCESS:
                        case NET_RX_CN_LOW:
                        case NET_RX_CN_MOD:
                                break;

                        case NET_RX_CN_HIGH:
                                rx_work_limit -= NET_RX_CN_HIGH; /* additional*/
                                break;
                        case NET_RX_DROP:
                                rx_work_limit = -1;
                                break;
                        default:
                                printk("unknown feedback return code %d\n", mit_sel);
                                break;
                        }

                        drop = atomic_read(&netdev_dropping);
                        if (drop) {
throttle:
                                rx_work_limit = -1;
                                mit_sel = NET_RX_DROP;

                                if (tp->fc_bit) {
                                        long ioaddr = dev->base_addr;

                                        /* disable Rx & RxNoBuf ints. */
                                        outl(tulip_tbl[tp->chip_id].valid_intrs&RX_A_NBF_STOP, ioaddr + CSR7);
                                        set_bit(tp->fc_bit, &netdev_fc_xoff);
                                }
                        }
#endif
			dev->last_rx = jiffies;
			tp->stats.rx_packets++;
			tp->stats.rx_bytes += pkt_len;
		}
		received++;
		entry = (++tp->cur_rx) % RX_RING_SIZE;
	}
#ifdef CONFIG_NET_HW_FLOWCONTROL

        /* We use this simplistic scheme for IM. It's proven by
           real life installations. We can have IM enabled
           continuesly but this would cause unnecessary latency.
           Unfortunely we can't use all the NET_RX_* feedback here.
           This would turn on IM for devices that is not contributing
           to backlog congestion with unnecessary latency.

           We monitor the device RX-ring and have:

           HW Interrupt Mitigation either ON or OFF.

           ON:  More then 1 pkt received (per intr.) OR we are dropping
           OFF: Only 1 pkt received

           Note. We only use min and max (0, 15) settings from mit_table */


        if( tp->flags &  HAS_INTR_MITIGATION) {
                if((received > 1 || mit_sel == NET_RX_DROP)
                   && tp->mit_sel != 15 ) {
                        tp->mit_sel = 15;
                        tp->mit_change = 1; /* Force IM change */
                }
                if((received <= 1 && mit_sel != NET_RX_DROP) && tp->mit_sel != 0 ) {
                        tp->mit_sel = 0;
                        tp->mit_change = 1; /* Force IM change */
                }
        }

        return RX_RING_SIZE+1; /* maxrx+1 */
#else
	return received;
#endif
}
Esempio n. 9
0
/* The interrupt handler does all of the Rx thread work and cleans up
   after the Tx thread. */
irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
{
	struct net_device *dev = (struct net_device *)dev_instance;
	struct tulip_private *tp = (struct tulip_private *)dev->priv;
	long ioaddr = dev->base_addr;
	int csr5;
	int entry;
	int missed;
	int rx = 0;
	int tx = 0;
	int oi = 0;
	int maxrx = RX_RING_SIZE;
	int maxtx = TX_RING_SIZE;
	int maxoi = TX_RING_SIZE;
	unsigned int work_count = tulip_max_interrupt_work;
	unsigned int handled = 0;

	/* Let's see whether the interrupt really is for us */
	csr5 = inl(ioaddr + CSR5);

        if (tp->flags & HAS_PHY_IRQ) 
	        handled = phy_interrupt (dev);
    
	if ((csr5 & (NormalIntr|AbnormalIntr)) == 0)
		return IRQ_RETVAL(handled);

	tp->nir++;

	do {
		/* Acknowledge all of the current interrupt sources ASAP. */
		outl(csr5 & 0x0001ffff, ioaddr + CSR5);

		if (tulip_debug > 4)
			printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
				   dev->name, csr5, inl(dev->base_addr + CSR5));

		if (csr5 & (RxIntr | RxNoBuf)) {
#ifdef CONFIG_NET_HW_FLOWCONTROL
                        if ((!tp->fc_bit) ||
			    (!test_bit(tp->fc_bit, &netdev_fc_xoff)))
#endif
				rx += tulip_rx(dev);
			tulip_refill_rx(dev);
		}

		if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
			unsigned int dirty_tx;

			spin_lock(&tp->lock);

			for (dirty_tx = tp->dirty_tx; tp->cur_tx - dirty_tx > 0;
				 dirty_tx++) {
				int entry = dirty_tx % TX_RING_SIZE;
				int status = le32_to_cpu(tp->tx_ring[entry].status);

				if (status < 0)
					break;			/* It still has not been Txed */

				/* Check for Rx filter setup frames. */
				if (tp->tx_buffers[entry].skb == NULL) {
					/* test because dummy frames not mapped */
					if (tp->tx_buffers[entry].mapping)
						pci_unmap_single(tp->pdev,
							 tp->tx_buffers[entry].mapping,
							 sizeof(tp->setup_frame),
							 PCI_DMA_TODEVICE);
					continue;
				}

				if (status & 0x8000) {
					/* There was an major error, log it. */
#ifndef final_version
					if (tulip_debug > 1)
						printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
							   dev->name, status);
#endif
					tp->stats.tx_errors++;
					if (status & 0x4104) tp->stats.tx_aborted_errors++;
					if (status & 0x0C00) tp->stats.tx_carrier_errors++;
					if (status & 0x0200) tp->stats.tx_window_errors++;
					if (status & 0x0002) tp->stats.tx_fifo_errors++;
					if ((status & 0x0080) && tp->full_duplex == 0)
						tp->stats.tx_heartbeat_errors++;
				} else {
					tp->stats.tx_bytes +=
						tp->tx_buffers[entry].skb->len;
					tp->stats.collisions += (status >> 3) & 15;
					tp->stats.tx_packets++;
				}

				pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
						 tp->tx_buffers[entry].skb->len,
						 PCI_DMA_TODEVICE);

				/* Free the original skb. */
				dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
				tp->tx_buffers[entry].skb = NULL;
				tp->tx_buffers[entry].mapping = 0;
				tx++;
			}

#ifndef final_version
			if (tp->cur_tx - dirty_tx > TX_RING_SIZE) {
				printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d.\n",
					   dev->name, dirty_tx, tp->cur_tx);
				dirty_tx += TX_RING_SIZE;
			}
#endif

			if (tp->cur_tx - dirty_tx < TX_RING_SIZE - 2)
				netif_wake_queue(dev);

			tp->dirty_tx = dirty_tx;
			if (csr5 & TxDied) {
				if (tulip_debug > 2)
					printk(KERN_WARNING "%s: The transmitter stopped."
						   "  CSR5 is %x, CSR6 %x, new CSR6 %x.\n",
						   dev->name, csr5, inl(ioaddr + CSR6), tp->csr6);
				tulip_restart_rxtx(tp);
			}
			spin_unlock(&tp->lock);
		}

		/* Log errors. */
		if (csr5 & AbnormalIntr) {	/* Abnormal error summary bit. */
			if (csr5 == 0xffffffff)
				break;
			if (csr5 & TxJabber) tp->stats.tx_errors++;
			if (csr5 & TxFIFOUnderflow) {
				if ((tp->csr6 & 0xC000) != 0xC000)
					tp->csr6 += 0x4000;	/* Bump up the Tx threshold */
				else
					tp->csr6 |= 0x00200000;  /* Store-n-forward. */
				/* Restart the transmit process. */
				tulip_restart_rxtx(tp);
				outl(0, ioaddr + CSR1);
			}
			if (csr5 & (RxDied | RxNoBuf)) {
				if (tp->flags & COMET_MAC_ADDR) {
					outl(tp->mc_filter[0], ioaddr + 0xAC);
					outl(tp->mc_filter[1], ioaddr + 0xB0);
				}
			}
			if (csr5 & RxDied) {		/* Missed a Rx frame. */
                                tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
#ifdef CONFIG_NET_HW_FLOWCONTROL
				if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
					tp->stats.rx_errors++;
					tulip_start_rxtx(tp);
				}
#else
				tp->stats.rx_errors++;
				tulip_start_rxtx(tp);
#endif
			}
			/*
			 * NB: t21142_lnk_change() does a del_timer_sync(), so be careful if this
			 * call is ever done under the spinlock
			 */
			if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) {
				if (tp->link_change)
					(tp->link_change)(dev, csr5);
			}
			if (csr5 & SytemError) {
				int error = (csr5 >> 23) & 7;
				/* oops, we hit a PCI error.  The code produced corresponds
				 * to the reason:
				 *  0 - parity error
				 *  1 - master abort
				 *  2 - target abort
				 * Note that on parity error, we should do a software reset
				 * of the chip to get it back into a sane state (according
				 * to the 21142/3 docs that is).
				 *   -- rmk
				 */
				printk(KERN_ERR "%s: (%lu) System Error occurred (%d)\n",
					dev->name, tp->nir, error);
			}
			/* Clear all error sources, included undocumented ones! */
			outl(0x0800f7ba, ioaddr + CSR5);
			oi++;
		}
Esempio n. 10
0
static inline void serial_out(int offset, int value)
{
	outl(value,  uart_base + offset);
}
Esempio n. 11
0
static __inline__ void serial_out(struct async_struct *info, int offset,
				int value)
{
	outl(value, info->port+(offset<<2));
}
Esempio n. 12
0
/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
   of available transceivers.  */
void t21142_timer(unsigned long data)
{
#if 0
	/*RTnet*/struct rtnet_device *rtdev = (/*RTnet*/struct rtnet_device *)data;
	struct tulip_private *tp = (struct tulip_private *)rtdev->priv;
	long ioaddr = rtdev->base_addr;
	int csr12 = inl(ioaddr + CSR12);
	int next_tick = 60*HZ;
	int new_csr6 = 0;

	if (tulip_debug > 2)
		/*RTnet*/rtdm_printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
			   rtdev->name, csr12, medianame[rtdev->if_port]);
	if (tulip_media_cap[rtdev->if_port] & MediaIsMII) {
		tulip_check_duplex(dev);
		next_tick = 60*HZ;
	} else if (tp->nwayset) {
		/* Don't screw up a negotiated session! */
		if (tulip_debug > 1)
			/*RTnet*/rtdm_printk(KERN_INFO"%s: Using NWay-set %s media, csr12 %8.8x.\n",
				   rtdev->name, medianame[rtdev->if_port], csr12);
	} else if (tp->medialock) {
			;
	} else if (rtdev->if_port == 3) {
		if (csr12 & 2) {	/* No 100mbps link beat, revert to 10mbps. */
			if (tulip_debug > 1)
				/*RTnet*/rtdm_printk(KERN_INFO"%s: No 21143 100baseTx link beat, %8.8x, "
					   "trying NWay.\n", rtdev->name, csr12);
			t21142_start_nway(dev);
			next_tick = 3*HZ;
		}
	} else if ((csr12 & 0x7000) != 0x5000) {
		/* Negotiation failed.  Search media types. */
		if (tulip_debug > 1)
			/*RTnet*/rtdm_printk(KERN_INFO"%s: 21143 negotiation failed, status %8.8x.\n",
				   rtdev->name, csr12);
		if (!(csr12 & 4)) {		/* 10mbps link beat good. */
			new_csr6 = 0x82420000;
			rtdev->if_port = 0;
			outl(0, ioaddr + CSR13);
			outl(0x0003FFFF, ioaddr + CSR14);
			outw(t21142_csr15[rtdev->if_port], ioaddr + CSR15);
			outl(t21142_csr13[rtdev->if_port], ioaddr + CSR13);
		} else {
			/* Select 100mbps port to check for link beat. */
			new_csr6 = 0x83860000;
			rtdev->if_port = 3;
			outl(0, ioaddr + CSR13);
			outl(0x0003FF7F, ioaddr + CSR14);
			outw(8, ioaddr + CSR15);
			outl(1, ioaddr + CSR13);
		}
		if (tulip_debug > 1)
			/*RTnet*/rtdm_printk(KERN_INFO"%s: Testing new 21143 media %s.\n",
				   rtdev->name, medianame[rtdev->if_port]);
		if (new_csr6 != (tp->csr6 & ~0x00D5)) {
			tp->csr6 &= 0x00D5;
			tp->csr6 |= new_csr6;
			outl(0x0301, ioaddr + CSR12);
			tulip_restart_rxtx(tp);
		}
		next_tick = 3*HZ;
	}

	/* mod_timer synchronizes us with potential add_timer calls
	 * from interrupts.
	 */
	/*RTnet*/MUST_REMOVE_mod_timer(&tp->timer, RUN_AT(next_tick));
#endif
}
Esempio n. 13
0
void t21142_lnk_change(/*RTnet*/struct rtnet_device *rtdev, int csr5)
{
	struct tulip_private *tp = (struct tulip_private *)rtdev->priv;
	long ioaddr = rtdev->base_addr;
	int csr12 = inl(ioaddr + CSR12);

	if (tulip_debug > 1)
		/*RTnet*/rtdm_printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, "
			   "%8.8x.\n", rtdev->name, csr12, csr5, inl(ioaddr + CSR14));

	/* If NWay finished and we have a negotiated partner capability. */
	if (tp->nway  &&  !tp->nwayset  &&  (csr12 & 0x7000) == 0x5000) {
		int setup_done = 0;
		int negotiated = tp->sym_advertise & (csr12 >> 16);
		tp->lpar = csr12 >> 16;
		tp->nwayset = 1;
		if (negotiated & 0x0100)		rtdev->if_port = 5;
		else if (negotiated & 0x0080)	rtdev->if_port = 3;
		else if (negotiated & 0x0040)	rtdev->if_port = 4;
		else if (negotiated & 0x0020)	rtdev->if_port = 0;
		else {
			tp->nwayset = 0;
			if ((csr12 & 2) == 0  &&  (tp->sym_advertise & 0x0180))
				rtdev->if_port = 3;
		}
		tp->full_duplex = (tulip_media_cap[rtdev->if_port] & MediaAlwaysFD) ? 1:0;

		if (tulip_debug > 1) {
			if (tp->nwayset)
				/*RTnet*/rtdm_printk(KERN_INFO "%s: Switching to %s based on link "
					   "negotiation %4.4x & %4.4x = %4.4x.\n",
					   rtdev->name, medianame[rtdev->if_port], tp->sym_advertise,
					   tp->lpar, negotiated);
			else
				/*RTnet*/rtdm_printk(KERN_INFO "%s: Autonegotiation failed, using %s,"
					   " link beat status %4.4x.\n",
					   rtdev->name, medianame[rtdev->if_port], csr12);
		}

		if (tp->mtable) {
			int i;
			for (i = 0; i < tp->mtable->leafcount; i++)
				if (tp->mtable->mleaf[i].media == rtdev->if_port) {
					int startup = ! ((tp->chip_id == DC21143 && tp->revision == 65));
					tp->cur_index = i;
					tulip_select_media(rtdev, startup);
					setup_done = 1;
					break;
				}
		}
		if ( ! setup_done) {
			tp->csr6 = (rtdev->if_port & 1 ? 0x838E0000 : 0x82420000) | (tp->csr6 & 0x20ff);
			if (tp->full_duplex)
				tp->csr6 |= 0x0200;
			outl(1, ioaddr + CSR13);
		}
#if 0							/* Restart shouldn't be needed. */
		outl(tp->csr6 | RxOn, ioaddr + CSR6);
		if (tulip_debug > 2)
			/*RTnet*/rtdm_printk(KERN_DEBUG "%s:  Restarting Tx and Rx, CSR5 is %8.8x.\n",
				   rtdev->name, inl(ioaddr + CSR5));
#endif
		tulip_start_rxtx(tp);
		if (tulip_debug > 2)
			/*RTnet*/rtdm_printk(KERN_DEBUG "%s:  Setting CSR6 %8.8x/%x CSR12 %8.8x.\n",
				   rtdev->name, tp->csr6, inl(ioaddr + CSR6),
				   inl(ioaddr + CSR12));
	} else if ((tp->nwayset  &&  (csr5 & 0x08000000)
Esempio n. 14
0
static int dhahelper_port(dhahelper_port_t * arg)
{
	dhahelper_port_t port;
	if (copy_from_user(&port, arg, sizeof(dhahelper_port_t)))
	{
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy from userspace\n");
		return -EFAULT;
	}
	switch(port.operation)
	{
		case PORT_OP_READ:
		{
		    switch(port.size)
		    {
			case 1:
			    port.value = inb(port.addr);
			    break;
			case 2:
			    port.value = inw(port.addr);
			    break;
			case 4:
			    port.value = inl(port.addr);
			    break;
			default:
			    if (dhahelper_verbosity > 0)
				printk(KERN_ERR "dhahelper: invalid port read size (%d)\n",
				    port.size);
			    return -EINVAL;
		    }
		    break;
		}
		case PORT_OP_WRITE:
		{
		    switch(port.size)
		    {
			case 1:
			    outb(port.value, port.addr);
			    break;
			case 2:
			    outw(port.value, port.addr);
			    break;
			case 4:
			    outl(port.value, port.addr);
			    break;
			default:
			    if (dhahelper_verbosity > 0)
				printk(KERN_ERR "dhahelper: invalid port write size (%d)\n",
				    port.size);
			    return -EINVAL;
		    }
		    break;
		}
		default:
		    if (dhahelper_verbosity > 0)
		        printk(KERN_ERR "dhahelper: invalid port operation (%d)\n",
		    	    port.operation);
		    return -EINVAL;
	}
	/* copy back only if read was performed */
	if (port.operation == PORT_OP_READ)
	if (copy_to_user(arg, &port, sizeof(dhahelper_port_t)))
	{
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy to userspace\n");
		return -EFAULT;
	}
	return 0;
}
Esempio n. 15
0
static inline void rdc321x_conf_or(unsigned addr, u32 value)
{
	outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR);
	value |= inl(RDC3210_CFGREG_DATA);
	outl(value, RDC3210_CFGREG_DATA);
}
Esempio n. 16
0
CARD32
vmwareReadReg (uint16 indexReg, uint16 valueReg, int index)
{
	outl (indexReg, index);
	return inl (valueReg);
}
Esempio n. 17
0
static inline u32 rdc321x_conf_read(unsigned addr)
{
	outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR);

	return inl(RDC3210_CFGREG_DATA);
}
Esempio n. 18
0
void
vmwareWriteReg (uint16 indexReg, uint16 valueReg, int index, CARD32 value)
{
	outl (indexReg, index);
	outl (valueReg, value);
}
Esempio n. 19
0
void GOWORLD_GWMTF9360A_Init(void)
{
#ifdef OPT_SPI_CS_BY_GPD2	
	outl(inl(REG_GPDFUN)& ~0x00000030, REG_GPDFUN);				// set GPD_2 to be GPIO pin
#else	
	outl(inl(REG_GPDFUN)& ~0x00C00000, REG_GPDFUN);				// set GPD_11 to be GPIO pin
#endif	
	
	outl(inl(REG_GPBFUN)& ~0x3C000000, REG_GPBFUN);				// set GPB_14/GPB_13 to be GPIO pins
	
	// set output mode	
	outl(inl(REG_GPIOB_OMD) | (BIT14+BIT13), REG_GPIOB_OMD);				// set GPB_14/GPB_13 to be output mode

#ifdef OPT_SPI_CS_BY_GPD2		
	outl(inl(REG_GPIOD_OMD) | (BIT2), REG_GPIOD_OMD);				// set GPD_2 to be output mode
#else	
	outl(inl(REG_GPIOD_OMD) | (BIT11), REG_GPIOD_OMD);				// set GPD_11 to be output mode
#endif	

	// set internal pull-up resistor	
	outl(inl(REG_GPIOB_PUEN) | (BIT14+BIT13), REG_GPIOB_PUEN);				// set GPB_14/GPB_13 to be internal pullup
	
#ifdef OPT_SPI_CS_BY_GPD2	
	outl(inl(REG_GPIOD_PUEN) | (BIT2), REG_GPIOD_PUEN);				// set GPD_2 to be internal pullup
#else	
	outl(inl(REG_GPIOD_PUEN) | (BIT11), REG_GPIOD_PUEN);				// set GPD_11 to be internal pullup
#endif	
	
	// initial LCM register
	delay_loop(10);		
	GWMTF9360A_WriteReg(0x01, 0x0000);
	GWMTF9360A_WriteReg(0x02, 0x0200);
	GWMTF9360A_WriteReg(0x03, 0x6364);	
	GWMTF9360A_WriteReg(0x04, 0x0400);		
//	GWMTF9360A_WriteReg(0x05, 0x0000);
	GWMTF9360A_WriteReg(0x0A, 0x4008);
	GWMTF9360A_WriteReg(0x0B, 0xD400);	
	GWMTF9360A_WriteReg(0x0D, 0x3229);		
	GWMTF9360A_WriteReg(0x0E, 0x3200);
	GWMTF9360A_WriteReg(0x0F, 0x0000);
	GWMTF9360A_WriteReg(0x16, 0x9F80);	
//	GWMTF9360A_WriteReg(0x17, 0x0000);		
	GWMTF9360A_WriteReg(0x30, 0x0000);
	GWMTF9360A_WriteReg(0x31, 0x0407);
	GWMTF9360A_WriteReg(0x32, 0x0202);	
	GWMTF9360A_WriteReg(0x33, 0x0000);		
	GWMTF9360A_WriteReg(0x34, 0x0505);
	GWMTF9360A_WriteReg(0x35, 0x0003);
	GWMTF9360A_WriteReg(0x36, 0x0707);	
	GWMTF9360A_WriteReg(0x37, 0x0000);		
	GWMTF9360A_WriteReg(0x3A, 0x0904);
	GWMTF9360A_WriteReg(0x3B, 0x0904);
	GWMTF9360A_WriteReg(0x01, 0x0000);	
	GWMTF9360A_WriteReg(0x01, 0x0000);		
	GWMTF9360A_WriteReg(0x01, 0x0000);
	GWMTF9360A_WriteReg(0x01, 0x0000);
	GWMTF9360A_WriteReg(0x01, 0x0000);	
	GWMTF9360A_WriteReg(0x01, 0x0000);		
	
	
	
}
Esempio n. 20
0
void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
	unsigned char b_DataLengthInBits)
{

	char c_BitPos = 0;

	unsigned int dw_RegisterValue = 0;

   /*****************************/

	/* Enable EEPROM Chip Select */

   /*****************************/

	dw_RegisterValue = 0x2;

   /********************************************************************/

	/* Toggle EEPROM's Chip select to get it out of Shift Register Mode */

   /********************************************************************/

	outl(dw_RegisterValue, dw_Address);

   /***************/

	/* Wait 0.1 ms */

   /***************/

	udelay(100);

   /*******************************************/

	/* Send EEPROM command - one bit at a time */

   /*******************************************/

	for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--)
	{

      /**********************************/

		/* Check if current bit is 0 or 1 */

      /**********************************/

		if (dw_EepromCommand & (1 << c_BitPos))
		{

	 /***********/

			/* Write 1 */

	 /***********/

			dw_RegisterValue = dw_RegisterValue | 0x4;

		}

		else
		{

	 /***********/

			/* Write 0 */

	 /***********/

			dw_RegisterValue = dw_RegisterValue & 0x3;

		}

      /*********************/

		/* Write the command */

      /*********************/

		outl(dw_RegisterValue, dw_Address);

      /***************/

		/* Wait 0.1 ms */

      /***************/

		udelay(100);

      /****************************/

		/* Trigger the EEPROM clock */

      /****************************/

		v_EepromClock76(dw_Address, dw_RegisterValue);

	}

}
Esempio n. 21
0
static int w55fa93fb_ioctl_device(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
	unsigned int buffer[5];
	
	memset(buffer,0,5);
	
	switch(cmd)
	{
		case IOCTLCLEARSCREEN:	
			memset((void *)video_cpu_mmap, 0xff, video_alloc_len); 		
			break;
		#if 0		
		case VIDEO_ACTIVE_WINDOW_COORDINATES:
			/* Get the start line of video window */
			copy_from_user((unsigned int *)buffer, (void *)arg, 1*sizeof(unsigned int));			
			/* Reset the original start line of video window */
			outl(0x000107FF, REG_LCM_VA_WIN);
			outl( ((buffer[0]&0x7FF) << 16) | inl(REG_LCM_VA_WIN), REG_LCM_VA_WIN);
			break;
		#endif
		case VIDEO_DISPLAY_ON:
			outl(inl(REG_GPDFUN) & ~MF_GPD1, REG_GPDFUN);	
			outl(inl(REG_GPIOD_OMD) | 0x02, REG_GPIOD_OMD);				
			outl(inl(REG_GPIOD_DOUT) | 0x02, REG_GPIOD_DOUT);		// backlight ON (for Nuvoton FA93 demo board only)
			break;
			
		case VIDEO_DISPLAY_OFF:
			outl(inl(REG_GPDFUN) & ~MF_GPD1, REG_GPDFUN);	
			outl(inl(REG_GPIOD_OMD) | 0x02, REG_GPIOD_OMD);				
			outl(inl(REG_GPIOD_DOUT) & ~0x02, REG_GPIOD_DOUT);		// backlight OFF (for Nuvoton FA93 demo board only)
			break;
			
		case IOCTL_LCD_BRIGHTNESS:
			// Need to implement PWM backlight control here !!!			
			printk("Set Backlight\n");
			copy_from_user((unsigned int *)buffer, (void *)arg, 1*sizeof(unsigned int));
			w55fa93fb_set_CMR(buffer[0]);
			break;

		case VIDEO_DISPLAY_LCD:

			printk("video displayed by LCD only\n");


			// given clock divider for VPOST 
//			outl((inl(REG_CLKDIV1) & ~VPOST_S) | (0x03 << 3), REG_CLKDIV1);	// 00:clock from CLK_in, 01:32K, 10:APLL, 11:UPLL
		
			// enable VPOST function pins
		   	outl(inl(REG_GPBFUN) | MF_GPB15, REG_GPBFUN);						// enable LPCLK pin
   			outl(inl(REG_GPCFUN) | 0x0000FFFF, REG_GPCFUN);						// enable LVDATA[7:0] pins
   			outl(inl(REG_GPDFUN) | (MF_GPD10+MF_GPD9), REG_GPDFUN);	// enable HSYNC/VSYNC pins	
			
			// configure LCD interface  // enable sync with TV, LCD type select 
		   	outl(inl(REG_LCM_LCDCPrm)& ~LCDCPrm_LCDSynTv, REG_LCM_LCDCPrm);	// async with TV
   			outl((inl(REG_LCM_LCDCPrm)& ~LCDCPrm_LCDTYPE) | 0x01, REG_LCM_LCDCPrm);	// Sync-type TFT LCD

			outl((inl(REG_LCM_LCDCPrm)& ~LCDCPrm_LCDDataSel) | 0x0C, REG_LCM_LCDCPrm);	// RGB ThroughMode
		
			// configure LCD parallel data bus 
		   	outl( (inl(REG_LCM_LCDCCtl)& ~LCDCCtl_PRDB_SEL) | (0x00 << 20), REG_LCM_LCDCCtl);	// 16-bit mode 
		   	//outl( (inl(REG_LCM_LCDCCtl)& ~LCDCCtl_PRDB_SEL) | (0x01 << 20), REG_LCM_LCDCCtl);	// 18-bit mode 		   	
			
//			printk("REG_LCM_LCDCCtl = 0x%x\n", inl(REG_LCM_LCDCCtl));		   	
			/*
			0x0  // 16-bit mode (RGB565 output)
			0x1  // 18-bit mode (RGB666 output)
			0x2  // 24-bit mode (RGB888 output)		
			*/
		
			// set both "active pixel per line" and "active lines per screen" for Syn type LCD   
		   	outl(0x03BF00F0, REG_LCM_TCON3);	// 320x240
		   	
		   	outl(0x01400102, REG_LCM_TCON4);	// signal polarity
		
			// set TV control register and LCD from frame buffer source
		   	outl((inl(REG_LCM_TVCtl)& 0xFFFFF0DA)|(0x00000410), REG_LCM_TVCtl);   // DAC disable	
		   	
			// enable LCD controller
			outl((inl(REG_LCM_LCDCCtl)& 0xFFFEFFF0)|(0x10003), REG_LCM_LCDCCtl);  // RGB565, little-endian

			break;				


		case VIDEO_DISPLAY_TV:
			printk("video displayed by TV only\n");


			// enable VPOST function pins
		   	outl(inl(REG_GPBFUN) & ~MF_GPB15, REG_GPBFUN);						// disable LPCLK pin
		   	outl(inl(REG_GPCFUN) & ~0xFFFFFFFF, REG_GPCFUN);					// disable LVDATA[15:0] pins
		   	outl(inl(REG_GPDFUN) & ~(MF_GPD11+MF_GPD10+MF_GPD9), REG_GPDFUN);	// disable HSYNC/VSYNC/VDEN pins	

			outl((inl(REG_CLKDIV1) & ~VPOST_S) | (0x00 << 3), REG_CLKDIV1);	// 00:clock from CLK_in, 01:32K, 10:APLL, 11:UPLL
			outl((inl(REG_CLKDIV1) & ~VPOST_N1) | (0x00 << 8), REG_CLKDIV1);	// divider value = 0x01 (temp)

		   	outl(inl(REG_LCM_LCDCPrm) | LCDCPrm_LCDSynTv, REG_LCM_LCDCPrm);	// sync with TV
			
			outl((inl(REG_LCM_LCDCCtl) & ~LCDCCtl_LCDRUN), REG_LCM_LCDCCtl); // LCD off
			
	    	outl((inl(REG_LCM_TVCtl)& 0xFFFFF0CA)|(0x00000501), REG_LCM_TVCtl);   // DAC enabled
	    	
			outl((inl(REG_LCM_LCDCCtl)& 0xFFFEFFF0)|(0x10002), REG_LCM_LCDCCtl); // LCD off, RGB565 format

			break;				


		 case IOCTL_LCD_ENABLE_INT:
             outl((inl(REG_LCM_LCDCInt) & 0xFFFFFF00) | 0x20000, REG_LCM_LCDCInt); // enable VIN
	         //_auto_disable = 0;
                break;
	        case IOCTL_LCD_DISABLE_INT:
	          outl((inl(REG_LCM_LCDCInt) & 0xFFFFFF00) & ~0x20000, REG_LCM_LCDCInt); // disable VIN
#if DUAL_BUF
            		while (w55fa93_edma_isbusy(VDMA_CH));
#endif            
	                
	                _auto_disable = 1;
	                break;

#if DUAL_BUF
		case IOCTL_LCD_GET_DMA_BASE:
		  if(copy_to_user((unsigned int *)arg, (unsigned int *)&_bg_mem_p, sizeof(unsigned int)) < 0) {
		    printk("failed..\n");
		    return(-EFAULT);
		  }
			printk("!!!%x\n", *(unsigned int *)&_bg_mem_p);
			break;
#endif            
		case DUMP_LCD_REG:		//ken add
		{
			unsigned int reg_array[5];
			reg_array[0] = inl(REG_LCM_TCON1);
			reg_array[1] = inl(REG_LCM_TCON2);
			reg_array[2] = inl(REG_LCM_TCON3);
			reg_array[3] = inl(REG_LCM_TCON4);
			reg_array[4] = inl(REG_LCM_LCDCCtl);
			if(copy_to_user((unsigned int *)arg, (unsigned int *)&reg_array, 5*sizeof(unsigned int)) < 0) {
		    		printk("failed..\n");
		    		return(-EFAULT);
		  	}	
		}		
			break;
		default:
			break;	
	}
		
	return 0;    
}
Esempio n. 22
0
void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value)
{

        char c_BitPos = 0;

	unsigned int dw_RegisterValue = 0;

	unsigned int dw_RegisterValueRead = 0;

   /*************************************************/

	/* Send EEPROM read command and offset to EEPROM */

   /*************************************************/

	v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2),
		EE76_CMD_LEN);

   /*******************************/

	/* Get the last register value */

   /*******************************/

	dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2;

   /*****************************/

	/* Set the 16-bit value of 0 */

   /*****************************/

	*pw_Value = 0;

   /************************/

	/* Get the 16-bit value */

   /************************/

	for (c_BitPos = 0; c_BitPos < 16; c_BitPos++)
	{

      /****************************/

		/* Trigger the EEPROM clock */

      /****************************/

		v_EepromClock76(dw_Address, dw_RegisterValue);

      /**********************/

		/* Get the result bit */

      /**********************/

		dw_RegisterValueRead = inl(dw_Address);

      /***************/

		/* Wait 0.1 ms */

      /***************/

		udelay(100);

      /***************************************/

		/* Get bit value and shift into result */

      /***************************************/

		if (dw_RegisterValueRead & 0x8)
		{

	 /**********/

			/* Read 1 */

	 /**********/

			*pw_Value = (*pw_Value << 1) | 0x1;

		}

		else
		{

	 /**********/

			/* Read 0 */

	 /**********/

			*pw_Value = (*pw_Value << 1);

		}

	}

   /*************************/

	/* Clear all EEPROM bits */

   /*************************/

	dw_RegisterValue = 0x0;

   /********************************************************************/

	/* Toggle EEPROM's Chip select to get it out of Shift Register Mode */

   /********************************************************************/

	outl(dw_RegisterValue, dw_Address);

   /***************/

	/* Wait 0.1 ms */

   /***************/

	udelay(100);

}
Esempio n. 23
0
static void i82801ix_power_options(device_t dev)
{
    u8 reg8;
    u16 reg16, pmbase;
    u32 reg32;
    const char *state;
    /* Get the chip configuration */
    config_t *config = dev->chip_info;

    int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
    int nmi_option;

    /* BIOS must program... */
    reg32 = pci_read_config32(dev, 0xac);
    pci_write_config32(dev, 0xac, reg32 | (1 << 30) | (3 << 8));

    /* Which state do we want to goto after g3 (power restored)?
     * 0 == S0 Full On
     * 1 == S5 Soft Off
     *
     * If the option is not existent (Laptops), use MAINBOARD_POWER_ON.
     */
    if (get_option(&pwr_on, "power_on_after_fail") < 0)
        pwr_on = MAINBOARD_POWER_ON;

    reg8 = pci_read_config8(dev, D31F0_GEN_PMCON_3);
    reg8 &= 0xfe;
    switch (pwr_on) {
    case MAINBOARD_POWER_OFF:
        reg8 |= 1;
        state = "off";
        break;
    case MAINBOARD_POWER_ON:
        reg8 &= ~1;
        state = "on";
        break;
    case MAINBOARD_POWER_KEEP:
        reg8 &= ~1;
        state = "state keep";
        break;
    default:
        state = "undefined";
    }

    reg8 |= (3 << 4);	/* avoid #S4 assertions */
    reg8 &= ~(1 << 3);	/* minimum asssertion is 1 to 2 RTCCLK */

    pci_write_config8(dev, D31F0_GEN_PMCON_3, reg8);
    printk(BIOS_INFO, "Set power %s after power failure.\n", state);

    /* Set up NMI on errors. */
    reg8 = inb(0x61);
    reg8 &= 0x0f;		/* Higher Nibble must be 0 */
    reg8 &= ~(1 << 3);	/* IOCHK# NMI Enable */
    // reg8 &= ~(1 << 2);	/* PCI SERR# Enable */
    reg8 |= (1 << 2); /* PCI SERR# Disable for now */
    outb(reg8, 0x61);

    reg8 = inb(0x74); /* Read from 0x74 as 0x70 is write only. */
    nmi_option = NMI_OFF;
    get_option(&nmi_option, "nmi");
    if (nmi_option) {
        printk(BIOS_INFO, "NMI sources enabled.\n");
        reg8 &= ~(1 << 7);	/* Set NMI. */
    } else {
        printk(BIOS_INFO, "NMI sources disabled.\n");
        reg8 |= ( 1 << 7);	/* Can't mask NMI from PCI-E and NMI_NOW */
    }
    outb(reg8, 0x70);

    /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
    reg16 = pci_read_config16(dev, D31F0_GEN_PMCON_1);
    reg16 &= ~(3 << 0);	// SMI# rate 1 minute
    reg16 |= (1 << 2);	// CLKRUN_EN - Mobile/Ultra only
    reg16 |= (1 << 3);	// Speedstep Enable - Mobile/Ultra only
    reg16 |= (1 << 5);	// CPUSLP_EN Desktop only

    if (config->c4onc3_enable)
        reg16 |= (1 << 7);

    // another laptop wants this?
    // reg16 &= ~(1 << 10);	// BIOS_PCI_EXP_EN - Desktop/Mobile only
    reg16 |= (1 << 10);	// BIOS_PCI_EXP_EN - Desktop/Mobile only
#if DEBUG_PERIODIC_SMIS
    /* Set DEBUG_PERIODIC_SMIS in i82801ix.h to debug using
     * periodic SMIs.
     */
    reg16 |= (3 << 0); // Periodic SMI every 8s
#endif
    if (config->c5_enable)
        reg16 |= (1 << 11); /* Enable C5, C6 and PMSYNC# */
    pci_write_config16(dev, D31F0_GEN_PMCON_1, reg16);

    /* Set exit timings for C5/C6. */
    if (config->c5_enable) {
        reg8 = pci_read_config8(dev, D31F0_C5_EXIT_TIMING);
        reg8 &= ~((7 << 3) | (7 << 0));
        if (config->c6_enable)
            reg8 |= (5 << 3) | (3 << 0); /* 38-44us PMSYNC# to STPCLK#,
							95-102us DPRSTP# to STP_CPU# */
        else
            reg8 |= (0 << 3) | (1 << 0); /* 16-17us PMSYNC# to STPCLK#,
							34-40us DPRSTP# to STP_CPU# */
        pci_write_config8(dev, D31F0_C5_EXIT_TIMING, reg8);
    }

    // Set the board's GPI routing.
    i82801ix_gpi_routing(dev);

    pmbase = pci_read_config16(dev, 0x40) & 0xfffe;

    outl(config->gpe0_en, pmbase + 0x28);
    outw(config->alt_gp_smi_en, pmbase + 0x38);

    /* Set up power management block and determine sleep mode */
    reg16 = inw(pmbase + 0x00); /* PM1_STS */
    outw(reg16, pmbase + 0x00); /* Clear status bits. At least bit11 (power
				       button override) must be cleared or SCI
				       will be constantly fired and OSPM must
				       not know about it (ACPI spec says to
				       ignore the bit). */
    reg32 = inl(pmbase + 0x04); // PM1_CNT
    reg32 &= ~(7 << 10);	// SLP_TYP
    outl(reg32, pmbase + 0x04);

    /* Set duty cycle for hardware throttling (defaults to 0x0: 50%). */
    reg32 = inl(pmbase + 0x10);
    reg32 &= ~(7 << 5);
    reg32 |= (config->throttle_duty & 7) << 5;
    outl(reg32, pmbase + 0x10);
}
Esempio n. 24
0
static int __init asr_get_base_address(void)
{
	unsigned char low, high;
	const char *type = "";

	asr_length = 1;

	switch (asr_type) {
	case ASMTYPE_TOPAZ:
		/* SELECT SuperIO CHIP FOR QUERYING
		   (WRITE 0x07 TO BOTH 0x2E and 0x2F) */
		outb(0x07, 0x2e);
		outb(0x07, 0x2f);

		/* SELECT AND READ THE HIGH-NIBBLE OF THE GPIO BASE ADDRESS */
		outb(0x60, 0x2e);
		high = inb(0x2f);

		/* SELECT AND READ THE LOW-NIBBLE OF THE GPIO BASE ADDRESS */
		outb(0x61, 0x2e);
		low = inb(0x2f);

		asr_base = (high << 16) | low;
		asr_read_addr = asr_write_addr =
			asr_base + TOPAZ_ASR_REG_OFFSET;
		asr_length = 5;

		break;

	case ASMTYPE_JASPER:
		type = "Jaspers ";
#if 0
		u32 r;
		/* Suggested fix */
		pdev = pci_get_bus_and_slot(0, DEVFN(0x1f, 0));
		if (pdev == NULL)
			return -ENODEV;
		pci_read_config_dword(pdev, 0x58, &r);
		asr_base = r & 0xFFFE;
		pci_dev_put(pdev);
#else
		/* FIXME: need to use pci_config_lock here,
		   but it's not exported */

/*		spin_lock_irqsave(&pci_config_lock, flags);*/

		/* Select the SuperIO chip in the PCI I/O port register */
		outl(0x8000f858, 0xcf8);

		/* BUS 0, Slot 1F, fnc 0, offset 58 */

		/*
		 * Read the base address for the SuperIO chip.
		 * Only the lower 16 bits are valid, but the address is word
		 * aligned so the last bit must be masked off.
		 */
		asr_base = inl(0xcfc) & 0xfffe;

/*		spin_unlock_irqrestore(&pci_config_lock, flags);*/
#endif
		asr_read_addr = asr_write_addr =
			asr_base + JASPER_ASR_REG_OFFSET;
		asr_toggle_mask = JASPER_ASR_TOGGLE_MASK;
		asr_disable_mask = JASPER_ASR_DISABLE_MASK;
		asr_length = JASPER_ASR_REG_OFFSET + 1;

		break;

	case ASMTYPE_PEARL:
		type = "Pearls ";
		asr_base = PEARL_BASE;
		asr_read_addr = PEARL_READ;
		asr_write_addr = PEARL_WRITE;
		asr_toggle_mask = PEARL_ASR_TOGGLE_MASK;
		asr_disable_mask = PEARL_ASR_DISABLE_MASK;
		asr_length = 4;
		break;

	case ASMTYPE_JUNIPER:
		type = "Junipers ";
		asr_base = JUNIPER_BASE_ADDRESS;
		asr_read_addr = asr_write_addr = asr_base;
		asr_toggle_mask = JUNIPER_ASR_TOGGLE_MASK;
		asr_disable_mask = JUNIPER_ASR_DISABLE_MASK;
		break;

	case ASMTYPE_SPRUCE:
		type = "Spruce's ";
		asr_base = SPRUCE_BASE_ADDRESS;
		asr_read_addr = asr_write_addr = asr_base;
		asr_toggle_mask = SPRUCE_ASR_TOGGLE_MASK;
		asr_disable_mask = SPRUCE_ASR_DISABLE_MASK;
		break;
	}

	if (!request_region(asr_base, asr_length, "ibmasr")) {
		printk(KERN_ERR PFX "address %#x already in use\n",
			asr_base);
		return -EBUSY;
	}

	printk(KERN_INFO PFX "found %sASR @ addr %#x\n", type, asr_base);

	return 0;
}
Esempio n. 25
0
static void TDFXWriteChipLongPIO(TDFXPtr pTDFX, int chip, int addr, int val) {
  outl(pTDFX->PIOBase[chip]+addr, val);
}
Esempio n. 26
0
static inline void
Write_hfc32(hfc4s8s_hw * a, u_char b, u_long c)
{
	SetRegAddr(a, b);
	outl(c, a->iobase);
}
Esempio n. 27
0
static void intel_gma_init(const struct northbridge_intel_gm45_config *info,
			   u8 *mmio, u32 physbase, u16 piobase, u32 lfb)
{

	int i;
	u8 edid_data[128];
	struct edid edid;
	struct edid_mode *mode;
	u32 hactive, vactive, right_border, bottom_border;
	int hpolarity, vpolarity;
	u32 vsync, hsync, vblank, hblank, hfront_porch, vfront_porch;
	u32 candp1, candn;
	u32 best_delta = 0xffffffff;
	u32 target_frequency;
	u32 pixel_p1 = 1;
	u32 pixel_n = 1;
	u32 pixel_m1 = 1;
	u32 pixel_m2 = 1;
	u32 link_frequency = info->gfx.link_frequency_270_mhz ? 270000 : 162000;
	u32 data_m1;
	u32 data_n1 = 0x00800000;
	u32 link_m1;
	u32 link_n1 = 0x00080000;

	vga_gr_write(0x18, 0);

	/* Setup GTT.  */
	for (i = 0; i < 0x2000; i++)
	{
		outl((i << 2) | 1, piobase);
		outl(physbase + (i << 12) + 1, piobase + 4);
	}

	write32(mmio + ADPA, 0x40008c18);
	write32(mmio + 0x7041c, 0x0);
	write32(mmio + _DPLL_B_MD, 0x3);

	vga_misc_write(0x67);

	const u8 cr[] = { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
		    0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
		    0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
		    0xff
	};
	vga_cr_write(0x11, 0);

	for (i = 0; i <= 0x18; i++)
		vga_cr_write(i, cr[i]);

	power_port(mmio);

	intel_gmbus_read_edid(mmio + GMBUS0, 3, 0x50, edid_data, 128);
	decode_edid(edid_data,
		    sizeof(edid_data), &edid);
	mode = &edid.mode;

	/* Disable screen memory to prevent garbage from appearing.  */
	vga_sr_write(1, vga_sr_read(1) | 0x20);

	hactive = edid.x_resolution;
	vactive = edid.y_resolution;
	right_border = mode->hborder;
	bottom_border = mode->vborder;
	hpolarity = (mode->phsync == '-');
	vpolarity = (mode->pvsync == '-');
	vsync = mode->vspw;
	hsync = mode->hspw;
	vblank = mode->vbl;
	hblank = mode->hbl;
	hfront_porch = mode->hso;
	vfront_porch = mode->vso;

	target_frequency = mode->lvds_dual_channel ? mode->pixel_clock
		: (2 * mode->pixel_clock);
	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		vga_sr_write(1, 1);
		vga_sr_write(0x2, 0xf);
		vga_sr_write(0x3, 0x0);
		vga_sr_write(0x4, 0xe);
		vga_gr_write(0, 0x0);
		vga_gr_write(1, 0x0);
		vga_gr_write(2, 0x0);
		vga_gr_write(3, 0x0);
		vga_gr_write(4, 0x0);
		vga_gr_write(5, 0x0);
		vga_gr_write(6, 0x5);
		vga_gr_write(7, 0xf);
		vga_gr_write(0x10, 0x1);
		vga_gr_write(0x11, 0);

		edid.bytes_per_line = (edid.bytes_per_line + 63) & ~63;

		write32(mmio + DSPCNTR(0), DISPPLANE_BGRX888);
		write32(mmio + DSPADDR(0), 0);
		write32(mmio + DSPSTRIDE(0), edid.bytes_per_line);
		write32(mmio + DSPSURF(0), 0);
		for (i = 0; i < 0x100; i++)
			write32(mmio + LGC_PALETTE(0) + 4 * i, i * 0x010101);
	} else {
		vga_textmode_init();
	}

	/* Find suitable divisors.  */
	for (candp1 = 1; candp1 <= 8; candp1++) {
		for (candn = 5; candn <= 10; candn++) {
			u32 cur_frequency;
			u32 m; /* 77 - 131.  */
			u32 denom; /* 35 - 560.  */
			u32 current_delta;

			denom = candn * candp1 * 7;
			/* Doesnt overflow for up to
			   5000000 kHz = 5 GHz.  */
			m = (target_frequency * denom + 60000) / 120000;

			if (m < 77 || m > 131)
				continue;

			cur_frequency = (120000 * m) / denom;
			if (target_frequency > cur_frequency)
				current_delta = target_frequency - cur_frequency;
			else
				current_delta = cur_frequency - target_frequency;


			if (best_delta > current_delta) {
				best_delta = current_delta;
				pixel_n = candn;
				pixel_p1 = candp1;
				pixel_m2 = ((m + 3) % 5) + 7;
				pixel_m1 = (m - pixel_m2) / 5;
			}
		}
	}

	if (best_delta == 0xffffffff) {
		printk (BIOS_ERR, "Couldn't find GFX clock divisors\n");
		return;
	}

	link_m1 = ((uint64_t)link_n1 * mode->pixel_clock) / link_frequency;
	data_m1 = ((uint64_t)data_n1 * 18 * mode->pixel_clock)
		/ (link_frequency * 8 * 4);

	printk(BIOS_INFO, "bringing up panel at resolution %d x %d\n",
	       hactive, vactive);
	printk(BIOS_DEBUG, "Borders %d x %d\n",
	       right_border, bottom_border);
	printk(BIOS_DEBUG, "Blank %d x %d\n",
	       hblank, vblank);
	printk(BIOS_DEBUG, "Sync %d x %d\n",
	       hsync, vsync);
	printk(BIOS_DEBUG, "Front porch %d x %d\n",
	       hfront_porch, vfront_porch);
	printk(BIOS_DEBUG, (info->gfx.use_spread_spectrum_clock
			    ? "Spread spectrum clock\n" : "DREF clock\n"));
	printk(BIOS_DEBUG,
	       mode->lvds_dual_channel ? "Dual channel\n" : "Single channel\n");
	printk(BIOS_DEBUG, "Polarities %d, %d\n",
	       hpolarity, vpolarity);
	printk(BIOS_DEBUG, "Data M1=%d, N1=%d\n",
	       data_m1, data_n1);
	printk(BIOS_DEBUG, "Link frequency %d kHz\n",
	       link_frequency);
	printk(BIOS_DEBUG, "Link M1=%d, N1=%d\n",
	       link_m1, link_n1);
	printk(BIOS_DEBUG, "Pixel N=%d, M1=%d, M2=%d, P1=%d\n",
	       pixel_n, pixel_m1, pixel_m2, pixel_p1);
	printk(BIOS_DEBUG, "Pixel clock %d kHz\n",
	       120000 * (5 * pixel_m1 + pixel_m2) / pixel_n
	       / (pixel_p1 * 7));

	write32(mmio + LVDS,
		(hpolarity << 20) | (vpolarity << 21)
		| (mode->lvds_dual_channel ? LVDS_CLOCK_B_POWERUP_ALL
		   | LVDS_CLOCK_BOTH_POWERUP_ALL : 0)
		| LVDS_BORDER_ENABLE | LVDS_CLOCK_A_POWERUP_ALL);
	mdelay(1);
	write32(mmio + PP_CONTROL, PANEL_UNLOCK_REGS
		| (read32(mmio + PP_CONTROL) & ~PANEL_UNLOCK_MASK));
	write32(mmio + FP0(0),
		((pixel_n - 2) << 16)
		| ((pixel_m1 - 2) << 8) | pixel_m2);
	write32(mmio + DPLL(0),
		DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
		| (mode->lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
		   : DPLLB_LVDS_P2_CLOCK_DIV_14)
		| (0x10000 << (pixel_p1 - 1))
		| ((info->gfx.use_spread_spectrum_clock ? 3 : 0) << 13)
		| (0x1 << (pixel_p1 - 1)));
	mdelay(1);
	write32(mmio + DPLL(0),
		DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
		| (mode->lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
		   : DPLLB_LVDS_P2_CLOCK_DIV_14)
		| (0x10000 << (pixel_p1 - 1))
		| ((info->gfx.use_spread_spectrum_clock ? 3 : 0) << 13)
		| (0x1 << (pixel_p1 - 1)));
	/* Re-lock the registers.  */
	write32(mmio + PP_CONTROL,
		(read32(mmio + PP_CONTROL) & ~PANEL_UNLOCK_MASK));

	write32(mmio + LVDS,
		(hpolarity << 20) | (vpolarity << 21)
		| (mode->lvds_dual_channel ? LVDS_CLOCK_B_POWERUP_ALL
		   | LVDS_CLOCK_BOTH_POWERUP_ALL : 0)
		| LVDS_BORDER_ENABLE | LVDS_CLOCK_A_POWERUP_ALL);

	write32(mmio + HTOTAL(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive - 1));
	write32(mmio + HBLANK(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive + right_border - 1));
	write32(mmio + HSYNC(0),
		((hactive + right_border + hfront_porch + hsync - 1) << 16)
		| (hactive + right_border + hfront_porch - 1));

	write32(mmio + VTOTAL(0), ((vactive + bottom_border + vblank - 1) << 16)
		| (vactive - 1));
	write32(mmio + VBLANK(0), ((vactive + bottom_border + vblank - 1) << 16)
		| (vactive + bottom_border - 1));
	write32(mmio + VSYNC(0),
		(vactive + bottom_border + vfront_porch + vsync - 1)
		| (vactive + bottom_border + vfront_porch - 1));

	write32(mmio + PIPECONF(0), PIPECONF_DISABLE);

	write32(mmio + PF_WIN_POS(0), 0);
	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		write32(mmio + PIPESRC(0), ((hactive - 1) << 16)
			| (vactive - 1));
		write32(mmio + PF_CTL(0), 0);
		write32(mmio + PF_WIN_SZ(0), 0);
		write32(mmio + PFIT_CONTROL, 0x20000000);
	} else {
		write32(mmio + PIPESRC(0), (639 << 16) | 399);
		write32(mmio + PF_CTL(0), PF_ENABLE | PF_FILTER_MED_3x3);
		write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
		write32(mmio + PFIT_CONTROL, 0x80000000);
	}

	mdelay(1);

	write32(mmio + PIPE_DATA_M1(0), 0x7e000000 | data_m1);
	write32(mmio + PIPE_DATA_N1(0), data_n1);
	write32(mmio + PIPE_LINK_M1(0), link_m1);
	write32(mmio + PIPE_LINK_N1(0), link_n1);

	write32(mmio + 0x000f000c, 0x00002040);
	mdelay(1);
	write32(mmio + 0x000f000c, 0x00002050);
	write32(mmio + 0x00060100, 0x00044000);
	mdelay(1);
	write32(mmio + PIPECONF(0), PIPECONF_BPP_6);
	write32(mmio + 0x000f0008, 0x00000040);
	write32(mmio + 0x000f000c, 0x00022050);
	write32(mmio + PIPECONF(0), PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
	write32(mmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);

	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		write32(mmio + VGACNTRL, 0xc4008e | VGA_DISP_DISABLE);
		write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE
			| DISPPLANE_BGRX888);
		mdelay(1);
	} else {
		write32(mmio + VGACNTRL, 0xc4008e);
	}

	write32(mmio + TRANS_HTOTAL(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive - 1));
	write32(mmio + TRANS_HBLANK(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive + right_border - 1));
	write32(mmio + TRANS_HSYNC(0),
		((hactive + right_border + hfront_porch + hsync - 1) << 16)
		| (hactive + right_border + hfront_porch - 1));

	write32(mmio + TRANS_VTOTAL(0),
		((vactive + bottom_border + vblank - 1) << 16)
		| (vactive - 1));
	write32(mmio + TRANS_VBLANK(0),
		((vactive + bottom_border + vblank - 1) << 16)
		| (vactive + bottom_border - 1));
	write32(mmio + TRANS_VSYNC(0),
		(vactive + bottom_border + vfront_porch + vsync - 1)
		| (vactive + bottom_border + vfront_porch - 1));

	write32(mmio + 0x00060100, 0xb01c4000);
	write32(mmio + 0x000f000c, 0xb01a2050);
	mdelay(1);
	write32(mmio + TRANSCONF(0), TRANS_ENABLE | TRANS_6BPC
		);
	write32(mmio + LVDS,
		LVDS_PORT_ENABLE
		| (hpolarity << 20) | (vpolarity << 21)
		| (mode->lvds_dual_channel ? LVDS_CLOCK_B_POWERUP_ALL
		   | LVDS_CLOCK_BOTH_POWERUP_ALL : 0)
		| LVDS_BORDER_ENABLE | LVDS_CLOCK_A_POWERUP_ALL);

	write32(mmio + PP_CONTROL, PANEL_POWER_ON | PANEL_POWER_RESET);

	/* Enable screen memory.  */
	vga_sr_write(1, vga_sr_read(1) & ~0x20);

	/* Clear interrupts. */
	write32(mmio + DEIIR, 0xffffffff);
	write32(mmio + SDEIIR, 0xffffffff);

	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		memset((void *) lfb, 0,
		       edid.x_resolution * edid.y_resolution * 4);
		set_vbe_mode_info_valid(&edid, lfb);
	}
}
Esempio n. 28
0
static inline void
fWrite_hfc32(hfc4s8s_hw * a, u_long c)
{
	outl(c, a->iobase);
}
Esempio n. 29
0
static __inline__ u32 dispc_reg_out(u32 offset, u32 val)
{
   outl(val, offset);
   return (val);
}
Esempio n. 30
0
static struct sal_ret_values
sal_emulator (long index, unsigned long in1, unsigned long in2,
	      unsigned long in3, unsigned long in4, unsigned long in5,
	      unsigned long in6, unsigned long in7)
{
	long r9  = 0;
	long r10 = 0;
	long r11 = 0;
	long status;

	/*
	 * Don't do a "switch" here since that gives us code that
	 * isn't self-relocatable.
	 */
	status = 0;
	if (index == SAL_FREQ_BASE) {
		if (in1 == SAL_FREQ_BASE_PLATFORM)
			r9 = 200000000;
		else if (in1 == SAL_FREQ_BASE_INTERVAL_TIMER) {
			/*
			 * Is this supposed to be the cr.itc frequency
			 * or something platform specific?  The SAL
			 * doc ain't exactly clear on this...
			 */
			r9 = 700000000;
		} else if (in1 == SAL_FREQ_BASE_REALTIME_CLOCK)
			r9 = 1;
		else
			status = -1;
	} else if (index == SAL_SET_VECTORS) {
		;
	} else if (index == SAL_GET_STATE_INFO) {
		;
	} else if (index == SAL_GET_STATE_INFO_SIZE) {
		;
	} else if (index == SAL_CLEAR_STATE_INFO) {
		;
	} else if (index == SAL_MC_RENDEZ) {
		;
	} else if (index == SAL_MC_SET_PARAMS) {
		;
	} else if (index == SAL_CACHE_FLUSH) {
		;
	} else if (index == SAL_CACHE_INIT) {
		;
#ifdef CONFIG_PCI
	} else if (index == SAL_PCI_CONFIG_READ) {
		/*
		 * in1 contains the PCI configuration address and in2
		 * the size of the read.  The value that is read is
		 * returned via the general register r9.
		 */
                outl(BUILD_CMD(in1), 0xCF8);
                if (in2 == 1)                           /* Reading byte  */
                        r9 = inb(0xCFC + ((REG_OFFSET(in1) & 3)));
                else if (in2 == 2)                      /* Reading word  */
                        r9 = inw(0xCFC + ((REG_OFFSET(in1) & 2)));
                else                                    /* Reading dword */
                        r9 = inl(0xCFC);
                status = PCIBIOS_SUCCESSFUL;
	} else if (index == SAL_PCI_CONFIG_WRITE) {
	      	/*
		 * in1 contains the PCI configuration address, in2 the
		 * size of the write, and in3 the actual value to be
		 * written out.
		 */
                outl(BUILD_CMD(in1), 0xCF8);
                if (in2 == 1)                           /* Writing byte  */
                        outb(in3, 0xCFC + ((REG_OFFSET(in1) & 3)));
                else if (in2 == 2)                      /* Writing word  */
                        outw(in3, 0xCFC + ((REG_OFFSET(in1) & 2)));
                else                                    /* Writing dword */
                        outl(in3, 0xCFC);
                status = PCIBIOS_SUCCESSFUL;
#endif /* CONFIG_PCI */
	} else if (index == SAL_UPDATE_PAL) {
		;
	} else {
		status = -1;
	}
	return ((struct sal_ret_values) {status, r9, r10, r11});