Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 600cc333 authored by Skylar Chang's avatar Skylar Chang
Browse files

msm: ipa3: BUG on uC error



In case RG10 workaround is enabled AP is crashing on uC error
because of command timeout. This change enables IPA driver to
crash the device upon uC error with meaningful error print.

Change-Id: I9dac337263965e7a1d49205ddfa5e09e2bc282a0
CRs-Fixed: 981451
Acked-by: default avatarAdy Abraham <adya@qti.qualcomm.com>
Signed-off-by: default avatarSkylar Chang <chiaweic@codeaurora.org>
parent 67928fab
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -1094,6 +1094,47 @@ enum ipa3_hw_features {
	IPA_HW_FEATURE_MAX    = IPA_HW_NUM_FEATURES
};

/**
 * enum ipa3_hw_2_cpu_events - Values that represent HW event to be sent to CPU.
 * @IPA_HW_2_CPU_EVENT_ERROR : Event specify a system error is detected by the
 * device
 * @IPA_HW_2_CPU_EVENT_LOG_INFO : Event providing logging specific information
 */
enum ipa3_hw_2_cpu_events {
	IPA_HW_2_CPU_EVENT_ERROR     =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 1),
	IPA_HW_2_CPU_EVENT_LOG_INFO  =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 2),
};

/**
 * enum ipa3_hw_errors - Common error types.
 * @IPA_HW_ERROR_NONE : No error persists
 * @IPA_HW_INVALID_DOORBELL_ERROR : Invalid data read from doorbell
 * @IPA_HW_DMA_ERROR : Unexpected DMA error
 * @IPA_HW_FATAL_SYSTEM_ERROR : HW has crashed and requires reset.
 * @IPA_HW_INVALID_OPCODE : Invalid opcode sent
 * @IPA_HW_ZIP_ENGINE_ERROR : ZIP engine error
 */
enum ipa3_hw_errors {
	IPA_HW_ERROR_NONE              =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 0),
	IPA_HW_INVALID_DOORBELL_ERROR  =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 1),
	IPA_HW_DMA_ERROR               =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 2),
	IPA_HW_FATAL_SYSTEM_ERROR      =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 3),
	IPA_HW_INVALID_OPCODE          =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 4),
	IPA_HW_ZIP_ENGINE_ERROR        =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 5),
	IPA_HW_CONS_DISABLE_CMD_GSI_STOP_FAILURE =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 6),
	IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 7)
};

/**
 * struct IpaHwSharedMemCommonMapping_t - Structure referring to the common
 * section in 128B shared memory located in offset zero of SW Partition in IPA
@@ -1155,6 +1196,20 @@ union IpaHwFeatureInfoData_t {
	u32 raw32b;
} __packed;

/**
 * union IpaHwErrorEventData_t - HW->CPU Common Events
 * @errorType : Entered when a system error is detected by the HW. Type of
 * error is specified by IPA_HW_ERRORS
 * @reserved : Reserved
 */
union IpaHwErrorEventData_t {
	struct IpaHwErrorEventParams_t {
		u32 errorType:8;
		u32 reserved:24;
	} __packed params;
	u32 raw32b;
} __packed;

/**
 * struct IpaHwEventInfoData_t - Structure holding the parameters for
 * statistics and config info
@@ -1306,6 +1361,7 @@ union IpaHwMhiDlUlSyncCmdData_t {
 * @uc_status: The last status provided by the uC
 * @uc_zip_error: uC has notified the APPS upon a ZIP engine error
 * @uc_error_type: error type from uC error event
 * @uc_error_timestamp: tag timer sampled after uC crashed
 */
struct ipa3_uc_ctx {
	bool uc_inited;
@@ -1321,6 +1377,7 @@ struct ipa3_uc_ctx {
	u32 uc_status;
	bool uc_zip_error;
	u32 uc_error_type;
	u32 uc_error_timestamp;
};

/**
@@ -2335,4 +2392,5 @@ void ipa3_inc_acquire_wakelock(void);
void ipa3_dec_release_wakelock(void);
int ipa3_load_fws(const struct firmware *firmware);
int ipa3_register_ipa_ready_cb(void (*ipa_ready_cb)(void *), void *user_data);
const char *ipa_hw_error_str(enum ipa3_hw_errors err_type);
#endif /* _IPA3_I_H_ */
+21 −0
Original line number Diff line number Diff line
@@ -134,6 +134,20 @@ static int ipa3_handle_interrupt(int irq_num, bool isr_context)
		suspend_interrupt_data->endpoints = suspend_data;
		interrupt_data = suspend_interrupt_data;
		break;
	case IPA_UC_IRQ_0:
		if (ipa3_ctx->apply_rg10_wa) {
			/*
			 * Early detect of uC crash. If RG10 workaround is
			 * enable uC crash will not be detected as before
			 * processing uC event the interrupt is cleared using
			 * uC register write which times out as it crashed
			 * already.
			 */
			if (ipa3_ctx->uc_ctx.uc_sram_mmio->eventOp ==
			    IPA_HW_2_CPU_EVENT_ERROR)
				ipa3_ctx->uc_ctx.uc_failed = true;
		}
		break;
	default:
		break;
	}
