fusee-primary: add reference counting to AHB redirect

The SDMMC driver is currently the only user of the AHB redirect, but the
upcoming XUSB driver will also need to use the AHB redirect, potentially at the
same time. This ensures that the AHB redirect will not be disabled unexpectedly
if one driver is deinitialized without the other.
This commit is contained in:
misson20000 2020-10-18 14:59:53 -07:00
parent f98ce0c909
commit 4499c4392d
3 changed files with 26 additions and 18 deletions

View file

@ -22,7 +22,6 @@
FATFS sd_fs;
static bool g_sd_mounted = false;
static bool g_sd_initialized = false;
static bool g_ahb_redirect_enabled = false;
sdmmc_t g_sd_sdmmc;
sdmmc_device_t g_sd_device;
@ -34,10 +33,7 @@ bool mount_sd(void)
return true;
/* Enable AHB redirection if necessary. */
if (!g_ahb_redirect_enabled) {
mc_enable_ahb_redirect();
g_ahb_redirect_enabled = true;
}
mc_acquire_ahb_redirect();
if (!g_sd_initialized) {
/* Initialize SD. */
@ -68,10 +64,7 @@ void unmount_sd(void)
}
/* Disable AHB redirection if necessary. */
if (g_ahb_redirect_enabled) {
mc_disable_ahb_redirect();
g_ahb_redirect_enabled = false;
}
mc_release_ahb_redirect();
}
uint32_t get_file_size(const char *filename)

View file

@ -124,16 +124,21 @@ void mc_config_carveout_finalize()
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
}
void mc_enable_ahb_redirect()
static int mc_ahb_redirect_users = 0;
void mc_acquire_ahb_redirect()
{
volatile tegra_car_t *car = car_get_regs();
car->lvl2_clk_gate_ovrd = ((car->lvl2_clk_gate_ovrd & 0xFFF7FFFF) | 0x80000);
if ((mc_ahb_redirect_users++) == 0)
{
volatile tegra_car_t *car = car_get_regs();
car->lvl2_clk_gate_ovrd = ((car->lvl2_clk_gate_ovrd & 0xFFF7FFFF) | 0x80000);
MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
MAKE_MC_REG(MC_IRAM_TOM) = 0x4003F000;
MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
MAKE_MC_REG(MC_IRAM_TOM) = 0x4003F000;
}
}
void mc_disable_ahb_redirect()
static void mc_disable_ahb_redirect()
{
volatile tegra_car_t *car = car_get_regs();
@ -141,6 +146,16 @@ void mc_disable_ahb_redirect()
MAKE_MC_REG(MC_IRAM_TOM) = 0;
car->lvl2_clk_gate_ovrd &= 0xFFF7FFFF;
mc_ahb_redirect_users = 0;
}
void mc_release_ahb_redirect()
{
if ((--mc_ahb_redirect_users) == 0)
{
mc_disable_ahb_redirect();
}
}
void mc_enable()
@ -166,4 +181,4 @@ void mc_enable()
udelay(5);
mc_disable_ahb_redirect();
}
}

View file

@ -598,8 +598,8 @@ typedef enum {
void mc_config_tsec_carveout(uint32_t bom, uint32_t size1mb, bool lock);
void mc_config_carveout();
void mc_config_carveout_finalize();
void mc_enable_ahb_redirect();
void mc_disable_ahb_redirect();
void mc_acquire_ahb_redirect();
void mc_release_ahb_redirect();
void mc_enable();
#endif