[PATCH v5] libata: pata_samsung: Add Samsung PATA controller driver

Kukjin Kim kgene.kim at samsung.com
Wed Jun 30 06:39:25 EDT 2010


Maurus Cuelenaere wrote:
> 
Hi Maurus :-)

>  Op 29-06-10 13:05, Kukjin Kim schreef:
> > From: Abhilash Kesavan <a.kesavan at samsung.com>
> >
> > Adds support for the Samsung PATA controller. This driver is based on the
> > Libata subsystem and references the earlier patches sent for IDE subsystem.
> >
> > Signed-off-by: Abhilash Kesavan <a.kesavan at samsung.com>
> > Signed-off-by: Kukjin Kim <kgene.kim at samsung.com>
> > Cc: Ben Dooks <ben-linux at fluff.org>
> > ---
> >  drivers/ata/Kconfig           |    9 +
> >  drivers/ata/Makefile          |    1 +
> >  drivers/ata/pata_samsung_cf.c |  728
> +++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 738 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/ata/pata_samsung_cf.c
> >
> > diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
> > index 73f8833..51e28e7 100644
> > --- a/drivers/ata/Kconfig
> > +++ b/drivers/ata/Kconfig
> > @@ -796,6 +796,15 @@ config PATA_RZ1000
> >
> >  	  If unsure, say N.
> >
> > +config PATA_SAMSUNG_CF
> > +	tristate "Samsung SoC PATA support"
> > +	depends on SAMSUNG_DEV_IDE
> > +	help
> > +	  This option enables basic support for Samsung's S3C/S5P board
> > +	  PATA controllers via the new ATA layer
> > +
> > +	  If unsure, say N.
> > +
> >  config PATA_WINBOND_VLB
> >  	tristate "Winbond W83759A VLB PATA support (Experimental)"
> >  	depends on ISA && EXPERIMENTAL
> > diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
> > index 7ef89d7..9576776 100644
> > --- a/drivers/ata/Makefile
> > +++ b/drivers/ata/Makefile
> > @@ -87,6 +87,7 @@ obj-$(CONFIG_PATA_OF_PLATFORM)	+=
> pata_of_platform.o
> >  obj-$(CONFIG_PATA_QDI)		+= pata_qdi.o
> >  obj-$(CONFIG_PATA_RB532)	+= pata_rb532_cf.o
> >  obj-$(CONFIG_PATA_RZ1000)	+= pata_rz1000.o
> > +obj-$(CONFIG_PATA_SAMSUNG_CF)	+= pata_samsung_cf.o
> >  obj-$(CONFIG_PATA_WINBOND_VLB)	+= pata_winbond.o
> >
> >  # Should be last but two libata driver
> > diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c
> > new file mode 100644
> > index 0000000..26b96c3
> > --- /dev/null
> > +++ b/drivers/ata/pata_samsung_cf.c
> > @@ -0,0 +1,728 @@
> > +/*
> > + * Copyright (c) 2010 Samsung Electronics Co., Ltd.
> > + *		http://www.samsung.com
> > + *
> > + * PATA driver for Samsung SoCs.
> > + * Supports CF Interface in True IDE mode. Currently only PIO mode has been
> > + * implemented; UDMA support has to be added.
> > + *
> > + * Based on:
> > + *	PATA driver for AT91SAM9260 Static Memory Controller
> > + *	PATA driver for Toshiba SCC controller
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms of the GNU General Public License version 2
> > + * as published by the Free Software Foundation.
> > +*/
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/init.h>
> > +#include <linux/clk.h>
> > +#include <linux/libata.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/slab.h>
> > +
> > +#include <plat/ata.h>
> > +#include <plat/regs-ata.h>
> > +
> > +#define DRV_NAME "pata_samsung_cf"
> > +#define DRV_VERSION "0.1"
> > +
> > +enum s3c_cpu_type {
> > +	TYPE_S3C64XX,
> > +	TYPE_S5PC100,
> > +	TYPE_S5PV210,
> > +};
> > +
> > +/*
> > + * struct s3c_ide_info - S3C PATA instance.
> > + * @clk: The clock resource for this controller.
> > + * @ide_addr: The area mapped for the hardware registers.
> > + * @sfr_addr: The area mapped for the special function registers.
> > + * @irq: The IRQ number we are using.
> > + * @cpu_type: The exact type of this controller.
> > + * @fifo_status_reg: The ATA_FIFO_STATUS register offset.
> > + */
> > +struct s3c_ide_info {
> > +	struct clk *clk;
> > +	void __iomem *ide_addr;
> > +	void __iomem *sfr_addr;
> > +	unsigned int irq;
> > +	enum s3c_cpu_type cpu_type;
> > +	unsigned int fifo_status_reg;
> > +};
> > +
> > +static void pata_s3c_set_endian(void __iomem *s3c_ide_regbase, u8 mode)
> > +{
> > +	u32 reg = readl(s3c_ide_regbase + S3C_ATA_CFG);
> > +	reg = mode ? (reg & ~S3C_ATA_CFG_SWAP) : (reg |
> S3C_ATA_CFG_SWAP);
> > +	writel(reg, s3c_ide_regbase + S3C_ATA_CFG);
> > +}
> > +
> > +static void pata_s3c_cfg_mode(void __iomem *s3c_ide_sfrbase)
> > +{
> > +	/* Select true-ide as the internal operating mode */
> > +	writel(readl(s3c_ide_sfrbase + S3C_CFATA_MUX) |
> S3C_CFATA_MUX_TRUEIDE,
> > +		s3c_ide_sfrbase + S3C_CFATA_MUX);
> > +}
> > +
> > +static unsigned long
> > +pata_s3c_setup_timing(struct s3c_ide_info *info, const struct ata_timing *ata)
> > +{
> > +	int t1 = ata->setup;
> > +	int t2 = ata->act8b;
> > +	int t2i = ata->rec8b;
> > +	ulong piotime;
> > +
> > +	piotime = ((t2i & 0xff) << 12) | ((t2 & 0xff) << 4) | (t1 & 0xf);
> > +
> > +	return piotime;
> > +}
> > +
> > +static void pata_s3c_set_piomode(struct ata_port *ap, struct ata_device *adev)
> > +{
> > +	struct s3c_ide_info *info = ap->host->private_data;
> > +	struct ata_timing timing;
> > +	int cycle_time;
> > +	ulong ata_cfg = readl(info->ide_addr + S3C_ATA_CFG);
> > +	ulong piotime;
> > +
> > +	/* Enables IORDY if mode requires it */
> > +	if (ata_pio_need_iordy(adev))
> > +		ata_cfg |= S3C_ATA_CFG_IORDYEN;
> > +	else
> > +		ata_cfg &= ~S3C_ATA_CFG_IORDYEN;
> > +
> > +	cycle_time = (int)(1000000000UL / clk_get_rate(info->clk));
> > +
> > +	ata_timing_compute(adev, adev->pio_mode, &timing,
> > +					cycle_time * 1000, 0);
> > +
> > +	piotime = pata_s3c_setup_timing(info, &timing);
> > +
> > +	writel(ata_cfg, info->ide_addr + S3C_ATA_CFG);
> > +	writel(piotime, info->ide_addr + S3C_ATA_PIO_TIME);
> > +}
> > +
> > +/*
> > + * Waits until the IDE controller is able to perform next read/write
> > + * operation to the disk. Needed for 64XX series boards only.
> > + */
> > +static int wait_for_host_ready(struct s3c_ide_info *info)
> > +{
> > +	ulong timeout;
> > +	void __iomem *fifo_reg = info->ide_addr + info->fifo_status_reg;
> > +
> 
> Shouldn't this have an if (type != S3C64XX) return 0; ?
> 
Actually, wait_for_host_ready() is called only by pata_s3c_port_ops methods which applies specifically to s3c64xx.

> > +	/* wait for maximum of 20 msec */
> > +	timeout = jiffies + msecs_to_jiffies(20);
> > +	while (time_before(jiffies, timeout)) {
> > +		if ((readl(fifo_reg) >> 28) == 0)
> > +			return 0;
> > +	}
> > +	return -EBUSY;
> > +}
> 
> --


Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim at samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.




More information about the linux-arm-kernel mailing list