@@ -251,6 +265,13 @@ static void ipa3_process_interrupts(bool isr_context)
			}
			bmsk = bmsk << 1;
		}
		/*
		 * In case uC failed interrupt cannot be cleared.
		 * Device will crash as part of handling uC event handler.
		 */
		if (ipa3_ctx->apply_rg10_wa && ipa3_ctx->uc_ctx.uc_failed)
			break;

		ipa3_uc_rg10_write_reg(IPA_IRQ_CLR_EE_n, ipa_ee, reg);
		reg = ipahal_read_reg_n(IPA_IRQ_STTS_EE_n, ipa_ee);
		/* since the suspend interrupt HW bug we must
+3 −56
Original line number Diff line number Diff line
@@ -78,47 +78,6 @@ enum ipa3_hw_2_cpu_responses {
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 2),
};

/**
 * enum ipa3_hw_2_cpu_events - Values that represent HW event to be sent to CPU.
 * @IPA_HW_2_CPU_EVENT_ERROR : Event specify a system error is detected by the
 * device
 * @IPA_HW_2_CPU_EVENT_LOG_INFO : Event providing logging specific information
 */
enum ipa3_hw_2_cpu_events {
	IPA_HW_2_CPU_EVENT_ERROR     =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 1),
	IPA_HW_2_CPU_EVENT_LOG_INFO  =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 2),
};

/**
 * enum ipa3_hw_errors - Common error types.
 * @IPA_HW_ERROR_NONE : No error persists
 * @IPA_HW_INVALID_DOORBELL_ERROR : Invalid data read from doorbell
 * @IPA_HW_DMA_ERROR : Unexpected DMA error
 * @IPA_HW_FATAL_SYSTEM_ERROR : HW has crashed and requires reset.
 * @IPA_HW_INVALID_OPCODE : Invalid opcode sent
 * @IPA_HW_ZIP_ENGINE_ERROR : ZIP engine error
 */
enum ipa3_hw_errors {
	IPA_HW_ERROR_NONE              =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 0),
	IPA_HW_INVALID_DOORBELL_ERROR  =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 1),
	IPA_HW_DMA_ERROR               =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 2),
	IPA_HW_FATAL_SYSTEM_ERROR      =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 3),
	IPA_HW_INVALID_OPCODE          =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 4),
	IPA_HW_ZIP_ENGINE_ERROR        =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 5),
	IPA_HW_CONS_DISABLE_CMD_GSI_STOP_FAILURE =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 6),
	IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE =
		FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 7)
};

/**
 * struct IpaHwResetPipeCmdData_t - Structure holding the parameters
 * for IPA_CPU_2_HW_CMD_MEMCPY command.
@@ -180,20 +139,6 @@ union IpaHwCpuCmdCompletedResponseData_t {
	u32 raw32b;
} __packed;

/**
 * union IpaHwErrorEventData_t - HW->CPU Common Events
 * @errorType : Entered when a system error is detected by the HW. Type of
 * error is specified by IPA_HW_ERRORS
 * @reserved : Reserved
 */
union IpaHwErrorEventData_t {
	struct IpaHwErrorEventParams_t {
		u32 errorType:8;
		u32 reserved:24;
	} __packed params;
	u32 raw32b;
} __packed;

/**
 * union IpaHwUpdateFlagsCmdData_t - Structure holding the parameters for
 * IPA_CPU_2_HW_CMD_UPDATE_FLAGS command
@@ -230,7 +175,7 @@ do { \

struct ipa3_uc_hdlrs ipa3_uc_hdlrs[IPA_HW_NUM_FEATURES] = { { 0 } };

static inline const char *ipa_hw_error_str(enum ipa3_hw_errors err_type)
const char *ipa_hw_error_str(enum ipa3_hw_errors err_type)
{
	const char *str;

@@ -383,6 +328,8 @@ static void ipa3_uc_event_handler(enum ipa_irq_type interrupt,
			IPAERR("IPA has encountered a ZIP engine error\n");
			ipa3_ctx->uc_ctx.uc_zip_error = true;
		}
		ipa3_ctx->uc_ctx.uc_error_timestamp =
			ipahal_read_reg(IPA_TAG_TIMER);
		BUG();
	} else if (ipa3_ctx->uc_ctx.uc_sram_mmio->eventOp ==
		IPA_HW_2_CPU_EVENT_LOG_INFO) {
+4 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ static const char *ipareg_name_to_str[IPA_REG_MAX] = {
	__stringify(IPA_ENABLED_PIPES),
	__stringify(IPA_COMP_SW_RESET),
	__stringify(IPA_VERSION),
	__stringify(IPA_TAG_TIMER),
	__stringify(IPA_COMP_HW_VERSION),
	__stringify(IPA_SPARE_REG_1),
	__stringify(IPA_SPARE_REG_2),
@@ -844,6 +845,9 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
	[IPA_HW_v3_0][IPA_VERSION] = {
		ipareg_construct_dummy, ipareg_parse_dummy,
		0x00000034, 0},
	[IPA_HW_v3_0][IPA_TAG_TIMER] = {
		ipareg_construct_dummy, ipareg_parse_dummy,
		0x00000060, 0 },
	[IPA_HW_v3_0][IPA_COMP_HW_VERSION] = {
		ipareg_construct_dummy, ipareg_parse_dummy,
		0x00000030, 0},
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ enum ipahal_reg_name {
	IPA_ENABLED_PIPES,
	IPA_COMP_SW_RESET,
	IPA_VERSION,
	IPA_TAG_TIMER,
	IPA_COMP_HW_VERSION,
	IPA_SPARE_REG_1,
	IPA_SPARE_REG_2,