5 Replies Latest reply on Feb 28, 2019 4:34 AM by VinayakS_26

    Set sdio drive strength on CYW43364

      Hi,

      I have a board mounting a CYW43364-based module running a linux-based system.

       

      I want to change sdio drive strength for the chip.

       

      According to brcmf_sdio_drivestrengthinit in drivers/net/wireless/brcm80211/brcmfmac/sdio.c it seems I cannot do it, but since the device is treated as CYW43430 and that I don't have an application manual of the chip (a document describing registers) I need some hint.

       

      For instance it seems to be possible to achieve this goal when using a CYW43362 device...

       

      Also devicetree bindings documentation doesn't help so much since it is the same for all brcmfmac devices ["brcm,drive-strength : drive strength used for SDIO pins on device in mA (default = 6)."].

       

      I checked also mainline 4.20 kernel version and the mentioned function (brcmf_sdio_drivestrengthinit) shed no more light.

       

      Thank you for an help

        • 1. Re: Set sdio drive strength on CYW43364
          VinayakS_26

          Hi,


          Could you printout the current driver strength that is being used in the dhd driver.

          Is it same as the default macro 

            DEFAULT_SDIO_DRIVE_STRENGTH 6

           

          Regards

          Vinayak

          • 2. Re: Set sdio drive strength on CYW43364

            Hi Vinayak, thanks for the answer.
            It's not clear to me what you are asking. If you watch at brcmf_sdio_drivestrengthinit function in drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c

            it look like this:

             

            brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,

                                         struct brcmf_chip *ci, u32 drivestrength)

            {

                    [...] /* variables definition */

                    if (!(ci->cc_caps & CC_CAP_PMU))

                            return;

             

                    /* set-up registers according to the chipset */

                    switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {

                    case SDIOD_DRVSTR_KEY(BRCM_CC_4330_CHIP_ID, 12):

                            str_tab = sdiod_drvstr_tab1_1v8;

                            str_mask = 0x00003800;

                            str_shift = 11;

                            break;

                    case SDIOD_DRVSTR_KEY(BRCM_CC_4334_CHIP_ID, 17):

                            str_tab = sdiod_drvstr_tab6_1v8;

                            str_mask = 0x00001800;

                            str_shift = 11;

                            break;

                    case SDIOD_DRVSTR_KEY(BRCM_CC_43143_CHIP_ID, 17):

                            /* note: 43143 does not support tristate */

                            i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;

                            if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {

                                    str_tab = sdiod_drvstr_tab2_3v3;

                                    str_mask = 0x00000007;

                                    str_shift = 0;

                            } else

                                    brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",

                                              ci->name, drivestrength);

                            break;

                    case SDIOD_DRVSTR_KEY(BRCM_CC_43362_CHIP_ID, 13):

                            str_tab = sdiod_drive_strength_tab5_1v8;

                            str_mask = 0x00003800;

                            str_shift = 11;

                            break;

                    default:

                            /* With my device CYW43364 treated as CYW43430 I fall in this case */

                            brcmf_dbg(INFO, "No SDIO driver strength init needed for chip %s rev %d pmurev %d\n",

                                      ci->name, ci->chiprev, ci->pmurev);

                            break;

                    }

             

                    if (str_tab != NULL) {

                            [...] /* I don't enter this piece of code! */

                            /* write drive strength setting */

                            brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);

                    }

            }

             

            So, if I'm well understanding the code, I can choose whatever drive strength using devicetree, but nothing is really set on the device.

            The drive strength seems to be never set for my chipset.

            If you want me to do some test and/or read registers, please let me know how to behave.
            Thanks,

             

            Davide

            • 3. Re: Set sdio drive strength on CYW43364
              VinayakS_26

              Could you print out the the ci->chip and ci->pmurev, just to confirm the chip ID and the PMU revision.

              I believe you require the values to the following parameters for 43430 if i am not mistaken

              str_tab ,str_mask ,str_shift.

              1 of 1 people found this helpful
              • 4. Re: Set sdio drive strength on CYW43364

                Hi Vinayak, thanks for the answer.

                 

                In my situation:

                ci->chip = 43430

                ci->name="43430"

                ci->chiprev = 1

                ci->pmurev = 24

                 

                If you could give me str_tab ,str_mask ,str_shift for 43364 it would be great!

                 

                Thanks,

                Davide

                 

                • 5. Re: Set sdio drive strength on CYW43364
                  VinayakS_26

                  Hi,

                   

                  I was referring to this particular code in sdio.c

                  if (sdiodev->settings->bus.sdio.drive_strength)

                        drivestrength = sdiodev->settings->bus.sdio.drive_strength;

                  else

                        drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;

                  brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength);

                   

                   

                  The DEFAULT_SDIO_DRIVE_STRENGTH is set as 6mA.

                   

                  Now for the values

                  The drive strength for the device is either provided by the sdio core registers(standard way) or the PMU Chipcontrol registers(as backup).

                   

                  The definition you see in the function brcmf_sdio_drivestrengthinit() are only for PMU chipcontrol registers.

                  See addr = CORE_CC_REG(pmu->base, chipcontrol_addr);

                  in brcmf_sdio_drivestrengthinit()

                   

                  But these are defined only for certain chip ids. For the other chip ids, the drive strength is provided by sdio core itself.

                   

                  Regards,

                  Vinayak

                   

                  PS sorry for the late reply

                   

                  1 of 1 people found this helpful