drivers: qcom: rpmh-rsc: clear active mode configuration for waketcs
For RSCs that have sleep & wake TCS but no dedicated active TCS, wake TCS can be re-purposed to send active requests. Once the active requests are sent and response is received, the active mode configuration needs to be cleared so that controller can use wake TCS for sending wake requests in 'solver' state while executing low power modes. Change-Id: I0d15c290db48d08158fdbff2cd91505563dc3fd5 Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org>
This commit is contained in:
parent
4f1ac463da
commit
a316de8e18
@ -200,6 +200,42 @@ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void __tcs_trigger(struct rsc_drv *drv, int tcs_id, bool trigger)
|
||||
{
|
||||
u32 enable;
|
||||
|
||||
/*
|
||||
* HW req: Clear the DRV_CONTROL and enable TCS again
|
||||
* While clearing ensure that the AMC mode trigger is cleared
|
||||
* and then the mode enable is cleared.
|
||||
*/
|
||||
enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0);
|
||||
enable &= ~TCS_AMC_MODE_TRIGGER;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
enable &= ~TCS_AMC_MODE_ENABLE;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
|
||||
if (trigger) {
|
||||
/* Enable the AMC mode on the TCS and then trigger the TCS */
|
||||
enable = TCS_AMC_MODE_ENABLE;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
enable |= TCS_AMC_MODE_TRIGGER;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
data = read_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, 0);
|
||||
if (enable)
|
||||
data |= BIT(tcs_id);
|
||||
else
|
||||
data &= ~BIT(tcs_id);
|
||||
write_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* tcs_tx_done: TX Done interrupt handler
|
||||
*/
|
||||
@ -236,6 +272,21 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
|
||||
}
|
||||
|
||||
trace_rpmh_tx_done(drv, i, req, err);
|
||||
|
||||
/*
|
||||
* if wake tcs was re-purposed for sending active
|
||||
* votes, clear AMC trigger & enable modes and
|
||||
* disable interrupt for this TCS
|
||||
*/
|
||||
if (!drv->tcs[ACTIVE_TCS].num_tcs) {
|
||||
__tcs_trigger(drv, i, false);
|
||||
/*
|
||||
* Disable interrupt for this TCS to avoid being
|
||||
* spammed with interrupts coming when the solver
|
||||
* sends its wake votes.
|
||||
*/
|
||||
enable_tcs_irq(drv, i, false);
|
||||
}
|
||||
skip:
|
||||
/* Reclaim the TCS */
|
||||
write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0);
|
||||
@ -283,28 +334,6 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
|
||||
write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, cmd_enable);
|
||||
}
|
||||
|
||||
static void __tcs_trigger(struct rsc_drv *drv, int tcs_id)
|
||||
{
|
||||
u32 enable;
|
||||
|
||||
/*
|
||||
* HW req: Clear the DRV_CONTROL and enable TCS again
|
||||
* While clearing ensure that the AMC mode trigger is cleared
|
||||
* and then the mode enable is cleared.
|
||||
*/
|
||||
enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0);
|
||||
enable &= ~TCS_AMC_MODE_TRIGGER;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
enable &= ~TCS_AMC_MODE_ENABLE;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
|
||||
/* Enable the AMC mode on the TCS and then trigger the TCS */
|
||||
enable = TCS_AMC_MODE_ENABLE;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
enable |= TCS_AMC_MODE_TRIGGER;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
}
|
||||
|
||||
static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
|
||||
const struct tcs_request *msg)
|
||||
{
|
||||
@ -375,10 +404,12 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg)
|
||||
|
||||
tcs->req[tcs_id - tcs->offset] = msg;
|
||||
set_bit(tcs_id, drv->tcs_in_use);
|
||||
if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS)
|
||||
enable_tcs_irq(drv, tcs_id, true);
|
||||
spin_unlock(&drv->lock);
|
||||
|
||||
__tcs_buffer_write(drv, tcs_id, 0, msg);
|
||||
__tcs_trigger(drv, tcs_id);
|
||||
__tcs_trigger(drv, tcs_id, true);
|
||||
|
||||
done_write:
|
||||
spin_unlock_irqrestore(&tcs->lock, flags);
|
||||
|
Loading…
Reference in New Issue
Block a user