Commit 2ca997e5 authored by Andrey Filippov's avatar Andrey Filippov


parents 67bbf1dd b2a72326
This diff is collapsed.
obj-$(CONFIG_ATA) += libata.o
# non-SFF interface
obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o libahci_debug.o
obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o
obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o libahci_debug.o
obj-$(CONFIG_AHCI_ELPHEL) += ahci_elphel.o libahci.o libahci_platform.o libahci_debug.o
obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_ST) += ahci_st.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_TEGRA) += ahci_tegra.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_XGENE) += ahci_xgene.o libahci.o libahci_platform.o
# SFF w/ custom DMA
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
obj-$(CONFIG_PATA_ARASAN_CF) += pata_arasan_cf.o
obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o
obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o
obj-$(CONFIG_SATA_SX4) += sata_sx4.o
obj-$(CONFIG_ATA_PIIX) += ata_piix.o
obj-$(CONFIG_SATA_MV) += sata_mv.o
obj-$(CONFIG_SATA_NV) += sata_nv.o
obj-$(CONFIG_SATA_PROMISE) += sata_promise.o
obj-$(CONFIG_SATA_RCAR) += sata_rcar.o
obj-$(CONFIG_SATA_SIL) += sata_sil.o
obj-$(CONFIG_SATA_SIS) += sata_sis.o
obj-$(CONFIG_SATA_SVW) += sata_svw.o
obj-$(CONFIG_SATA_ULI) += sata_uli.o
obj-$(CONFIG_SATA_VIA) += sata_via.o
obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o
obj-$(CONFIG_PATA_ALI) += pata_ali.o
obj-$(CONFIG_PATA_AMD) += pata_amd.o
obj-$(CONFIG_PATA_ARTOP) += pata_artop.o
obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o
obj-$(CONFIG_PATA_ATP867X) += pata_atp867x.o
obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o
obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o
obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o
obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o
obj-$(CONFIG_PATA_CS5535) += pata_cs5535.o
obj-$(CONFIG_PATA_CS5536) += pata_cs5536.o
obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o
obj-$(CONFIG_PATA_EFAR) += pata_efar.o
obj-$(CONFIG_PATA_EP93XX) += pata_ep93xx.o
obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o
obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o
obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o
obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o
obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
obj-$(CONFIG_PATA_IMX) += pata_imx.o
obj-$(CONFIG_PATA_IT8213) += pata_it8213.o
obj-$(CONFIG_PATA_IT821X) += pata_it821x.o
obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o
obj-$(CONFIG_PATA_MACIO) += pata_macio.o
obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o
obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o
obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o
obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
obj-$(CONFIG_PATA_PDC2027X) += pata_pdc2027x.o
obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o
obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o
obj-$(CONFIG_PATA_RDC) += pata_rdc.o
obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o
obj-$(CONFIG_PATA_SCC) += pata_scc.o
obj-$(CONFIG_PATA_SCH) += pata_sch.o
obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o
obj-$(CONFIG_PATA_SIL680) += pata_sil680.o
obj-$(CONFIG_PATA_SIS) += pata_sis.o
obj-$(CONFIG_PATA_TOSHIBA) += pata_piccolo.o
obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
obj-$(CONFIG_PATA_VIA) += pata_via.o
obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o
# SFF PIO only
obj-$(CONFIG_PATA_AT32) += pata_at32.o
obj-$(CONFIG_PATA_AT91) += pata_at91.o
obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o
obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o
obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
obj-$(CONFIG_PATA_OPTI) += pata_opti.o
obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.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_PXA) += pata_pxa.o
# Should be last but two libata driver
obj-$(CONFIG_PATA_ACPI) += pata_acpi.o
# Should be last but one libata driver
obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
libata-y := libata-core.o libata-scsi.o libata-eh.o libata-transport.o
libata-$(CONFIG_ATA_SFF) += libata-sff.o
libata-$(CONFIG_SATA_PMP) += libata-pmp.o
libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
libata-$(CONFIG_SATA_ZPODD) += libata-zpodd.o
......@@ -19,13 +19,14 @@
#include <linux/ahci_platform.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include "ahci.h"
#include "libahci_debug.h"
#define DRV_NAME "elphel-ahci"
#define MARKER "+"
/* Property names from device tree, these are specific for the controller */
#define PROP_NAME_CLB_OFFS "clb_offs"
......@@ -39,6 +40,7 @@ static const struct of_device_id ahci_elphel_of_match[];
struct elphel_ahci_priv {
u32 clb_offs;
u32 fb_offs;
u32 base_addr;
static int elphel_port_start(struct ata_port *ap)
......@@ -50,8 +52,12 @@ static int elphel_port_start(struct ata_port *ap)
struct ahci_host_priv *hpriv = ap->host->private_data;
const struct elphel_ahci_priv *dpriv = hpriv->plat_data;
dev_info(dev, "starting port %d", ap->port_no);
/*pp = devm_kzalloc(dev, sizeof(struct ahci_port_priv), GFP_KERNEL);
pp = devm_kzalloc(dev, sizeof(struct ahci_port_priv), GFP_KERNEL);
if (!pp)
return -ENOMEM;
......@@ -60,34 +66,47 @@ static int elphel_port_start(struct ata_port *ap)
return -ENOMEM;
memset(mem, 0, AHCI_CMD_TBL_AR_SZ);
pp->cmd_tbl = mem;
pp->cmd_tbl_dma = mem_dma;*/
pp->cmd_tbl_dma = mem_dma;
* Set predefined addresses
/*pp->cmd_slot = hpriv->mmio + dpriv->clb_offs;
pp->cmd_slot_dma = virt_to_phys(pp->cmd_slot);
pp->cmd_slot = hpriv->mmio + dpriv->clb_offs;
//pp->cmd_slot_dma = virt_to_phys(pp->cmd_slot);
pp->cmd_slot_dma = 0x80000000 + dpriv->clb_offs;
pp->rx_fis = hpriv->mmio + dpriv->fb_offs;
pp->rx_fis_dma = virt_to_phys(pp->rx_fis);*/
//pp->rx_fis_dma = virt_to_phys(pp->rx_fis);
pp->rx_fis_dma = 0x80000000 + dpriv->fb_offs;
/*dev_info(dev, "cmd_slot: 0x%p", pp->cmd_slot);
dev_info(dev, "cmd_slot_dma: 0x%08u", pp->cmd_slot_dma);
dev_info(dev, "rx_fis: 0x%p", pp->rx_fis);
dev_info(dev, "rx_fis_dma: 0x%08u", pp->rx_fis_dma);
dev_info(dev, "base_addr: 0x%08u", dpriv->base_addr);*/
* Save off initial list of interrupts to be enabled.
* This could be changed later
/*pp->intr_mask = DEF_PORT_IRQ;
pp->intr_mask = DEF_PORT_IRQ;
ap->private_data = pp;
return ahci_port_resume(ap);*/
return 0;
return ahci_port_resume(ap);
static int elphel_parse_prop(const struct device_node *devn,
struct device *dev,
struct elphel_ahci_priv *dpriv)
u64 size;
unsigned int flags;
const __be32 *val;
struct resource res;
if (!devn) {
dev_err(dev, "device tree node is not found");
......@@ -98,6 +117,14 @@ static int elphel_parse_prop(const struct device_node *devn,
dpriv->clb_offs = be32_to_cpup(val);
val = of_get_property(devn, PROP_NAME_FB_OFFS, NULL);
dpriv->fb_offs = be32_to_cpup(val);
val = of_get_address(devn, 0, NULL, NULL);
if (val != NULL) {
dpriv->base_addr = be32_to_cpu(val);
dev_info(dev, "base_addr: 0x%08u", dpriv->base_addr);
} else {
dev_err(dev, "can not get register address");
//of_address_to_resource(devn, 0, &res);
return 0;
......@@ -109,11 +136,12 @@ static int elphel_drv_probe(struct platform_device *pdev)
struct elphel_ahci_priv *drv_priv;
struct device *dev = &pdev->dev;
const struct of_device_id *match;
void __iomem *mmio = NULL;
struct resource *res;
unsigned int reg_val;
dev_info(&pdev->dev, "probing Elphel AHCI driver");
drv_priv = devm_kzalloc(dev, sizeof(struct elphel_ahci_priv), GFP_KERNEL);
if (!drv_priv)
return -ENOMEM;
......@@ -126,39 +154,44 @@ static int elphel_drv_probe(struct platform_device *pdev)
if (ret != 0)
return ret;
/*hpriv = ahci_platform_get_resources(pdev);
hpriv = ahci_platform_get_resources(pdev);
if (IS_ERR(hpriv))
return PTR_ERR(hpriv);
hpriv->plat_data = drv_priv;
dev_info(dev, "ahci platform resources set");*/
dev_info(dev, "get IORESOURCE_MEM");
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "can not get resourse");
return -EINVAL;
dev_info(dev, "resource name: %s", res->name);
dev_info(dev, "resource start: 0x%08x", res->start);
dev_info(dev, "resource end: 0x%08x", res->end);
/*mmio = hpriv->mmio;
if (!mmio) {
dev_err(dev, "mmio pointer is not initialized");
return -EINVAL;
dev_info(dev, "mmio pointer: 0x%08p", mmio);
dev_info(dev, "HOST CAP register: 0x%08x", readl(mmio + HOST_CAP));
hpriv->plat_data = drv_priv;
/*ret = ahci_platform_init_host(pdev, hpriv, &ahci_elphel_port_info,
reg_val = readl(hpriv->mmio + HOST_CAP);
dev_info(dev, "HOST CAP register: 0x%08x", reg_val);
reg_val = readl(hpriv->mmio + HOST_CTL);
dev_info(dev, "HOST GHC register: 0x%08x", reg_val);
reg_val = readl(hpriv->mmio + HOST_IRQ_STAT);
dev_info(dev, "HOST IS register: 0x%08x", reg_val);
reg_val = readl(hpriv->mmio + HOST_PORTS_IMPL);
dev_info(dev, "HOST PI register: 0x%08x", reg_val);
reg_val = readl(hpriv->mmio + HOST_VERSION);
dev_info(dev, "HOST VS register: 0x%08x", reg_val);
phys_addr_t paddr = virt_to_phys(hpriv->mmio);
void *vaddr = phys_to_virt(paddr);
dev_err(dev, "current mmio virt addr: 0x%p\n", hpriv->mmio);
dev_err(dev, "current mmio virt addr as uint: 0x%08x\n", hpriv->mmio);
dev_err(dev, "mmio phys addr: 0x%08x\n", paddr);
dev_err(dev, "mmio phys addr as tr: 0x%p\n", paddr);
dev_err(dev, "back converted mmio virt addr: 0x%p\n", vaddr);
//printk(KERN_DEBUG, "current mmio virt addr: %p\n", hpriv->mmio);
//printk(KERN_DEBUG, "mmio phys addr: %u\n", paddr);
//printk(KERN_DEBUG, "back converted mmio virt addr: %p\n", vaddr);
printk(KERN_DEBUG "======");
ret = ahci_platform_init_host(pdev, hpriv, &ahci_elphel_port_info,
if (ret) {
dev_err(dev, "can not initialize platform host");
return ret;
dev_info(dev, "ahci platform host initialized");*/
dev_info(dev, "ahci platform host initialized");
return 0;
......@@ -166,12 +199,30 @@ static int elphel_drv_probe(struct platform_device *pdev)
static int elphel_drv_remove(struct platform_device *pdev)
dev_info(&pdev->dev, "removing Elphel AHCI driver");
return 0;
static unsigned int elphel_read_id(struct ata_device *dev, struct ata_taskfile *tf, u16 *id)
u32 err_mask;
struct device *d = &dev->tdev;
err_mask = ata_do_dev_read_id(dev, tf, id);
if (err_mask)
return err_mask;
dev_info(d, "issue identify command");
return 0;
static struct ata_port_operations ahci_elphel_ops = {
.inherits = &ahci_ops,
.port_start = elphel_port_start,
.read_id = elphel_read_id,
static const struct ata_port_info ahci_elphel_port_info = {
This diff is collapsed.
This diff is collapsed.
* libahci_debug.h
* Created on: Jan 20, 2016
* Author: mk
#include "ahci.h"
#define ROOT_DIR_NAME "ahci_exp"
#define FILE_NAME_CFIS "cfis"
#define FILE_NAME_CHDR "chdr"
#define MARKER "++"
#define EVT_MARKER ">"
#define CMD_FIS_SZ 20
#define CMD_HDR_SZ 16
#define CMD_DMA_BUFSZ 512
#define PORT_RESERVED_2 40
/* Total size of dump buffer in bytes*/
#define SEGMENT_SIZE 0x10000
/* The sizes below are in DWORDs*/
#define GHC_SZ 0x0B
#define PORT_REG_SZ 0x20
#define CLB_SZ 0x08
#define FIS_SZ 0x40
#define DUMP_LEN 0x240
/* The length of delimiter line in memory */
#define MARKER_LEN 0x10
/* Offset to the end of nearest 16 DWORD string */
#define ALIGN_OFFSET 0x0d
struct libahci_debug_list {
unsigned int debug;
unsigned int port_n;
char *libahci_debug_buf;
int head;
int tail;
struct list_head node;
struct mutex read_mutex;
wait_queue_head_t debug_wait;
spinlock_t debug_list_lock;
struct ahci_cmd_fis {
__le32 dw0;
__le32 dw1;
__le32 dw2;
__le32 dw3;
__le32 dw4;
struct ahci_cmd {
struct ahci_cmd_hdr hdr;
struct ahci_cmd_fis fis;
struct scatterlist sg;
char *sg_buff;
int cmd_sent;
struct mem_buffer {
volatile u32 *vaddr;
dma_addr_t paddr;
ssize_t size;
struct dump_record {
u32 reg_ghc[GHC_SZ];
u32 reg_port[PORT_REG_SZ];
u32 reg_clb[CLB_SZ];
u32 reg_fis[FIS_SZ];
u32 cntr;
// AHCI Port registers
struct port_regs {
// Port command list base address
u32 PxCLB;
// Port command list based address upper 32-bits
u32 PxCLBU;
// Port FIS base address
u32 PxFB;
// Port FIS base address upper 32-bits
u32 PxFBU;
u32 PxIS;
u32 PxIE;
u32 PxCMD;
u32 reserved_1;
u32 PxTFD;
u32 PxSIG;
u32 PxSSTS;
u32 PxSCTL;
u32 PxSERR;
u32 PxSACT;
u32 PxCI;
u32 PxSNTF;
u32 PxFBS;
char reserved_2[PORT_RESERVED_2];
struct host_regs {
u32 CAP;
u32 GHC;
u32 IS;
u32 PI;
u32 VS;
u32 CCC_CTL;
u32 EM_LOC;
u32 EM_CTL;
u32 CAP2;
u32 BOHC;
int libahci_debug_init(struct ata_host *host);
void libahci_debug_exit(void);
void libahci_debug_event(const struct ata_port *port ,char *msg, size_t msg_sz);
void libahci_debug_dump_region(const struct ata_port *ap, const u32 *buf, size_t buff_sz, const char* prefix);
void libahci_debug_dump_irq(u32 status);
void libahci_debug_dump_sg(const struct ata_queued_cmd *qc, const char *prefix);
void libahci_debug_irq_notify(const struct ata_port *ap);
void libahci_debug_exec_cmd(struct ata_port *ap);
void libahci_debug_wait_flag(void);
unsigned int libahci_debug_state_dump(struct ata_port *ap);
#endif /* _LIBAHCI_DEBUG_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment