2019-05-19 15:08:20 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2012-04-12 16:13:16 +04:00
/*
* EP93XX PATA controller driver .
*
* Copyright ( c ) 2012 , Metasoft s . c .
* Rafal Prylowski < prylowski @ metasoft . pl >
*
* Based on pata_scc . c , pata_icside . c and on earlier version of EP93XX
* PATA driver by Lennert Buytenhek and Alessandro Zummo .
* Read / Write timings , resource management and other improvements
* from driver by Joao Ramos and Bartlomiej Zolnierkiewicz .
* DMA engine support based on spi - ep93xx . c by Mika Westerberg .
*
* Original copyrights :
*
* Support for Cirrus Logic ' s EP93xx ( EP9312 , EP9315 ) CPUs
* PATA host controller driver .
*
* Copyright ( c ) 2009 , Bartlomiej Zolnierkiewicz
*
* Heavily based on the ep93xx - ide . c driver :
*
* Copyright ( c ) 2009 , Joao Ramos < joao . ramos @ inov . pt >
* INESC Inovacao ( INOV )
*
* EP93XX PATA controller driver .
* Copyright ( C ) 2007 Lennert Buytenhek < buytenh @ wantstofly . org >
*
* An ATA driver for the Cirrus Logic EP93xx PATA controller .
*
* Based on an earlier version by Alessandro Zummo , which is :
* Copyright ( C ) 2006 Tower Technologies
*/
2013-01-21 14:08:58 +04:00
# include <linux/err.h>
2012-04-12 16:13:16 +04:00
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/blkdev.h>
# include <scsi/scsi_host.h>
# include <linux/ata.h>
# include <linux/libata.h>
# include <linux/platform_device.h>
# include <linux/delay.h>
# include <linux/dmaengine.h>
# include <linux/ktime.h>
2012-08-24 17:12:11 +04:00
# include <linux/platform_data/dma-ep93xx.h>
2019-04-15 23:17:11 +03:00
# include <linux/soc/cirrus/ep93xx.h>
2012-04-12 16:13:16 +04:00
# define DRV_NAME "ep93xx-ide"
# define DRV_VERSION "1.0"
enum {
/* IDE Control Register */
IDECTRL = 0x00 ,
IDECTRL_CS0N = ( 1 < < 0 ) ,
IDECTRL_CS1N = ( 1 < < 1 ) ,
IDECTRL_DIORN = ( 1 < < 5 ) ,
IDECTRL_DIOWN = ( 1 < < 6 ) ,
IDECTRL_INTRQ = ( 1 < < 9 ) ,
IDECTRL_IORDY = ( 1 < < 10 ) ,
/*
* the device IDE register to be accessed is selected through
* IDECTRL register ' s specific bitfields ' DA ' , ' CS1N ' and ' CS0N ' :
* b4 b3 b2 b1 b0
* A2 A1 A0 CS1N CS0N
* the values filled in this structure allows the value to be directly
* ORed to the IDECTRL register , hence giving directly the A [ 2 : 0 ] and
* CS1N / CS0N values for each IDE register .
* The values correspond to the transformation :
* ( ( real IDE address ) < < 2 ) | CS1N value < < 1 | CS0N value
*/
IDECTRL_ADDR_CMD = 0 + 2 , /* CS1 */
IDECTRL_ADDR_DATA = ( ATA_REG_DATA < < 2 ) + 2 ,
IDECTRL_ADDR_ERROR = ( ATA_REG_ERR < < 2 ) + 2 ,
IDECTRL_ADDR_FEATURE = ( ATA_REG_FEATURE < < 2 ) + 2 ,
IDECTRL_ADDR_NSECT = ( ATA_REG_NSECT < < 2 ) + 2 ,
IDECTRL_ADDR_LBAL = ( ATA_REG_LBAL < < 2 ) + 2 ,
IDECTRL_ADDR_LBAM = ( ATA_REG_LBAM < < 2 ) + 2 ,
IDECTRL_ADDR_LBAH = ( ATA_REG_LBAH < < 2 ) + 2 ,
IDECTRL_ADDR_DEVICE = ( ATA_REG_DEVICE < < 2 ) + 2 ,
IDECTRL_ADDR_STATUS = ( ATA_REG_STATUS < < 2 ) + 2 ,
IDECTRL_ADDR_COMMAND = ( ATA_REG_CMD < < 2 ) + 2 ,
IDECTRL_ADDR_ALTSTATUS = ( 0x06 < < 2 ) + 1 , /* CS0 */
IDECTRL_ADDR_CTL = ( 0x06 < < 2 ) + 1 , /* CS0 */
/* IDE Configuration Register */
IDECFG = 0x04 ,
IDECFG_IDEEN = ( 1 < < 0 ) ,
IDECFG_PIO = ( 1 < < 1 ) ,
IDECFG_MDMA = ( 1 < < 2 ) ,
IDECFG_UDMA = ( 1 < < 3 ) ,
IDECFG_MODE_SHIFT = 4 ,
IDECFG_MODE_MASK = ( 0xf < < 4 ) ,
IDECFG_WST_SHIFT = 8 ,
IDECFG_WST_MASK = ( 0x3 < < 8 ) ,
/* MDMA Operation Register */
IDEMDMAOP = 0x08 ,
/* UDMA Operation Register */
IDEUDMAOP = 0x0c ,
IDEUDMAOP_UEN = ( 1 < < 0 ) ,
IDEUDMAOP_RWOP = ( 1 < < 1 ) ,
/* PIO/MDMA/UDMA Data Registers */
IDEDATAOUT = 0x10 ,
IDEDATAIN = 0x14 ,
IDEMDMADATAOUT = 0x18 ,
IDEMDMADATAIN = 0x1c ,
IDEUDMADATAOUT = 0x20 ,
IDEUDMADATAIN = 0x24 ,
/* UDMA Status Register */
IDEUDMASTS = 0x28 ,
IDEUDMASTS_DMAIDE = ( 1 < < 16 ) ,
IDEUDMASTS_INTIDE = ( 1 < < 17 ) ,
IDEUDMASTS_SBUSY = ( 1 < < 18 ) ,
IDEUDMASTS_NDO = ( 1 < < 24 ) ,
IDEUDMASTS_NDI = ( 1 < < 25 ) ,
IDEUDMASTS_N4X = ( 1 < < 26 ) ,
/* UDMA Debug Status Register */
IDEUDMADEBUG = 0x2c ,
} ;
struct ep93xx_pata_data {
const struct platform_device * pdev ;
void __iomem * ide_base ;
struct ata_timing t ;
bool iordy ;
unsigned long udma_in_phys ;
unsigned long udma_out_phys ;
struct dma_chan * dma_rx_channel ;
struct ep93xx_dma_data dma_rx_data ;
struct dma_chan * dma_tx_channel ;
struct ep93xx_dma_data dma_tx_data ;
} ;
static void ep93xx_pata_clear_regs ( void __iomem * base )
{
writel ( IDECTRL_CS0N | IDECTRL_CS1N | IDECTRL_DIORN |
IDECTRL_DIOWN , base + IDECTRL ) ;
writel ( 0 , base + IDECFG ) ;
writel ( 0 , base + IDEMDMAOP ) ;
writel ( 0 , base + IDEUDMAOP ) ;
writel ( 0 , base + IDEDATAOUT ) ;
writel ( 0 , base + IDEDATAIN ) ;
writel ( 0 , base + IDEMDMADATAOUT ) ;
writel ( 0 , base + IDEMDMADATAIN ) ;
writel ( 0 , base + IDEUDMADATAOUT ) ;
writel ( 0 , base + IDEUDMADATAIN ) ;
writel ( 0 , base + IDEUDMADEBUG ) ;
}
static bool ep93xx_pata_check_iordy ( void __iomem * base )
{
return ! ! ( readl ( base + IDECTRL ) & IDECTRL_IORDY ) ;
}
/*
* According to EP93xx User ' s Guide , WST field of IDECFG specifies number
* of HCLK cycles to hold the data bus after a PIO write operation .
* It should be programmed to guarantee following delays :
*
* PIO Mode [ ns ]
* 0 30
* 1 20
* 2 15
* 3 10
* 4 5
*
* Maximum possible value for HCLK is 100 MHz .
*/
static int ep93xx_pata_get_wst ( int pio_mode )
{
int val ;
if ( pio_mode = = 0 )
val = 3 ;
else if ( pio_mode < 3 )
val = 2 ;
else
val = 1 ;
return val < < IDECFG_WST_SHIFT ;
}
static void ep93xx_pata_enable_pio ( void __iomem * base , int pio_mode )
{
writel ( IDECFG_IDEEN | IDECFG_PIO |
ep93xx_pata_get_wst ( pio_mode ) |
( pio_mode < < IDECFG_MODE_SHIFT ) , base + IDECFG ) ;
}
/*
* Based on delay loop found in mach - pxa / mp900 . c .
*
* Single iteration should take 5 cpu cycles . This is 25 ns assuming the
* fastest ep93xx cpu speed ( 200 MHz ) and is better optimized for PIO4 timings
* than eg . 20 ns .
*/
static void ep93xx_pata_delay ( unsigned long count )
{
__asm__ volatile (
" 0: \n "
" mov r0, r0 \n "
" subs %0, %1, #1 \n "
" bge 0b \n "
: " =r " ( count )
: " 0 " ( count )
) ;
}
static unsigned long ep93xx_pata_wait_for_iordy ( void __iomem * base ,
unsigned long t2 )
{
/*
* According to ATA specification , IORDY pin can be first sampled
* tA = 35 ns after activation of DIOR - / DIOW - . Maximum IORDY pulse
* width is tB = 1250 ns .
*
* We are already t2 delay loop iterations after activation of
* DIOR - / DIOW - , so we set timeout to ( 1250 + 35 ) / 25 - t2 additional
* delay loop iterations .
*/
unsigned long start = ( 1250 + 35 ) / 25 - t2 ;
unsigned long counter = start ;
while ( ! ep93xx_pata_check_iordy ( base ) & & counter - - )
ep93xx_pata_delay ( 1 ) ;
return start - counter ;
}
/* common part at start of ep93xx_pata_read/write() */
static void ep93xx_pata_rw_begin ( void __iomem * base , unsigned long addr ,
unsigned long t1 )
{
writel ( IDECTRL_DIOWN | IDECTRL_DIORN | addr , base + IDECTRL ) ;
ep93xx_pata_delay ( t1 ) ;
}
/* common part at end of ep93xx_pata_read/write() */
static void ep93xx_pata_rw_end ( void __iomem * base , unsigned long addr ,
bool iordy , unsigned long t0 , unsigned long t2 ,
unsigned long t2i )
{
ep93xx_pata_delay ( t2 ) ;
/* lengthen t2 if needed */
if ( iordy )
t2 + = ep93xx_pata_wait_for_iordy ( base , t2 ) ;
writel ( IDECTRL_DIOWN | IDECTRL_DIORN | addr , base + IDECTRL ) ;
if ( t0 > t2 & & t0 - t2 > t2i )
ep93xx_pata_delay ( t0 - t2 ) ;
else
ep93xx_pata_delay ( t2i ) ;
}
static u16 ep93xx_pata_read ( struct ep93xx_pata_data * drv_data ,
unsigned long addr ,
bool reg )
{
void __iomem * base = drv_data - > ide_base ;
const struct ata_timing * t = & drv_data - > t ;
unsigned long t0 = reg ? t - > cyc8b : t - > cycle ;
unsigned long t2 = reg ? t - > act8b : t - > active ;
unsigned long t2i = reg ? t - > rec8b : t - > recover ;
ep93xx_pata_rw_begin ( base , addr , t - > setup ) ;
writel ( IDECTRL_DIOWN | addr , base + IDECTRL ) ;
/*
* The IDEDATAIN register is loaded from the DD pins at the positive
* edge of the DIORN signal . ( EP93xx UG p27 - 14 )
*/
ep93xx_pata_rw_end ( base , addr , drv_data - > iordy , t0 , t2 , t2i ) ;
return readl ( base + IDEDATAIN ) ;
}
/* IDE register read */
static u16 ep93xx_pata_read_reg ( struct ep93xx_pata_data * drv_data ,
unsigned long addr )
{
return ep93xx_pata_read ( drv_data , addr , true ) ;
}
/* PIO data read */
static u16 ep93xx_pata_read_data ( struct ep93xx_pata_data * drv_data ,
unsigned long addr )
{
return ep93xx_pata_read ( drv_data , addr , false ) ;
}
static void ep93xx_pata_write ( struct ep93xx_pata_data * drv_data ,
u16 value , unsigned long addr ,
bool reg )
{
void __iomem * base = drv_data - > ide_base ;
const struct ata_timing * t = & drv_data - > t ;
unsigned long t0 = reg ? t - > cyc8b : t - > cycle ;
unsigned long t2 = reg ? t - > act8b : t - > active ;
unsigned long t2i = reg ? t - > rec8b : t - > recover ;
ep93xx_pata_rw_begin ( base , addr , t - > setup ) ;
/*
* Value from IDEDATAOUT register is driven onto the DD pins when
* DIOWN is low . ( EP93xx UG p27 - 13 )
*/
writel ( value , base + IDEDATAOUT ) ;
writel ( IDECTRL_DIORN | addr , base + IDECTRL ) ;
ep93xx_pata_rw_end ( base , addr , drv_data - > iordy , t0 , t2 , t2i ) ;
}
/* IDE register write */
static void ep93xx_pata_write_reg ( struct ep93xx_pata_data * drv_data ,
u16 value , unsigned long addr )
{
ep93xx_pata_write ( drv_data , value , addr , true ) ;
}
/* PIO data write */
static void ep93xx_pata_write_data ( struct ep93xx_pata_data * drv_data ,
u16 value , unsigned long addr )
{
ep93xx_pata_write ( drv_data , value , addr , false ) ;
}
static void ep93xx_pata_set_piomode ( struct ata_port * ap ,
struct ata_device * adev )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
struct ata_device * pair = ata_dev_pair ( adev ) ;
/*
* Calculate timings for the delay loop , assuming ep93xx cpu speed
* is 200 MHz ( maximum possible for ep93xx ) . If actual cpu speed is
* slower , we will wait a bit longer in each delay .
* Additional division of cpu speed by 5 , because single iteration
* of our delay loop takes 5 cpu cycles ( 25 ns ) .
*/
unsigned long T = 1000000 / ( 200 / 5 ) ;
ata_timing_compute ( adev , adev - > pio_mode , & drv_data - > t , T , 0 ) ;
if ( pair & & pair - > pio_mode ) {
struct ata_timing t ;
ata_timing_compute ( pair , pair - > pio_mode , & t , T , 0 ) ;
ata_timing_merge ( & t , & drv_data - > t , & drv_data - > t ,
ATA_TIMING_SETUP | ATA_TIMING_8BIT ) ;
}
drv_data - > iordy = ata_pio_need_iordy ( adev ) ;
ep93xx_pata_enable_pio ( drv_data - > ide_base ,
adev - > pio_mode - XFER_PIO_0 ) ;
}
/* Note: original code is ata_sff_check_status */
static u8 ep93xx_pata_check_status ( struct ata_port * ap )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
return ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_STATUS ) ;
}
static u8 ep93xx_pata_check_altstatus ( struct ata_port * ap )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
return ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_ALTSTATUS ) ;
}
/* Note: original code is ata_sff_tf_load */
static void ep93xx_pata_tf_load ( struct ata_port * ap ,
const struct ata_taskfile * tf )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
unsigned int is_addr = tf - > flags & ATA_TFLAG_ISADDR ;
if ( tf - > ctl ! = ap - > last_ctl ) {
ep93xx_pata_write_reg ( drv_data , tf - > ctl , IDECTRL_ADDR_CTL ) ;
ap - > last_ctl = tf - > ctl ;
ata_wait_idle ( ap ) ;
}
if ( is_addr & & ( tf - > flags & ATA_TFLAG_LBA48 ) ) {
ep93xx_pata_write_reg ( drv_data , tf - > hob_feature ,
IDECTRL_ADDR_FEATURE ) ;
ep93xx_pata_write_reg ( drv_data , tf - > hob_nsect ,
IDECTRL_ADDR_NSECT ) ;
ep93xx_pata_write_reg ( drv_data , tf - > hob_lbal ,
IDECTRL_ADDR_LBAL ) ;
ep93xx_pata_write_reg ( drv_data , tf - > hob_lbam ,
IDECTRL_ADDR_LBAM ) ;
ep93xx_pata_write_reg ( drv_data , tf - > hob_lbah ,
IDECTRL_ADDR_LBAH ) ;
}
if ( is_addr ) {
ep93xx_pata_write_reg ( drv_data , tf - > feature ,
IDECTRL_ADDR_FEATURE ) ;
ep93xx_pata_write_reg ( drv_data , tf - > nsect , IDECTRL_ADDR_NSECT ) ;
ep93xx_pata_write_reg ( drv_data , tf - > lbal , IDECTRL_ADDR_LBAL ) ;
ep93xx_pata_write_reg ( drv_data , tf - > lbam , IDECTRL_ADDR_LBAM ) ;
ep93xx_pata_write_reg ( drv_data , tf - > lbah , IDECTRL_ADDR_LBAH ) ;
}
if ( tf - > flags & ATA_TFLAG_DEVICE )
ep93xx_pata_write_reg ( drv_data , tf - > device ,
IDECTRL_ADDR_DEVICE ) ;
ata_wait_idle ( ap ) ;
}
/* Note: original code is ata_sff_tf_read */
static void ep93xx_pata_tf_read ( struct ata_port * ap , struct ata_taskfile * tf )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
tf - > command = ep93xx_pata_check_status ( ap ) ;
tf - > feature = ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_FEATURE ) ;
tf - > nsect = ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_NSECT ) ;
tf - > lbal = ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_LBAL ) ;
tf - > lbam = ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_LBAM ) ;
tf - > lbah = ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_LBAH ) ;
tf - > device = ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_DEVICE ) ;
if ( tf - > flags & ATA_TFLAG_LBA48 ) {
ep93xx_pata_write_reg ( drv_data , tf - > ctl | ATA_HOB ,
IDECTRL_ADDR_CTL ) ;
tf - > hob_feature = ep93xx_pata_read_reg ( drv_data ,
IDECTRL_ADDR_FEATURE ) ;
tf - > hob_nsect = ep93xx_pata_read_reg ( drv_data ,
IDECTRL_ADDR_NSECT ) ;
tf - > hob_lbal = ep93xx_pata_read_reg ( drv_data ,
IDECTRL_ADDR_LBAL ) ;
tf - > hob_lbam = ep93xx_pata_read_reg ( drv_data ,
IDECTRL_ADDR_LBAM ) ;
tf - > hob_lbah = ep93xx_pata_read_reg ( drv_data ,
IDECTRL_ADDR_LBAH ) ;
ep93xx_pata_write_reg ( drv_data , tf - > ctl , IDECTRL_ADDR_CTL ) ;
ap - > last_ctl = tf - > ctl ;
}
}
/* Note: original code is ata_sff_exec_command */
static void ep93xx_pata_exec_command ( struct ata_port * ap ,
const struct ata_taskfile * tf )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
ep93xx_pata_write_reg ( drv_data , tf - > command ,
IDECTRL_ADDR_COMMAND ) ;
ata_sff_pause ( ap ) ;
}
/* Note: original code is ata_sff_dev_select */
static void ep93xx_pata_dev_select ( struct ata_port * ap , unsigned int device )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
u8 tmp = ATA_DEVICE_OBS ;
if ( device ! = 0 )
tmp | = ATA_DEV1 ;
ep93xx_pata_write_reg ( drv_data , tmp , IDECTRL_ADDR_DEVICE ) ;
ata_sff_pause ( ap ) ; /* needed; also flushes, for mmio */
}
/* Note: original code is ata_sff_set_devctl */
static void ep93xx_pata_set_devctl ( struct ata_port * ap , u8 ctl )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
ep93xx_pata_write_reg ( drv_data , ctl , IDECTRL_ADDR_CTL ) ;
}
/* Note: original code is ata_sff_data_xfer */
2016-12-30 17:01:17 +03:00
static unsigned int ep93xx_pata_data_xfer ( struct ata_queued_cmd * qc ,
2012-04-12 16:13:16 +04:00
unsigned char * buf ,
unsigned int buflen , int rw )
{
2016-12-30 17:01:17 +03:00
struct ata_port * ap = qc - > dev - > link - > ap ;
2012-04-12 16:13:16 +04:00
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
u16 * data = ( u16 * ) buf ;
unsigned int words = buflen > > 1 ;
/* Transfer multiple of 2 bytes */
while ( words - - )
if ( rw = = READ )
* data + + = cpu_to_le16 (
ep93xx_pata_read_data (
drv_data , IDECTRL_ADDR_DATA ) ) ;
else
ep93xx_pata_write_data ( drv_data , le16_to_cpu ( * data + + ) ,
IDECTRL_ADDR_DATA ) ;
/* Transfer trailing 1 byte, if any. */
if ( unlikely ( buflen & 0x01 ) ) {
unsigned char pad [ 2 ] = { } ;
buf + = buflen - 1 ;
if ( rw = = READ ) {
* pad = cpu_to_le16 (
ep93xx_pata_read_data (
drv_data , IDECTRL_ADDR_DATA ) ) ;
* buf = pad [ 0 ] ;
} else {
pad [ 0 ] = * buf ;
ep93xx_pata_write_data ( drv_data , le16_to_cpu ( * pad ) ,
IDECTRL_ADDR_DATA ) ;
}
words + + ;
}
return words < < 1 ;
}
/* Note: original code is ata_devchk */
static bool ep93xx_pata_device_is_present ( struct ata_port * ap ,
unsigned int device )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
u8 nsect , lbal ;
ap - > ops - > sff_dev_select ( ap , device ) ;
ep93xx_pata_write_reg ( drv_data , 0x55 , IDECTRL_ADDR_NSECT ) ;
ep93xx_pata_write_reg ( drv_data , 0xaa , IDECTRL_ADDR_LBAL ) ;
ep93xx_pata_write_reg ( drv_data , 0xaa , IDECTRL_ADDR_NSECT ) ;
ep93xx_pata_write_reg ( drv_data , 0x55 , IDECTRL_ADDR_LBAL ) ;
ep93xx_pata_write_reg ( drv_data , 0x55 , IDECTRL_ADDR_NSECT ) ;
ep93xx_pata_write_reg ( drv_data , 0xaa , IDECTRL_ADDR_LBAL ) ;
nsect = ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_NSECT ) ;
lbal = ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_LBAL ) ;
if ( ( nsect = = 0x55 ) & & ( lbal = = 0xaa ) )
return true ;
return false ;
}
/* Note: original code is ata_sff_wait_after_reset */
static int ep93xx_pata_wait_after_reset ( struct ata_link * link ,
unsigned int devmask ,
unsigned long deadline )
{
struct ata_port * ap = link - > ap ;
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
unsigned int dev0 = devmask & ( 1 < < 0 ) ;
unsigned int dev1 = devmask & ( 1 < < 1 ) ;
int rc , ret = 0 ;
ata_msleep ( ap , ATA_WAIT_AFTER_RESET ) ;
/* always check readiness of the master device */
rc = ata_sff_wait_ready ( link , deadline ) ;
/*
* - ENODEV means the odd clown forgot the D7 pulldown resistor
* and TF status is 0xff , bail out on it too .
*/
if ( rc )
return rc ;
/*
* if device 1 was found in ata_devchk , wait for register
* access briefly , then wait for BSY to clear .
*/
if ( dev1 ) {
int i ;
ap - > ops - > sff_dev_select ( ap , 1 ) ;
/*
* Wait for register access . Some ATAPI devices fail
* to set nsect / lbal after reset , so don ' t waste too
* much time on it . We ' re gonna wait for ! BSY anyway .
*/
for ( i = 0 ; i < 2 ; i + + ) {
u8 nsect , lbal ;
nsect = ep93xx_pata_read_reg ( drv_data ,
IDECTRL_ADDR_NSECT ) ;
lbal = ep93xx_pata_read_reg ( drv_data ,
IDECTRL_ADDR_LBAL ) ;
if ( nsect = = 1 & & lbal = = 1 )
break ;
msleep ( 50 ) ; /* give drive a breather */
}
rc = ata_sff_wait_ready ( link , deadline ) ;
if ( rc ) {
if ( rc ! = - ENODEV )
return rc ;
ret = rc ;
}
}
/* is all this really necessary? */
ap - > ops - > sff_dev_select ( ap , 0 ) ;
if ( dev1 )
ap - > ops - > sff_dev_select ( ap , 1 ) ;
if ( dev0 )
ap - > ops - > sff_dev_select ( ap , 0 ) ;
return ret ;
}
/* Note: original code is ata_bus_softreset */
static int ep93xx_pata_bus_softreset ( struct ata_port * ap , unsigned int devmask ,
unsigned long deadline )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
ep93xx_pata_write_reg ( drv_data , ap - > ctl , IDECTRL_ADDR_CTL ) ;
udelay ( 20 ) ; /* FIXME: flush */
ep93xx_pata_write_reg ( drv_data , ap - > ctl | ATA_SRST , IDECTRL_ADDR_CTL ) ;
udelay ( 20 ) ; /* FIXME: flush */
ep93xx_pata_write_reg ( drv_data , ap - > ctl , IDECTRL_ADDR_CTL ) ;
ap - > last_ctl = ap - > ctl ;
return ep93xx_pata_wait_after_reset ( & ap - > link , devmask , deadline ) ;
}
static void ep93xx_pata_release_dma ( struct ep93xx_pata_data * drv_data )
{
if ( drv_data - > dma_rx_channel ) {
dma_release_channel ( drv_data - > dma_rx_channel ) ;
drv_data - > dma_rx_channel = NULL ;
}
if ( drv_data - > dma_tx_channel ) {
dma_release_channel ( drv_data - > dma_tx_channel ) ;
drv_data - > dma_tx_channel = NULL ;
}
}
static bool ep93xx_pata_dma_filter ( struct dma_chan * chan , void * filter_param )
{
if ( ep93xx_dma_chan_is_m2p ( chan ) )
return false ;
chan - > private = filter_param ;
return true ;
}
static void ep93xx_pata_dma_init ( struct ep93xx_pata_data * drv_data )
{
const struct platform_device * pdev = drv_data - > pdev ;
dma_cap_mask_t mask ;
struct dma_slave_config conf ;
dma_cap_zero ( mask ) ;
dma_cap_set ( DMA_SLAVE , mask ) ;
/*
* Request two channels for IDE . Another possibility would be
* to request only one channel , and reprogram it ' s direction at
* start of new transfer .
*/
drv_data - > dma_rx_data . port = EP93XX_DMA_IDE ;
2018-10-04 05:37:54 +03:00
drv_data - > dma_rx_data . direction = DMA_DEV_TO_MEM ;
2012-04-12 16:13:16 +04:00
drv_data - > dma_rx_data . name = " ep93xx-pata-rx " ;
drv_data - > dma_rx_channel = dma_request_channel ( mask ,
ep93xx_pata_dma_filter , & drv_data - > dma_rx_data ) ;
if ( ! drv_data - > dma_rx_channel )
return ;
drv_data - > dma_tx_data . port = EP93XX_DMA_IDE ;
2018-10-04 05:37:54 +03:00
drv_data - > dma_tx_data . direction = DMA_MEM_TO_DEV ;
2012-04-12 16:13:16 +04:00
drv_data - > dma_tx_data . name = " ep93xx-pata-tx " ;
drv_data - > dma_tx_channel = dma_request_channel ( mask ,
ep93xx_pata_dma_filter , & drv_data - > dma_tx_data ) ;
if ( ! drv_data - > dma_tx_channel ) {
dma_release_channel ( drv_data - > dma_rx_channel ) ;
return ;
}
/* Configure receive channel direction and source address */
memset ( & conf , 0 , sizeof ( conf ) ) ;
2018-10-04 05:37:54 +03:00
conf . direction = DMA_DEV_TO_MEM ;
2012-04-12 16:13:16 +04:00
conf . src_addr = drv_data - > udma_in_phys ;
conf . src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES ;
if ( dmaengine_slave_config ( drv_data - > dma_rx_channel , & conf ) ) {
dev_err ( & pdev - > dev , " failed to configure rx dma channel \n " ) ;
ep93xx_pata_release_dma ( drv_data ) ;
return ;
}
/* Configure transmit channel direction and destination address */
memset ( & conf , 0 , sizeof ( conf ) ) ;
2018-10-04 05:37:54 +03:00
conf . direction = DMA_MEM_TO_DEV ;
2012-04-12 16:13:16 +04:00
conf . dst_addr = drv_data - > udma_out_phys ;
conf . dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES ;
if ( dmaengine_slave_config ( drv_data - > dma_tx_channel , & conf ) ) {
dev_err ( & pdev - > dev , " failed to configure tx dma channel \n " ) ;
ep93xx_pata_release_dma ( drv_data ) ;
}
}
static void ep93xx_pata_dma_start ( struct ata_queued_cmd * qc )
{
struct dma_async_tx_descriptor * txd ;
struct ep93xx_pata_data * drv_data = qc - > ap - > host - > private_data ;
void __iomem * base = drv_data - > ide_base ;
struct ata_device * adev = qc - > dev ;
u32 v = qc - > dma_dir = = DMA_TO_DEVICE ? IDEUDMAOP_RWOP : 0 ;
struct dma_chan * channel = qc - > dma_dir = = DMA_TO_DEVICE
? drv_data - > dma_tx_channel : drv_data - > dma_rx_channel ;
2014-05-25 13:19:05 +04:00
txd = dmaengine_prep_slave_sg ( channel , qc - > sg , qc - > n_elem , qc - > dma_dir ,
DMA_CTRL_ACK ) ;
2012-04-12 16:13:16 +04:00
if ( ! txd ) {
dev_err ( qc - > ap - > dev , " failed to prepare slave for sg dma \n " ) ;
return ;
}
txd - > callback = NULL ;
txd - > callback_param = NULL ;
if ( dmaengine_submit ( txd ) < 0 ) {
dev_err ( qc - > ap - > dev , " failed to submit dma transfer \n " ) ;
return ;
}
dma_async_issue_pending ( channel ) ;
/*
* When enabling UDMA operation , IDEUDMAOP register needs to be
* programmed in three step sequence :
* 1 ) set or clear the RWOP bit ,
* 2 ) perform dummy read of the register ,
* 3 ) set the UEN bit .
*/
writel ( v , base + IDEUDMAOP ) ;
readl ( base + IDEUDMAOP ) ;
writel ( v | IDEUDMAOP_UEN , base + IDEUDMAOP ) ;
writel ( IDECFG_IDEEN | IDECFG_UDMA |
( ( adev - > xfer_mode - XFER_UDMA_0 ) < < IDECFG_MODE_SHIFT ) ,
base + IDECFG ) ;
}
static void ep93xx_pata_dma_stop ( struct ata_queued_cmd * qc )
{
struct ep93xx_pata_data * drv_data = qc - > ap - > host - > private_data ;
void __iomem * base = drv_data - > ide_base ;
/* terminate all dma transfers, if not yet finished */
dmaengine_terminate_all ( drv_data - > dma_rx_channel ) ;
dmaengine_terminate_all ( drv_data - > dma_tx_channel ) ;
/*
* To properly stop IDE - DMA , IDEUDMAOP register must to be cleared
* and IDECTRL register must be set to default value .
*/
writel ( 0 , base + IDEUDMAOP ) ;
writel ( readl ( base + IDECTRL ) | IDECTRL_DIOWN | IDECTRL_DIORN |
IDECTRL_CS0N | IDECTRL_CS1N , base + IDECTRL ) ;
ep93xx_pata_enable_pio ( drv_data - > ide_base ,
qc - > dev - > pio_mode - XFER_PIO_0 ) ;
ata_sff_dma_pause ( qc - > ap ) ;
}
static void ep93xx_pata_dma_setup ( struct ata_queued_cmd * qc )
{
qc - > ap - > ops - > sff_exec_command ( qc - > ap , & qc - > tf ) ;
}
static u8 ep93xx_pata_dma_status ( struct ata_port * ap )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
u32 val = readl ( drv_data - > ide_base + IDEUDMASTS ) ;
/*
* UDMA Status Register bits :
*
* DMAIDE - DMA request signal from UDMA state machine ,
* INTIDE - INT line generated by UDMA because of errors in the
* state machine ,
* SBUSY - UDMA state machine busy , not in idle state ,
* NDO - error for data - out not completed ,
* NDI - error for data - in not completed ,
* N4X - error for data transferred not multiplies of four
* 32 - bit words .
* ( EP93xx UG p27 - 17 )
*/
if ( val & IDEUDMASTS_NDO | | val & IDEUDMASTS_NDI | |
val & IDEUDMASTS_N4X | | val & IDEUDMASTS_INTIDE )
return ATA_DMA_ERR ;
/* read INTRQ (INT[3]) pin input state */
if ( readl ( drv_data - > ide_base + IDECTRL ) & IDECTRL_INTRQ )
return ATA_DMA_INTR ;
if ( val & IDEUDMASTS_SBUSY | | val & IDEUDMASTS_DMAIDE )
return ATA_DMA_ACTIVE ;
return 0 ;
}
/* Note: original code is ata_sff_softreset */
static int ep93xx_pata_softreset ( struct ata_link * al , unsigned int * classes ,
unsigned long deadline )
{
struct ata_port * ap = al - > ap ;
unsigned int slave_possible = ap - > flags & ATA_FLAG_SLAVE_POSS ;
unsigned int devmask = 0 ;
int rc ;
u8 err ;
/* determine if device 0/1 are present */
if ( ep93xx_pata_device_is_present ( ap , 0 ) )
devmask | = ( 1 < < 0 ) ;
if ( slave_possible & & ep93xx_pata_device_is_present ( ap , 1 ) )
devmask | = ( 1 < < 1 ) ;
/* select device 0 again */
ap - > ops - > sff_dev_select ( al - > ap , 0 ) ;
/* issue bus reset */
rc = ep93xx_pata_bus_softreset ( ap , devmask , deadline ) ;
/* if link is ocuppied, -ENODEV too is an error */
if ( rc & & ( rc ! = - ENODEV | | sata_scr_valid ( al ) ) ) {
2012-12-04 08:30:55 +04:00
ata_link_err ( al , " SRST failed (errno=%d) \n " , rc ) ;
2012-04-12 16:13:16 +04:00
return rc ;
}
/* determine by signature whether we have ATA or ATAPI devices */
classes [ 0 ] = ata_sff_dev_classify ( & al - > device [ 0 ] , devmask & ( 1 < < 0 ) ,
& err ) ;
if ( slave_possible & & err ! = 0x81 )
classes [ 1 ] = ata_sff_dev_classify ( & al - > device [ 1 ] ,
devmask & ( 1 < < 1 ) , & err ) ;
return 0 ;
}
/* Note: original code is ata_sff_drain_fifo */
static void ep93xx_pata_drain_fifo ( struct ata_queued_cmd * qc )
{
int count ;
struct ata_port * ap ;
struct ep93xx_pata_data * drv_data ;
/* We only need to flush incoming data when a command was running */
if ( qc = = NULL | | qc - > dma_dir = = DMA_TO_DEVICE )
return ;
ap = qc - > ap ;
drv_data = ap - > host - > private_data ;
/* Drain up to 64K of data before we give up this recovery method */
for ( count = 0 ; ( ap - > ops - > sff_check_status ( ap ) & ATA_DRQ )
& & count < 65536 ; count + = 2 )
ep93xx_pata_read_reg ( drv_data , IDECTRL_ADDR_DATA ) ;
/* Can become DEBUG later */
if ( count )
2012-12-04 08:30:55 +04:00
ata_port_dbg ( ap , " drained %d bytes to clear DRQ. \n " , count ) ;
2012-04-12 16:13:16 +04:00
}
static int ep93xx_pata_port_start ( struct ata_port * ap )
{
struct ep93xx_pata_data * drv_data = ap - > host - > private_data ;
/*
* Set timings to safe values at startup ( = number of ns from ATA
* specification ) , we ' ll switch to properly calculated values later .
*/
drv_data - > t = * ata_timing_find_mode ( XFER_PIO_0 ) ;
return 0 ;
}
static struct scsi_host_template ep93xx_pata_sht = {
ATA_BASE_SHT ( DRV_NAME ) ,
/* ep93xx dma implementation limit */
. sg_tablesize = 32 ,
/* ep93xx dma can't transfer 65536 bytes at once */
. dma_boundary = 0x7fff ,
} ;
static struct ata_port_operations ep93xx_pata_port_ops = {
. inherits = & ata_bmdma_port_ops ,
. qc_prep = ata_noop_qc_prep ,
. softreset = ep93xx_pata_softreset ,
. hardreset = ATA_OP_NULL ,
. sff_dev_select = ep93xx_pata_dev_select ,
. sff_set_devctl = ep93xx_pata_set_devctl ,
. sff_check_status = ep93xx_pata_check_status ,
. sff_check_altstatus = ep93xx_pata_check_altstatus ,
. sff_tf_load = ep93xx_pata_tf_load ,
. sff_tf_read = ep93xx_pata_tf_read ,
. sff_exec_command = ep93xx_pata_exec_command ,
. sff_data_xfer = ep93xx_pata_data_xfer ,
. sff_drain_fifo = ep93xx_pata_drain_fifo ,
. sff_irq_clear = ATA_OP_NULL ,
. set_piomode = ep93xx_pata_set_piomode ,
. bmdma_setup = ep93xx_pata_dma_setup ,
. bmdma_start = ep93xx_pata_dma_start ,
. bmdma_stop = ep93xx_pata_dma_stop ,
. bmdma_status = ep93xx_pata_dma_status ,
. cable_detect = ata_cable_unknown ,
. port_start = ep93xx_pata_port_start ,
} ;
2012-12-22 01:19:58 +04:00
static int ep93xx_pata_probe ( struct platform_device * pdev )
2012-04-12 16:13:16 +04:00
{
struct ep93xx_pata_data * drv_data ;
struct ata_host * host ;
struct ata_port * ap ;
2014-07-17 16:13:23 +04:00
int irq ;
2012-04-12 16:13:16 +04:00
struct resource * mem_res ;
void __iomem * ide_base ;
int err ;
err = ep93xx_ide_acquire_gpio ( pdev ) ;
if ( err )
return err ;
/* INT[3] (IRQ_EP93XX_EXT3) line connected as pull down */
irq = platform_get_irq ( pdev , 0 ) ;
if ( irq < 0 ) {
err = - ENXIO ;
goto err_rel_gpio ;
}
mem_res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2013-01-21 14:08:58 +04:00
ide_base = devm_ioremap_resource ( & pdev - > dev , mem_res ) ;
if ( IS_ERR ( ide_base ) ) {
err = PTR_ERR ( ide_base ) ;
2012-04-12 16:13:16 +04:00
goto err_rel_gpio ;
}
drv_data = devm_kzalloc ( & pdev - > dev , sizeof ( * drv_data ) , GFP_KERNEL ) ;
if ( ! drv_data ) {
err = - ENXIO ;
goto err_rel_gpio ;
}
drv_data - > pdev = pdev ;
drv_data - > ide_base = ide_base ;
drv_data - > udma_in_phys = mem_res - > start + IDEUDMADATAIN ;
drv_data - > udma_out_phys = mem_res - > start + IDEUDMADATAOUT ;
ep93xx_pata_dma_init ( drv_data ) ;
/* allocate host */
host = ata_host_alloc ( & pdev - > dev , 1 ) ;
if ( ! host ) {
err = - ENXIO ;
goto err_rel_dma ;
}
ep93xx_pata_clear_regs ( ide_base ) ;
host - > private_data = drv_data ;
ap = host - > ports [ 0 ] ;
ap - > dev = & pdev - > dev ;
ap - > ops = & ep93xx_pata_port_ops ;
ap - > flags | = ATA_FLAG_SLAVE_POSS ;
ap - > pio_mask = ATA_PIO4 ;
/*
* Maximum UDMA modes :
* EP931x rev . E0 - UDMA2
* EP931x rev . E1 - UDMA3
* EP931x rev . E2 - UDMA4
*
* MWDMA support was removed from EP931x rev . E2 ,
* so this driver supports only UDMA modes .
*/
if ( drv_data - > dma_rx_channel & & drv_data - > dma_tx_channel ) {
int chip_rev = ep93xx_chip_revision ( ) ;
if ( chip_rev = = EP93XX_CHIP_REV_E1 )
ap - > udma_mask = ATA_UDMA3 ;
else if ( chip_rev = = EP93XX_CHIP_REV_E2 )
ap - > udma_mask = ATA_UDMA4 ;
else
ap - > udma_mask = ATA_UDMA2 ;
}
/* defaults, pio 0 */
ep93xx_pata_enable_pio ( ide_base , 0 ) ;
dev_info ( & pdev - > dev , " version " DRV_VERSION " \n " ) ;
/* activate host */
err = ata_host_activate ( host , irq , ata_bmdma_interrupt , 0 ,
& ep93xx_pata_sht ) ;
if ( err = = 0 )
return 0 ;
err_rel_dma :
ep93xx_pata_release_dma ( drv_data ) ;
err_rel_gpio :
ep93xx_ide_release_gpio ( pdev ) ;
return err ;
}
2012-12-22 01:19:58 +04:00
static int ep93xx_pata_remove ( struct platform_device * pdev )
2012-04-12 16:13:16 +04:00
{
struct ata_host * host = platform_get_drvdata ( pdev ) ;
struct ep93xx_pata_data * drv_data = host - > private_data ;
ata_host_detach ( host ) ;
ep93xx_pata_release_dma ( drv_data ) ;
ep93xx_pata_clear_regs ( drv_data - > ide_base ) ;
ep93xx_ide_release_gpio ( pdev ) ;
return 0 ;
}
static struct platform_driver ep93xx_pata_platform_driver = {
. driver = {
. name = DRV_NAME ,
} ,
. probe = ep93xx_pata_probe ,
2012-12-22 01:19:58 +04:00
. remove = ep93xx_pata_remove ,
2012-04-12 16:13:16 +04:00
} ;
module_platform_driver ( ep93xx_pata_platform_driver ) ;
MODULE_AUTHOR ( " Alessandro Zummo, Lennert Buytenhek, Joao Ramos, "
" Bartlomiej Zolnierkiewicz, Rafal Prylowski " ) ;
MODULE_DESCRIPTION ( " low-level driver for cirrus ep93xx IDE controller " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_VERSION ( DRV_VERSION ) ;
MODULE_ALIAS ( " platform:pata_ep93xx " ) ;