From: Frans Pop <elendil@planet.nl>
To: linux-arm@vger.kernel.org
Cc: Mark Lord <liml@rtr.ca>,
linux-ide@vger.kernel.org, Saeed Bishara <saeed@marvell.com>,
Nicolas Pitre <nico@cam.org>,
Lennert Buytenhek <buytenh@wantstofly.org>
Subject: [PATCH,v2][1/2] sata-mv: enable HDD led blinking when NCQ is active for GenIIe
Date: Wed, 11 Mar 2009 08:15:51 +0100 [thread overview]
Message-ID: <200903110815.52650.elendil@planet.nl> (raw)
In-Reply-To: <200903110813.25650.elendil@planet.nl>
For some Marvell chips the HDD led does not blink when there is
disk I/O if NCQ is enabled. Add a quirk that enables blink mode for
the led when NCQ is used on any of the ports of a host controller.
The code to enable the blink mode is based on an earlier patch
proposed by Saeed Bishara.
Signed-off-by: Frans Pop <elendil@planet.nl>
Cc: Mark Lord <liml@rtr.ca>
Cc: Saeed Bishara <saeed.bishara@gmail.com>
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 7007edd..4057647 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -205,6 +205,11 @@ enum {
HC_COAL_IRQ = (1 << 4), /* IRQ coalescing */
DEV_IRQ = (1 << 8), /* shift by port # */
+ IIE_LED_CTRL_OFS = 0x2c,
+ IIE_LED_CTRL_BLINK = (1 << 0), /* Active LED blink */
+ IIE_LED_CTRL_ACT_PRESENCE = (1 << 2), /* Multiplex presence with */
+ /* the active LED */
+
/* Shadow block registers */
SHD_BLK_OFS = 0x100,
SHD_CTL_AST_OFS = 0x20, /* ofs from SHD_BLK_OFS */
@@ -359,6 +364,8 @@ enum {
MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */
MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */
MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */
+ MV_HP_NCQ_LED_QUIRK = (1 << 12),
+ MV_HP_LED_BL_EN = (1 << 13), /* is led blinking enabled? */
/* Port private flags (pp_flags) */
MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */
@@ -480,11 +487,19 @@ struct mv_hw_ops {
unsigned int port);
void (*enable_leds)(struct mv_host_priv *hpriv, void __iomem *mmio);
void (*read_preamp)(struct mv_host_priv *hpriv, int idx,
- void __iomem *mmio);
+ void __iomem *mmio);
int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int n_hc);
void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio);
void (*reset_bus)(struct ata_host *host, void __iomem *mmio);
+ void (*enable_led_blink)(struct mv_host_priv *hpriv,
+ void __iomem *mmio, int enable_blink);
+
+ /*
+ * ->inherits must be the last field and all the preceding
+ * fields must be pointers.
+ */
+ const struct mv_hw_ops *inherits;
};
static int mv_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val);
@@ -530,6 +545,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
void __iomem *mmio);
static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
+static void mv_iie_enable_led_blink(struct mv_host_priv *hpriv,
+ void __iomem *mmio, int enable_blink);
static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
@@ -705,6 +722,11 @@ static const struct mv_hw_ops mv6xxx_ops = {
.reset_bus = mv_reset_pci_bus,
};
+static const struct mv_hw_ops mv6xxx_iie_ops = {
+ .inherits = &mv6xxx_ops,
+ .enable_led_blink = mv_iie_enable_led_blink,
+};
+
static const struct mv_hw_ops mv_soc_ops = {
.phy_errata = mv6_phy_errata,
.enable_leds = mv_soc_enable_leds,
@@ -712,6 +734,7 @@ static const struct mv_hw_ops mv_soc_ops = {
.reset_hc = mv_soc_reset_hc,
.reset_flash = mv_soc_reset_flash,
.reset_bus = mv_soc_reset_bus,
+ .enable_led_blink = mv_iie_enable_led_blink,
};
/*
@@ -852,6 +875,55 @@ static void mv_enable_port_irqs(struct ata_port *ap,
mv_set_main_irq_mask(ap->host, disable_bits, enable_bits);
}
+static int mv_has_port_using_ncq(struct ata_host *host)
+{
+ int port;
+ struct mv_host_priv *hpriv = host->private_data;
+
+ for (port = 0; port < hpriv->n_ports; port++) {
+ struct ata_port *ap = host->ports[port];
+ struct mv_port_priv *pp = ap->private_data;
+
+ if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
+ (pp->pp_flags & MV_PP_FLAG_NCQ_EN))
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Some chips have an erratum which causes the HDD led not to blink
+ * during I/O when NCQ is enabled. Enabling the blink mode of the
+ * led makes activity visible in that case.
+ */
+static void mv_quirk_blink_led_when_ncq(struct ata_port *ap,
+ int enable)
+{
+ struct mv_host_priv *hpriv = ap->host->private_data;
+ void __iomem *mmio = hpriv->base;
+
+ if (!hpriv->ops->enable_led_blink)
+ return;
+
+ if (enable) {
+ if (!(hpriv->hp_flags & MV_HP_LED_BL_EN)) {
+ hpriv->ops->enable_led_blink(hpriv, mmio, true);
+ hpriv->hp_flags |= MV_HP_LED_BL_EN;
+ }
+ return;
+ } else {
+ if (!(hpriv->hp_flags & MV_HP_LED_BL_EN))
+ return;
+ }
+
+ /* Does any other port still use NCQ? */
+ if (!mv_has_port_using_ncq(ap->host)) {
+ hpriv->ops->enable_led_blink(hpriv, mmio, false);
+ hpriv->hp_flags &= ~MV_HP_LED_BL_EN;
+ }
+}
+
/**
* mv_start_dma - Enable eDMA engine
* @base: port base address
@@ -952,6 +1024,7 @@ static int mv_stop_edma(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data;
+ struct mv_host_priv *hpriv = ap->host->private_data;
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
return 0;
@@ -961,6 +1034,10 @@ static int mv_stop_edma(struct ata_port *ap)
ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
return -EIO;
}
+
+ if (hpriv->hp_flags & MV_HP_NCQ_LED_QUIRK)
+ mv_quirk_blink_led_when_ncq(ap, false);
+
return 0;
}
@@ -1222,6 +1299,9 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
}
if (want_ncq) {
+ if (hpriv->hp_flags & MV_HP_NCQ_LED_QUIRK)
+ mv_quirk_blink_led_when_ncq(ap, true);
+
cfg |= EDMA_CFG_NCQ;
pp->pp_flags |= MV_PP_FLAG_NCQ_EN;
} else
@@ -2690,6 +2770,19 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
return;
}
+static void mv_iie_enable_led_blink(struct mv_host_priv *hpriv,
+ void __iomem *mmio, int enable_blink)
+{
+ void __iomem *hc_mmio = mv_hc_base(mmio, 0);
+ u32 tmp = readl(hc_mmio + IIE_LED_CTRL_OFS);
+
+ /* enable/disable blinking mode */
+ if (enable_blink)
+ writel(tmp | IIE_LED_CTRL_BLINK, hc_mmio + IIE_LED_CTRL_OFS);
+ else
+ writel(tmp & ~IIE_LED_CTRL_BLINK, hc_mmio + IIE_LED_CTRL_OFS);
+}
+
static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
{
u32 ifcfg = readl(port_mmio + SATA_INTERFACE_CFG_OFS);
@@ -2997,8 +3090,8 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
}
/* drop through */
case chip_6042:
- hpriv->ops = &mv6xxx_ops;
- hp_flags |= MV_HP_GEN_IIE;
+ hpriv->ops = &mv6xxx_iie_ops;
+ hp_flags |= MV_HP_GEN_IIE | MV_HP_NCQ_LED_QUIRK;
if (board_idx == chip_6042 && mv_pci_cut_through_okay(host))
hp_flags |= MV_HP_CUT_THROUGH;
@@ -3016,7 +3109,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
case chip_soc:
hpriv->ops = &mv_soc_ops;
hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
- MV_HP_ERRATA_60X1C0;
+ MV_HP_ERRATA_60X1C0 | MV_HP_NCQ_LED_QUIRK;
break;
default:
next prev parent reply other threads:[~2009-03-11 7:15 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-11 7:13 [PATCH,v2][0/2] sata_mv: harddisk activity led no longer responsive on QNAP TS-109 Frans Pop
2009-03-11 7:15 ` Frans Pop [this message]
2009-03-11 12:47 ` [PATCH,v2][1/2] sata-mv: enable HDD led blinking when NCQ is active for GenIIe Mark Lord
2009-03-11 13:08 ` Frans Pop
2009-03-11 14:15 ` Mark Lord
2009-03-12 11:40 ` Frans Pop
2009-03-12 14:14 ` Mark Lord
2009-03-12 14:15 ` Mark Lord
2009-03-12 14:26 ` Mark Lord
2009-03-13 8:07 ` Frans Pop
2009-03-13 13:04 ` Mark Lord
2009-03-13 18:19 ` Frans Pop
2009-03-13 19:09 ` Mark Lord
2009-03-14 11:57 ` Frans Pop
2009-03-14 14:53 ` Mark Lord
2009-03-15 10:18 ` Frans Pop
2009-03-12 14:27 ` Frans Pop
2009-03-12 14:31 ` Mark Lord
2009-03-11 7:17 ` [PATCH,v2][2/2] sata-mv: add module parameter msq_blink_led to enable quirk " Frans Pop
2009-03-11 12:33 ` [PATCH,v2][0/2] sata_mv: harddisk activity led no longer responsive on QNAP TS-109 Mark Lord
2009-03-11 12:58 ` Mark Lord
2009-03-11 13:01 ` Frans Pop
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200903110815.52650.elendil@planet.nl \
--to=elendil@planet.nl \
--cc=buytenh@wantstofly.org \
--cc=liml@rtr.ca \
--cc=linux-arm@vger.kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=nico@cam.org \
--cc=saeed@marvell.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.