mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] Add support for new JMicron memstick controllers
@ 2010-12-07  7:56 Takashi Iwai
  2010-12-07  7:56 ` [PATCH 1/3] memstick: Fix setup for JMicron 38x controllers Takashi Iwai
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Takashi Iwai @ 2010-12-07  7:56 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Alex Dubov, Aries Lee

This patch series fix and correct setups for JMicron 38x memory-stick
controllers, and add the support for new controller chips.

The patches have been tested with MS-pro devices on 2.6.37-rc4.


thanks,

Takashi


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] memstick: Fix setup for JMicron 38x controllers
  2010-12-07  7:56 [PATCH 0/3] Add support for new JMicron memstick controllers Takashi Iwai
@ 2010-12-07  7:56 ` Takashi Iwai
  2010-12-07  7:56 ` [PATCH 2/3] memstick: Set PMOS values propery " Takashi Iwai
  2010-12-07  7:56 ` [PATCH 3/3] memstick: Add support for JMicron JMB 385 and 390 controllers Takashi Iwai
  2 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2010-12-07  7:56 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Alex Dubov, Aries Lee, Takashi Iwai

This patch corrects the definition of clock values for JMicron 38x
controllers and sets the value properly per interface type.
Also, it adds a check for TPC errors in the interrupt handler.

Signed-off-by: Aries Lee <arieslee@jmicron.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 drivers/memstick/host/jmb38x_ms.c |   66 ++++++++++++++++++++-----------------
 1 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index f2b894c..c90ba50 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -61,6 +61,7 @@ struct jmb38x_ms_host {
 	struct memstick_request *req;
 	unsigned char           cmd_flags;
 	unsigned char           io_pos;
+	unsigned char           ifmode;
 	unsigned int            io_word[2];
 };
 
@@ -136,15 +137,14 @@ struct jmb38x_ms {
 #define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
 #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
 
+#define CLOCK_CONTROL_BY_MMIO 0x00000008
 #define CLOCK_CONTROL_40MHZ   0x00000001
-#define CLOCK_CONTROL_50MHZ   0x0000000a
-#define CLOCK_CONTROL_60MHZ   0x00000008
-#define CLOCK_CONTROL_62_5MHZ 0x0000000c
+#define CLOCK_CONTROL_50MHZ   0x00000002
+#define CLOCK_CONTROL_60MHZ   0x00000010
+#define CLOCK_CONTROL_62_5MHZ 0x00000004
 #define CLOCK_CONTROL_OFF     0x00000000
 
 #define PCI_CTL_CLOCK_DLY_ADDR   0x000000b0
-#define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00
-#define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000
 
 enum {
 	CMD_READY    = 0x01,
@@ -390,8 +390,13 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
 
 	if (host->req->data_dir == READ)
 		cmd |= TPC_DIR;
-	if (host->req->need_card_int)
-		cmd |= TPC_WAIT_INT;
+
+	if (host->req->need_card_int) {
+		if (host->ifmode == MEMSTICK_SERIAL)
+			cmd |= TPC_GET_INT;
+		else
+			cmd |= TPC_WAIT_INT;
+	}
 
 	data = host->req->data;
 
@@ -529,7 +534,10 @@ static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
 		if (irq_status & INT_STATUS_ANY_ERR) {
 			if (irq_status & INT_STATUS_CRC_ERR)
 				host->req->error = -EILSEQ;
-			else
+			else if (irq_status & INT_STATUS_TPC_ERR) {
+				dev_dbg(&host->chip->pdev->dev, "TPC_ERR\n");
+				jmb38x_ms_complete_cmd(msh, 0);
+			} else
 				host->req->error = -ETIME;
 		} else {
 			if (host->cmd_flags & DMA_DATA) {
@@ -644,7 +652,6 @@ static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
 		ndelay(20);
 	}
 	dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
-	/* return -EIO; */
 
 reset_next:
 	writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
@@ -675,7 +682,7 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
 {
 	struct jmb38x_ms_host *host = memstick_priv(msh);
 	unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
-	unsigned int clock_ctl = CLOCK_CONTROL_40MHZ, clock_delay = 0;
+	unsigned int clock_ctl = CLOCK_CONTROL_BY_MMIO, clock_delay = 0;
 	int rc = 0;
 
 	switch (param) {
@@ -687,9 +694,7 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
 
 			host_ctl = 7;
 			host_ctl |= HOST_CONTROL_POWER_EN
-				    | HOST_CONTROL_CLOCK_EN
-				    | HOST_CONTROL_HW_OC_P
-				    | HOST_CONTROL_TDELAY_EN;
+				 | HOST_CONTROL_CLOCK_EN;
 			writel(host_ctl, host->addr + HOST_CONTROL);
 
 			writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
@@ -712,41 +717,42 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
 			return -EINVAL;
 		break;
 	case MEMSTICK_INTERFACE:
+		dev_dbg(&host->chip->pdev->dev,
+			"Set Host Interface Mode to %d\n", value);
+		host_ctl &= ~(HOST_CONTROL_FAST_CLK | HOST_CONTROL_REI |
+			      HOST_CONTROL_REO);
+		host_ctl |= HOST_CONTROL_TDELAY_EN | HOST_CONTROL_HW_OC_P;
 		host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
-		pci_read_config_dword(host->chip->pdev,
-				      PCI_CTL_CLOCK_DLY_ADDR,
-				      &clock_delay);
-		clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B
-					: ~PCI_CTL_CLOCK_DLY_MASK_A;
 
 		if (value == MEMSTICK_SERIAL) {
-			host_ctl &= ~HOST_CONTROL_FAST_CLK;
-			host_ctl &= ~HOST_CONTROL_REO;
 			host_ctl |= HOST_CONTROL_IF_SERIAL
 				    << HOST_CONTROL_IF_SHIFT;
 			host_ctl |= HOST_CONTROL_REI;
-			clock_ctl = CLOCK_CONTROL_40MHZ;
+			clock_ctl |= CLOCK_CONTROL_40MHZ;
+			clock_delay = 0;
 		} else if (value == MEMSTICK_PAR4) {
-			host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO;
+			host_ctl |= HOST_CONTROL_FAST_CLK;
 			host_ctl |= HOST_CONTROL_IF_PAR4
 				    << HOST_CONTROL_IF_SHIFT;
-			host_ctl &= ~HOST_CONTROL_REI;
-			clock_ctl = CLOCK_CONTROL_40MHZ;
-			clock_delay |= host->id ? (4 << 12) : (4 << 8);
+			host_ctl |= HOST_CONTROL_REO;
+			clock_ctl |= CLOCK_CONTROL_40MHZ;
+			clock_delay = 4;
 		} else if (value == MEMSTICK_PAR8) {
 			host_ctl |= HOST_CONTROL_FAST_CLK;
 			host_ctl |= HOST_CONTROL_IF_PAR8
 				    << HOST_CONTROL_IF_SHIFT;
-			host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO);
-			clock_ctl = CLOCK_CONTROL_50MHZ;
+			clock_ctl |= CLOCK_CONTROL_50MHZ;
+			clock_delay = 0;
 		} else
 			return -EINVAL;
 
 		writel(host_ctl, host->addr + HOST_CONTROL);
+		writel(CLOCK_CONTROL_OFF, host->addr + CLOCK_CONTROL);
 		writel(clock_ctl, host->addr + CLOCK_CONTROL);
-		pci_write_config_dword(host->chip->pdev,
-				       PCI_CTL_CLOCK_DLY_ADDR,
-				       clock_delay);
+		pci_write_config_byte(host->chip->pdev,
+				      PCI_CTL_CLOCK_DLY_ADDR + 1,
+				      clock_delay);
+		host->ifmode = value;
 		break;
 	};
 	return 0;
-- 
1.7.3.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/3] memstick: Set PMOS values propery for JMicron 38x controllers
  2010-12-07  7:56 [PATCH 0/3] Add support for new JMicron memstick controllers Takashi Iwai
  2010-12-07  7:56 ` [PATCH 1/3] memstick: Fix setup for JMicron 38x controllers Takashi Iwai
@ 2010-12-07  7:56 ` Takashi Iwai
  2010-12-07  7:56 ` [PATCH 3/3] memstick: Add support for JMicron JMB 385 and 390 controllers Takashi Iwai
  2 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2010-12-07  7:56 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Alex Dubov, Aries Lee, Takashi Iwai

Add a function jmb38x_ms_pmos() to enable / disable PMOS setups for
JMicron 38x controllers.

Signed-off-by: Aries Lee <arieslee@jmicron.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 drivers/memstick/host/jmb38x_ms.c |   37 +++++++++++++++++++++++++++++++++----
 1 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index c90ba50..4ce8773 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -758,6 +758,35 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
 	return 0;
 }
 
+#define PCI_PMOS0_CONTROL		0xae
+#define  PMOS0_ENABLE			0x01
+#define  PMOS0_OVERCURRENT_LEVEL_2_4V	0x06
+#define  PMOS0_EN_OVERCURRENT_DEBOUNCE	0x40
+#define  PMOS0_SW_LED_POLARITY_ENABLE	0x80
+#define  PMOS0_ACTIVE_BITS (PMOS0_ENABLE | PMOS0_EN_OVERCURRENT_DEBOUNCE | \
+			    PMOS0_OVERCURRENT_LEVEL_2_4V)
+#define PCI_CLOCK_CTL			0xb9
+
+static int jmb38x_ms_pmos(struct pci_dev *pdev, int flag)
+{
+	unsigned char val;
+
+	pci_read_config_byte(pdev, PCI_PMOS0_CONTROL, &val);
+	if (flag)
+		val |= PMOS0_ACTIVE_BITS;
+	else
+		val &= ~PMOS0_ACTIVE_BITS;
+	pci_write_config_byte(pdev, PCI_PMOS0_CONTROL, val);
+	dev_dbg(&pdev->dev, "JMB38x: set PMOS0 val 0x%x\n", val);
+
+	pci_read_config_byte(pdev, PCI_CLOCK_CTL, &val);
+	pci_write_config_byte(pdev, PCI_CLOCK_CTL, val & ~0x0f);
+	pci_write_config_byte(pdev, PCI_CLOCK_CTL, val | 0x01);
+	dev_dbg(&pdev->dev, "Clock Control by PCI config is disabled!\n");
+
+        return 0;
+}
+
 #ifdef CONFIG_PM
 
 static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state)
@@ -790,8 +819,7 @@ static int jmb38x_ms_resume(struct pci_dev *dev)
 		return rc;
 	pci_set_master(dev);
 
-	pci_read_config_dword(dev, 0xac, &rc);
-	pci_write_config_dword(dev, 0xac, rc | 0x00470000);
+	jmb38x_ms_pmos(dev, 1);
 
 	for (rc = 0; rc < jm->host_cnt; ++rc) {
 		if (!jm->hosts[rc])
@@ -900,8 +928,7 @@ static int jmb38x_ms_probe(struct pci_dev *pdev,
 		goto err_out;
 	}
 
-	pci_read_config_dword(pdev, 0xac, &rc);
-	pci_write_config_dword(pdev, 0xac, rc | 0x00470000);
+	jmb38x_ms_pmos(pdev, 1);
 
 	cnt = jmb38x_ms_count_slots(pdev);
 	if (!cnt) {
@@ -982,6 +1009,8 @@ static void jmb38x_ms_remove(struct pci_dev *dev)
 		jmb38x_ms_free_host(jm->hosts[cnt]);
 	}
 
+	jmb38x_ms_pmos(dev, 0);
+
 	pci_set_drvdata(dev, NULL);
 	pci_release_regions(dev);
 	pci_disable_device(dev);
-- 
1.7.3.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/3] memstick: Add support for JMicron JMB 385 and 390 controllers
  2010-12-07  7:56 [PATCH 0/3] Add support for new JMicron memstick controllers Takashi Iwai
  2010-12-07  7:56 ` [PATCH 1/3] memstick: Fix setup for JMicron 38x controllers Takashi Iwai
  2010-12-07  7:56 ` [PATCH 2/3] memstick: Set PMOS values propery " Takashi Iwai
@ 2010-12-07  7:56 ` Takashi Iwai
  2010-12-08  1:48   ` Alex Dubov
  2 siblings, 1 reply; 5+ messages in thread
From: Takashi Iwai @ 2010-12-07  7:56 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Alex Dubov, Aries Lee, Takashi Iwai

Signed-off-by: Aries Lee <arieslee@jmicron.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 drivers/memstick/host/jmb38x_ms.c |   17 +++++++++++++++--
 include/linux/pci_ids.h           |    2 ++
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 4ce8773..d89d925 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -765,6 +765,8 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
 #define  PMOS0_SW_LED_POLARITY_ENABLE	0x80
 #define  PMOS0_ACTIVE_BITS (PMOS0_ENABLE | PMOS0_EN_OVERCURRENT_DEBOUNCE | \
 			    PMOS0_OVERCURRENT_LEVEL_2_4V)
+#define PCI_PMOS1_CONTROL		0xbd
+#define  PMOS1_ACTIVE_BITS		0x4a
 #define PCI_CLOCK_CTL			0xb9
 
 static int jmb38x_ms_pmos(struct pci_dev *pdev, int flag)
@@ -779,6 +781,16 @@ static int jmb38x_ms_pmos(struct pci_dev *pdev, int flag)
 	pci_write_config_byte(pdev, PCI_PMOS0_CONTROL, val);
 	dev_dbg(&pdev->dev, "JMB38x: set PMOS0 val 0x%x\n", val);
 
+	if (pci_resource_flags(pdev, 1)) {
+		pci_read_config_byte(pdev, PCI_PMOS1_CONTROL, &val);
+		if (flag)
+			val |= PMOS1_ACTIVE_BITS;
+		else
+			val &= ~PMOS1_ACTIVE_BITS;
+		pci_write_config_byte(pdev, PCI_PMOS1_CONTROL, val);
+		dev_dbg(&pdev->dev, "JMB38x: set PMOS1 val 0x%x\n", val);
+	}
+
 	pci_read_config_byte(pdev, PCI_CLOCK_CTL, &val);
 	pci_write_config_byte(pdev, PCI_CLOCK_CTL, val & ~0x0f);
 	pci_write_config_byte(pdev, PCI_CLOCK_CTL, val | 0x01);
@@ -1018,8 +1030,9 @@ static void jmb38x_ms_remove(struct pci_dev *dev)
 }
 
 static struct pci_device_id jmb38x_ms_id_tbl [] = {
-	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS, PCI_ANY_ID,
-	  PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS) },
+	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB385_MS) },
+	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB390_MS) },
 	{ }
 };
 
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index d369b53..d7df8e0 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2362,6 +2362,8 @@
 #define PCI_DEVICE_ID_JMICRON_JMB38X_SD	0x2381
 #define PCI_DEVICE_ID_JMICRON_JMB38X_MMC 0x2382
 #define PCI_DEVICE_ID_JMICRON_JMB38X_MS	0x2383
+#define PCI_DEVICE_ID_JMICRON_JMB385_MS	0x2388
+#define PCI_DEVICE_ID_JMICRON_JMB390_MS	0x2393
 
 #define PCI_VENDOR_ID_KORENIX		0x1982
 #define PCI_DEVICE_ID_KORENIX_JETCARDF0	0x1600
-- 
1.7.3.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 3/3] memstick: Add support for JMicron JMB 385 and 390 controllers
  2010-12-07  7:56 ` [PATCH 3/3] memstick: Add support for JMicron JMB 385 and 390 controllers Takashi Iwai
@ 2010-12-08  1:48   ` Alex Dubov
  0 siblings, 0 replies; 5+ messages in thread
From: Alex Dubov @ 2010-12-08  1:48 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Aries Lee, Takashi Iwai

Hi everybody.

It appears, this series of patches rectifies the issues with Jmicron
discussed earlier.

Andrew, can we put in my last four small patches as well?



      

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-12-08  1:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-07  7:56 [PATCH 0/3] Add support for new JMicron memstick controllers Takashi Iwai
2010-12-07  7:56 ` [PATCH 1/3] memstick: Fix setup for JMicron 38x controllers Takashi Iwai
2010-12-07  7:56 ` [PATCH 2/3] memstick: Set PMOS values propery " Takashi Iwai
2010-12-07  7:56 ` [PATCH 3/3] memstick: Add support for JMicron JMB 385 and 390 controllers Takashi Iwai
2010-12-08  1:48   ` Alex Dubov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome