blob: 479e30fbd3ca65d7a941f18c553f421644bfd94b [file] [log] [blame]
/*
* Misc utility routines for DHD's accessing PMU core.
*
* Copyright (C) 2023, Broadcom.
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
*
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
* you also meet, for each linked independent module, the terms and conditions of
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
*
*
* <<Broadcom-WL-IPTag/Dual:>>
*/
#include <typedefs.h>
#include <bcmdefs.h>
#include <osl.h>
#include <bcmutils.h>
#include <siutils.h>
#include <bcmdevs.h>
#include <sbchipc.h>
#include <hndsoc.h>
#include "hndpmu_priv.h"
#include <hndpmu_dhd.h>
/**
* Balance between stable SDIO operation and power consumption is achieved using this function.
* Note that each drive strength table is for a specific VDDIO of the SDIO pads, ideally this
* function should read the VDDIO itself to select the correct table. For now it has been solved
* with the 'BCM_SDIO_VDDIO' preprocessor constant.
*
* 'drivestrength': desired pad drive strength in mA. Drive strength of 0 requests tri-state (if
* hardware supports this), if no hw support drive strength is not programmed.
*/
void
BCMINITFN(si_sdiod_drive_strength_init)(si_t *sih, osl_t *osh, uint32 drivestrength)
{
/*
* Note:
* This function used to set the SDIO drive strength via PMU_CHIPCTL1 for the
* 43143, 4330, 4334, 4336, 43362 chips. These chips are now no longer supported, so
* the code has been deleted.
* Newer chips have the SDIO drive strength setting via a GCI Chip Control register,
* but the bit definitions are chip-specific. We are keeping this function available
* (accessed via DHD 'sdiod_drive' IOVar) in case these newer chips need to provide access.
*/
UNUSED_PARAMETER(sih);
UNUSED_PARAMETER(osh);
UNUSED_PARAMETER(drivestrength);
}
void
si_pmu_set_min_res_mask(si_t *sih, osl_t *osh, uint min_res_mask)
{
pmuregs_t *pmu;
uint origidx;
/* Remember original core before switch to chipc/pmu */
origidx = si_coreidx(sih);
if (AOB_ENAB(sih)) {
pmu = si_setcore(sih, PMU_CORE_ID, 0);
}
else {
pmu = si_setcoreidx(sih, SI_CC_IDX);
}
ASSERT(pmu != NULL);
W_REG(osh, PMU_REG_ADDR(pmu, MinResourceMask), min_res_mask);
OSL_DELAY(100);
/* Return to original core */
si_setcoreidx(sih, origidx);
}
static bool
si_pmu_cap_fast_lpo(si_t *sih)
{
return (PMU_REG(sih, CoreCapabilitiesExt, 0, 0) & PCAP_EXT_USE_MUXED_ILP_CLK_MASK) ?
TRUE : FALSE;
}
int
si_pmu_fast_lpo_disable(si_t *sih)
{
if (!si_pmu_cap_fast_lpo(sih)) {
PMU_ERROR(("si_pmu_fast_lpo_disable: No Fast LPO capability\n"));
return BCME_ERROR;
}
PMU_REG(sih, PMUControlExt,
PCTL_EXT_FASTLPO_ENAB |
PCTL_EXT_FASTLPO_SWENAB |
PCTL_EXT_FASTLPO_PCIE_SWENAB,
0);
CAN_SLEEP() ? OSL_SLEEP(1) : OSL_DELAY(1000);
return BCME_OK;
}