Commit c85e6e54 authored by David Francis's avatar David Francis Committed by Alex Deucher

drm/amd/display: Create new i2c resource

[Why]
I2C code did not match dc resource model and was generally
unpleasant

[How]
Move code into new svelte dce_i2c files, replacing various i2c
objects with two structs: dce_i2c_sw and dce_i2c_hw.  Fully split
sw and hw code paths.  Remove all redundant declarations.  Use
address lists to distinguish between versions.  Change dce80 code
to newer register access macros.
Signed-off-by: default avatarDavid Francis <David.Francis@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent d6257ab5
...@@ -71,8 +71,6 @@ ...@@ -71,8 +71,6 @@
#include "modules/inc/mod_freesync.h" #include "modules/inc/mod_freesync.h"
#include "i2caux_interface.h"
/* basic init/fini API */ /* basic init/fini API */
static int amdgpu_dm_init(struct amdgpu_device *adev); static int amdgpu_dm_init(struct amdgpu_device *adev);
static void amdgpu_dm_fini(struct amdgpu_device *adev); static void amdgpu_dm_fini(struct amdgpu_device *adev);
...@@ -3610,9 +3608,9 @@ static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -3610,9 +3608,9 @@ static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap,
cmd.payloads[i].data = msgs[i].buf; cmd.payloads[i].data = msgs[i].buf;
} }
if (dal_i2caux_submit_i2c_command( if (dc_submit_i2c(
ddc_service->ctx->i2caux, ddc_service->ctx->dc,
ddc_service->ddc_pin, ddc_service->ddc_pin->hw_info.ddc_channel,
&cmd)) &cmd))
result = num; result = num;
...@@ -3648,6 +3646,7 @@ create_i2c(struct ddc_service *ddc_service, ...@@ -3648,6 +3646,7 @@ create_i2c(struct ddc_service *ddc_service,
snprintf(i2c->base.name, sizeof(i2c->base.name), "AMDGPU DM i2c hw bus %d", link_index); snprintf(i2c->base.name, sizeof(i2c->base.name), "AMDGPU DM i2c hw bus %d", link_index);
i2c_set_adapdata(&i2c->base, i2c); i2c_set_adapdata(&i2c->base, i2c);
i2c->ddc_service = ddc_service; i2c->ddc_service = ddc_service;
i2c->ddc_service->ddc_pin->hw_info.ddc_channel = link_index;
return i2c; return i2c;
} }
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#include "bios_parser_interface.h" #include "bios_parser_interface.h"
#include "bios_parser_common.h" #include "bios_parser_common.h"
/* TODO remove - only needed for default i2c speed */
#include "dc.h" #include "dc.h"
#define THREE_PERCENT_OF_10000 300 #define THREE_PERCENT_OF_10000 300
...@@ -2671,11 +2671,9 @@ static bool i2c_read( ...@@ -2671,11 +2671,9 @@ static bool i2c_read(
cmd.payloads = payloads; cmd.payloads = payloads;
cmd.number_of_payloads = ARRAY_SIZE(payloads); cmd.number_of_payloads = ARRAY_SIZE(payloads);
result = dc_submit_i2c(
/* TODO route this through drm i2c_adapter */ ddc->ctx->dc,
result = dal_i2caux_submit_i2c_command( ddc->hw_info.ddc_channel,
ddc->ctx->i2caux,
ddc,
&cmd); &cmd);
} }
......
...@@ -54,6 +54,9 @@ ...@@ -54,6 +54,9 @@
#include "hubp.h" #include "hubp.h"
#include "dc_link_dp.h" #include "dc_link_dp.h"
#include "dce/dce_i2c.h"
#define DC_LOGGER \ #define DC_LOGGER \
dc->ctx->logger dc->ctx->logger
...@@ -1673,9 +1676,8 @@ bool dc_submit_i2c( ...@@ -1673,9 +1676,8 @@ bool dc_submit_i2c(
struct dc_link *link = dc->links[link_index]; struct dc_link *link = dc->links[link_index];
struct ddc_service *ddc = link->ddc; struct ddc_service *ddc = link->ddc;
return dce_i2c_submit_command(
return dal_i2caux_submit_i2c_command( dc->res_pool,
ddc->ctx->i2caux,
ddc->ddc_pin, ddc->ddc_pin,
cmd); cmd);
} }
......
...@@ -1530,8 +1530,8 @@ static bool i2c_write(struct pipe_ctx *pipe_ctx, ...@@ -1530,8 +1530,8 @@ static bool i2c_write(struct pipe_ctx *pipe_ctx,
payload.write = true; payload.write = true;
cmd.payloads = &payload; cmd.payloads = &payload;
if (dc_submit_i2c(pipe_ctx->stream->ctx->dc, if (dm_helpers_submit_i2c(pipe_ctx->stream->ctx,
pipe_ctx->stream->sink->link->link_index, &cmd)) pipe_ctx->stream->sink->link, &cmd))
return true; return true;
return false; return false;
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \ DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \
dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \ dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \
dce_clocks.o dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o dce_clocks.o dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o \
dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o
AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE)) AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))
......
/*
* Copyright 2018 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "dce_i2c.h"
#include "reg_helper.h"
bool dce_i2c_submit_command(
struct resource_pool *pool,
struct ddc *ddc,
struct i2c_command *cmd)
{
struct dce_i2c_hw *dce_i2c_hw;
struct dce_i2c_sw *dce_i2c_sw;
if (!ddc) {
BREAK_TO_DEBUGGER();
return false;
}
if (!cmd) {
BREAK_TO_DEBUGGER();
return false;
}
/* The software engine is only available on dce8 */
dce_i2c_sw = dce_i2c_acquire_i2c_sw_engine(pool, ddc);
if (!dce_i2c_sw) {
dce_i2c_hw = acquire_i2c_hw_engine(pool, ddc);
if (!dce_i2c_hw)
return false;
return dce_i2c_submit_command_hw(pool, ddc, cmd, dce_i2c_hw);
}
return dce_i2c_submit_command_sw(pool, ddc, cmd, dce_i2c_sw);
}
/*
* Copyright 2018 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DCE_I2C_H__
#define __DCE_I2C_H__
#include "inc/core_types.h"
#include "dce_i2c_hw.h"
#include "dce_i2c_sw.h"
enum dce_i2c_transaction_status {
DCE_I2C_TRANSACTION_STATUS_UNKNOWN = (-1L),
DCE_I2C_TRANSACTION_STATUS_SUCCEEDED,
DCE_I2C_TRANSACTION_STATUS_FAILED_CHANNEL_BUSY,
DCE_I2C_TRANSACTION_STATUS_FAILED_TIMEOUT,
DCE_I2C_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR,
DCE_I2C_TRANSACTION_STATUS_FAILED_NACK,
DCE_I2C_TRANSACTION_STATUS_FAILED_INCOMPLETE,
DCE_I2C_TRANSACTION_STATUS_FAILED_OPERATION,
DCE_I2C_TRANSACTION_STATUS_FAILED_INVALID_OPERATION,
DCE_I2C_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW,
DCE_I2C_TRANSACTION_STATUS_FAILED_HPD_DISCON
};
enum dce_i2c_transaction_operation {
DCE_I2C_TRANSACTION_READ,
DCE_I2C_TRANSACTION_WRITE
};
struct dce_i2c_transaction_payload {
enum dce_i2c_transaction_address_space address_space;
uint32_t address;
uint32_t length;
uint8_t *data;
};
struct dce_i2c_transaction_request {
enum dce_i2c_transaction_operation operation;
struct dce_i2c_transaction_payload payload;
enum dce_i2c_transaction_status status;
};
bool dce_i2c_submit_command(
struct resource_pool *pool,
struct ddc *ddc,
struct i2c_command *cmd);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright 2018 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DCE_I2C_SW_H__
#define __DCE_I2C_SW_H__
enum {
DCE_I2C_DEFAULT_I2C_SW_SPEED = 50,
I2C_SW_RETRIES = 10,
I2C_SW_TIMEOUT_DELAY = 3000,
};
struct dce_i2c_sw {
struct ddc *ddc;
struct dc_context *ctx;
uint32_t clock_delay;
uint32_t speed;
};
void dce_i2c_sw_construct(
struct dce_i2c_sw *dce_i2c_sw,
struct dc_context *ctx);
bool dce_i2c_submit_command_sw(
struct resource_pool *pool,
struct ddc *ddc,
struct i2c_command *cmd,
struct dce_i2c_sw *dce_i2c_sw);
struct dce_i2c_sw *dce_i2c_acquire_i2c_sw_engine(
struct resource_pool *pool,
struct ddc *ddc);
#endif
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "dce/dce_dmcu.h" #include "dce/dce_dmcu.h"
#include "dce/dce_aux.h" #include "dce/dce_aux.h"
#include "dce/dce_abm.h" #include "dce/dce_abm.h"
#include "dce/dce_i2c.h"
#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
#include "gmc/gmc_8_2_d.h" #include "gmc/gmc_8_2_d.h"
...@@ -602,7 +603,40 @@ struct aux_engine *dce100_aux_engine_create( ...@@ -602,7 +603,40 @@ struct aux_engine *dce100_aux_engine_create(
return &aux_engine->base; 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 *dce100_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;
dce100_i2c_hw_construct(dce_i2c_hw, ctx, inst,
&i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
return dce_i2c_hw;
}
struct clock_source *dce100_clock_source_create( struct clock_source *dce100_clock_source_create(
struct dc_context *ctx, struct dc_context *ctx,
struct dc_bios *bios, struct dc_bios *bios,
...@@ -658,7 +692,14 @@ static void destruct(struct dce110_resource_pool *pool) ...@@ -658,7 +692,14 @@ static void destruct(struct dce110_resource_pool *pool)
if (pool->base.engines[i] != NULL) if (pool->base.engines[i] != NULL)
dce110_engine_destroy(&pool->base.engines[i]); 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++) { for (i = 0; i < pool->base.stream_enc_count; i++) {
...@@ -970,6 +1011,14 @@ static bool construct( ...@@ -970,6 +1011,14 @@ static bool construct(
"DC:failed to create aux engine!!\n"); "DC:failed to create aux engine!!\n");
goto res_create_fail; goto res_create_fail;
} }
pool->base.hw_i2cs[i] = dce100_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] = NULL;
} }
dc->caps.max_planes = pool->base.pipe_count; dc->caps.max_planes = pool->base.pipe_count;
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "dce/dce_aux.h" #include "dce/dce_aux.h"
#include "dce/dce_abm.h" #include "dce/dce_abm.h"
#include "dce/dce_dmcu.h" #include "dce/dce_dmcu.h"
#include "dce/dce_i2c.h"
#define DC_LOGGER \ #define DC_LOGGER \
dc->ctx->logger dc->ctx->logger
...@@ -620,7 +621,40 @@ struct aux_engine *dce110_aux_engine_create( ...@@ -620,7 +621,40 @@ struct aux_engine *dce110_aux_engine_create(
return &aux_engine->base; 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_DCE110(__SHIFT)
};
static const struct dce_i2c_mask i2c_masks = {
I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
};
struct dce_i2c_hw *dce110_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;
dce100_i2c_hw_construct(dce_i2c_hw, ctx, inst,
&i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
return dce_i2c_hw;
}
struct clock_source *dce110_clock_source_create( struct clock_source *dce110_clock_source_create(
struct dc_context *ctx, struct dc_context *ctx,
struct dc_bios *bios, struct dc_bios *bios,
...@@ -687,7 +721,14 @@ static void destruct(struct dce110_resource_pool *pool) ...@@ -687,7 +721,14 @@ static void destruct(struct dce110_resource_pool *pool)
if (pool->base.engines[i] != NULL) if (pool->base.engines[i] != NULL)
dce110_engine_destroy(&pool->base.engines[i]); 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++) { for (i = 0; i < pool->base.stream_enc_count; i++) {
...@@ -1303,6 +1344,14 @@ static bool construct( ...@@ -1303,6 +1344,14 @@ static bool construct(
"DC:failed to create aux engine!!\n"); "DC:failed to create aux engine!!\n");
goto res_create_fail; goto res_create_fail;
} }
pool->base.hw_i2cs[i] = dce110_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] = NULL;
} }
dc->fbc_compressor = dce110_compressor_create(ctx); dc->fbc_compressor = dce110_compressor_create(ctx);
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "dce/dce_abm.h" #include "dce/dce_abm.h"
#include "dce/dce_dmcu.h" #include "dce/dce_dmcu.h"
#include "dce/dce_aux.h" #include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
#include "reg_helper.h" #include "reg_helper.h"
...@@ -620,7 +621,40 @@ struct aux_engine *dce112_aux_engine_create( ...@@ -620,7 +621,40 @@ struct aux_engine *dce112_aux_engine_create(
return &aux_engine->base; 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_DCE110(__SHIFT)
};
static const struct dce_i2c_mask i2c_masks = {
I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
};
struct dce_i2c_hw *dce112_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;
dce112_i2c_hw_construct(dce_i2c_hw, ctx, inst,
&i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
return dce_i2c_hw;
}
struct clock_source *dce112_clock_source_create( struct clock_source *dce112_clock_source_create(
struct dc_context *ctx, struct dc_context *ctx,
struct dc_bios *bios, struct dc_bios *bios,
...@@ -676,7 +710,14 @@ static void destruct(struct dce110_resource_pool *pool) ...@@ -676,7 +710,14 @@ static void destruct(struct dce110_resource_pool *pool)
kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i])); kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
pool->base.timing_generators[i] = NULL; pool->base.timing_generators[i] = NULL;
} }
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++) { for (i = 0; i < pool->base.stream_enc_count; i++) {
...@@ -1252,6 +1293,14 @@ static bool construct( ...@@ -1252,6 +1293,14 @@ static bool construct(
"DC:failed to create aux engine!!\n"); "DC:failed to create aux engine!!\n");
goto res_create_fail; goto res_create_fail;
} }
pool->base.hw_i2cs[i] = dce112_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] = NULL;
} }
if (!resource_construct(num_virtual_links, dc, &pool->base, if (!resource_construct(num_virtual_links, dc, &pool->base,
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "dce/dce_abm.h" #include "dce/dce_abm.h"
#include "dce/dce_dmcu.h" #include "dce/dce_dmcu.h"
#include "dce/dce_aux.h" #include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
#include "dce/dce_12_0_offset.h" #include "dce/dce_12_0_offset.h"
#include "dce/dce_12_0_sh_mask.h" #include "dce/dce_12_0_sh_mask.h"
...@@ -392,7 +393,40 @@ struct aux_engine *dce120_aux_engine_create( ...@@ -392,7 +393,40 @@ struct aux_engine *dce120_aux_engine_create(
return &aux_engine->base; 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_DCE110(__SHIFT)
};
static const struct dce_i2c_mask i2c_masks = {
I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
};
struct dce_i2c_hw *dce120_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;
dce112_i2c_hw_construct(dce_i2c_hw, ctx, inst,
&i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
return dce_i2c_hw;
}
static const struct bios_registers bios_regs = { static const struct bios_registers bios_regs = {
.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 + NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX) .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 + NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX)
}; };
...@@ -501,7 +535,14 @@ static void destruct(struct dce110_resource_pool *pool) ...@@ -501,7 +535,14 @@ static void destruct(struct dce110_resource_pool *pool)
if (pool->base.engines[i] != NULL) if (pool->base.engines[i] != NULL)
dce110_engine_destroy(&pool->base.engines[i]); 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.audio_count; i++) { for (i = 0; i < pool->base.audio_count; i++) {
...@@ -957,6 +998,7 @@ static bool construct( ...@@ -957,6 +998,7 @@ static bool construct(
goto res_create_fail; goto res_create_fail;
} }
irq_init_data.ctx = dc->ctx; irq_init_data.ctx = dc->ctx;
pool->base.irqs = dal_irq_service_dce120_create(&irq_init_data); pool->base.irqs = dal_irq_service_dce120_create(&irq_init_data);
if (!pool->base.irqs) if (!pool->base.irqs)
...@@ -1021,13 +1063,20 @@ static bool construct( ...@@ -1021,13 +1063,20 @@ static bool construct(
"DC: failed to create output pixel processor!\n"); "DC: failed to create output pixel processor!\n");
} }
pool->base.engines[i] = dce120_aux_engine_create(ctx, i); pool->base.engines[i] = dce120_aux_engine_create(ctx, i);
if (pool->base.engines[i] == NULL) { if (pool->base.engines[i] == NULL) {
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
dm_error( dm_error(
"DC:failed to create aux engine!!\n"); "DC:failed to create aux engine!!\n");
goto res_create_fail; goto res_create_fail;
} }
pool->base.hw_i2cs[i] = dce120_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] = NULL;
/* check next valid pipe */ /* check next valid pipe */
j++; j++;
} }
......
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#include "dce/dce_dmcu.h" #include "dce/dce_dmcu.h"
#include "dce/dce_aux.h" #include "dce/dce_aux.h"
#include "dce/dce_abm.h" #include "dce/dce_abm.h"
#include "dce/dce_i2c.h"
/* TODO remove this include */ /* TODO remove this include */
#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
...@@ -480,7 +481,54 @@ struct aux_engine *dce80_aux_engine_create( ...@@ -480,7 +481,54 @@ struct aux_engine *dce80_aux_engine_create(
return &aux_engine->base; 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( static struct stream_encoder *dce80_stream_encoder_create(
enum engine_id eng_id, enum engine_id eng_id,
struct dc_context *ctx) struct dc_context *ctx)
...@@ -691,6 +739,14 @@ static void destruct(struct dce110_resource_pool *pool) ...@@ -691,6 +739,14 @@ static void destruct(struct dce110_resource_pool *pool)
if (pool->base.engines[i] != NULL) if (pool->base.engines[i] != NULL)
dce110_engine_destroy(&pool->base.engines[i]); 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++) { for (i = 0; i < pool->base.stream_enc_count; i++) {
...@@ -887,6 +943,7 @@ static bool dce80_construct( ...@@ -887,6 +943,7 @@ static bool dce80_construct(
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
goto res_create_fail; goto res_create_fail;
} }
if (dm_pp_get_static_clocks(ctx, &static_clk_info)) if (dm_pp_get_static_clocks(ctx, &static_clk_info))
pool->base.dccg->max_clks_state = pool->base.dccg->max_clks_state =
static_clk_info.max_clocks_state; static_clk_info.max_clocks_state;
...@@ -943,6 +1000,20 @@ static bool dce80_construct( ...@@ -943,6 +1000,20 @@ static bool dce80_construct(
"DC:failed to create aux engine!!\n"); "DC:failed to create aux engine!!\n");
goto res_create_fail; 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.max_planes = pool->base.pipe_count;
...@@ -1129,6 +1200,20 @@ static bool dce81_construct( ...@@ -1129,6 +1200,20 @@ static bool dce81_construct(
dm_error("DC: failed to create output pixel processor!\n"); dm_error("DC: failed to create output pixel processor!\n");
goto res_create_fail; 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.max_planes = pool->base.pipe_count;
...@@ -1311,6 +1396,20 @@ static bool dce83_construct( ...@@ -1311,6 +1396,20 @@ static bool dce83_construct(
dm_error("DC: failed to create output pixel processor!\n"); dm_error("DC: failed to create output pixel processor!\n");
goto res_create_fail; 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.max_planes = pool->base.pipe_count;
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include "dce/dce_abm.h" #include "dce/dce_abm.h"
#include "dce/dce_dmcu.h" #include "dce/dce_dmcu.h"
#include "dce/dce_aux.h" #include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
const struct _vcs_dpi_ip_params_st dcn1_0_ip = { const struct _vcs_dpi_ip_params_st dcn1_0_ip = {
.rob_buffer_size_kbytes = 64, .rob_buffer_size_kbytes = 64,
...@@ -610,7 +611,40 @@ struct aux_engine *dcn10_aux_engine_create( ...@@ -610,7 +611,40 @@ struct aux_engine *dcn10_aux_engine_create(
return &aux_engine->base; 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_DCE110(__SHIFT)
};
static const struct dce_i2c_mask i2c_masks = {
I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
};
struct dce_i2c_hw *dcn10_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;
dcn1_i2c_hw_construct(dce_i2c_hw, ctx, inst,
&i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
return dce_i2c_hw;
}
static struct mpc *dcn10_mpc_create(struct dc_context *ctx) static struct mpc *dcn10_mpc_create(struct dc_context *ctx)
{ {
struct dcn10_mpc *mpc10 = kzalloc(sizeof(struct dcn10_mpc), struct dcn10_mpc *mpc10 = kzalloc(sizeof(struct dcn10_mpc),
...@@ -862,6 +896,14 @@ static void destruct(struct dcn10_resource_pool *pool) ...@@ -862,6 +896,14 @@ static void destruct(struct dcn10_resource_pool *pool)
if (pool->base.engines[i] != NULL) if (pool->base.engines[i] != NULL)
pool->base.engines[i]->funcs->destroy_engine(&pool->base.engines[i]); pool->base.engines[i]->funcs->destroy_engine(&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++) for (i = 0; i < pool->base.stream_enc_count; i++)
...@@ -1300,7 +1342,14 @@ static bool construct( ...@@ -1300,7 +1342,14 @@ static bool construct(
"DC:failed to create aux engine!!\n"); "DC:failed to create aux engine!!\n");
goto fail; goto fail;
} }
pool->base.hw_i2cs[i] = dcn10_i2c_hw_create(ctx, i);
if (pool->base.hw_i2cs[i] == NULL) {
BREAK_TO_DEBUGGER();
dm_error(
"DC:failed to create hw i2c!!\n");
goto fail;
}
pool->base.sw_i2cs[i] = NULL;
/* check next valid pipe */ /* check next valid pipe */
j++; j++;
} }
......
...@@ -144,6 +144,9 @@ struct resource_pool { ...@@ -144,6 +144,9 @@ struct resource_pool {
struct mpc *mpc; struct mpc *mpc;
struct pp_smu_funcs_rv *pp_smu; struct pp_smu_funcs_rv *pp_smu;
struct pp_smu_display_requirement_rv pp_smu_req; struct pp_smu_display_requirement_rv pp_smu_req;
struct dce_i2c_hw *hw_i2cs[MAX_PIPES];
struct dce_i2c_sw *sw_i2cs[MAX_PIPES];
bool i2c_hw_buffer_in_use;
unsigned int pipe_count; unsigned int pipe_count;
unsigned int underlay_pipe_index; unsigned int underlay_pipe_index;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment