/tools/perf/scripts/python/

'>wip-mc2-ver2 LITMUS^RT and MC^2 V1 support for the i.MX6 processor family.Namhoon Kim
aboutsummaryrefslogblamecommitdiffstats
path: root/drivers/ide/siimage.c
blob: 6a1849bb476ce1ad78e438dee2f55120cf3c8924 (plain) (tree)
1
2
3
4
5
6
7
8
  
                                                                   
                                       
                                                         
                                                         


                                                                               






                                                                         



                                                                     
                                                                

                                                                     
                                              


                                                                       
                    




                                                                            

        
                 

   


                         

                       
                     
 

                          


                                                               
  

                                                 
 

                                             
                              





                                      

              
      

                 
 


                                                             
  

                                                 
 

                                           
                                                   








                                                                          

                                                                          
   
 


                                                            
 
                         
                                              
                                           
            
                                           

                    
 








                                                                          
 

                                                                     
                                              
                                                                 
                                                
 
                         
                                              
                                           
            
                                           
                             


                    

                                                              
                                                     

                   
                            








                                                                
                                                     

                    
                            








                                                                         


                                                     






                                                                           


                                                     






                                                                           


                                                     




                                                       
   



                                                                          
  
                                                                        
                                                     
   
 
                                                  
 



                                                                 
 


                                                                  
 

                                 
                                 

                                   
                                 

                                 
                                 

                                        
                      
         
 
                    

 

                                                  


                                                           

 
   
                                                                        
                   
                     

                                                              
                   
   
 
                                                                  
 

                                                                                   
 
                                                        
                                                          


                                                              
                                                              
                                                                 
                                                               
                                      


                                                                              
                                    
                                                

                                                                    
                   
                                                          


                                          
         
 



                                            





                                               


                                                  






                                               
                                                  

 
   
                                                                        
                   
                     
  
                                                      
   
 
                                                                  
 


                                                                                
 
                                                        
                                                                 

                                                


                                                                              

                                                              
                                                  
 
                                                               
                                                    

                                      
 
                                       




                                               
                                   



                                                             

                                                   
                                           

         
                                                   

                                      

 









                                                          
   
                                                                      




                                                                        

                                                        
 
                                              

                                                                    
 
                              


                                                                               
 
                                                                 


                                                                
                                                                     

                                                                       

                                                                             
                                                               
 
                                




                                                      
                                                                         

                         


                 

                                                   
                                                     

                                                        
                                               

 
   
                                                           




                                                                        

                                                  
 






                                                                     
 
                                                 
                                                                                  
                                                                   
                                      
                 
         

                 


   
                                                  




                                                                     
 


                                                  

                                                                          



         

                                                           

                                                                         
                                                                        

   
                                                    
 

                                                     
                                      
                                    
 
                                                                       
 

                                    












                                                                
                 

                                          

         







                                                          
                                                                    










                                                                             

         
                                          
 
                                                    



                                                    
                                                                    











                                                                    





                                                                         

                                                                 
         
 








                                                                           
                                                                            

                                                                          
                                                                            

   
                                                    
 
                                                        

                                                       
                                                
                                                        
                           
 
          
                                           
           
                                           
 
                               

          

                                                                          
           
                                               







                                   


                                                                              








                                            







                                                                       

         
                             
 
                                                                  



                                                  

                                                                
 
                                               





                                                                            
 



                 

                                                         





                                                                       
                                             
 

                                       
                                     
                                                          












                                                               
                                               
 
                                                    
                                                     
 




                                              

                                             


   
                                                       

                                 
                                                                          

   
                                            
 


                                                          
 
                                                                

 



                                                      
                                               









                                                       
                                               



                                                       


                                                   
                                                
                                              
                                                       
                                                           
                                                   
                                                          

  
                                                         
                                                         
                                                         

                                                         
                                                         
                                                         
                                                         

                                                         

         
                                                        

                                                             


   
                                                                 


                              
                                                                             

                                                                      
 
                                                                                
 



                                                          

                                 
                  






                                     
                                                                                






                                                                            










                                                                         
                                                                           
                                                              
                        
                                                         














                                                                  

 
                                               
















                                                                  

                                                          
                              
                                                          
                                                          




                                          
                                               


                                           
                                         

                                          

  
                                        
 
                                                            

 

                                         
                                                   

 
                              
                              



                                                    
/*
 * Copyright (C) 2001-2002	Andre Hedrick <andre@linux-ide.org>
 * Copyright (C) 2003		Red Hat
 * Copyright (C) 2007-2008	MontaVista Software, Inc.
 * Copyright (C) 2007-2008	Bartlomiej Zolnierkiewicz
 *
 *  May be copied or modified under the terms of the GNU General Public License
 *
 *  Documentation for CMD680:
 *  http://gkernel.sourceforge.net/specs/sii/sii-0680a-v1.31.pdf.bz2
 *
 *  Documentation for SiI 3112:
 *  http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
 *
 *  Errata and other documentation only available under NDA.
 *
 *
 *  FAQ Items:
 *	If you are using Marvell SATA-IDE adapters with Maxtor drives
 *	ensure the system is set up for ATA100/UDMA5, not UDMA6.
 *
 *	If you are using WD drives with SATA bridges you must set the
 *	drive to "Single". "Master" will hang.
 *
 *	If you have strange problems with nVidia chipset systems please
 *	see the SI support documentation and update your system BIOS
 *	if necessary
 *
 *  The Dell DRAC4 has some interesting features including effectively hot
 *  unplugging/replugging the virtual CD interface when the DRAC is reset.
 *  This often causes drivers/ide/siimage to panic but is ok with the rather
 *  smarter code in libata.
 *
 * TODO:
 * - VDMA support
 */

#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/io.h>

#define DRV_NAME "siimage"

/**
 *	pdev_is_sata		-	check if device is SATA
 *	@pdev:	PCI device to check
 *
 *	Returns true if this is a SATA controller
 */

static int pdev_is_sata(struct pci_dev *pdev)
{
#ifdef CONFIG_BLK_DEV_IDE_SATA
	switch (pdev->device) {
	case PCI_DEVICE_ID_SII_3112:
	case PCI_DEVICE_ID_SII_1210SA:
		return 1;
	case PCI_DEVICE_ID_SII_680:
		return 0;
	}
	BUG();
#endif
	return 0;
}

/**
 *	is_sata			-	check if hwif is SATA
 *	@hwif:	interface to check
 *
 *	Returns true if this is a SATA controller
 */

static inline int is_sata(ide_hwif_t *hwif)
{
	return pdev_is_sata(to_pci_dev(hwif->dev));
}

/**
 *	siimage_selreg		-	return register base
 *	@hwif: interface
 *	@r: config offset
 *
 *	Turn a config register offset into the right address in either
 *	PCI space or MMIO space to access the control register in question
 *	Thankfully this is a configuration operation, so isn't performance
 *	critical.
 */

static unsigned long siimage_selreg(ide_hwif_t *hwif, int r)
{
	unsigned long base = (unsigned long)hwif->hwif_data;

	base += 0xA0 + r;
	if (hwif->host_flags & IDE_HFLAG_MMIO)
		base += hwif->channel << 6;
	else
		base += hwif->channel << 4;
	return base;
}

/**
 *	siimage_seldev		-	return register base
 *	@hwif: interface
 *	@r: config offset
 *
 *	Turn a config register offset into the right address in either
 *	PCI space or MMIO space to access the control register in question
 *	including accounting for the unit shift.
 */

static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
{
	ide_hwif_t *hwif	= drive->hwif;
	unsigned long base	= (unsigned long)hwif->hwif_data;
	u8 unit			= drive->dn & 1;

	base += 0xA0 + r;
	if (hwif->host_flags & IDE_HFLAG_MMIO)
		base += hwif->channel << 6;
	else
		base += hwif->channel << 4;
	base |= unit << unit;
	return base;
}

static u8 sil_ioread8(struct pci_dev *dev, unsigned long addr)
{
	struct ide_host *host = pci_get_drvdata(dev);
	u8 tmp = 0;

	if (host->host_priv)
		tmp = readb((void __iomem *)addr);
	else
		pci_read_config_byte(dev, addr, &tmp);

	return tmp;
}

static u16 sil_ioread16(struct pci_dev *dev, unsigned long addr)
{
	struct ide_host *host = pci_get_drvdata(dev);
	u16 tmp = 0;

	if (host->host_priv)
		tmp = readw((void __iomem *)addr);
	else
		pci_read_config_word(dev, addr, &tmp);

	return tmp;
}

static void sil_iowrite8(struct pci_dev *dev, u8 val, unsigned long addr)
{
	struct ide_host *host = pci_get_drvdata(dev);

	if (host->host_priv)
		writeb(val, (void __iomem *)addr);
	else
		pci_write_config_byte(dev, addr, val);
}

static void sil_iowrite16(struct pci_dev *dev, u16 val, unsigned long addr)
{
	struct ide_host *host = pci_get_drvdata(dev);

	if (host->host_priv)
		writew(val, (void __iomem *)addr);
	else
		pci_write_config_word(dev, addr, val);
}

static void sil_iowrite32(struct pci_dev *dev, u32 val, unsigned long addr)
{
	struct ide_host *host = pci_get_drvdata(dev);

	if (host->host_priv)
		writel(val, (void __iomem *)addr);
	else
		pci_write_config_dword(dev, addr, val);
}

/**
 *	sil_udma_filter		-	compute UDMA mask
 *	@drive: IDE device
 *
 *	Compute the available UDMA speeds for the device on the interface.
 *
 *	For the CMD680 this depends on the clocking mode (scsc), for the
 *	SI3112 SATA controller life is a bit simpler.
 */

static u8 sil_pata_udma_filter(ide_drive_t *drive)
{
	ide_hwif_t *hwif	= drive->hwif;
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	unsigned long base	= (unsigned long)hwif->hwif_data;
	u8 scsc, mask		= 0;

	base += (hwif->host_flags & IDE_HFLAG_MMIO) ? 0x4A : 0x8A;

	scsc = sil_ioread8(dev, base);

	switch (scsc & 0x30) {
	case 0x10:	/* 133 */
		mask = ATA_UDMA6;
		break;
	case 0x20:	/* 2xPCI */
		mask = ATA_UDMA6;
		break;
	case 0x00:	/* 100 */
		mask = ATA_UDMA5;
		break;
	default: 	/* Disabled ? */
		BUG();
	}

	return mask;
}

static u8 sil_sata_udma_filter(ide_drive_t *drive)
{
	char *m = (char *)&drive->id[ATA_ID_PROD];

	return strstr(m, "Maxtor") ? ATA_UDMA5 : ATA_UDMA6;
}

/**
 *	sil_set_pio_mode	-	set host controller for PIO mode
 *	@hwif: port
 *	@drive: drive
 *
 *	Load the timing settings for this device mode into the
 *	controller.
 */

static void sil_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
	static const u16 tf_speed[]   = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
	static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };

	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	ide_drive_t *pair	= ide_get_pair_dev(drive);
	u32 speedt		= 0;
	u16 speedp		= 0;
	unsigned long addr	= siimage_seldev(drive, 0x04);
	unsigned long tfaddr	= siimage_selreg(hwif,	0x02);
	unsigned long base	= (unsigned long)hwif->hwif_data;
	const u8 pio		= drive->pio_mode - XFER_PIO_0;
	u8 tf_pio		= pio;
	u8 mmio			= (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
	u8 addr_mask		= hwif->channel ? (mmio ? 0xF4 : 0x84)
						: (mmio ? 0xB4 : 0x80);
	u8 mode			= 0;
	u8 unit			= drive->dn & 1;

	/* trim *taskfile* PIO to the slowest of the master/slave */
	if (pair) {
		u8 pair_pio = pair->pio_mode - XFER_PIO_0;

		if (pair_pio < tf_pio)
			tf_pio = pair_pio;
	}

	/* cheat for now and use the docs */
	speedp = data_speed[pio];
	speedt = tf_speed[tf_pio];

	sil_iowrite16(dev, speedp, addr);
	sil_iowrite16(dev, speedt, tfaddr);

	/* now set up IORDY */
	speedp = sil_ioread16(dev, tfaddr - 2);
	speedp &= ~0x200;

	mode = sil_ioread8(dev, base + addr_mask);
	mode &= ~(unit ? 0x30 : 0x03);

	if (ide_pio_need_iordy(drive, pio)) {
		speedp |= 0x200;
		mode |= unit ? 0x10 : 0x01;
	}

	sil_iowrite16(dev, speedp, tfaddr - 2);
	sil_iowrite8(dev, mode, base + addr_mask);
}

/**
 *	sil_set_dma_mode	-	set host controller for DMA mode
 *	@hwif: port
 *	@drive: drive
 *
 *	Tune the SiI chipset for the desired DMA mode.
 */

static void sil_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
	static const u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
	static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
	static const u16 dma[]	 = { 0x2208, 0x10C2, 0x10C1 };

	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	unsigned long base	= (unsigned long)hwif->hwif_data;
	u16 ultra = 0, multi	= 0;
	u8 mode = 0, unit	= drive->dn & 1;
	u8 mmio			= (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
	u8 scsc = 0, addr_mask	= hwif->channel ? (mmio ? 0xF4 : 0x84)
						: (mmio ? 0xB4 : 0x80);
	unsigned long ma	= siimage_seldev(drive, 0x08);