gpu: nvgpu: reorganization of MC interrupts control

Previously, unit interrupt enabling/disabling and corresponding MC level
interrupt enabling/disabling was not done at the same time.
With this change, stall and nonstall interrupt for units are programmed
at MC level along with individual unit interrupts. Kept access to MC
interrupt registers through mc.intr_lock spinlock.

For doing this separated CE and GR interrupt mask functions.
mc.intr_enable is only used when there is global interrupt
control to be set. Removed mc_gp10b.c as mc_gp10b_intr_enable
is now removed. Removed following functions - mc_gv100_intr_enable,
mc_gv11b_intr_enable & intr_tu104_enable. Removed intr_pmu_unit_config
as we can use the generic unit interrupt control function.

JIRA NVGPU-4336

Change-Id: Ibd296d4a60fda6ba930f18f518ee56ab3f9dacad
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2196178
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Sagar Kamble
2019-09-11 14:57:19 +05:30
committed by Alex Waterman
parent daf5475f50
commit a8c9c800cd
49 changed files with 752 additions and 411 deletions

View File

@@ -185,7 +185,24 @@ bool nvgpu_engine_check_valid_id(struct gk20a *g, u32 engine_id);
*/
u32 nvgpu_engine_get_gr_id(struct gk20a *g);
/**
* @brief Get intr mask for the engines supported by the chip.
* @brief Get intr mask for the GR engine supported by the chip.
*
* @param g[in] The GPU driver struct.
*
* For each of #nvgpu_fifo.num_engines, get pointer to
* #nvgpu_engine_info. Use this to get #nvgpu_engine_info.intr_mask.
* If #nvgpu_engine_info.engine_num type matches with
* #NVGPU_ENGINE_GR, local intr_mask variable is logically ORed with
* #nvgpu_engine_info.intr_mask.
*
* @return Interrupt mask for GR engine.
* @retval 0 if #nvgpu_fifo.num_engines is 0.
* @retval 0 if all of the supported engine enum types don't match with
* #NVGPU_ENGINE_GR.
*/
u32 nvgpu_gr_engine_interrupt_mask(struct gk20a *g);
/**
* @brief Get intr mask for the CE engines supported by the chip.
*
* @param g [in] The GPU driver struct.
*
@@ -193,16 +210,18 @@ u32 nvgpu_engine_get_gr_id(struct gk20a *g);
* #nvgpu_engine_info. Use this to get #nvgpu_engine_info.intr_mask.
* If #nvgpu_engine_info.engine_num type matches with
* #NVGPU_ENGINE_GRCE or #NVGPU_ENGINE_ASYNC_CE but interrupt handlers
* are not supported, local intr_mask variable is not logically ORed with
* are not supported or engine_enum type matches with #NVGPU_ENGINE_GR
* , local intr_mask variable is not logically ORed with
* #nvgpu_engine_info.intr_mask.
*
* @return Interrupt mask for h/w engines that support interrupt handlers.
* @return Interrupt mask for CE engines that support interrupt handlers.
* @retval 0 if #nvgpu_fifo.num_engines is 0.
* @retval 0 if all of the supported engine enum types match with
* #NVGPU_ENGINE_GRCE or #NVGPU_ENGINE_ASYNC_CE and does not
* support interrupt handler.
* support interrupt handler or engine enum type matches with
* #NVGPU_ENGINE_GR.
*/
u32 nvgpu_engine_interrupt_mask(struct gk20a *g);
u32 nvgpu_ce_engine_interrupt_mask(struct gk20a *g);
/**
* @brief Get intr mask for the h/w engine id.
*

View File

@@ -184,9 +184,6 @@ struct railgate_stats {
};
#endif
#define MC_INTR_UNIT_DISABLE false
#define MC_INTR_UNIT_ENABLE true
#define GPU_LIT_NUM_GPCS 0
#define GPU_LIT_NUM_PES_PER_GPC 1
#define GPU_LIT_NUM_ZCULL_BANKS 2

View File

@@ -72,53 +72,6 @@ struct gops_mc {
u32 (*get_chip_details)(struct gk20a *g,
u32 *arch, u32 *impl, u32 *rev);
/**
* @brief Clear the GPU device interrupts at master level.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked before powering off or finishing
* SW quiesce of nvgpu driver.
*
* Steps:
* - Write U32_MAX to the stalling interrupts enable clear register.
* mc_intr_en_clear_r are write only registers which clear
* the corresponding bit in INTR_EN whenever a 1 is written
* to it.
* - Write U32_MAX to the non-stalling interrupts enable clear register.
*/
void (*intr_mask)(struct gk20a *g);
/**
* @brief Enable the applicable GPU device interrupts at master level.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked during #nvgpu_finalize_poweron before
* enabling the individual HW units interrupts.
*
* Steps:
* - Get the engine interrupts mask for supported FIFO engines by
* calling #nvgpu_engine_interrupt_mask.
* - Clear the GPU device interrupts.
* - Set the master level interrupts masks to be used for
* enabling/disabling the interrupts at runtime in
* #intr_stall_pause, #intr_stall_resume,
* #intr_nonstall_pause and #intr_nonstall_resume.
* - Initialize the stalling interrupts bitmask
* #intr_mask_restore[#NVGPU_MC_INTR_STALLING] with various
* units (FIFO, HUB, PRIV_RING, PBUS, LTC) OR'ing with engine
* interrupts mask.
* - Initialize the non-stalling interrupts bitmask
* #intr_mask_restore[#NVGPU_MC_INTR_NONSTALLING] with FIFO
* unit OR'ing with engine interrupts mask.
* - Write the bitmasks to the stalling and the non-stalling interrupts
* enable registers respectively (mc_intr_en_set_r()).
*
* @return 0 in case of success, < 0 in case of failure.
*/
int (*intr_enable)(struct gk20a *g);
/**
* @brief Read the the stalling interrupts status register.
*
@@ -135,20 +88,6 @@ struct gops_mc {
*/
u32 (*intr_stall)(struct gk20a *g);
/**
* @brief Disable/Pause the stalling interrupts.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked to disable the stalling interrupts before
* the ISR is executed.
*
* Steps:
* - Write U32_MAX to the stalling interrupts enable clear register
* (mc_intr_en_clear_r(#NVGPU_MC_INTR_STALLING)).
*/
void (*intr_stall_pause)(struct gk20a *g);
/**
* @brief Interrupt Service Routine (ISR) for handling the stalling
* interrupts.
@@ -184,22 +123,6 @@ struct gops_mc {
*/
void (*isr_stall)(struct gk20a *g);
/**
* @brief Enable/Resume the stalling interrupts.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked to enable the stalling interrupts after
* the ISR is executed.
*
* Steps:
* - Enable the stalling interrupts as configured during #intr_enable.
* Write #intr_mask_restore[#NVGPU_MC_INTR_STALLING] to the
* stalling interrupts enable set register
* (mc_intr_en_set_r(#NVGPU_MC_INTR_STALLING)).
*/
void (*intr_stall_resume)(struct gk20a *g);
/**
* @brief Read the non-stalling interrupts status register.
*
@@ -216,20 +139,6 @@ struct gops_mc {
*/
u32 (*intr_nonstall)(struct gk20a *g);
/**
* @brief Disable/Pause the non-stalling interrupts.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked to disable the non-stalling interrupts
* before the ISR is executed.
*
* Steps:
* - Write U32_MAX to the non-stalling interrupts enable clear register
* (mc_intr_en_clear_r(#NVGPU_MC_INTR_NONSTALLING)).
*/
void (*intr_nonstall_pause)(struct gk20a *g);
/**
* @brief Interrupt Service Routine (ISR) for handling the non-stalling
* interrupts.
@@ -256,23 +165,6 @@ struct gops_mc {
*/
u32 (*isr_nonstall)(struct gk20a *g);
/**
* @brief Enable/Resume the non-stalling interrupts.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked to enable the non-stalling interrupts after
* the ISR is executed.
*
* Steps:
* - Enable the non-stalling interrupts as configured during
* #intr_enable.
* Write #intr_mask_restore[#NVGPU_MC_INTR_NONSTALLING]
* to the non-stalling interrupts enable set register
* (mc_intr_en_set_r(#NVGPU_MC_INTR_NONSTALLING)).
*/
void (*intr_nonstall_resume)(struct gk20a *g);
/**
* @brief Check if stalling or engine interrupts are pending.
*
@@ -345,10 +237,10 @@ struct gops_mc {
* @param g [in] The GPU driver struct.
* @param unit [in] Value designating the GPU HW unit/engine
* controlled by MC. Supported values are:
* - NVGPU_UNIT_FIFO
* - NVGPU_UNIT_PERFMON
* - NVGPU_UNIT_GRAPH
* - NVGPU_UNIT_BLG
* - #NVGPU_UNIT_FIFO
* - #NVGPU_UNIT_PERFMON
* - #NVGPU_UNIT_GRAPH
* - #NVGPU_UNIT_BLG
*
* This function is invoked to get the reset mask of the engines for
* resetting CE, GR, FIFO during #nvgpu_finalize_poweron.
@@ -385,6 +277,24 @@ struct gops_mc {
/** @cond DOXYGEN_SHOULD_SKIP_THIS */
void (*intr_mask)(struct gk20a *g);
void (*intr_enable)(struct gk20a *g);
void (*intr_stall_unit_config)(struct gk20a *g, u32 unit,
bool enable);
void (*intr_nonstall_unit_config)(struct gk20a *g, u32 unit,
bool enable);
void (*intr_stall_pause)(struct gk20a *g);
void (*intr_stall_resume)(struct gk20a *g);
void (*intr_nonstall_pause)(struct gk20a *g);
void (*intr_nonstall_resume)(struct gk20a *g);
void (*enable)(struct gk20a *g, u32 units);
void (*disable)(struct gk20a *g, u32 units);
@@ -407,10 +317,6 @@ struct gops_mc {
void (*fbpa_isr)(struct gk20a *g);
#endif
#ifdef CONFIG_NVGPU_LS_PMU
void (*intr_pmu_unit_config)(struct gk20a *g,
bool enable);
#endif
/** @endcond DOXYGEN_SHOULD_SKIP_THIS */
};

