aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c129
1 files changed, 127 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
index 604c62969ead..d68f951f9869 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
@@ -56,6 +56,7 @@
#include "dce/dce_dmcu.h"
#include "dce/dce_aux.h"
#include "dce/dce_abm.h"
+#include "dce/dce_i2c.h"
/* TODO remove this include */
#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
@@ -366,6 +367,7 @@ static const struct resource_caps res_cap = {
.num_audio = 6,
.num_stream_encoder = 6,
.num_pll = 3,
+ .num_ddc = 6,
};
static const struct resource_caps res_cap_81 = {
@@ -373,6 +375,7 @@ static const struct resource_caps res_cap_81 = {
.num_audio = 7,
.num_stream_encoder = 7,
.num_pll = 3,
+ .num_ddc = 6,
};
static const struct resource_caps res_cap_83 = {
@@ -380,6 +383,7 @@ static const struct resource_caps res_cap_83 = {
.num_audio = 6,
.num_stream_encoder = 6,
.num_pll = 2,
+ .num_ddc = 2,
};
static const struct dce_dmcu_registers dmcu_regs = {
@@ -480,7 +484,54 @@ struct aux_engine *dce80_aux_engine_create(
return &aux_engine->base;
}
+#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
+
+static const struct dce_i2c_registers i2c_hw_regs[] = {
+ i2c_inst_regs(1),
+ i2c_inst_regs(2),
+ i2c_inst_regs(3),
+ i2c_inst_regs(4),
+ i2c_inst_regs(5),
+ i2c_inst_regs(6),
+};
+
+static const struct dce_i2c_shift i2c_shifts = {
+ I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
+};
+
+static const struct dce_i2c_mask i2c_masks = {
+ I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
+};
+
+struct dce_i2c_hw *dce80_i2c_hw_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dce_i2c_hw *dce_i2c_hw =
+ kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
+
+ if (!dce_i2c_hw)
+ return NULL;
+
+ dce_i2c_hw_construct(dce_i2c_hw, ctx, inst,
+ &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
+
+ return dce_i2c_hw;
+}
+
+struct dce_i2c_sw *dce80_i2c_sw_create(
+ struct dc_context *ctx)
+{
+ struct dce_i2c_sw *dce_i2c_sw =
+ kzalloc(sizeof(struct dce_i2c_sw), GFP_KERNEL);
+ if (!dce_i2c_sw)
+ return NULL;
+
+ dce_i2c_sw_construct(dce_i2c_sw, ctx);
+
+ return dce_i2c_sw;
+}
static struct stream_encoder *dce80_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
@@ -599,8 +650,7 @@ static const struct encoder_feature_support link_enc_feature = {
.max_hdmi_deep_color = COLOR_DEPTH_121212,
.max_hdmi_pixel_clock = 297000,
.flags.bits.IS_HBR2_CAPABLE = true,
- .flags.bits.IS_TPS3_CAPABLE = true,
- .flags.bits.IS_YCBCR_CAPABLE = true
+ .flags.bits.IS_TPS3_CAPABLE = true
};
struct link_encoder *dce80_link_encoder_create(
@@ -688,9 +738,19 @@ static void destruct(struct dce110_resource_pool *pool)
kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
pool->base.timing_generators[i] = NULL;
}
+ }
+ for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
if (pool->base.engines[i] != NULL)
dce110_engine_destroy(&pool->base.engines[i]);
+ if (pool->base.hw_i2cs[i] != NULL) {
+ kfree(pool->base.hw_i2cs[i]);
+ pool->base.hw_i2cs[i] = NULL;
+ }
+ if (pool->base.sw_i2cs[i] != NULL) {
+ kfree(pool->base.sw_i2cs[i]);
+ pool->base.sw_i2cs[i] = NULL;
+ }
}
for (i = 0; i < pool->base.stream_enc_count; i++) {
@@ -887,6 +947,7 @@ static bool dce80_construct(
BREAK_TO_DEBUGGER();
goto res_create_fail;
}
+
if (dm_pp_get_static_clocks(ctx, &static_clk_info))
pool->base.dccg->max_clks_state =
static_clk_info.max_clocks_state;
@@ -935,7 +996,9 @@ static bool dce80_construct(
dm_error("DC: failed to create output pixel processor!\n");
goto res_create_fail;
}
+ }
+ for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
pool->base.engines[i] = dce80_aux_engine_create(ctx, i);
if (pool->base.engines[i] == NULL) {
BREAK_TO_DEBUGGER();
@@ -943,6 +1006,20 @@ static bool dce80_construct(
"DC:failed to create aux engine!!\n");
goto res_create_fail;
}
+ pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i);
+ if (pool->base.hw_i2cs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create i2c engine!!\n");
+ goto res_create_fail;
+ }
+ pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx);
+ if (pool->base.sw_i2cs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create sw i2c!!\n");
+ goto res_create_fail;
+ }
}
dc->caps.max_planes = pool->base.pipe_count;
@@ -1131,6 +1208,30 @@ static bool dce81_construct(
}
}
+ for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
+ pool->base.engines[i] = dce80_aux_engine_create(ctx, i);
+ if (pool->base.engines[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create aux engine!!\n");
+ goto res_create_fail;
+ }
+ pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i);
+ if (pool->base.hw_i2cs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create i2c engine!!\n");
+ goto res_create_fail;
+ }
+ pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx);
+ if (pool->base.sw_i2cs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create sw i2c!!\n");
+ goto res_create_fail;
+ }
+ }
+
dc->caps.max_planes = pool->base.pipe_count;
dc->caps.disable_dp_clk_share = true;
@@ -1313,6 +1414,30 @@ static bool dce83_construct(
}
}
+ for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
+ pool->base.engines[i] = dce80_aux_engine_create(ctx, i);
+ if (pool->base.engines[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create aux engine!!\n");
+ goto res_create_fail;
+ }
+ pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i);
+ if (pool->base.hw_i2cs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create i2c engine!!\n");
+ goto res_create_fail;
+ }
+ pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx);
+ if (pool->base.sw_i2cs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create sw i2c!!\n");
+ goto res_create_fail;
+ }
+ }
+
dc->caps.max_planes = pool->base.pipe_count;
dc->caps.disable_dp_clk_share = true;