LCOV - code coverage report
Current view: top level - drivers/bcma - driver_chipcommon_pmu.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 272 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 17 0.0 %
Branches: 0 95 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Broadcom specific AMBA
       3                 :            :  * ChipCommon Power Management Unit driver
       4                 :            :  *
       5                 :            :  * Copyright 2009, Michael Buesch <m@bues.ch>
       6                 :            :  * Copyright 2007, 2011, Broadcom Corporation
       7                 :            :  * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
       8                 :            :  *
       9                 :            :  * Licensed under the GNU/GPL. See COPYING for details.
      10                 :            :  */
      11                 :            : 
      12                 :            : #include "bcma_private.h"
      13                 :            : #include <linux/export.h>
      14                 :            : #include <linux/bcma/bcma.h>
      15                 :            : 
      16                 :          0 : u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
      17                 :            : {
      18                 :          0 :         bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset);
      19                 :          0 :         bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR);
      20                 :          0 :         return bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA);
      21                 :            : }
      22                 :            : EXPORT_SYMBOL_GPL(bcma_chipco_pll_read);
      23                 :            : 
      24                 :          0 : void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
      25                 :            : {
      26                 :          0 :         bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset);
      27                 :          0 :         bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR);
      28                 :          0 :         bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value);
      29                 :          0 : }
      30                 :            : EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
      31                 :            : 
      32                 :          0 : void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
      33                 :            :                              u32 set)
      34                 :            : {
      35                 :          0 :         bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset);
      36                 :          0 :         bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR);
      37                 :          0 :         bcma_pmu_maskset32(cc, BCMA_CC_PMU_PLLCTL_DATA, mask, set);
      38                 :          0 : }
      39                 :            : EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
      40                 :            : 
      41                 :          0 : void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
      42                 :            :                                  u32 offset, u32 mask, u32 set)
      43                 :            : {
      44                 :          0 :         bcma_pmu_write32(cc, BCMA_CC_PMU_CHIPCTL_ADDR, offset);
      45                 :          0 :         bcma_pmu_read32(cc, BCMA_CC_PMU_CHIPCTL_ADDR);
      46                 :          0 :         bcma_pmu_maskset32(cc, BCMA_CC_PMU_CHIPCTL_DATA, mask, set);
      47                 :          0 : }
      48                 :            : EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
      49                 :            : 
      50                 :          0 : void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
      51                 :            :                                 u32 set)
      52                 :            : {
      53                 :          0 :         bcma_pmu_write32(cc, BCMA_CC_PMU_REGCTL_ADDR, offset);
      54                 :          0 :         bcma_pmu_read32(cc, BCMA_CC_PMU_REGCTL_ADDR);
      55                 :          0 :         bcma_pmu_maskset32(cc, BCMA_CC_PMU_REGCTL_DATA, mask, set);
      56                 :          0 : }
      57                 :            : EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
      58                 :            : 
      59                 :            : static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc)
      60                 :            : {
      61                 :            :         u32 ilp_ctl, alp_hz;
      62                 :            : 
      63                 :            :         if (!(bcma_pmu_read32(cc, BCMA_CC_PMU_STAT) &
      64                 :            :               BCMA_CC_PMU_STAT_EXT_LPO_AVAIL))
      65                 :            :                 return 0;
      66                 :            : 
      67                 :            :         bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
      68                 :            :                          BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
      69                 :            :         usleep_range(1000, 2000);
      70                 :            : 
      71                 :            :         ilp_ctl = bcma_pmu_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
      72                 :            :         ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK;
      73                 :            : 
      74                 :            :         bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
      75                 :            : 
      76                 :            :         alp_hz = ilp_ctl * 32768 / 4;
      77                 :            :         return (alp_hz + 50000) / 100000 * 100;
      78                 :            : }
      79                 :            : 
      80                 :          0 : static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq)
      81                 :            : {
      82                 :          0 :         struct bcma_bus *bus = cc->core->bus;
      83                 :          0 :         u32 freq_tgt_target = 0, freq_tgt_current;
      84                 :          0 :         u32 pll0, mask;
      85                 :            : 
      86         [ #  # ]:          0 :         switch (bus->chipinfo.id) {
      87                 :          0 :         case BCMA_CHIP_ID_BCM43142:
      88                 :            :                 /* pmu2_xtaltab0_adfll_485 */
      89   [ #  #  #  #  :          0 :                 switch (xtalfreq) {
                   #  # ]
      90                 :            :                 case 12000:
      91                 :          0 :                         freq_tgt_target = 0x50D52;
      92                 :          0 :                         break;
      93                 :            :                 case 20000:
      94                 :            :                         freq_tgt_target = 0x307FE;
      95                 :            :                         break;
      96                 :            :                 case 26000:
      97                 :          0 :                         freq_tgt_target = 0x254EA;
      98                 :          0 :                         break;
      99                 :            :                 case 37400:
     100                 :          0 :                         freq_tgt_target = 0x19EF8;
     101                 :          0 :                         break;
     102                 :            :                 case 52000:
     103                 :          0 :                         freq_tgt_target = 0x12A75;
     104                 :          0 :                         break;
     105                 :            :                 }
     106                 :            :                 break;
     107                 :            :         }
     108                 :            : 
     109                 :          0 :         if (!freq_tgt_target) {
     110                 :          0 :                 bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n",
     111                 :            :                          xtalfreq);
     112                 :          0 :                 return;
     113                 :            :         }
     114                 :            : 
     115                 :          0 :         pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0);
     116                 :          0 :         freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >>
     117                 :            :                 BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
     118                 :            : 
     119         [ #  # ]:          0 :         if (freq_tgt_current == freq_tgt_target) {
     120                 :            :                 bcma_debug(bus, "Target TGT frequency already set\n");
     121                 :            :                 return;
     122                 :            :         }
     123                 :            : 
     124                 :            :         /* Turn off PLL */
     125         [ #  # ]:          0 :         switch (bus->chipinfo.id) {
     126                 :          0 :         case BCMA_CHIP_ID_BCM43142:
     127                 :          0 :                 mask = (u32)~(BCMA_RES_4314_HT_AVAIL |
     128                 :            :                               BCMA_RES_4314_MACPHY_CLK_AVAIL);
     129                 :            : 
     130                 :          0 :                 bcma_pmu_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
     131                 :          0 :                 bcma_pmu_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
     132                 :          0 :                 bcma_wait_value(cc->core, BCMA_CLKCTLST,
     133                 :            :                                 BCMA_CLKCTLST_HAVEHT, 0, 20000);
     134                 :          0 :                 break;
     135                 :            :         }
     136                 :            : 
     137                 :          0 :         pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK;
     138                 :          0 :         pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
     139                 :          0 :         bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0);
     140                 :            : 
     141                 :            :         /* Flush */
     142         [ #  # ]:          0 :         if (cc->pmu.rev >= 2)
     143                 :          0 :                 bcma_pmu_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
     144                 :            : 
     145                 :            :         /* TODO: Do we need to update OTP? */
     146                 :            : }
     147                 :            : 
     148                 :          0 : static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
     149                 :            : {
     150                 :          0 :         struct bcma_bus *bus = cc->core->bus;
     151                 :          0 :         u32 xtalfreq = bcma_pmu_xtalfreq(cc);
     152                 :            : 
     153         [ #  # ]:          0 :         switch (bus->chipinfo.id) {
     154                 :          0 :         case BCMA_CHIP_ID_BCM43142:
     155         [ #  # ]:          0 :                 if (xtalfreq == 0)
     156                 :          0 :                         xtalfreq = 20000;
     157                 :          0 :                 bcma_pmu2_pll_init0(cc, xtalfreq);
     158                 :          0 :                 break;
     159                 :            :         }
     160                 :          0 : }
     161                 :            : 
     162                 :            : static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
     163                 :            : {
     164                 :            :         struct bcma_bus *bus = cc->core->bus;
     165                 :            :         u32 min_msk = 0, max_msk = 0;
     166                 :            : 
     167                 :            :         switch (bus->chipinfo.id) {
     168                 :            :         case BCMA_CHIP_ID_BCM4313:
     169                 :            :                 min_msk = 0x200D;
     170                 :            :                 max_msk = 0xFFFF;
     171                 :            :                 break;
     172                 :            :         case BCMA_CHIP_ID_BCM43142:
     173                 :            :                 min_msk = BCMA_RES_4314_LPLDO_PU |
     174                 :            :                           BCMA_RES_4314_PMU_SLEEP_DIS |
     175                 :            :                           BCMA_RES_4314_PMU_BG_PU |
     176                 :            :                           BCMA_RES_4314_CBUCK_LPOM_PU |
     177                 :            :                           BCMA_RES_4314_CBUCK_PFM_PU |
     178                 :            :                           BCMA_RES_4314_CLDO_PU |
     179                 :            :                           BCMA_RES_4314_LPLDO2_LVM |
     180                 :            :                           BCMA_RES_4314_WL_PMU_PU |
     181                 :            :                           BCMA_RES_4314_LDO3P3_PU |
     182                 :            :                           BCMA_RES_4314_OTP_PU |
     183                 :            :                           BCMA_RES_4314_WL_PWRSW_PU |
     184                 :            :                           BCMA_RES_4314_LQ_AVAIL |
     185                 :            :                           BCMA_RES_4314_LOGIC_RET |
     186                 :            :                           BCMA_RES_4314_MEM_SLEEP |
     187                 :            :                           BCMA_RES_4314_MACPHY_RET |
     188                 :            :                           BCMA_RES_4314_WL_CORE_READY;
     189                 :            :                 max_msk = 0x3FFFFFFF;
     190                 :            :                 break;
     191                 :            :         default:
     192                 :            :                 bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n",
     193                 :            :                            bus->chipinfo.id);
     194                 :            :         }
     195                 :            : 
     196                 :            :         /* Set the resource masks. */
     197                 :            :         if (min_msk)
     198                 :            :                 bcma_pmu_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
     199                 :            :         if (max_msk)
     200                 :            :                 bcma_pmu_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
     201                 :            : 
     202                 :            :         /*
     203                 :            :          * Add some delay; allow resources to come up and settle.
     204                 :            :          * Delay is required for SoC (early init).
     205                 :            :          */
     206                 :            :         usleep_range(2000, 2500);
     207                 :            : }
     208                 :            : 
     209                 :            : /* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
     210                 :          0 : void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
     211                 :            : {
     212                 :          0 :         struct bcma_bus *bus = cc->core->bus;
     213                 :          0 :         u32 val;
     214                 :            : 
     215                 :          0 :         val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
     216         [ #  # ]:          0 :         if (enable) {
     217                 :          0 :                 val |= BCMA_CHIPCTL_4331_EXTPA_EN;
     218         [ #  # ]:          0 :                 if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
     219                 :          0 :                         val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
     220         [ #  # ]:          0 :                 else if (bus->chipinfo.rev > 0)
     221                 :          0 :                         val |= BCMA_CHIPCTL_4331_EXTPA_EN2;
     222                 :            :         } else {
     223                 :          0 :                 val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
     224                 :          0 :                 val &= ~BCMA_CHIPCTL_4331_EXTPA_EN2;
     225                 :          0 :                 val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
     226                 :            :         }
     227                 :          0 :         bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
     228                 :          0 : }
     229                 :            : 
     230                 :          0 : static void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
     231                 :            : {
     232                 :          0 :         struct bcma_bus *bus = cc->core->bus;
     233                 :            : 
     234   [ #  #  #  # ]:          0 :         switch (bus->chipinfo.id) {
     235                 :          0 :         case BCMA_CHIP_ID_BCM4313:
     236                 :            :                 /*
     237                 :            :                  * enable 12 mA drive strenth for 4313 and set chipControl
     238                 :            :                  * register bit 1
     239                 :            :                  */
     240                 :          0 :                 bcma_chipco_chipctl_maskset(cc, 0,
     241                 :            :                                             ~BCMA_CCTRL_4313_12MA_LED_DRIVE,
     242                 :            :                                             BCMA_CCTRL_4313_12MA_LED_DRIVE);
     243                 :          0 :                 break;
     244                 :          0 :         case BCMA_CHIP_ID_BCM4331:
     245                 :            :         case BCMA_CHIP_ID_BCM43431:
     246                 :            :                 /* Ext PA lines must be enabled for tx on BCM4331 */
     247                 :          0 :                 bcma_chipco_bcm4331_ext_pa_lines_ctl(cc, true);
     248                 :          0 :                 break;
     249                 :          0 :         case BCMA_CHIP_ID_BCM43224:
     250                 :            :         case BCMA_CHIP_ID_BCM43421:
     251                 :            :                 /*
     252                 :            :                  * enable 12 mA drive strenth for 43224 and set chipControl
     253                 :            :                  * register bit 15
     254                 :            :                  */
     255         [ #  # ]:          0 :                 if (bus->chipinfo.rev == 0) {
     256                 :          0 :                         bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL,
     257                 :            :                                           ~BCMA_CCTRL_43224_GPIO_TOGGLE,
     258                 :            :                                           BCMA_CCTRL_43224_GPIO_TOGGLE);
     259                 :          0 :                         bcma_chipco_chipctl_maskset(cc, 0,
     260                 :            :                                                     ~BCMA_CCTRL_43224A0_12MA_LED_DRIVE,
     261                 :            :                                                     BCMA_CCTRL_43224A0_12MA_LED_DRIVE);
     262                 :            :                 } else {
     263                 :          0 :                         bcma_chipco_chipctl_maskset(cc, 0,
     264                 :            :                                                     ~BCMA_CCTRL_43224B0_12MA_LED_DRIVE,
     265                 :            :                                                     BCMA_CCTRL_43224B0_12MA_LED_DRIVE);
     266                 :            :                 }
     267                 :            :                 break;
     268                 :            :         default:
     269                 :            :                 bcma_debug(bus, "Workarounds unknown or not needed for device 0x%04X\n",
     270                 :            :                            bus->chipinfo.id);
     271                 :            :         }
     272                 :          0 : }
     273                 :            : 
     274                 :          0 : void bcma_pmu_early_init(struct bcma_drv_cc *cc)
     275                 :            : {
     276                 :          0 :         struct bcma_bus *bus = cc->core->bus;
     277                 :          0 :         u32 pmucap;
     278                 :            : 
     279         [ #  # ]:          0 :         if (cc->core->id.rev >= 35 &&
     280         [ #  # ]:          0 :             cc->capabilities_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) {
     281                 :          0 :                 cc->pmu.core = bcma_find_core(bus, BCMA_CORE_PMU);
     282         [ #  # ]:          0 :                 if (!cc->pmu.core)
     283                 :          0 :                         bcma_warn(bus, "Couldn't find expected PMU core");
     284                 :            :         }
     285         [ #  # ]:          0 :         if (!cc->pmu.core)
     286                 :          0 :                 cc->pmu.core = cc->core;
     287                 :            : 
     288                 :          0 :         pmucap = bcma_pmu_read32(cc, BCMA_CC_PMU_CAP);
     289                 :          0 :         cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
     290                 :            : 
     291                 :          0 :         bcma_debug(bus, "Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
     292                 :            :                    pmucap);
     293                 :          0 : }
     294                 :            : 
     295                 :          0 : void bcma_pmu_init(struct bcma_drv_cc *cc)
     296                 :            : {
     297         [ #  # ]:          0 :         if (cc->pmu.rev == 1)
     298                 :          0 :                 bcma_pmu_mask32(cc, BCMA_CC_PMU_CTL,
     299                 :            :                                 ~BCMA_CC_PMU_CTL_NOILPONW);
     300                 :            :         else
     301                 :          0 :                 bcma_pmu_set32(cc, BCMA_CC_PMU_CTL,
     302                 :            :                                BCMA_CC_PMU_CTL_NOILPONW);
     303                 :            : 
     304                 :          0 :         bcma_pmu_pll_init(cc);
     305                 :          0 :         bcma_pmu_resources_init(cc);
     306                 :          0 :         bcma_pmu_workarounds(cc);
     307                 :          0 : }
     308                 :            : 
     309                 :          0 : u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc)
     310                 :            : {
     311                 :          0 :         struct bcma_bus *bus = cc->core->bus;
     312                 :            : 
     313   [ #  #  #  # ]:          0 :         switch (bus->chipinfo.id) {
     314                 :            :         case BCMA_CHIP_ID_BCM4313:
     315                 :            :         case BCMA_CHIP_ID_BCM43224:
     316                 :            :         case BCMA_CHIP_ID_BCM43225:
     317                 :            :         case BCMA_CHIP_ID_BCM43227:
     318                 :            :         case BCMA_CHIP_ID_BCM43228:
     319                 :            :         case BCMA_CHIP_ID_BCM4331:
     320                 :            :         case BCMA_CHIP_ID_BCM43421:
     321                 :            :         case BCMA_CHIP_ID_BCM43428:
     322                 :            :         case BCMA_CHIP_ID_BCM43431:
     323                 :            :         case BCMA_CHIP_ID_BCM4716:
     324                 :            :         case BCMA_CHIP_ID_BCM47162:
     325                 :            :         case BCMA_CHIP_ID_BCM4748:
     326                 :            :         case BCMA_CHIP_ID_BCM4749:
     327                 :            :         case BCMA_CHIP_ID_BCM5357:
     328                 :            :         case BCMA_CHIP_ID_BCM53572:
     329                 :            :         case BCMA_CHIP_ID_BCM6362:
     330                 :            :                 /* always 20Mhz */
     331                 :            :                 return 20000 * 1000;
     332                 :          0 :         case BCMA_CHIP_ID_BCM4706:
     333                 :            :         case BCMA_CHIP_ID_BCM5356:
     334                 :            :                 /* always 25Mhz */
     335                 :          0 :                 return 25000 * 1000;
     336                 :          0 :         case BCMA_CHIP_ID_BCM43460:
     337                 :            :         case BCMA_CHIP_ID_BCM4352:
     338                 :            :         case BCMA_CHIP_ID_BCM4360:
     339         [ #  # ]:          0 :                 if (cc->status & BCMA_CC_CHIPST_4360_XTAL_40MZ)
     340                 :            :                         return 40000 * 1000;
     341                 :            :                 else
     342                 :          0 :                         return 20000 * 1000;
     343                 :          0 :         default:
     344                 :          0 :                 bcma_warn(bus, "No ALP clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
     345                 :            :                           bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
     346                 :            :         }
     347                 :          0 :         return BCMA_CC_PMU_ALP_CLOCK;
     348                 :            : }
     349                 :            : 
     350                 :            : /* Find the output of the "m" pll divider given pll controls that start with
     351                 :            :  * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
     352                 :            :  */
     353                 :          0 : static u32 bcma_pmu_pll_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
     354                 :            : {
     355                 :          0 :         u32 tmp, div, ndiv, p1, p2, fc;
     356                 :          0 :         struct bcma_bus *bus = cc->core->bus;
     357                 :            : 
     358   [ #  #  #  # ]:          0 :         BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
     359                 :            : 
     360         [ #  # ]:          0 :         BUG_ON(!m || m > 4);
     361                 :            : 
     362         [ #  # ]:          0 :         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
     363                 :            :             bus->chipinfo.id == BCMA_CHIP_ID_BCM4749) {
     364                 :            :                 /* Detect failure in clock setting */
     365                 :          0 :                 tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
     366         [ #  # ]:          0 :                 if (tmp & 0x40000)
     367                 :            :                         return 133 * 1000000;
     368                 :            :         }
     369                 :            : 
     370                 :          0 :         tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
     371                 :          0 :         p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
     372                 :          0 :         p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
     373                 :            : 
     374                 :          0 :         tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
     375                 :          0 :         div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
     376                 :            :                 BCMA_CC_PPL_MDIV_MASK;
     377                 :            : 
     378                 :          0 :         tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
     379                 :          0 :         ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
     380                 :            : 
     381                 :            :         /* Do calculation in Mhz */
     382                 :          0 :         fc = bcma_pmu_get_alp_clock(cc) / 1000000;
     383                 :          0 :         fc = (p1 * ndiv * fc) / p2;
     384                 :            : 
     385                 :            :         /* Return clock in Hertz */
     386                 :          0 :         return (fc / div) * 1000000;
     387                 :            : }
     388                 :            : 
     389                 :          0 : static u32 bcma_pmu_pll_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m)
     390                 :            : {
     391                 :          0 :         u32 tmp, ndiv, p1div, p2div;
     392                 :          0 :         u32 clock;
     393                 :            : 
     394         [ #  # ]:          0 :         BUG_ON(!m || m > 4);
     395                 :            : 
     396                 :            :         /* Get N, P1 and P2 dividers to determine CPU clock */
     397                 :          0 :         tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PMU6_4706_PROCPLL_OFF);
     398                 :          0 :         ndiv = (tmp & BCMA_CC_PMU6_4706_PROC_NDIV_INT_MASK)
     399                 :          0 :                 >> BCMA_CC_PMU6_4706_PROC_NDIV_INT_SHIFT;
     400                 :          0 :         p1div = (tmp & BCMA_CC_PMU6_4706_PROC_P1DIV_MASK)
     401                 :          0 :                 >> BCMA_CC_PMU6_4706_PROC_P1DIV_SHIFT;
     402                 :          0 :         p2div = (tmp & BCMA_CC_PMU6_4706_PROC_P2DIV_MASK)
     403                 :          0 :                 >> BCMA_CC_PMU6_4706_PROC_P2DIV_SHIFT;
     404                 :            : 
     405                 :          0 :         tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
     406         [ #  # ]:          0 :         if (tmp & BCMA_CC_CHIPST_4706_PKG_OPTION)
     407                 :            :                 /* Low cost bonding: Fixed reference clock 25MHz and m = 4 */
     408                 :          0 :                 clock = (25000000 / 4) * ndiv * p2div / p1div;
     409                 :            :         else
     410                 :            :                 /* Fixed reference clock 25MHz and m = 2 */
     411                 :          0 :                 clock = (25000000 / 2) * ndiv * p2div / p1div;
     412                 :            : 
     413         [ #  # ]:          0 :         if (m == BCMA_CC_PMU5_MAINPLL_SSB)
     414                 :          0 :                 clock = clock / 4;
     415                 :            : 
     416                 :          0 :         return clock;
     417                 :            : }
     418                 :            : 
     419                 :            : /* query bus clock frequency for PMU-enabled chipcommon */
     420                 :          0 : u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc)
     421                 :            : {
     422                 :          0 :         struct bcma_bus *bus = cc->core->bus;
     423                 :            : 
     424   [ #  #  #  #  :          0 :         switch (bus->chipinfo.id) {
                   #  # ]
     425                 :          0 :         case BCMA_CHIP_ID_BCM4716:
     426                 :            :         case BCMA_CHIP_ID_BCM4748:
     427                 :            :         case BCMA_CHIP_ID_BCM47162:
     428                 :          0 :                 return bcma_pmu_pll_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
     429                 :            :                                           BCMA_CC_PMU5_MAINPLL_SSB);
     430                 :          0 :         case BCMA_CHIP_ID_BCM5356:
     431                 :          0 :                 return bcma_pmu_pll_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
     432                 :            :                                           BCMA_CC_PMU5_MAINPLL_SSB);
     433                 :          0 :         case BCMA_CHIP_ID_BCM5357:
     434                 :            :         case BCMA_CHIP_ID_BCM4749:
     435                 :          0 :                 return bcma_pmu_pll_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
     436                 :            :                                           BCMA_CC_PMU5_MAINPLL_SSB);
     437                 :          0 :         case BCMA_CHIP_ID_BCM4706:
     438                 :          0 :                 return bcma_pmu_pll_clock_bcm4706(cc,
     439                 :            :                                                   BCMA_CC_PMU4706_MAINPLL_PLL0,
     440                 :            :                                                   BCMA_CC_PMU5_MAINPLL_SSB);
     441                 :            :         case BCMA_CHIP_ID_BCM53572:
     442                 :            :                 return 75000000;
     443                 :          0 :         default:
     444                 :          0 :                 bcma_warn(bus, "No bus clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
     445                 :            :                           bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
     446                 :            :         }
     447                 :          0 :         return BCMA_CC_PMU_HT_CLOCK;
     448                 :            : }
     449                 :            : EXPORT_SYMBOL_GPL(bcma_pmu_get_bus_clock);
     450                 :            : 
     451                 :            : /* query cpu clock frequency for PMU-enabled chipcommon */
     452                 :          0 : u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc)
     453                 :            : {
     454                 :          0 :         struct bcma_bus *bus = cc->core->bus;
     455                 :            : 
     456         [ #  # ]:          0 :         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53572)
     457                 :            :                 return 300000000;
     458                 :            : 
     459                 :            :         /* New PMUs can have different clock for bus and CPU */
     460         [ #  # ]:          0 :         if (cc->pmu.rev >= 5) {
     461                 :          0 :                 u32 pll;
     462      [ #  #  # ]:          0 :                 switch (bus->chipinfo.id) {
     463                 :          0 :                 case BCMA_CHIP_ID_BCM4706:
     464                 :          0 :                         return bcma_pmu_pll_clock_bcm4706(cc,
     465                 :            :                                                 BCMA_CC_PMU4706_MAINPLL_PLL0,
     466                 :            :                                                 BCMA_CC_PMU5_MAINPLL_CPU);
     467                 :            :                 case BCMA_CHIP_ID_BCM5356:
     468                 :            :                         pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
     469                 :            :                         break;
     470                 :            :                 case BCMA_CHIP_ID_BCM5357:
     471                 :            :                 case BCMA_CHIP_ID_BCM4749:
     472                 :            :                         pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
     473                 :            :                         break;
     474                 :          0 :                 default:
     475                 :          0 :                         pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
     476                 :          0 :                         break;
     477                 :            :                 }
     478                 :            : 
     479                 :          0 :                 return bcma_pmu_pll_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
     480                 :            :         }
     481                 :            : 
     482                 :            :         /* On old PMUs CPU has the same clock as the bus */
     483                 :          0 :         return bcma_pmu_get_bus_clock(cc);
     484                 :            : }
     485                 :            : 
     486                 :            : static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset,
     487                 :            :                                          u32 value)
     488                 :            : {
     489                 :            :         bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset);
     490                 :            :         bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value);
     491                 :            : }
     492                 :            : 
     493                 :          0 : void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
     494                 :            : {
     495                 :          0 :         u32 tmp = 0;
     496                 :          0 :         u8 phypll_offset = 0;
     497                 :          0 :         u8 bcm5357_bcm43236_p1div[] = {0x1, 0x5, 0x5};
     498                 :          0 :         u8 bcm5357_bcm43236_ndiv[] = {0x30, 0xf6, 0xfc};
     499                 :          0 :         struct bcma_bus *bus = cc->core->bus;
     500                 :            : 
     501   [ #  #  #  #  :          0 :         switch (bus->chipinfo.id) {
                   #  # ]
     502                 :          0 :         case BCMA_CHIP_ID_BCM5357:
     503                 :            :         case BCMA_CHIP_ID_BCM4749:
     504                 :            :         case BCMA_CHIP_ID_BCM53572:
     505                 :            :                 /* 5357[ab]0, 43236[ab]0, and 6362b0 */
     506                 :            : 
     507                 :            :                 /*
     508                 :            :                  * BCM5357 needs to touch PLL1_PLLCTL[02],
     509                 :            :                  * so offset PLL0_PLLCTL[02] by 6
     510                 :            :                  */
     511         [ #  # ]:          0 :                 phypll_offset = (bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
     512         [ #  # ]:          0 :                        bus->chipinfo.id == BCMA_CHIP_ID_BCM4749 ||
     513                 :            :                        bus->chipinfo.id == BCMA_CHIP_ID_BCM53572) ? 6 : 0;
     514                 :            : 
     515                 :            :                 /* RMW only the P1 divider */
     516                 :          0 :                 bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR,
     517                 :            :                                 BCMA_CC_PMU_PLL_CTL0 + phypll_offset);
     518                 :          0 :                 tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA);
     519                 :          0 :                 tmp &= (~(BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK));
     520                 :          0 :                 tmp |= (bcm5357_bcm43236_p1div[spuravoid] << BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT);
     521                 :          0 :                 bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp);
     522                 :            : 
     523                 :            :                 /* RMW only the int feedback divider */
     524                 :          0 :                 bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR,
     525                 :            :                                 BCMA_CC_PMU_PLL_CTL2 + phypll_offset);
     526                 :          0 :                 tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA);
     527                 :          0 :                 tmp &= ~(BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK);
     528                 :          0 :                 tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT;
     529                 :          0 :                 bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp);
     530                 :            : 
     531                 :          0 :                 tmp = BCMA_CC_PMU_CTL_PLL_UPD;
     532                 :          0 :                 break;
     533                 :            : 
     534                 :          0 :         case BCMA_CHIP_ID_BCM4331:
     535                 :            :         case BCMA_CHIP_ID_BCM43431:
     536         [ #  # ]:          0 :                 if (spuravoid == 2) {
     537                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
     538                 :            :                                                      0x11500014);
     539                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
     540                 :            :                                                      0x0FC00a08);
     541         [ #  # ]:          0 :                 } else if (spuravoid == 1) {
     542                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
     543                 :            :                                                      0x11500014);
     544                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
     545                 :            :                                                      0x0F600a08);
     546                 :            :                 } else {
     547                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
     548                 :            :                                                      0x11100014);
     549                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
     550                 :            :                                                      0x03000a08);
     551                 :            :                 }
     552                 :            :                 tmp = BCMA_CC_PMU_CTL_PLL_UPD;
     553                 :            :                 break;
     554                 :            : 
     555                 :          0 :         case BCMA_CHIP_ID_BCM43224:
     556                 :            :         case BCMA_CHIP_ID_BCM43225:
     557                 :            :         case BCMA_CHIP_ID_BCM43421:
     558         [ #  # ]:          0 :                 if (spuravoid == 1) {
     559                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
     560                 :            :                                                      0x11500010);
     561                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
     562                 :            :                                                      0x000C0C06);
     563                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
     564                 :            :                                                      0x0F600a08);
     565                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
     566                 :            :                                                      0x00000000);
     567                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
     568                 :            :                                                      0x2001E920);
     569                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
     570                 :            :                                                      0x88888815);
     571                 :            :                 } else {
     572                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
     573                 :            :                                                      0x11100010);
     574                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
     575                 :            :                                                      0x000c0c06);
     576                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
     577                 :            :                                                      0x03000a08);
     578                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
     579                 :            :                                                      0x00000000);
     580                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
     581                 :            :                                                      0x200005c0);
     582                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
     583                 :            :                                                      0x88888815);
     584                 :            :                 }
     585                 :            :                 tmp = BCMA_CC_PMU_CTL_PLL_UPD;
     586                 :            :                 break;
     587                 :            : 
     588                 :          0 :         case BCMA_CHIP_ID_BCM4716:
     589                 :            :         case BCMA_CHIP_ID_BCM4748:
     590                 :            :         case BCMA_CHIP_ID_BCM47162:
     591         [ #  # ]:          0 :                 if (spuravoid == 1) {
     592                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
     593                 :            :                                                      0x11500060);
     594                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
     595                 :            :                                                      0x080C0C06);
     596                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
     597                 :            :                                                      0x0F600000);
     598                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
     599                 :            :                                                      0x00000000);
     600                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
     601                 :            :                                                      0x2001E924);
     602                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
     603                 :            :                                                      0x88888815);
     604                 :            :                 } else {
     605                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
     606                 :            :                                                      0x11100060);
     607                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
     608                 :            :                                                      0x080c0c06);
     609                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
     610                 :            :                                                      0x03000000);
     611                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
     612                 :            :                                                      0x00000000);
     613                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
     614                 :            :                                                      0x200005c0);
     615                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
     616                 :            :                                                      0x88888815);
     617                 :            :                 }
     618                 :            : 
     619                 :            :                 tmp = BCMA_CC_PMU_CTL_PLL_UPD | BCMA_CC_PMU_CTL_NOILPONW;
     620                 :            :                 break;
     621                 :            : 
     622                 :          0 :         case BCMA_CHIP_ID_BCM43131:
     623                 :            :         case BCMA_CHIP_ID_BCM43217:
     624                 :            :         case BCMA_CHIP_ID_BCM43227:
     625                 :            :         case BCMA_CHIP_ID_BCM43228:
     626                 :            :         case BCMA_CHIP_ID_BCM43428:
     627                 :            :                 /* LCNXN */
     628                 :            :                 /*
     629                 :            :                  * PLL Settings for spur avoidance on/off mode,
     630                 :            :                  * no on2 support for 43228A0
     631                 :            :                  */
     632         [ #  # ]:          0 :                 if (spuravoid == 1) {
     633                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
     634                 :            :                                                      0x01100014);
     635                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
     636                 :            :                                                      0x040C0C06);
     637                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
     638                 :            :                                                      0x03140A08);
     639                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
     640                 :            :                                                      0x00333333);
     641                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
     642                 :            :                                                      0x202C2820);
     643                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
     644                 :            :                                                      0x88888815);
     645                 :            :                 } else {
     646                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
     647                 :            :                                                      0x11100014);
     648                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
     649                 :            :                                                      0x040c0c06);
     650                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
     651                 :            :                                                      0x03000a08);
     652                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
     653                 :            :                                                      0x00000000);
     654                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
     655                 :            :                                                      0x200005c0);
     656                 :          0 :                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
     657                 :            :                                                      0x88888815);
     658                 :            :                 }
     659                 :            :                 tmp = BCMA_CC_PMU_CTL_PLL_UPD;
     660                 :            :                 break;
     661                 :          0 :         default:
     662                 :          0 :                 bcma_err(bus, "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
     663                 :            :                          bus->chipinfo.id);
     664                 :          0 :                 break;
     665                 :            :         }
     666                 :            : 
     667                 :          0 :         tmp |= bcma_pmu_read32(cc, BCMA_CC_PMU_CTL);
     668                 :          0 :         bcma_pmu_write32(cc, BCMA_CC_PMU_CTL, tmp);
     669                 :          0 : }
     670                 :            : EXPORT_SYMBOL_GPL(bcma_pmu_spuravoid_pllupdate);

Generated by: LCOV version 1.14