View File

@@ -153,11 +153,39 @@ enum nvgpu_unit {
#define NVGPU_NONSTALL_OPS_WAKEUP_SEMAPHORE BIT32(0)
#define NVGPU_NONSTALL_OPS_POST_EVENTS BIT32(1)
/** MC interrupt for Bus unit. */
#define MC_INTR_UNIT_BUS 0
/** MC interrupt for PRIV_RING unit. */
#define MC_INTR_UNIT_PRIV_RING 1
/** MC interrupt for FIFO unit. */
#define MC_INTR_UNIT_FIFO 2
/** MC interrupt for LTC unit. */
#define MC_INTR_UNIT_LTC 3
/** MC interrupt for HUB unit. */
#define MC_INTR_UNIT_HUB 4
/** MC interrupt for GR unit. */
#define MC_INTR_UNIT_GR 5
/** MC interrupt for PMU unit. */
#define MC_INTR_UNIT_PMU 6
/** MC interrupt for CE unit. */
#define MC_INTR_UNIT_CE 7
/** MC interrupt for NVLINK unit. */
#define MC_INTR_UNIT_NVLINK 8
/** MC interrupt for FBPA unit. */
#define MC_INTR_UNIT_FBPA 9
/** Value to be passed to mc.intr_*_unit_config to enable the interrupt. */
#define MC_INTR_ENABLE true
/** Value to be passed to mc.intr_*_unit_config to disable the interrupt. */
#define MC_INTR_DISABLE false
/**
* This struct holds the variables needed to manage the configuration and
* interrupt handling of the units/engines.
*/
struct nvgpu_mc {
struct nvgpu_spinlock intr_lock;
/** Lock to access the mc_enable_r */
struct nvgpu_spinlock enable_lock;
@@ -246,4 +274,182 @@ struct nvgpu_mc {
*/
void nvgpu_wait_for_deferred_interrupts(struct gk20a *g);
/**
* @brief Clear the GPU device interrupts at master level.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked before powering off or finishing
* SW quiesce of nvgpu driver.
*
* Steps:
* - Acquire the spinlock g->mc.intr_lock.
* - Write U32_MAX to the stalling interrupts enable clear register.
* mc_intr_en_clear_r are write only registers which clear
* the corresponding bit in INTR_EN whenever a 1 is written
* to it.
* - Set g->mc.intr_mask_restore[NVGPU_MC_INTR_STALLING] and
* g->mc.intr_mask_restore[NVGPU_MC_INTR_NONSTALLING] to 0.
* - Write U32_MAX to the non-stalling interrupts enable clear register.
* - Release the spinlock g->mc.intr_lock.
*/
void nvgpu_mc_intr_mask(struct gk20a *g);
void nvgpu_mc_log_pending_intrs(struct gk20a *g);
void nvgpu_mc_intr_enable(struct gk20a *g);
/**
* @brief Enable the stalling interrupts for GPU unit at the master
* level.
*
* @param g [in] The GPU driver struct.
* @param unit [in] Value designating the GPU HW unit/engine
* controlled by MC. Supported values are:
* - #MC_INTR_UNIT_BUS
* - #MC_INTR_UNIT_PRIV_RING
* - #MC_INTR_UNIT_FIFO
* - #MC_INTR_UNIT_LTC
* - #MC_INTR_UNIT_HUB
* - #MC_INTR_UNIT_GR
* - #MC_INTR_UNIT_PMU
* - #MC_INTR_UNIT_CE
* - #MC_INTR_UNIT_NVLINK
* - #MC_INTR_UNIT_FBPA
* @param enable [in] Boolean control to enable/disable the stalling
* interrupt. Supported values are:
* - #MC_INTR_ENABLE
* - #MC_INTR_DISABLE
*
* This function is invoked during individual unit's init before
* enabling that unit's interrupts.
*
* Steps:
* - Get the interrupt bitmask for \a unit.
* - Acquire the spinlock g->mc.intr_lock.
* - If interrupt is to be enabled
* - Set interrupt bitmask in
* #intr_mask_restore[#NVGPU_MC_INTR_STALLING].
* - Write the interrupt bitmask to the register
* mc_intr_en_set_r(#NVGPU_MC_INTR_STALLING).
* - Else
* - Clear interrupt bitmask in
* #intr_mask_restore[#NVGPU_MC_INTR_STALLING].
* - Write the interrupt bitmask to the register
* mc_intr_en_clear_r(#NVGPU_MC_INTR_STALLING).
* - Release the spinlock g->mc.intr_lock.
*/
void nvgpu_mc_intr_stall_unit_config(struct gk20a *g, u32 unit, bool enable);
/**
* @brief Enable the non-stalling interrupts for GPU unit at the master
* level.
*
* @param g [in] The GPU driver struct.
* @param unit [in] Value designating the GPU HW unit/engine
* controlled by MC. Supported values are:
* - #MC_INTR_UNIT_BUS
* - #MC_INTR_UNIT_PRIV_RING
* - #MC_INTR_UNIT_FIFO
* - #MC_INTR_UNIT_LTC
* - #MC_INTR_UNIT_HUB
* - #MC_INTR_UNIT_GR
* - #MC_INTR_UNIT_PMU
* - #MC_INTR_UNIT_CE
* - #MC_INTR_UNIT_NVLINK
* - #MC_INTR_UNIT_FBPA
* @param enable [in] Boolean control to enable/disable the stalling
* interrupt. Supported values are:
* - #MC_INTR_ENABLE
* - #MC_INTR_DISABLE
*
* This function is invoked during individual unit's init before
* enabling that unit's interrupts.
*
* Steps:
* - Get the interrupt bitmask for \a unit.
* - Acquire the spinlock g->mc.intr_lock.
* - If interrupt is to be enabled
* - Set interrupt bitmask in
* #intr_mask_restore[#NVGPU_MC_INTR_NONSTALLING].
* - Write the interrupt bitmask to the register
* mc_intr_en_set_r(#NVGPU_MC_INTR_NONSTALLING).
* - Else
* - Clear interrupt bitmask in
* #intr_mask_restore[#NVGPU_MC_INTR_NONSTALLING].
* - Write the interrupt bitmask to the register
* mc_intr_en_clear_r(#NVGPU_MC_INTR_NONSTALLING).
* - Release the spinlock g->mc.intr_lock.
*/
void nvgpu_mc_intr_nonstall_unit_config(struct gk20a *g, u32 unit, bool enable);
/**
* @brief Disable/Pause the stalling interrupts.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked to disable the stalling interrupts before
* the ISR is executed.
*
* Steps:
* - Acquire the spinlock g->mc.intr_lock.
* - Write U32_MAX to the stalling interrupts enable clear register
* (mc_intr_en_clear_r(#NVGPU_MC_INTR_STALLING)).
* - Release the spinlock g->mc.intr_lock.
*/
void nvgpu_mc_intr_stall_pause(struct gk20a *g);
/**
* @brief Enable/Resume the stalling interrupts.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked to enable the stalling interrupts after
* the ISR is executed.
*
* Steps:
* - Acquire the spinlock g->mc.intr_lock.
* - Enable the stalling interrupts as configured during #intr_enable.
* Write #intr_mask_restore[#NVGPU_MC_INTR_STALLING] to the
* stalling interrupts enable set register
* (mc_intr_en_set_r(#NVGPU_MC_INTR_STALLING)).
* - Release the spinlock g->mc.intr_lock.
*/
void nvgpu_mc_intr_stall_resume(struct gk20a *g);
/**
* @brief Disable/Pause the non-stalling interrupts.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked to disable the non-stalling interrupts
* before the ISR is executed.
*
* Steps:
* - Acquire the spinlock g->mc.intr_lock.
* - Write U32_MAX to the non-stalling interrupts enable clear register
* (mc_intr_en_clear_r(#NVGPU_MC_INTR_NONSTALLING)).
* - Release the spinlock g->mc.intr_lock.
*/
void nvgpu_mc_intr_nonstall_pause(struct gk20a *g);
/**
* @brief Enable/Resume the non-stalling interrupts.
*
* @param g [in] The GPU driver struct.
*
* This function is invoked to enable the non-stalling interrupts after
* the ISR is executed.
*
* Steps:
* - Acquire the spinlock g->mc.intr_lock.
* - Enable the non-stalling interrupts as configured during
* #intr_enable.
* Write #intr_mask_restore[#NVGPU_MC_INTR_NONSTALLING]
* to the non-stalling interrupts enable set register
* (mc_intr_en_set_r(#NVGPU_MC_INTR_NONSTALLING)).
* - Release the spinlock g->mc.intr_lock.
*/
void nvgpu_mc_intr_nonstall_resume(struct gk20a *g);
#endif

View File

@@ -102,4 +102,16 @@ struct nvgpu_raw_spinlock {
struct __nvgpu_posix_lock lock;
};
static inline void nvgpu_spinlock_irqsave(struct nvgpu_spinlock *mutex,
unsigned long flags)
{
nvgpu_posix_lock_acquire(&mutex->lock);
}
static inline void nvgpu_spinunlock_irqrestore(struct nvgpu_spinlock *mutex,
unsigned long flags)
{
nvgpu_posix_lock_release(&mutex->lock);
}
#endif /* NVGPU_POSIX_LOCK_H */