1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-18 10:35:55 +00:00

Add support for 64bit addressing to AHCI and Marvell controllers.

Munged into ATA shape and Marvell specifics my yours truely.

Submitted by: jhb
This commit is contained in:
Søren Schmidt 2007-04-06 16:18:59 +00:00
parent 9dd50a972f
commit 16194fc40b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=168430
5 changed files with 28 additions and 15 deletions

View File

@ -445,6 +445,7 @@ struct ata_dma {
#define ATA_DMA_READ 0x01 /* transaction is a read */
#define ATA_DMA_LOADED 0x02 /* DMA tables etc loaded */
#define ATA_DMA_ACTIVE 0x04 /* DMA transfer in progress */
#define ATA_DMA_64BIT 0x10 /* supports 64bit addressing */
void (*alloc)(device_t dev);
void (*free)(device_t dev);

View File

@ -503,6 +503,7 @@ ata_ahci_allocate(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
u_int64_t work;
int offset = ch->unit << 7;
/* set the SATA resources */
@ -521,13 +522,13 @@ ata_ahci_allocate(device_t dev)
ch->hw.command = NULL; /* not used here */
/* setup work areas */
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLB + offset,
ch->dma->work_bus + ATA_AHCI_CL_OFFSET);
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLBU + offset, 0x00000000);
work = ch->dma->work_bus + ATA_AHCI_CL_OFFSET;
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLB + offset, work & 0xffffffff);
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLBU + offset, work >> 32);
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FB + offset,
ch->dma->work_bus + ATA_AHCI_FB_OFFSET);
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBU + offset, 0x00000000);
work = ch->dma->work_bus + ATA_AHCI_FB_OFFSET;
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FB + offset, work & 0xffffffff);
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBU + offset, work >> 32);
/* enable wanted port interrupts */
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IE + offset,
@ -766,6 +767,7 @@ ata_ahci_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
static void
ata_ahci_dmainit(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
ata_dmainit(dev);
@ -773,6 +775,8 @@ ata_ahci_dmainit(device_t dev)
/* note start and stop are not used here */
ch->dma->setprd = ata_ahci_dmasetprd;
ch->dma->max_iosize = 8192 * DEV_BSIZE;
if (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_64BIT)
ch->dma->flags |= ATA_DMA_64BIT;
}
}
@ -2417,7 +2421,7 @@ ata_marvell_edma_allocate(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
bus_addr_t work = ch->dma->work_bus;
u_int64_t work = ch->dma->work_bus;
int i;
/* clear work area */
@ -2470,7 +2474,7 @@ ata_marvell_edma_allocate(device_t dev)
ATA_OUTL(ctlr->r_res1, 0x02000 + ATA_MV_EDMA_BASE(ch), (1<<11) | (1<<13));
/* request queue base high */
ATA_OUTL(ctlr->r_res1, 0x02010 + ATA_MV_EDMA_BASE(ch), (work >> 16) >> 16);
ATA_OUTL(ctlr->r_res1, 0x02010 + ATA_MV_EDMA_BASE(ch), work >> 32);
/* request queue in ptr */
ATA_OUTL(ctlr->r_res1, 0x02014 + ATA_MV_EDMA_BASE(ch), work & 0xffffffff);
@ -2480,7 +2484,7 @@ ata_marvell_edma_allocate(device_t dev)
/* response queue base high */
work += 1024;
ATA_OUTL(ctlr->r_res1, 0x0201c + ATA_MV_EDMA_BASE(ch), (work >> 16) >> 16);
ATA_OUTL(ctlr->r_res1, 0x0201c + ATA_MV_EDMA_BASE(ch), work >> 32);
/* response queue in ptr */
ATA_OUTL(ctlr->r_res1, 0x02020 + ATA_MV_EDMA_BASE(ch), 0x0);
@ -2568,7 +2572,7 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
/* fill in this request */
quadp[0] = (long)ch->dma->sg_bus & 0xffffffff;
quadp[1] = (ch->dma->sg_bus & 0xffffffff00000000ull) >> 32;
quadp[1] = (u_int64_t)ch->dma->sg_bus >> 32;
wordp[4] = (request->flags & ATA_R_READ ? 0x01 : 0x00) | (tag<<1);
i = 10;
@ -2721,12 +2725,17 @@ ata_marvell_edma_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs,
static void
ata_marvell_edma_dmainit(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
ata_dmainit(dev);
if (ch->dma) {
/* note start and stop are not used here */
ch->dma->setprd = ata_marvell_edma_dmasetprd;
device_printf(dev, "HW qword=%08x\n", ATA_INL(ctlr->r_res1, 0x00d00));
if (ATA_INL(ctlr->r_res1, 0x00d00) & 0x00000004)
ch->dma->flags |= ATA_DMA_64BIT;
}
}

View File

@ -95,22 +95,24 @@ ata_dmaalloc(device_t dev)
{
struct ata_channel *ch = device_get_softc(dev);
struct ata_dc_cb_args ccba;
int maxaddr = (ch->dma->flags & ATA_DMA_64BIT ?
BUS_SPACE_MAXADDR : BUS_SPACE_MAXADDR_32BIT);
if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma->alignment, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
maxaddr, BUS_SPACE_MAXADDR,
NULL, NULL, ch->dma->max_iosize,
ATA_DMA_ENTRIES, ch->dma->segsize,
0, NULL, NULL, &ch->dma->dmatag))
goto error;
if (bus_dma_tag_create(ch->dma->dmatag, PAGE_SIZE, PAGE_SIZE,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
maxaddr, BUS_SPACE_MAXADDR,
NULL, NULL, MAXTABSZ, 1, MAXTABSZ,
0, NULL, NULL, &ch->dma->sg_tag))
goto error;
if (bus_dma_tag_create(ch->dma->dmatag,ch->dma->alignment,ch->dma->boundary,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
maxaddr, BUS_SPACE_MAXADDR,
NULL, NULL, ch->dma->max_iosize,
ATA_DMA_ENTRIES, ch->dma->segsize,
0, NULL, NULL, &ch->dma->data_tag))
@ -131,7 +133,7 @@ ata_dmaalloc(device_t dev)
goto error;
if (bus_dma_tag_create(ch->dma->dmatag, PAGE_SIZE, 64 * 1024,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
maxaddr, BUS_SPACE_MAXADDR,
NULL, NULL, MAXWSPCSZ, 1, MAXWSPCSZ,
0, NULL, NULL, &ch->dma->work_tag))
goto error;

View File

@ -102,6 +102,7 @@ ata_begin_transaction(struct ata_request *request)
/* device reset doesn't interrupt */
if (request->u.ata.command == ATA_DEVICE_RESET) {
int timeout = 1000000;
do {
DELAY(10);

View File

@ -1,4 +1,4 @@
# Copyright (c) 2004 - 2006 Søren Schmidt <sos@FreeBSD.org>
# Copyright (c) 2004 - 2007 Søren Schmidt <sos@FreeBSD.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without