Hi Chris,

I have modified the PATCH file as your suggestions. It has been sent
today.

1. I didn't add " SDHCI_QUIRK_BROKEN_ADMA ".
= Because of O2 SD function has ADMA, ADMA2 and the other related
registers. It can't be controlled by the normal ADMA flag. So, the "
SDHCI_QUIRK_BROKEN_ADMA " flag isn't suitable for O2 chip.

2. I have removed the redundancy " pci_read_config_byte" routines as
your suggestions.
= For safety, we has suggested that we need those " pci_read_config_byte
" routines. If the chip was broken, the " pci_read_config_byte " can
protect the Linux OS crash. But we still remove the "
pci_read_config_byte " routines as your suggestions.

Best regards,
Jennifer
-----Original Message-----
From: Chris Ball [mailto:c...@laptop.org]
Sent: Thursday, November 18, 2010 12:16 PM
To: Jennifer Li (TP)
Cc: linux-mmc@vger.kernel.org; mario_limoncie...@dell.com;
joseph_...@dell.com; Chris Van Hoof; rezwanul_ka...@dell.com; Shirley
Her (SC); Rich Lin (TP); Samuel Guan(WH); Hardys Lv(WH); William Lian
(TP)
Subject: Re: [PATCH 2.6.32]: Add new device IDs and registers
forMULTIMEDIACARD (MMC), SECURE DIGITAL (SD) cards.

Hi Jennifer,

This is looking better, thanks -- just a few more questions:

On Tue, Nov 16, 2010 at 02:05:16PM +0800, Jennifer Li (TP) wrote:
> Root cause:
> O2Micro's ADMA and related functions can't work by default Linux SD
> driver. We need mark those related registers.

If the goal is to disable ADMA, have you tried using the BROKEN_ADMA
quirk?  Like this:

static const struct sdhci_pci_fixes sdhci_o2 = {
        .probe          = o2_probe,
        .quirks         = SDHCI_QUIRK_BROKEN_ADMA,
};

If you do this, do you still need to perform the PCI writes?

> +             ret = pci_read_config_byte(chip->pdev,
O2_SDMMC_MULTI_VCC3V, &scratch);
> +             if (ret)
> +                     return ret;
> +
> +             scratch = 0x08;
> +             ret = pci_write_config_byte(chip->pdev,
O2_SDMMC_MULTI_VCC3V, scratch);

Here you read in a value to scratch, but then you go ahead and write
0x08 to the register regardless.  We can skip the read here, right?

> +             ret = pci_read_config_byte(chip->pdev,
O2_SDMMC_CAPABILITIES, &scratch);
> +             if (ret)
> +                     return ret;
> +
> +             scratch |= 0x01;
> +             ret = pci_write_config_byte(chip->pdev,
O2_SDMMC_CAPABILITIES, scratch);
> +
> +             ret = pci_read_config_byte(chip->pdev,
O2_SDMMC_CAPABILITIES, &scratch);
> +             if (ret)
> +                     return ret;
> +
> +             scratch = 0x73;
> +             ret = pci_write_config_byte(chip->pdev,
O2_SDMMC_CAPABILITIES, scratch);

Here you write a value to O2_SDMMC_CAPABILITIES that's dependent on the
read value, but then after that you immediately overwrite the register
with 0x73 regardless of what was in it before.  Why perform the first
read-and-write cycle and the second read, if you're just going to write
0x73 in the end?

> +
> +             ret = pci_read_config_byte(chip->pdev, O2_SDMMC_ADMA1,
&scratch);
> +             if (ret)
> +                     return ret;
> +
> +             scratch = 0x39;
> +             ret = pci_write_config_byte(chip->pdev, O2_SDMMC_ADMA1,
scratch);
> +
> +             ret = pci_read_config_byte(chip->pdev, O2_SDMMC_ADMA2,
&scratch);
> +             if (ret)
> +                     return ret;
> +
> +             scratch = 0x08;
> +             ret = pci_write_config_byte(chip->pdev, O2_SDMMC_ADMA2,
scratch);

Same as above -- if the write isn't dependent on the read, I don't see
why to bother with the read.  Also, you can avoid assigning the return
value of pci_write_config_byte() to "ret" now that we aren't testing
that.

> Signed-off-by: Jennifer Li Developer <jennifer...@o2micro.com>

I don't think "Developer" should be here, since the text should just be
your name.

Thanks,

--
Chris Ball   <c...@laptop.org>   <http://printf.net/>
One Laptop Per Child




Unless otherwise stated, this e-mail message does not constitute a solicitation 
to buy or sell any products or services, or to participate in any particular 
trading strategy. This e-mail message and any attachments are intended solely 
for the use of the individual or entity to which it is addressed and may 
contain information that is confidential or legally privileged. If you are not 
the intended recipient, you are hereby notified that any dissemination, 
distribution, copying or other use of this message or its attachments is 
strictly prohibited. If you have received this message in error, please notify 
the sender immediately and permanently delete this message and any attachments. 
O2Micro International Ltd., and its subsidiaries and affiliates, are neither 
liable for the proper and complete transmission of the information contained in 
this communication, the accuracy of the information contained therein, nor for 
any delay in its receipt.


--- Begin Message ---
Hi,

Issue Description:
SD/MMC card can't be recognized by O2 chip.

Root cause:
O2Micro's ADMA and related functions can't work by default Linux SD
driver. We need mark those related registers.
        
Patch description: 
  - SET MULTI 3 to VCC3V# 
  - Disable CLK_REQ# support after media DET.
  - Choose programmable settings 
  - Enable SDMA
  - Disable ADMA1
  - Disable ADMA2
  - Disable the infinite transfer mode
 
Linux Kernel version:
This patch was based on Linux Kernel version 2.6.32. It should be added
from Linux kernel 2.6.32 and the newer kernel versions.

Supplement:
We are trying to add the enable ADMA patch later.

PATCH content:

Pci_ids.h

--- ../untitled folder/linux-2.6.32/include/linux/pci_ids.h
2009-12-03 11:51:21.000000000 +0800
+++ ./pci_ids.h 2010-11-15 17:56:26.103132569 +0800
@@ -2694,3 +2694,14 @@
 #define PCI_DEVICE_ID_RME_DIGI32       0x9896
 #define PCI_DEVICE_ID_RME_DIGI32_PRO   0x9897
 #define PCI_DEVICE_ID_RME_DIGI32_8     0x9898
+
+#define PCI_VENDOR_ID_O2               0x1217
+#define PCI_DEVICE_ID_O2_6729          0x6729
+#define PCI_DEVICE_ID_O2_6730          0x673a
+#define PCI_DEVICE_ID_O2_6832          0x6832
+#define PCI_DEVICE_ID_O2_6836          0x6836
+#define PCI_DEVICE_ID_O2_8120          0x8120
+#define PCI_DEVICE_ID_O2_8220          0x8220
+#define PCI_DEVICE_ID_O2_8320          0x8320
+#define PCI_DEVICE_ID_O2_8321          0x8321
+#define PCI_DEVICE_ID_O2_8221          0x8221


Sdhci-pci.c

--- linux-2.6.32/drivers/mmc/host/sdhci-pci.c   2009-12-03
11:51:21.000000000 +0800
+++ Q20101122sdhci-pci/sdhci-pci.c      2010-11-18 07:59:38.119873198
+0800
@@ -38,6 +38,14 @@
 
 #define MAX_SLOTS                      8
 
+#define O2_SDMMC_LOCK_WP 0xD3
+#define O2_SDMMC_MULTI_VCC3V 0xEE
+#define O2_SDMMC_CLKREQ 0xEC
+#define O2_SDMMC_CAPABILITIES 0xE0
+#define O2_SDMMC_ADMA1 0xE2
+#define O2_SDMMC_ADMA2 0xE7
+#define O2_SDMMC_INFINIT_MODE 0xF1
+
 struct sdhci_pci_chip;
 struct sdhci_pci_slot;
 
@@ -112,6 +120,78 @@ static const struct sdhci_pci_fixes sdhc
                          SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
 };
 
+static int o2_probe(struct sdhci_pci_chip *chip)
+{
+       int ret;
+       u8 scratch;
+
+       if ((chip->pdev->device == PCI_DEVICE_ID_O2_8220) ||
+           (chip->pdev->device == PCI_DEVICE_ID_O2_8320) ||
+           (chip->pdev->device == PCI_DEVICE_ID_O2_8321) ||
+           (chip->pdev->device == PCI_DEVICE_ID_O2_8221))
+           {
+               /* O2Micro's ADMA and releated function can't work on
default Linux SD driver.
+         * We need mark those related registers.
+         * - SET MULTI 3 to VCC3V# 
+         * - Disable CLK_REQ# support after media DET.
+         * - Choose programmable settings 
+         * - Enable SDMA
+         * - Disable ADMA1
+         * - Disable ADMA2
+         * - Disable the infinit transfer mode
+         */
+               ret = pci_read_config_byte(chip->pdev, O2_SDMMC_LOCK_WP,
&scratch);
+               if (ret)
+                       return ret;
+       
+               scratch &= 0x7f;
+               ret = pci_write_config_byte(chip->pdev,
O2_SDMMC_LOCK_WP, scratch);
+       
+               scratch = 0x08; 
+               ret = pci_write_config_byte(chip->pdev,
O2_SDMMC_MULTI_VCC3V, scratch);
+
+
+               ret = pci_read_config_byte(chip->pdev, O2_SDMMC_CLKREQ,
&scratch);
+               if (ret)
+                       return ret;
+       
+               scratch |= 0x20;        
+               ret = pci_write_config_byte(chip->pdev, O2_SDMMC_CLKREQ,
scratch);
+
+               ret = pci_read_config_byte(chip->pdev,
O2_SDMMC_CAPABILITIES, &scratch);
+               if (ret)
+                       return ret;
+       
+               scratch |= 0x01;
+               ret = pci_write_config_byte(chip->pdev,
O2_SDMMC_CAPABILITIES, scratch);
+       
+               scratch = 0x73;
+               ret = pci_write_config_byte(chip->pdev,
O2_SDMMC_CAPABILITIES, scratch);
+       
+               scratch = 0x39; 
+               ret = pci_write_config_byte(chip->pdev, O2_SDMMC_ADMA1,
scratch);
+
+               scratch = 0x08; 
+               ret = pci_write_config_byte(chip->pdev, O2_SDMMC_ADMA2,
scratch);
+
+               ret = pci_read_config_byte(chip->pdev,
O2_SDMMC_INFINIT_MODE, &scratch);
+               if (ret)
+                       return ret;
+       
+               scratch |= 0x08;
+               ret = pci_write_config_byte(chip->pdev,
O2_SDMMC_INFINIT_MODE, scratch);
+
+               ret = pci_read_config_byte(chip->pdev, O2_SDMMC_LOCK_WP,
&scratch);
+               if (ret)
+                       return ret;
+
+               scratch |= 0x80;        
+               ret = pci_write_config_byte(chip->pdev,
O2_SDMMC_LOCK_WP, scratch);
+
+               }
+       return 0;
+}
+
 static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
 {
        u8 scratch;
@@ -275,6 +355,10 @@ static int jmicron_resume(struct sdhci_p
        return 0;
 }
 
+static const struct sdhci_pci_fixes sdhci_o2 = {
+       .probe          = o2_probe,
+};
+
 static const struct sdhci_pci_fixes sdhci_jmicron = {
        .probe          = jmicron_probe,
 
@@ -370,6 +454,46 @@ static const struct pci_device_id pci_id
                .driver_data    = (kernel_ulong_t)&sdhci_via,
        },
 
+        {
+               .vendor         = PCI_VENDOR_ID_O2,
+               .device         = PCI_DEVICE_ID_O2_8120,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_o2,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_O2,
+               .device         = PCI_DEVICE_ID_O2_8220,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_o2,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_O2,
+               .device         = PCI_DEVICE_ID_O2_8320,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_o2,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_O2,
+               .device         = PCI_DEVICE_ID_O2_8221,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_o2,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_O2,
+               .device         = PCI_DEVICE_ID_O2_8321,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_o2,
+       },
+
        {       /* Generic SD host controller */
                PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8),
0xFFFF00)
        },


Signed-off-by: Jennifer Li <jennifer...@o2micro.com>

Best regards,
Jennifer

Attachment: pci_ids_patch
Description: pci_ids_patch

Attachment: sdhci-pci_patch
Description: sdhci-pci_patch


--- End Message ---

Reply via email to