* Re: linux-next 20170117 - lockdep whines and BUGs in ata_scsi_rbuf_fill()
From: Tejun Heo @ 2017-01-19 20:24 UTC (permalink / raw)
To: valdis.kletnieks; +Cc: Christoph Hellwig, linux-ide, linux-kernel
In-Reply-To: <21348.1484810915@turing-police.cc.vt.edu>
On Thu, Jan 19, 2017 at 02:28:35AM -0500, valdis.kletnieks@vt.edu wrote:
> linux-next 20170110 didn't exhibit this.
>
> Am seeing at boot a lockdep whine, followed by 3 BUGs. ata_scsi_rbuf_fill() is
> in the traceback for all of them. 'git log' hints that it's one of 6 commits
> against drivers/ata/libata-scsi.c by Christoph, but none of them spring out
> as being the guilty party. This ring any bells, or should I start
> cherrypicking reverts and bisecting?
>
> (-dirty due to a local patch to net/ipv6/addrconf.c for a VPN issue)
Reverted the offending commit yesterday. It should be fine now.
Thanks.
--
tejun
^ permalink raw reply
* Re: command emulation fix
From: Tejun Heo @ 2017-01-19 20:34 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-ide
In-Reply-To: <20170119202725.GB6403@lst.de>
Hello, Christoph.
On Thu, Jan 19, 2017 at 09:27:25PM +0100, Christoph Hellwig wrote:
> We can move to a small mempool instead. If we ever want discards
> (aka TRIM) to perform nicely on ATA a global static buffer isn't
> going to cut it. I've spent some time to optimize it for NVMe so
> that it's usable which I plan to submit soon. I've not looked ATA
> in that respect yet, but it's probably going to be an issue.
So, unless we allocate one mempool per port, we're gonna have to
synchronize around its use anyway. mempool can't guarantee allocation
to multiple users at the same time. If this is something which
affects scalability, I'm completley fine with making it per-port (or
device). Each ata_port carries 512 byte buffer anyway. Maybe we can
reuse that?
Thanks.
--
tejun
^ permalink raw reply
* Re: command emulation fix
From: Tejun Heo @ 2017-01-19 20:36 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-ide
In-Reply-To: <20170119203458.GC25390@mtj.duckdns.org>
On Thu, Jan 19, 2017 at 03:34:58PM -0500, Tejun Heo wrote:
> Hello, Christoph.
>
> On Thu, Jan 19, 2017 at 09:27:25PM +0100, Christoph Hellwig wrote:
> > We can move to a small mempool instead. If we ever want discards
> > (aka TRIM) to perform nicely on ATA a global static buffer isn't
> > going to cut it. I've spent some time to optimize it for NVMe so
> > that it's usable which I plan to submit soon. I've not looked ATA
> > in that respect yet, but it's probably going to be an issue.
>
> So, unless we allocate one mempool per port, we're gonna have to
> synchronize around its use anyway. mempool can't guarantee allocation
> to multiple users at the same time. If this is something which
> affects scalability, I'm completley fine with making it per-port (or
> device). Each ata_port carries 512 byte buffer anyway. Maybe we can
> reuse that?
But do you actually expect there to be scalability issues around this
buffer? Its uses are extremely short and libata operations are pretty
strongly synchronized to begin with.
Thanks.
--
tejun
^ permalink raw reply
* Re: command emulation fix
From: Christoph Hellwig @ 2017-01-19 20:27 UTC (permalink / raw)
To: Tejun Heo; +Cc: Christoph Hellwig, linux-ide
In-Reply-To: <20170119202316.GA25390@mtj.duckdns.org>
On Thu, Jan 19, 2017 at 03:23:16PM -0500, Tejun Heo wrote:
> Yeah, it is probably fine but I just feel weird about changing the
> code to introduce a possible failure case. Let's leave it as-is for
> now.
We can move to a small mempool instead. If we ever want discards
(aka TRIM) to perform nicely on ATA a global static buffer isn't
going to cut it. I've spent some time to optimize it for NVMe so
that it's usable which I plan to submit soon. I've not looked ATA
in that respect yet, but it's probably going to be an issue.
^ permalink raw reply
* Re: command emulation fix
From: Christoph Hellwig @ 2017-01-19 20:40 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, martin.petersen, linux-scsi
In-Reply-To: <20170119203458.GC25390@mtj.duckdns.org>
On Thu, Jan 19, 2017 at 03:34:58PM -0500, Tejun Heo wrote:
> So, unless we allocate one mempool per port, we're gonna have to
> synchronize around its use anyway. mempool can't guarantee allocation
> to multiple users at the same time. If this is something which
> affects scalability, I'm completley fine with making it per-port (or
> device). Each ata_port carries 512 byte buffer anyway. Maybe we can
> reuse that?
I'll play around with these things a bit more. For the slow
path ops I think I can get away without any dynamic allocation
at all - just use small on-stack buffers.
For DSM / Write Same we rewrite into the buffer the SCSI layer
provided us. This is a bit of an issue anyway as this might
modify user data that is not expected to be rewritten or even
mapped read-only. Maybe we need to kill off that emulation
entirely and just have ATA DSM using the ATA_16 CDB as another
provisioning option in sd.c. While that is a bit of a layering
violation it would solve a lot of problems with the way TRIM
is currently implemented.
^ permalink raw reply
* Re: command emulation fix
From: Christoph Hellwig @ 2017-01-19 20:41 UTC (permalink / raw)
To: Tejun Heo; +Cc: Christoph Hellwig, linux-ide
In-Reply-To: <20170119203646.GD25390@mtj.duckdns.org>
On Thu, Jan 19, 2017 at 03:36:46PM -0500, Tejun Heo wrote:
> But do you actually expect there to be scalability issues around this
> buffer? Its uses are extremely short and libata operations are pretty
> strongly synchronized to begin with.
Mostly for setups using JBODs with massive numbers of SATA disks.
This would mostly not be ahci or a real ATA driver but libsas calling
into libata for the translation.
^ permalink raw reply
* Re: command emulation fix
From: Tejun Heo @ 2017-01-19 20:45 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-ide
In-Reply-To: <20170119204135.GA6675@lst.de>
Hello,
On Thu, Jan 19, 2017 at 09:41:35PM +0100, Christoph Hellwig wrote:
> On Thu, Jan 19, 2017 at 03:36:46PM -0500, Tejun Heo wrote:
> > But do you actually expect there to be scalability issues around this
> > buffer? Its uses are extremely short and libata operations are pretty
> > strongly synchronized to begin with.
>
> Mostly for setups using JBODs with massive numbers of SATA disks.
>
> This would mostly not be ahci or a real ATA driver but libsas calling
> into libata for the translation.
Ah, understood.
Thanks for the explanation.
--
tejun
^ permalink raw reply
* Re: [PATCH] pata_legacy: Allow disabling of legacy PATA device probes on non-PCI systems
From: Tejun Heo @ 2017-01-19 21:37 UTC (permalink / raw)
To: whiteheadm
Cc: One Thousand Gnomes, Greg Kroah-Hartman, Sergei Shtylyov,
linux-ide
In-Reply-To: <CAP8WD_bS61spyQkd7cvktFf_dPc0wgNZ8qEa7GVrXgUobHQdvw@mail.gmail.com>
On Wed, Jan 11, 2017 at 08:54:21PM -0500, tedheadster wrote:
> Tejun,
> I'm interested in debugging this. What can I do to help?
Sorry about taking so long. I suck. :)
Can you please try the following patch and post what the kernel prints
out?
Thanks.
---
drivers/ata/pata_legacy.c | 2 ++
drivers/base/core.c | 9 +++++++++
include/linux/kobject.h | 1 +
lib/kobject.c | 22 ++++++++++++++++++++++
4 files changed, 34 insertions(+)
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -962,6 +962,8 @@ static __init int legacy_init_one(struct
if (IS_ERR(pdev))
return PTR_ERR(pdev);
+ pdev->dev.kobj.release_debug = true;
+
ret = -EBUSY;
if (devm_request_region(&pdev->dev, io, 8, "pata_legacy") == NULL ||
devm_request_region(&pdev->dev, io + 0x0206, 1,
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -803,8 +803,17 @@ static void device_release(struct kobjec
* is deleted but alive, so release devres here to avoid
* possible memory leak.
*/
+ if (kobj->release_debug)
+ dev_info(dev, "XXX device_release: drel=%pf trel=%pf cdrel=%pf\n",
+ dev->release,
+ dev->type ? dev->type->release : NULL,
+ dev->class ? dev->class->dev_release : NULL);
+
devres_release_all(dev);
+ if (kobj->release_debug)
+ dev_info(dev, "XXX device_release: devres_release_all() done\n");
+
if (dev->release)
dev->release(dev);
else if (dev->type && dev->type->release)
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -76,6 +76,7 @@ struct kobject {
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
+ unsigned int release_debug:1;
};
extern __printf(2, 3)
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -595,6 +595,13 @@ struct kobject *kobject_get(struct kobje
WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
"initialized, yet kobject_get() is being "
"called.\n", kobject_name(kobj), kobj);
+ if (kobj->release_debug)
+ printk("XXX kobject_get(%s): ref=%d++ (%pf:%pf:%pf)\n",
+ kobject_name(kobj),
+ atomic_read(&kobj->kref.refcount),
+ __builtin_return_address(1),
+ __builtin_return_address(2),
+ __builtin_return_address(3));
kref_get(&kobj->kref);
}
return kobj;
@@ -620,6 +627,14 @@ static void kobject_cleanup(struct kobje
pr_debug("kobject: '%s' (%p): %s, parent %p\n",
kobject_name(kobj), kobj, __func__, kobj->parent);
+ if (kobj->release_debug)
+ printk("XXX kobject_cleanup(%s): rel=%pf (%pf:%pf:%pf)\n",
+ kobject_name(kobj),
+ (t && t->release) ? t->release : NULL,
+ __builtin_return_address(1),
+ __builtin_return_address(2),
+ __builtin_return_address(3));
+
if (t && !t->release)
pr_debug("kobject: '%s' (%p): does not have a release() "
"function, it is broken and must be fixed.\n",
@@ -688,6 +703,13 @@ void kobject_put(struct kobject *kobj)
WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
"initialized, yet kobject_put() is being "
"called.\n", kobject_name(kobj), kobj);
+ if (kobj->release_debug)
+ printk("XXX kobject_put(%s): ref=%d-- (%pf:%pf:%pf)\n",
+ kobject_name(kobj),
+ atomic_read(&kobj->kref.refcount),
+ __builtin_return_address(1),
+ __builtin_return_address(2),
+ __builtin_return_address(3));
kref_put(&kobj->kref, kobject_release);
}
}
^ permalink raw reply
* RE: [PATCH] ahci: qoriq: added ls2088a platforms support
From: Y.T. Tang @ 2017-01-20 3:05 UTC (permalink / raw)
To: Tejun Heo
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org,
linux-ide-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <20170118195351.GD9171-qYNAdHglDFBN0TnZuCh8vA@public.gmane.org>
> -----Original Message-----
> From: Tejun Heo [mailto:htejun-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org] On Behalf Of Tejun Heo
> Sent: Thursday, January 19, 2017 3:54 AM
> To: Y.T. Tang <yuantian.tang-3arQi8VN3Tc@public.gmane.org>
> Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org; mark.rutland-5wv7dgnIgG8@public.gmane.org; linux-ide-u79uwXL29TY76Z2rM5mHXA@public.gmane.org;
> devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-arm-
> kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> Subject: Re: [PATCH] ahci: qoriq: added ls2088a platforms support
>
> On Tue, Jan 17, 2017 at 02:12:01PM +0800, yuantian.tang-3arQi8VN3Tc@public.gmane.org wrote:
> > From: Tang Yuantian <Yuantian.Tang-3arQi8VN3Tc@public.gmane.org>
> >
> > Ls2088a is new introduced arm-based soc with sata support with
> > following features:
> > 1. Complies with the serial ATA 3.0 specification and the AHCI 1.3.1
> > specification
> > 2. Contains a high-speed descriptor-based DMA controller 3. Supports
> > the following:
> > a. Speeds of 1.5 Gb/s (first-generation SATA), 3 Gb/s
> > (second-generation SATA), and 6 Gb/s (third-generation SATA)
> > b. FIS-based switching
> > c. Native command queuing (NCQ) commands
> > d. Port multiplier operation
> > e. Asynchronous notification
> > f. SATA BIST mode
> >
> > Signed-off-by: Tang Yuantian <yuantian.tang-3arQi8VN3Tc@public.gmane.org>
>
> Reverted due to build failure. Did you even try to compile it before
> submission? We all make mistakes and that's fine but this one seems a bit
> too careless. Please don't do this.
>
Sorry for the trouble.
I never send a patch without testing. This patch depends on other two patches which I sent a long time ago which I thought they were merged.
Anyway, my mistake.
I will resend all the patches with correct order.
Regards,
Yuantian
> Thanks.
>
> --
> tejun
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 1/3 v2] ahci: qoriq: added a condition to enable dma coherence
From: yuantian.tang @ 2017-01-20 6:59 UTC (permalink / raw)
To: tj
Cc: mathieu.poirier, robin.murphy, robh+dt, mark.rutland, linux-ide,
devicetree, linux-kernel, linux-arm-kernel, Tang Yuantian,
Tang Yuantian
From: Tang Yuantian <Yuantian.Tang@nxp.com>
Enable DMA coherence in SATA controller on condition that
dma-coherent property exists in sata node in DTS.
Signed-off-by: Tang Yuantian <yuantian.tang@nxp.com>
---
v2:
- use of_dma_is_coherent() instead of open-coding.
drivers/ata/ahci_qoriq.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c
index 9884c8c..01ef662 100644
--- a/drivers/ata/ahci_qoriq.c
+++ b/drivers/ata/ahci_qoriq.c
@@ -59,6 +59,7 @@ struct ahci_qoriq_priv {
struct ccsr_ahci *reg_base;
enum ahci_qoriq_type type;
void __iomem *ecc_addr;
+ bool is_dmacoherent;
};
static const struct of_device_id ahci_qoriq_of_match[] = {
@@ -164,26 +165,31 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
- writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG,
+ reg_base + LS1021A_AXICC_ADDR);
break;
case AHCI_LS1043A:
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
- writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break;
case AHCI_LS2080A:
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
- writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break;
case AHCI_LS1046A:
writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr);
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
- writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break;
}
@@ -221,6 +227,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
if (IS_ERR(qoriq_priv->ecc_addr))
return PTR_ERR(qoriq_priv->ecc_addr);
}
+ qoriq_priv->is_dmacoherent = of_dma_is_coherent(np);
rc = ahci_platform_enable_resources(hpriv);
if (rc)
--
2.1.0.27.g96db324
^ permalink raw reply related
* [PATCH 2/3 v2] ahci: qoriq: report error when ecc register address is missing in dts
From: yuantian.tang @ 2017-01-20 6:59 UTC (permalink / raw)
To: tj
Cc: mathieu.poirier, robin.murphy, robh+dt, mark.rutland, linux-ide,
devicetree, linux-kernel, linux-arm-kernel, Tang Yuantian,
Tang Yuantian
In-Reply-To: <1484895576-40379-1-git-send-email-yuantian.tang@nxp.com>
From: Tang Yuantian <Yuantian.Tang@nxp.com>
For ls1021a, and armv8 chasis 2 socs, sata ecc must be disabled.
If ecc register is not found in sata node in dts, report error.
This is a chip erratum described as bellow:
The Read DMA operations get early termination indication from the
controller. This issue is observed as CRC error in the status registers.
The issue is due to address collision at address 0 in the dual port
memory. The read is a dummy read to flush out the header, but due to
collision the controller logs the mbit error reported by the ECC check
logic. This results in the early termination of the Read DMA operation
by the controller. The issue happens to all the interface
speeds(GEN1/2/3) for all the products.
Workaround:
Disable ECC feature on those platforms.
Signed-off-by: Tang Yuantian <yuantian.tang@nxp.com>
---
v2:
- refine the title and description
- change reporting warning to reporting error
drivers/ata/ahci_qoriq.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c
index 01ef662..137b1c7 100644
--- a/drivers/ata/ahci_qoriq.c
+++ b/drivers/ata/ahci_qoriq.c
@@ -46,7 +46,7 @@
#define LS1021A_AXICC_ADDR 0xC0
#define SATA_ECC_DISABLE 0x00020000
-#define LS1046A_SATA_ECC_DIS 0x80000000
+#define ECC_DIS_ARMV8_CH2 0x80000000
enum ahci_qoriq_type {
AHCI_LS1021A,
@@ -158,6 +158,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
switch (qpriv->type) {
case AHCI_LS1021A:
+ if (!qpriv->ecc_addr)
+ return -EINVAL;
writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2);
@@ -171,6 +173,9 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
break;
case AHCI_LS1043A:
+ if (!qpriv->ecc_addr)
+ return -EINVAL;
+ writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr);
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
if (qpriv->is_dmacoherent)
@@ -185,7 +190,9 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
break;
case AHCI_LS1046A:
- writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr);
+ if (!qpriv->ecc_addr)
+ return -EINVAL;
+ writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr);
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
if (qpriv->is_dmacoherent)
--
2.1.0.27.g96db324
^ permalink raw reply related
* [PATCH 3/3 v2] ahci: qoriq: added ls2088a platforms support
From: yuantian.tang @ 2017-01-20 6:59 UTC (permalink / raw)
To: tj
Cc: mathieu.poirier, robin.murphy, robh+dt, mark.rutland, linux-ide,
devicetree, linux-kernel, linux-arm-kernel, Tang Yuantian,
Tang Yuantian
In-Reply-To: <1484895576-40379-1-git-send-email-yuantian.tang@nxp.com>
From: Tang Yuantian <Yuantian.Tang@nxp.com>
Ls2088a is new introduced arm-based soc with sata support with
following features:
1. Complies with the serial ATA 3.0 specification and the AHCI 1.3.1
specification
2. Contains a high-speed descriptor-based DMA controller
3. Supports the following:
a. Speeds of 1.5 Gb/s (first-generation SATA), 3 Gb/s
(second-generation SATA), and 6 Gb/s (third-generation SATA)
b. FIS-based switching
c. Native command queuing (NCQ) commands
d. Port multiplier operation
e. Asynchronous notification
f. SATA BIST mode
Signed-off-by: Tang Yuantian <yuantian.tang@nxp.com>
---
v2:
- no change
drivers/ata/ahci_qoriq.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c
index 137b1c7..85d8332 100644
--- a/drivers/ata/ahci_qoriq.c
+++ b/drivers/ata/ahci_qoriq.c
@@ -53,6 +53,7 @@ enum ahci_qoriq_type {
AHCI_LS1043A,
AHCI_LS2080A,
AHCI_LS1046A,
+ AHCI_LS2088A,
};
struct ahci_qoriq_priv {
@@ -67,6 +68,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = {
{ .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
{ .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
{ .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
+ { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
{},
};
MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
@@ -198,6 +200,13 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
if (qpriv->is_dmacoherent)
writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break;
+
+ case AHCI_LS2088A:
+ writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
+ writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
+ if (qpriv->is_dmacoherent)
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+ break;
}
return 0;
--
2.1.0.27.g96db324
^ permalink raw reply related
* Re: [PATCH 0/3] ata: add m68k/Atari Falcon PATA support
From: Michael Schmitz @ 2017-01-20 7:49 UTC (permalink / raw)
To: Finn Thain
Cc: Bartlomiej Zolnierkiewicz, Tejun Heo, Geert Uytterhoeven,
linux-ide, Linux/m68k, Linux Kernel Development, Andreas Schwab
In-Reply-To: <alpine.LNX.2.00.1701151541230.7981@nippy.intranet>
Hi Finn,
Am 15.01.2017 um 17:42 schrieb Finn Thain:
>> No, we can't check either FDC or SCSI interrupts (or indeed any chip
>> registers) without touching the ST-DMA. The moment we select a FDC or
>> SCSI register for read, DMA is terminated no questions asked.
>>
>
> Perhaps we can convert DMA operations to PDMA (by polling with local irqs
> disabled) and avoid the whole problem of interrupt handlers executing
> during DMA transfers. The docs suggest that it is doable.
>
> "Poll or service the Disk Driver Controller interrupt on the MK68901 MFP
> General Purpose I/O Register to detect the completion of a WD1772 FDC
> command. Do not poll the FDC Busy or DMA Sector Count Zero status bits."
> -- ST HW Spec, p. 36.
> http://dev-docs.atariforge.org/files/ST_HW_Spec_1-7-1986.pdf
The MFP interrupt in question is the same as the one used by IDE
(wired-OR of IDE, FDC and SCSI), so we would still have to figure out
where the interrupt originated. Polling instead of taking the interrupt
does not change that fundamental problem (unless I'm missing something).
>
> On page 18 there is an algorithm for floppy writes which is interesting.
That one (and the ACSI algorithm which would apply to SCSI for Falcon)
does suggest it won't be possible to peek at the sector count register
to detect end of DMA. The addendum (note 841017G) makes it clear that a
write to the DMA mode register is required to look at the status
register error bit (which might terminate DMA).
Maybe the DMA address register can be used to check for DMA completion
... it's used to check for residual or lost bytes anyway so that appears
to work. And the FDC driver does use the same strategy to check if
enough track data have been read.
Leaves the case where DMA hasn't completed but may have been aborted by
a NCR5380 interrupt. I suppose we can detect that by checking for any
change in the DMA address while repeatedly reading the DMA address
register. No change means the DMA has got stuck. Not exactly pretty but
all I can come up with.
>
> I suspect that we will need to keep the FDC idle during SCSI transfers
> (and vice versa) much as the present stdma.c lock does.
>
> "The interrupt outputs of the internal floppy disk controller and the
> external ACSI DMA port are logically OR'ed. The pin of the MFP GPIP will
> read as a '0' if either the FDC or a selected ACSI device controller is
> asserting its interrupt request."
> -- ACSI/DMA Integration Guide, p.16.
> http://dev-docs.atariforge.org/files/ACSI_DMA_Guide_6-28-1991.pdf
On Falcon, the IDE interrupt is also OR'ed to the above two interrupt
lines, hence the need for including IDE in the locking scheme there.
>
> Polling the logically OR'ed interrupt sources to detect end-of-DMA will
> not be reliable unless we disable those sources that aren't relevant.
> Otherwise we access the DMA registers too early (which IIUC would kill the
> transfer). I'm afraid we shall have to expect that a few transfers will be
> interrupted by other devices in this way, and carefully check for this.
>
> For example, the 5380 SCSI bus reset interrupt is not maskable, which
> could affect FDC transfers. If this terminated the polling for DMA
> completion, the FDC driver then has to access the FDC registers and
> confirm that the transfer was not terminated early.
>
We'll have to make sure FDC and SCSI don't clash in their DMA and
interrupt use.
Cheers,
Michael
^ permalink raw reply
* Re: [PATCH v4 01/14] devicetree: bindings: add bindings for ahci-da850
From: Sekhar Nori @ 2017-01-20 10:49 UTC (permalink / raw)
To: Bartosz Golaszewski, Kevin Hilman, Patrick Titiano,
Michael Turquette, Tejun Heo, Rob Herring, Mark Rutland,
Russell King, David Lechner
Cc: linux-ide-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1484832588-18413-2-git-send-email-bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On Thursday 19 January 2017 06:59 PM, Bartosz Golaszewski wrote:
> Add DT bindings for the TI DA850 AHCI SATA controller.
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
> Documentation/devicetree/bindings/ata/ahci-da850.txt | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/ata/ahci-da850.txt
>
> diff --git a/Documentation/devicetree/bindings/ata/ahci-da850.txt b/Documentation/devicetree/bindings/ata/ahci-da850.txt
> new file mode 100644
> index 0000000..fd90662
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ata/ahci-da850.txt
> @@ -0,0 +1,15 @@
> +Device tree binding for the TI DA850 AHCI SATA Controller
> +---------------------------------------------------------
> +
> +Required properties:
> + - compatible: must be "ti,da850-ahci"
> + - reg: physical base addresses and sizes of the controller's register areas
> + - interrupts: interrupt specifier (refer to the interrupt binding)
> +
> +Example:
> +
> + sata: ahci@218000 {
Please fix the example too, when you fix Sergei's comment on 12/14
Thanks,
Sekhar
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v4 06/14] ARM: davinci: da850: model the SATA refclk
From: Sekhar Nori @ 2017-01-20 10:52 UTC (permalink / raw)
To: Bartosz Golaszewski, Kevin Hilman, Patrick Titiano,
Michael Turquette, Tejun Heo, Rob Herring, Mark Rutland,
Russell King, David Lechner
Cc: linux-ide, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <1484832588-18413-7-git-send-email-bgolaszewski@baylibre.com>
On Thursday 19 January 2017 06:59 PM, Bartosz Golaszewski wrote:
> Register a dummy clock modelling the external SATA oscillator for
I had asked about this earlier. I dont think calling it a dummy clock is
right. Can you fix it or respond to my earlier mail with any objections?
> da850 (both DT and board file mode).
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Thanks,
Sekhar
^ permalink raw reply
* Re: [PATCH v4 06/14] ARM: davinci: da850: model the SATA refclk
From: Bartosz Golaszewski @ 2017-01-20 10:55 UTC (permalink / raw)
To: Sekhar Nori
Cc: Kevin Hilman, Patrick Titiano, Michael Turquette, Tejun Heo,
Rob Herring, Mark Rutland, Russell King, David Lechner, linux-ide,
linux-devicetree, LKML, arm-soc
In-Reply-To: <fcbafcd6-4ecc-0f76-0f8c-960814c39423@ti.com>
2017-01-20 11:52 GMT+01:00 Sekhar Nori <nsekhar@ti.com>:
> On Thursday 19 January 2017 06:59 PM, Bartosz Golaszewski wrote:
>> Register a dummy clock modelling the external SATA oscillator for
>
> I had asked about this earlier. I dont think calling it a dummy clock is
> right. Can you fix it or respond to my earlier mail with any objections?
>
Sorry, I missed that - no objections against calling it a "fixed rate clock".
Thanks,
Bartosz
^ permalink raw reply
* [PATCH v5 01/14] devicetree: bindings: add bindings for ahci-da850
From: Bartosz Golaszewski @ 2017-01-20 11:21 UTC (permalink / raw)
To: Kevin Hilman, Sekhar Nori, Patrick Titiano, Michael Turquette,
Tejun Heo, Rob Herring, Mark Rutland, Russell King, David Lechner
Cc: linux-ide, devicetree, linux-kernel, linux-arm-kernel,
Bartosz Golaszewski
In-Reply-To: <1484911325-23425-1-git-send-email-bgolaszewski@baylibre.com>
Add DT bindings for the TI DA850 AHCI SATA controller.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
Documentation/devicetree/bindings/ata/ahci-da850.txt | 15 +++++++++++++++
1 file changed, 15 insertions(+)
create mode 100644 Documentation/devicetree/bindings/ata/ahci-da850.txt
diff --git a/Documentation/devicetree/bindings/ata/ahci-da850.txt b/Documentation/devicetree/bindings/ata/ahci-da850.txt
new file mode 100644
index 0000000..268fe87
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/ahci-da850.txt
@@ -0,0 +1,15 @@
+Device tree binding for the TI DA850 AHCI SATA Controller
+---------------------------------------------------------
+
+Required properties:
+ - compatible: must be "ti,da850-ahci"
+ - reg: physical base addresses and sizes of the controller's register areas
+ - interrupts: interrupt specifier (refer to the interrupt binding)
+
+Example:
+
+ sata: sata@218000 {
+ compatible = "ti,da850-ahci";
+ reg = <0x218000 0x2000>, <0x22c018 0x4>;
+ interrupts = <67>;
+ };
--
2.9.3
^ permalink raw reply related
* [PATCH v5 02/14] ARM: davinci_all_defconfig: enable SATA modules
From: Bartosz Golaszewski @ 2017-01-20 11:21 UTC (permalink / raw)
To: Kevin Hilman, Sekhar Nori, Patrick Titiano, Michael Turquette,
Tejun Heo, Rob Herring, Mark Rutland, Russell King, David Lechner
Cc: linux-ide, Bartosz Golaszewski, linux-kernel, linux-arm-kernel,
devicetree
In-Reply-To: <1484911325-23425-1-git-send-email-bgolaszewski@baylibre.com>
Add the da850-ahci driver to davinci defconfig.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/configs/davinci_all_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 8806754..a1b9c58 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -78,6 +78,8 @@ CONFIG_IDE=m
CONFIG_BLK_DEV_PALMCHIP_BK3710=m
CONFIG_SCSI=m
CONFIG_BLK_DEV_SD=m
+CONFIG_ATA=m
+CONFIG_AHCI_DA850=m
CONFIG_NETDEVICES=y
CONFIG_NETCONSOLE=y
CONFIG_TUN=m
--
2.9.3
^ permalink raw reply related
* [PATCH v5 03/14] ARM: davinci: add a clock lookup entry for the SATA clock
From: Bartosz Golaszewski @ 2017-01-20 11:21 UTC (permalink / raw)
To: Kevin Hilman, Sekhar Nori, Patrick Titiano, Michael Turquette,
Tejun Heo, Rob Herring, Mark Rutland, Russell King, David Lechner
Cc: linux-ide, Bartosz Golaszewski, linux-kernel, linux-arm-kernel,
devicetree
In-Reply-To: <1484911325-23425-1-git-send-email-bgolaszewski@baylibre.com>
This entry is needed for the ahci driver to get a functional clock.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/mach-davinci/da8xx-dt.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 9ee44da..b83e5d1 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -42,6 +42,7 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("ti,da830-ohci", 0x01e25000, "ohci-da8xx", NULL),
OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL),
OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL),
+ OF_DEV_AUXDATA("ti,da850-ahci", 0x01e18000, "ahci_da850", NULL),
{}
};
--
2.9.3
^ permalink raw reply related
* [PATCH v5 04/14] sata: ahci-da850: get the sata clock using a connection id
From: Bartosz Golaszewski @ 2017-01-20 11:21 UTC (permalink / raw)
To: Kevin Hilman, Sekhar Nori, Patrick Titiano, Michael Turquette,
Tejun Heo, Rob Herring, Mark Rutland, Russell King, David Lechner
Cc: linux-ide, Bartosz Golaszewski, linux-kernel, linux-arm-kernel,
devicetree
In-Reply-To: <1484911325-23425-1-git-send-email-bgolaszewski@baylibre.com>
In preparation for using two clocks in the driver (the sysclk2-based
clock and the external REFCLK), check if we got a functional clock
after calling ahci_platform_get_resources(). If not, retry calling
clk_get() with con_id specified.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/ata/ahci_da850.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index 267a3d3..8cfdc86 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -71,12 +71,28 @@ static int ahci_da850_probe(struct platform_device *pdev)
struct ahci_host_priv *hpriv;
struct resource *res;
void __iomem *pwrdn_reg;
+ struct clk *clk;
int rc;
hpriv = ahci_platform_get_resources(pdev);
if (IS_ERR(hpriv))
return PTR_ERR(hpriv);
+ /*
+ * Internally ahci_platform_get_resources() calls clk_get(dev, NULL)
+ * when trying to obtain the first clock. This SATA controller uses
+ * two clocks for which we specify two connection ids. If we don't
+ * have a clock at this point - call clk_get() again with
+ * con_id = "sata".
+ */
+ if (!hpriv->clks[0]) {
+ clk = clk_get(dev, "sata");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ hpriv->clks[0] = clk;
+ }
+
rc = ahci_platform_enable_resources(hpriv);
if (rc)
return rc;
--
2.9.3
^ permalink raw reply related
* [PATCH v5 05/14] ARM: davinci: da850: add con_id for the SATA clock
From: Bartosz Golaszewski @ 2017-01-20 11:21 UTC (permalink / raw)
To: Kevin Hilman, Sekhar Nori, Patrick Titiano, Michael Turquette,
Tejun Heo, Rob Herring, Mark Rutland, Russell King, David Lechner
Cc: linux-ide, Bartosz Golaszewski, linux-kernel, linux-arm-kernel,
devicetree
In-Reply-To: <1484911325-23425-1-git-send-email-bgolaszewski@baylibre.com>
The ahci-da850 SATA driver is now capable of retrieving clocks by
con_id. Add the connection id for the sysclk2-derived SATA clock.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/mach-davinci/da850.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 1d873d1..dbf1daa 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -571,7 +571,7 @@ static struct clk_lookup da850_clks[] = {
CLK("spi_davinci.0", NULL, &spi0_clk),
CLK("spi_davinci.1", NULL, &spi1_clk),
CLK("vpif", NULL, &vpif_clk),
- CLK("ahci_da850", NULL, &sata_clk),
+ CLK("ahci_da850", "sata", &sata_clk),
CLK("davinci-rproc.0", NULL, &dsp_clk),
CLK(NULL, NULL, &ehrpwm_clk),
CLK("ehrpwm.0", "fck", &ehrpwm0_clk),
--
2.9.3
^ permalink raw reply related
* [PATCH v5 06/14] ARM: davinci: da850: model the SATA refclk
From: Bartosz Golaszewski @ 2017-01-20 11:21 UTC (permalink / raw)
To: Kevin Hilman, Sekhar Nori, Patrick Titiano, Michael Turquette,
Tejun Heo, Rob Herring, Mark Rutland, Russell King, David Lechner
Cc: linux-ide, devicetree, linux-kernel, linux-arm-kernel,
Bartosz Golaszewski
In-Reply-To: <1484911325-23425-1-git-send-email-bgolaszewski@baylibre.com>
Register a fixed rate clock modelling the external SATA oscillator
for da850 (both DT and board file mode).
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/mach-davinci/da8xx-dt.c | 8 ++++++++
arch/arm/mach-davinci/devices-da8xx.c | 29 +++++++++++++++++++++++++++++
arch/arm/mach-davinci/include/mach/da8xx.h | 1 +
3 files changed, 38 insertions(+)
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index b83e5d1..55342ca 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -50,6 +50,9 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
static void __init da850_init_machine(void)
{
+ /* All existing boards use 100MHz SATA refclkpn */
+ static const unsigned long sata_refclkpn = 100 * 1000 * 1000;
+
int ret;
ret = da8xx_register_usb20_phy_clk(false);
@@ -61,6 +64,11 @@ static void __init da850_init_machine(void)
pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
__func__, ret);
+ ret = da850_register_sata_refclk(sata_refclkpn);
+ if (ret)
+ pr_warn("%s: registering SATA REFCLK failed: %d",
+ __func__, ret);
+
of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
davinci_pm_init();
}
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index c2457b3..cfceb32 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -24,6 +24,7 @@
#include <mach/common.h>
#include <mach/time.h>
#include <mach/da8xx.h>
+#include <mach/clock.h>
#include "cpuidle.h"
#include "sram.h"
@@ -1023,6 +1024,28 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect)
}
#ifdef CONFIG_ARCH_DAVINCI_DA850
+static struct clk sata_refclk = {
+ .name = "sata_refclk",
+ .set_rate = davinci_simple_set_rate,
+};
+
+static struct clk_lookup sata_refclk_lookup =
+ CLK("ahci_da850", "refclk", &sata_refclk);
+
+int __init da850_register_sata_refclk(int rate)
+{
+ int ret;
+
+ sata_refclk.rate = rate;
+ ret = clk_register(&sata_refclk);
+ if (ret)
+ return ret;
+
+ clkdev_add(&sata_refclk_lookup);
+
+ return 0;
+}
+
static struct resource da850_sata_resources[] = {
{
.start = DA850_SATA_BASE,
@@ -1055,9 +1078,15 @@ static struct platform_device da850_sata_device = {
int __init da850_register_sata(unsigned long refclkpn)
{
+ int ret;
+
/* please see comment in drivers/ata/ahci_da850.c */
BUG_ON(refclkpn != 100 * 1000 * 1000);
+ ret = da850_register_sata_refclk(refclkpn);
+ if (ret)
+ return ret;
+
return platform_device_register(&da850_sata_device);
}
#endif
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 85ff218..7e46422 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -95,6 +95,7 @@ int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
int da8xx_register_usb_refclkin(int rate);
int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
+int da850_register_sata_refclk(int rate);
int da8xx_register_emac(void);
int da8xx_register_uio_pruss(void);
int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
--
2.9.3
^ permalink raw reply related
* [PATCH v5 08/14] sata: ahci-da850: implement a workaround for the softreset quirk
From: Bartosz Golaszewski @ 2017-01-20 11:21 UTC (permalink / raw)
To: Kevin Hilman, Sekhar Nori, Patrick Titiano, Michael Turquette,
Tejun Heo, Rob Herring, Mark Rutland, Russell King, David Lechner
Cc: linux-ide, devicetree, linux-kernel, linux-arm-kernel,
Bartosz Golaszewski
In-Reply-To: <1484911325-23425-1-git-send-email-bgolaszewski@baylibre.com>
There's an issue with the da850 SATA controller: if port multiplier
support is compiled in, but we're connecting the drive directly to
the SATA port on the board, the drive can't be detected.
To make SATA work on the da850-lcdk board: first try to softreset
with pmp - if the operation fails with -EBUSY, retry without pmp.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/ata/ahci_da850.c | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index 7f5328f..11dd87e 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -54,11 +54,42 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg,
writel(val, ahci_base + SATA_P0PHYCR_REG);
}
+static int ahci_da850_softreset(struct ata_link *link,
+ unsigned int *class, unsigned long deadline)
+{
+ int pmp, ret;
+
+ pmp = sata_srst_pmp(link);
+
+ /*
+ * There's an issue with the SATA controller on da850 SoCs: if we
+ * enable Port Multiplier support, but the drive is connected directly
+ * to the board, it can't be detected. As a workaround: if PMP is
+ * enabled, we first call ahci_do_softreset() and pass it the result of
+ * sata_srst_pmp(). If this call fails, we retry with pmp = 0.
+ */
+ ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready);
+ if (pmp && ret == -EBUSY)
+ return ahci_do_softreset(link, class, 0,
+ deadline, ahci_check_ready);
+
+ return ret;
+}
+
+static struct ata_port_operations ahci_da850_port_ops = {
+ .inherits = &ahci_platform_ops,
+ .softreset = ahci_da850_softreset,
+ /*
+ * No need to override .pmp_softreset - it's only used for actual
+ * PMP-enabled ports.
+ */
+};
+
static const struct ata_port_info ahci_da850_port_info = {
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
- .port_ops = &ahci_platform_ops,
+ .port_ops = &ahci_da850_port_ops,
};
static struct scsi_host_template ahci_platform_sht = {
--
2.9.3
^ permalink raw reply related
* [PATCH v5 09/14] sata: ahci: export ahci_do_hardreset() locally
From: Bartosz Golaszewski @ 2017-01-20 11:22 UTC (permalink / raw)
To: Kevin Hilman, Sekhar Nori, Patrick Titiano, Michael Turquette,
Tejun Heo, Rob Herring, Mark Rutland, Russell King, David Lechner
Cc: linux-ide-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Bartosz Golaszewski
In-Reply-To: <1484911325-23425-1-git-send-email-bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
We need a way to retrieve the information about the online state of
the link in the ahci-da850 driver.
Create a new function: ahci_do_hardreset() which is called from
ahci_hardreset() for backwards compatibility, but has an additional
argument: 'online' - which can be used to check if the link is online
after this function returns.
The new routine will be used in the ahci-da850 driver to avoid code
duplication when implementing a workaround for tha da850 SATA
controller quirk/instability.
Signed-off-by: Bartosz Golaszewski <bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
---
drivers/ata/ahci.h | 3 +++
drivers/ata/libahci.c | 18 +++++++++++++-----
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 0cc08f8..5db6ab2 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -398,6 +398,9 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
int pmp, unsigned long deadline,
int (*check_ready)(struct ata_link *link));
+int ahci_do_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline, bool *online);
+
unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
int ahci_stop_engine(struct ata_port *ap);
void ahci_start_fis_rx(struct ata_port *ap);
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index ee7db31..3159f9e 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1519,8 +1519,8 @@ static int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class,
return rc;
}
-static int ahci_hardreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
+int ahci_do_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline, bool *online)
{
const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
struct ata_port *ap = link->ap;
@@ -1528,7 +1528,6 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
struct ahci_host_priv *hpriv = ap->host->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
struct ata_taskfile tf;
- bool online;
int rc;
DPRINTK("ENTER\n");
@@ -1540,17 +1539,26 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
tf.command = ATA_BUSY;
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
- rc = sata_link_hardreset(link, timing, deadline, &online,
+ rc = sata_link_hardreset(link, timing, deadline, online,
ahci_check_ready);
hpriv->start_engine(ap);
- if (online)
+ if (*online)
*class = ahci_dev_classify(ap);
DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
return rc;
}
+EXPORT_SYMBOL_GPL(ahci_do_hardreset);
+
+static int ahci_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
+{
+ bool online;
+
+ return ahci_do_hardreset(link, class, deadline, &online);
+}
static void ahci_postreset(struct ata_link *link, unsigned int *class)
{
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v5 11/14] sata: ahci-da850: un-hardcode the MPY bits
From: Bartosz Golaszewski @ 2017-01-20 11:22 UTC (permalink / raw)
To: Kevin Hilman, Sekhar Nori, Patrick Titiano, Michael Turquette,
Tejun Heo, Rob Herring, Mark Rutland, Russell King, David Lechner
Cc: linux-ide, devicetree, linux-kernel, linux-arm-kernel,
Bartosz Golaszewski
In-Reply-To: <1484911325-23425-1-git-send-email-bgolaszewski@baylibre.com>
All platforms using this driver now register the SATA refclk. Remove
the hardcoded default value from the driver and instead read the rate
of the external clock and calculate the required MPY value from it.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/ata/ahci_da850.c | 91 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 76 insertions(+), 15 deletions(-)
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index 0b2b1a4..9ed404d 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -29,17 +29,8 @@
#define SATA_PHY_TXSWING(x) ((x) << 19)
#define SATA_PHY_ENPLL(x) ((x) << 31)
-/*
- * The multiplier needed for 1.5GHz PLL output.
- *
- * NOTE: This is currently hardcoded to be suitable for 100MHz crystal
- * frequency (which is used by DA850 EVM board) and may need to be changed
- * if you would like to use this driver on some other board.
- */
-#define DA850_SATA_CLK_MULTIPLIER 7
-
static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg,
- void __iomem *ahci_base)
+ void __iomem *ahci_base, u32 mpy)
{
unsigned int val;
@@ -48,13 +39,61 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg,
val &= ~BIT(0);
writel(val, pwrdn_reg);
- val = SATA_PHY_MPY(DA850_SATA_CLK_MULTIPLIER + 1) | SATA_PHY_LOS(1) |
- SATA_PHY_RXCDR(4) | SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) |
- SATA_PHY_ENPLL(1);
+ val = SATA_PHY_MPY(mpy) | SATA_PHY_LOS(1) | SATA_PHY_RXCDR(4) |
+ SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) | SATA_PHY_ENPLL(1);
writel(val, ahci_base + SATA_P0PHYCR_REG);
}
+static u32 ahci_da850_calculate_mpy(unsigned long refclk_rate)
+{
+ u32 pll_output = 1500000000, needed;
+
+ /*
+ * We need to determine the value of the multiplier (MPY) bits.
+ * In order to include the 12.5 multiplier we need to first divide
+ * the refclk rate by ten.
+ *
+ * __div64_32() turned out to be unreliable, sometimes returning
+ * false results.
+ */
+ WARN((refclk_rate % 10) != 0, "refclk must be divisible by 10");
+ needed = pll_output / (refclk_rate / 10);
+
+ /*
+ * What we have now is (multiplier * 10).
+ *
+ * Let's determine the actual register value we need to write.
+ */
+
+ switch (needed) {
+ case 50:
+ return 0x1;
+ case 60:
+ return 0x2;
+ case 80:
+ return 0x4;
+ case 100:
+ return 0x5;
+ case 120:
+ return 0x6;
+ case 125:
+ return 0x7;
+ case 150:
+ return 0x8;
+ case 200:
+ return 0x9;
+ case 250:
+ return 0xa;
+ default:
+ /*
+ * We should have divided evenly - if not, return an invalid
+ * value.
+ */
+ return 0;
+ }
+}
+
static int ahci_da850_softreset(struct ata_link *link,
unsigned int *class, unsigned long deadline)
{
@@ -126,9 +165,10 @@ static int ahci_da850_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ahci_host_priv *hpriv;
- struct resource *res;
void __iomem *pwrdn_reg;
+ struct resource *res;
struct clk *clk;
+ u32 mpy;
int rc;
hpriv = ahci_platform_get_resources(pdev);
@@ -150,6 +190,27 @@ static int ahci_da850_probe(struct platform_device *pdev)
hpriv->clks[0] = clk;
}
+ /*
+ * The second clock used by ahci-da850 is the external REFCLK. If we
+ * didn't get it from ahci_platform_get_resources(), let's try to
+ * specify the con_id in clk_get().
+ */
+ if (!hpriv->clks[1]) {
+ clk = clk_get(dev, "refclk");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "unable to obtain the reference clock");
+ return -ENODEV;
+ } else {
+ hpriv->clks[1] = clk;
+ }
+ }
+
+ mpy = ahci_da850_calculate_mpy(clk_get_rate(hpriv->clks[1]));
+ if (mpy == 0) {
+ dev_err(dev, "invalid REFCLK multiplier value: 0x%x", mpy);
+ return -EINVAL;
+ }
+
rc = ahci_platform_enable_resources(hpriv);
if (rc)
return rc;
@@ -162,7 +223,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
if (!pwrdn_reg)
goto disable_resources;
- da850_sata_init(dev, pwrdn_reg, hpriv->mmio);
+ da850_sata_init(dev, pwrdn_reg, hpriv->mmio, mpy);
rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info,
&ahci_platform_sht);
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox