Browse Source

drm/amd/display: add aux arbitration logic

Signed-off-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Charlene Liu 8 years ago
parent
commit
ceda4e9800

+ 6 - 0
drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c

@@ -69,6 +69,12 @@ bool dal_aux_engine_acquire(
 	struct aux_engine *aux_engine = FROM_ENGINE(engine);
 	struct aux_engine *aux_engine = FROM_ENGINE(engine);
 
 
 	enum gpio_result result;
 	enum gpio_result result;
+	if (aux_engine->funcs->is_engine_available) {
+		/*check whether SW could use the engine*/
+		if (!aux_engine->funcs->is_engine_available(aux_engine)) {
+			return false;
+		}
+	}
 
 
 	result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
 	result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
 		GPIO_DDC_CONFIG_TYPE_MODE_AUX);
 		GPIO_DDC_CONFIG_TYPE_MODE_AUX);

+ 2 - 0
drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h

@@ -86,6 +86,8 @@ struct aux_engine_funcs {
 	enum aux_channel_operation_result (*get_channel_status)(
 	enum aux_channel_operation_result (*get_channel_status)(
 		struct aux_engine *engine,
 		struct aux_engine *engine,
 		uint8_t *returned_bytes);
 		uint8_t *returned_bytes);
+	bool (*is_engine_available) (
+		struct aux_engine *engine);
 };
 };
 
 
 struct aux_engine {
 struct aux_engine {

+ 28 - 2
drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c

@@ -93,15 +93,36 @@ static void destroy(
 }
 }
 
 
 #define SW_CAN_ACCESS_AUX 1
 #define SW_CAN_ACCESS_AUX 1
+#define DMCU_CAN_ACCESS_AUX 2
 
 
+static bool is_engine_available(
+	struct aux_engine *engine)
+{
+	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
+
+	uint32_t value = REG_READ(AUX_ARB_CONTROL);
+	uint32_t field = get_reg_field_value(
+			value,
+			AUX_ARB_CONTROL,
+			AUX_REG_RW_CNTL_STATUS);
+
+	return (field != DMCU_CAN_ACCESS_AUX);
+}
 static bool acquire_engine(
 static bool acquire_engine(
 	struct aux_engine *engine)
 	struct aux_engine *engine)
 {
 {
 	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
 	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
 
 
+	uint32_t value = REG_READ(AUX_ARB_CONTROL);
+	uint32_t field = get_reg_field_value(
+			value,
+			AUX_ARB_CONTROL,
+			AUX_REG_RW_CNTL_STATUS);
+	if (field == DMCU_CAN_ACCESS_AUX)
+	 return false;
 	/* enable AUX before request SW to access AUX */
 	/* enable AUX before request SW to access AUX */
-	uint32_t value = REG_READ(AUX_CONTROL);
-	uint32_t field = get_reg_field_value(value,
+	value = REG_READ(AUX_CONTROL);
+	field = get_reg_field_value(value,
 				AUX_CONTROL,
 				AUX_CONTROL,
 				AUX_EN);
 				AUX_EN);
 
 
@@ -395,6 +416,7 @@ static const struct aux_engine_funcs aux_engine_funcs = {
 	.submit_channel_request = submit_channel_request,
 	.submit_channel_request = submit_channel_request,
 	.process_channel_reply = process_channel_reply,
 	.process_channel_reply = process_channel_reply,
 	.get_channel_status = get_channel_status,
 	.get_channel_status = get_channel_status,
+	.is_engine_available = is_engine_available,
 };
 };
 
 
 static const struct engine_funcs engine_funcs = {
 static const struct engine_funcs engine_funcs = {
@@ -425,6 +447,10 @@ static bool construct(
 static void destruct(
 static void destruct(
 	struct aux_engine_dce110 *engine)
 	struct aux_engine_dce110 *engine)
 {
 {
+	struct aux_engine_dce110 *aux110 = engine;
+/*temp w/a, to do*/
+	REG_UPDATE(AUX_ARB_CONTROL, AUX_DMCU_DONE_USING_AUX_REG, 1);
+	REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1);
 	dal_aux_engine_destruct(&engine->base);
 	dal_aux_engine_destruct(&engine->base);
 }
 }