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:
parent
9dd50a972f
commit
16194fc40b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=168430
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user