diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1087-drm-amd-display-Fully-remove-i2caux-folder.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1087-drm-amd-display-Fully-remove-i2caux-folder.patch | 1556 |
1 files changed, 1556 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1087-drm-amd-display-Fully-remove-i2caux-folder.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1087-drm-amd-display-Fully-remove-i2caux-folder.patch new file mode 100644 index 00000000..13cb56a4 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1087-drm-amd-display-Fully-remove-i2caux-folder.patch @@ -0,0 +1,1556 @@ +From 7763493acdd452a0b756279fff87bac709af0cb0 Mon Sep 17 00:00:00 2001 +From: Leo Li <sunpeng.li@amd.com> +Date: Fri, 11 Jan 2019 10:41:17 -0500 +Subject: [PATCH 1087/2940] drm/amd/display: Fully remove i2caux folder + +This is a follow up to: +e28e1490794d ("drm/amd/display: Remove i2caux folder") + +Some files were still left, so delete all of them. + +CC: David Francis <David.Francis@amd.com> +CC: Harry Wentland <Harry.Wentland@amd.com> +Signed-off-by: Leo Li <sunpeng.li@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + .../gpu/drm/amd/display/dc/i2caux/Makefile | 99 --- + .../dc/i2caux/dce110/i2c_hw_engine_dce110.c | 573 ------------------ + .../display/dc/i2caux/dce112/i2caux_dce112.c | 129 ---- + .../display/dc/i2caux/dce112/i2caux_dce112.h | 32 - + .../dc/i2caux/dce80/i2c_sw_engine_dce80.c | 163 ----- + .../gpu/drm/amd/display/dc/i2caux/i2caux.c | 491 --------------- + 6 files changed, 1487 deletions(-) + delete mode 100644 drivers/gpu/drm/amd/display/dc/i2caux/Makefile + delete mode 100644 drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c + delete mode 100644 drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.c + delete mode 100644 drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.h + delete mode 100644 drivers/gpu/drm/amd/display/dc/i2caux/dce80/i2c_sw_engine_dce80.c + delete mode 100644 drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c + +diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/Makefile b/drivers/gpu/drm/amd/display/dc/i2caux/Makefile +deleted file mode 100644 +index a851d07f0190..000000000000 +--- a/drivers/gpu/drm/amd/display/dc/i2caux/Makefile ++++ /dev/null +@@ -1,99 +0,0 @@ +-# +-# Copyright 2017 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. +-# +-# +-# Makefile for the 'i2c' sub-component of DAL. +-# It provides the control and status of HW i2c engine of the adapter. +- +-I2CAUX = aux_engine.o engine_base.o i2caux.o i2c_engine.o \ +- i2c_generic_hw_engine.o i2c_hw_engine.o i2c_sw_engine.o +- +-AMD_DAL_I2CAUX = $(addprefix $(AMDDALPATH)/dc/i2caux/,$(I2CAUX)) +- +-AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX) +- +-############################################################################### +-# DCE 8x family +-############################################################################### +-I2CAUX_DCE80 = i2caux_dce80.o i2c_hw_engine_dce80.o \ +- i2c_sw_engine_dce80.o +- +-AMD_DAL_I2CAUX_DCE80 = $(addprefix $(AMDDALPATH)/dc/i2caux/dce80/,$(I2CAUX_DCE80)) +- +-AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCE80) +- +-############################################################################### +-# DCE 100 family +-############################################################################### +-I2CAUX_DCE100 = i2caux_dce100.o +- +-AMD_DAL_I2CAUX_DCE100 = $(addprefix $(AMDDALPATH)/dc/i2caux/dce100/,$(I2CAUX_DCE100)) +- +-AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCE100) +- +-############################################################################### +-# DCE 110 family +-############################################################################### +-I2CAUX_DCE110 = i2caux_dce110.o i2c_sw_engine_dce110.o i2c_hw_engine_dce110.o \ +- aux_engine_dce110.o +- +-AMD_DAL_I2CAUX_DCE110 = $(addprefix $(AMDDALPATH)/dc/i2caux/dce110/,$(I2CAUX_DCE110)) +- +-AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCE110) +- +-############################################################################### +-# DCE 112 family +-############################################################################### +-I2CAUX_DCE112 = i2caux_dce112.o +- +-AMD_DAL_I2CAUX_DCE112 = $(addprefix $(AMDDALPATH)/dc/i2caux/dce112/,$(I2CAUX_DCE112)) +- +-AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCE112) +- +-############################################################################### +-# DCN 1.0 family +-############################################################################### +-ifdef CONFIG_X86 +-I2CAUX_DCN1 = i2caux_dcn10.o +- +-AMD_DAL_I2CAUX_DCN1 = $(addprefix $(AMDDALPATH)/dc/i2caux/dcn10/,$(I2CAUX_DCN1)) +- +-AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCN1) +-endif +- +-############################################################################### +-# DCE 120 family +-############################################################################### +-I2CAUX_DCE120 = i2caux_dce120.o +- +-AMD_DAL_I2CAUX_DCE120 = $(addprefix $(AMDDALPATH)/dc/i2caux/dce120/,$(I2CAUX_DCE120)) +- +-AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCE120) +- +-############################################################################### +-# Diagnostics on FPGA +-############################################################################### +-I2CAUX_DIAG = i2caux_diag.o +- +-AMD_DAL_I2CAUX_DIAG = $(addprefix $(AMDDALPATH)/dc/i2caux/diagnostics/,$(I2CAUX_DIAG)) +- +-AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DIAG) +- +diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c +deleted file mode 100644 +index 137350142fb2..000000000000 +--- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c ++++ /dev/null +@@ -1,573 +0,0 @@ +-/* +- * Copyright 2012-15 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 "dm_services.h" +-#include "include/logger_interface.h" +-/* +- * Pre-requisites: headers required by header of this unit +- */ +- +-#include "include/i2caux_interface.h" +-#include "../engine.h" +-#include "../i2c_engine.h" +-#include "../i2c_hw_engine.h" +-#include "../i2c_generic_hw_engine.h" +-/* +- * Header of this unit +- */ +- +-#include "i2c_hw_engine_dce110.h" +- +-/* +- * Post-requisites: headers required by this unit +- */ +-#include "reg_helper.h" +- +-/* +- * This unit +- */ +-#define DC_LOGGER \ +- hw_engine->base.base.base.ctx->logger +- +-enum dc_i2c_status { +- DC_I2C_STATUS__DC_I2C_STATUS_IDLE, +- DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_SW, +- DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_HW +-}; +- +-enum dc_i2c_arbitration { +- DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_NORMAL, +- DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_HIGH +-}; +- +- +- +-/* +- * @brief +- * Cast pointer to 'struct i2c_hw_engine *' +- * to pointer 'struct i2c_hw_engine_dce110 *' +- */ +-#define FROM_I2C_HW_ENGINE(ptr) \ +- container_of((ptr), struct i2c_hw_engine_dce110, base) +-/* +- * @brief +- * Cast pointer to 'struct i2c_engine *' +- * to pointer to 'struct i2c_hw_engine_dce110 *' +- */ +-#define FROM_I2C_ENGINE(ptr) \ +- FROM_I2C_HW_ENGINE(container_of((ptr), struct i2c_hw_engine, base)) +- +-/* +- * @brief +- * Cast pointer to 'struct engine *' +- * to 'pointer to struct i2c_hw_engine_dce110 *' +- */ +-#define FROM_ENGINE(ptr) \ +- FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base)) +- +-#define CTX \ +- hw_engine->base.base.base.ctx +- +-#define REG(reg_name)\ +- (hw_engine->regs->reg_name) +- +-#undef FN +-#define FN(reg_name, field_name) \ +- hw_engine->i2c_shift->field_name, hw_engine->i2c_mask->field_name +- +- +-static void disable_i2c_hw_engine( +- struct i2c_hw_engine_dce110 *hw_engine) +-{ +- REG_UPDATE_N(SETUP, 1, FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 0); +-} +- +-static void release_engine( +- struct engine *engine) +-{ +- struct i2c_hw_engine_dce110 *hw_engine = FROM_ENGINE(engine); +- +- struct i2c_engine *base = NULL; +- bool safe_to_reset; +- +- base = &hw_engine->base.base; +- +- /* Restore original HW engine speed */ +- +- base->funcs->set_speed(base, hw_engine->base.original_speed); +- +- /* Release I2C */ +- REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1); +- +- /* Reset HW engine */ +- { +- uint32_t i2c_sw_status = 0; +- REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status); +- /* if used by SW, safe to reset */ +- safe_to_reset = (i2c_sw_status == 1); +- } +- +- if (safe_to_reset) +- REG_UPDATE_2( +- DC_I2C_CONTROL, +- DC_I2C_SOFT_RESET, 1, +- DC_I2C_SW_STATUS_RESET, 1); +- else +- REG_UPDATE(DC_I2C_CONTROL, DC_I2C_SW_STATUS_RESET, 1); +- +- /* HW I2c engine - clock gating feature */ +- if (!hw_engine->engine_keep_power_up_count) +- disable_i2c_hw_engine(hw_engine); +-} +- +-static bool setup_engine( +- struct i2c_engine *i2c_engine) +-{ +- struct i2c_hw_engine_dce110 *hw_engine = FROM_I2C_ENGINE(i2c_engine); +- uint32_t i2c_setup_limit = I2C_SETUP_TIME_LIMIT_DCE; +- uint32_t reset_length = 0; +- +- if (hw_engine->base.base.setup_limit != 0) +- i2c_setup_limit = hw_engine->base.base.setup_limit; +- +- /* Program pin select */ +- REG_UPDATE_6( +- DC_I2C_CONTROL, +- DC_I2C_GO, 0, +- DC_I2C_SOFT_RESET, 0, +- DC_I2C_SEND_RESET, 0, +- DC_I2C_SW_STATUS_RESET, 1, +- DC_I2C_TRANSACTION_COUNT, 0, +- DC_I2C_DDC_SELECT, hw_engine->engine_id); +- +- /* Program time limit */ +- if (hw_engine->base.base.send_reset_length == 0) { +- /*pre-dcn*/ +- REG_UPDATE_N( +- SETUP, 2, +- FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), i2c_setup_limit, +- FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1); +- } else { +- reset_length = hw_engine->base.base.send_reset_length; +- } +- /* Program HW priority +- * set to High - interrupt software I2C at any time +- * Enable restart of SW I2C that was interrupted by HW +- * disable queuing of software while I2C is in use by HW */ +- REG_UPDATE_2( +- DC_I2C_ARBITRATION, +- DC_I2C_NO_QUEUED_SW_GO, 0, +- DC_I2C_SW_PRIORITY, DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_NORMAL); +- +- return true; +-} +- +-static uint32_t get_speed( +- const struct i2c_engine *i2c_engine) +-{ +- const struct i2c_hw_engine_dce110 *hw_engine = FROM_I2C_ENGINE(i2c_engine); +- uint32_t pre_scale = 0; +- +- REG_GET(SPEED, DC_I2C_DDC1_PRESCALE, &pre_scale); +- +- /* [anaumov] it seems following is unnecessary */ +- /*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/ +- return pre_scale ? +- hw_engine->reference_frequency / pre_scale : +- hw_engine->base.default_speed; +-} +- +-static void set_speed( +- struct i2c_engine *i2c_engine, +- uint32_t speed) +-{ +- struct i2c_hw_engine_dce110 *hw_engine = FROM_I2C_ENGINE(i2c_engine); +- +- if (speed) { +- if (hw_engine->i2c_mask->DC_I2C_DDC1_START_STOP_TIMING_CNTL) +- REG_UPDATE_N( +- SPEED, 3, +- FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), hw_engine->reference_frequency / speed, +- FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2, +- FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1); +- else +- REG_UPDATE_N( +- SPEED, 2, +- FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), hw_engine->reference_frequency / speed, +- FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2); +- } +-} +- +-static inline void reset_hw_engine(struct engine *engine) +-{ +- struct i2c_hw_engine_dce110 *hw_engine = FROM_ENGINE(engine); +- +- REG_UPDATE_2( +- DC_I2C_CONTROL, +- DC_I2C_SW_STATUS_RESET, 1, +- DC_I2C_SW_STATUS_RESET, 1); +-} +- +-static bool is_hw_busy(struct engine *engine) +-{ +- struct i2c_hw_engine_dce110 *hw_engine = FROM_ENGINE(engine); +- uint32_t i2c_sw_status = 0; +- +- REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status); +- if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_IDLE) +- return false; +- +- reset_hw_engine(engine); +- +- REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status); +- return i2c_sw_status != DC_I2C_STATUS__DC_I2C_STATUS_IDLE; +-} +- +- +-#define STOP_TRANS_PREDICAT \ +- ((hw_engine->transaction_count == 3) || \ +- (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) || \ +- (request->action & I2CAUX_TRANSACTION_ACTION_I2C_READ)) +- +-#define SET_I2C_TRANSACTION(id) \ +- do { \ +- REG_UPDATE_N(DC_I2C_TRANSACTION##id, 5, \ +- FN(DC_I2C_TRANSACTION0, DC_I2C_STOP_ON_NACK0), 1, \ +- FN(DC_I2C_TRANSACTION0, DC_I2C_START0), 1, \ +- FN(DC_I2C_TRANSACTION0, DC_I2C_STOP0), STOP_TRANS_PREDICAT ? 1:0, \ +- FN(DC_I2C_TRANSACTION0, DC_I2C_RW0), (0 != (request->action & I2CAUX_TRANSACTION_ACTION_I2C_READ)), \ +- FN(DC_I2C_TRANSACTION0, DC_I2C_COUNT0), length); \ +- if (STOP_TRANS_PREDICAT) \ +- last_transaction = true; \ +- } while (false) +- +- +-static bool process_transaction( +- struct i2c_hw_engine_dce110 *hw_engine, +- struct i2c_request_transaction_data *request) +-{ +- uint32_t length = request->length; +- uint8_t *buffer = request->data; +- uint32_t value = 0; +- +- bool last_transaction = false; +- +- struct dc_context *ctx = NULL; +- +- ctx = hw_engine->base.base.base.ctx; +- +- +- +- switch (hw_engine->transaction_count) { +- case 0: +- SET_I2C_TRANSACTION(0); +- break; +- case 1: +- SET_I2C_TRANSACTION(1); +- break; +- case 2: +- SET_I2C_TRANSACTION(2); +- break; +- case 3: +- SET_I2C_TRANSACTION(3); +- break; +- default: +- /* TODO Warning ? */ +- break; +- } +- +- +- /* Write the I2C address and I2C data +- * into the hardware circular buffer, one byte per entry. +- * As an example, the 7-bit I2C slave address for CRT monitor +- * for reading DDC/EDID information is 0b1010001. +- * For an I2C send operation, the LSB must be programmed to 0; +- * for I2C receive operation, the LSB must be programmed to 1. */ +- if (hw_engine->transaction_count == 0) { +- value = REG_SET_4(DC_I2C_DATA, 0, +- DC_I2C_DATA_RW, false, +- DC_I2C_DATA, request->address, +- DC_I2C_INDEX, 0, +- DC_I2C_INDEX_WRITE, 1); +- hw_engine->buffer_used_write = 0; +- } else +- value = REG_SET_2(DC_I2C_DATA, 0, +- DC_I2C_DATA_RW, false, +- DC_I2C_DATA, request->address); +- +- hw_engine->buffer_used_write++; +- +- if (!(request->action & I2CAUX_TRANSACTION_ACTION_I2C_READ)) { +- while (length) { +- REG_SET_2(DC_I2C_DATA, value, +- DC_I2C_INDEX_WRITE, 0, +- DC_I2C_DATA, *buffer++); +- hw_engine->buffer_used_write++; +- --length; +- } +- } +- +- ++hw_engine->transaction_count; +- hw_engine->buffer_used_bytes += length + 1; +- +- return last_transaction; +-} +- +-static void execute_transaction( +- struct i2c_hw_engine_dce110 *hw_engine) +-{ +- REG_UPDATE_N(SETUP, 5, +- FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_EN), 0, +- FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_CLK_DRIVE_EN), 0, +- FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_SEL), 0, +- FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_TRANSACTION_DELAY), 0, +- FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_BYTE_DELAY), 0); +- +- +- REG_UPDATE_5(DC_I2C_CONTROL, +- DC_I2C_SOFT_RESET, 0, +- DC_I2C_SW_STATUS_RESET, 0, +- DC_I2C_SEND_RESET, 0, +- DC_I2C_GO, 0, +- DC_I2C_TRANSACTION_COUNT, hw_engine->transaction_count - 1); +- +- /* start I2C transfer */ +- REG_UPDATE(DC_I2C_CONTROL, DC_I2C_GO, 1); +- +- /* all transactions were executed and HW buffer became empty +- * (even though it actually happens when status becomes DONE) */ +- hw_engine->transaction_count = 0; +- hw_engine->buffer_used_bytes = 0; +-} +- +-static void submit_channel_request( +- struct i2c_engine *engine, +- struct i2c_request_transaction_data *request) +-{ +- request->status = I2C_CHANNEL_OPERATION_SUCCEEDED; +- +- if (!process_transaction(FROM_I2C_ENGINE(engine), request)) +- return; +- +- if (is_hw_busy(&engine->base)) { +- request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY; +- return; +- } +- +- execute_transaction(FROM_I2C_ENGINE(engine)); +-} +- +-static void process_channel_reply( +- struct i2c_engine *engine, +- struct i2c_reply_transaction_data *reply) +-{ +- uint32_t length = reply->length; +- uint8_t *buffer = reply->data; +- +- struct i2c_hw_engine_dce110 *hw_engine = +- FROM_I2C_ENGINE(engine); +- +- +- REG_SET_3(DC_I2C_DATA, 0, +- DC_I2C_INDEX, hw_engine->buffer_used_write, +- DC_I2C_DATA_RW, 1, +- DC_I2C_INDEX_WRITE, 1); +- +- while (length) { +- /* after reading the status, +- * if the I2C operation executed successfully +- * (i.e. DC_I2C_STATUS_DONE = 1) then the I2C controller +- * should read data bytes from I2C circular data buffer */ +- +- uint32_t i2c_data; +- +- REG_GET(DC_I2C_DATA, DC_I2C_DATA, &i2c_data); +- *buffer++ = i2c_data; +- +- --length; +- } +-} +- +-static enum i2c_channel_operation_result get_channel_status( +- struct i2c_engine *i2c_engine, +- uint8_t *returned_bytes) +-{ +- uint32_t i2c_sw_status = 0; +- struct i2c_hw_engine_dce110 *hw_engine = FROM_I2C_ENGINE(i2c_engine); +- uint32_t value = +- REG_GET(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, &i2c_sw_status); +- +- if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_SW) +- return I2C_CHANNEL_OPERATION_ENGINE_BUSY; +- else if (value & hw_engine->i2c_mask->DC_I2C_SW_STOPPED_ON_NACK) +- return I2C_CHANNEL_OPERATION_NO_RESPONSE; +- else if (value & hw_engine->i2c_mask->DC_I2C_SW_TIMEOUT) +- return I2C_CHANNEL_OPERATION_TIMEOUT; +- else if (value & hw_engine->i2c_mask->DC_I2C_SW_ABORTED) +- return I2C_CHANNEL_OPERATION_FAILED; +- else if (value & hw_engine->i2c_mask->DC_I2C_SW_DONE) +- return I2C_CHANNEL_OPERATION_SUCCEEDED; +- +- /* +- * this is the case when HW used for communication, I2C_SW_STATUS +- * could be zero +- */ +- return I2C_CHANNEL_OPERATION_SUCCEEDED; +-} +- +-static uint32_t get_hw_buffer_available_size( +- const struct i2c_hw_engine *engine) +-{ +- return I2C_HW_BUFFER_SIZE - +- FROM_I2C_HW_ENGINE(engine)->buffer_used_bytes; +-} +- +-static uint32_t get_transaction_timeout( +- const struct i2c_hw_engine *engine, +- uint32_t length) +-{ +- uint32_t speed = engine->base.funcs->get_speed(&engine->base); +- +- uint32_t period_timeout; +- uint32_t num_of_clock_stretches; +- +- if (!speed) +- return 0; +- +- period_timeout = (1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS) / speed; +- +- num_of_clock_stretches = 1 + (length << 3) + 1; +- num_of_clock_stretches += +- (FROM_I2C_HW_ENGINE(engine)->buffer_used_bytes << 3) + +- (FROM_I2C_HW_ENGINE(engine)->transaction_count << 1); +- +- return period_timeout * num_of_clock_stretches; +-} +- +-static void destroy( +- struct i2c_engine **i2c_engine) +-{ +- struct i2c_hw_engine_dce110 *engine_dce110 = +- FROM_I2C_ENGINE(*i2c_engine); +- +- dal_i2c_hw_engine_destruct(&engine_dce110->base); +- +- kfree(engine_dce110); +- +- *i2c_engine = NULL; +-} +- +-static const struct i2c_engine_funcs i2c_engine_funcs = { +- .destroy = destroy, +- .get_speed = get_speed, +- .set_speed = set_speed, +- .setup_engine = setup_engine, +- .submit_channel_request = submit_channel_request, +- .process_channel_reply = process_channel_reply, +- .get_channel_status = get_channel_status, +- .acquire_engine = dal_i2c_hw_engine_acquire_engine, +-}; +- +-static const struct engine_funcs engine_funcs = { +- .release_engine = release_engine, +- .get_engine_type = dal_i2c_hw_engine_get_engine_type, +- .acquire = dal_i2c_engine_acquire, +- .submit_request = dal_i2c_hw_engine_submit_request, +-}; +- +-static const struct i2c_hw_engine_funcs i2c_hw_engine_funcs = { +- .get_hw_buffer_available_size = get_hw_buffer_available_size, +- .get_transaction_timeout = get_transaction_timeout, +- .wait_on_operation_result = dal_i2c_hw_engine_wait_on_operation_result, +-}; +- +-static void construct( +- struct i2c_hw_engine_dce110 *hw_engine, +- const struct i2c_hw_engine_dce110_create_arg *arg) +-{ +- uint32_t xtal_ref_div = 0; +- +- dal_i2c_hw_engine_construct(&hw_engine->base, arg->ctx); +- +- hw_engine->base.base.base.funcs = &engine_funcs; +- hw_engine->base.base.funcs = &i2c_engine_funcs; +- hw_engine->base.funcs = &i2c_hw_engine_funcs; +- hw_engine->base.default_speed = arg->default_speed; +- +- hw_engine->regs = arg->regs; +- hw_engine->i2c_shift = arg->i2c_shift; +- hw_engine->i2c_mask = arg->i2c_mask; +- +- hw_engine->engine_id = arg->engine_id; +- +- hw_engine->buffer_used_bytes = 0; +- hw_engine->transaction_count = 0; +- hw_engine->engine_keep_power_up_count = 1; +- +- +- REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div); +- +- if (xtal_ref_div == 0) { +- DC_LOG_WARNING("Invalid base timer divider [%s]\n", +- __func__); +- xtal_ref_div = 2; +- } +- +- /*Calculating Reference Clock by divding original frequency by +- * XTAL_REF_DIV. +- * At upper level, uint32_t reference_frequency = +- * dal_i2caux_get_reference_clock(as) >> 1 +- * which already divided by 2. So we need x2 to get original +- * reference clock from ppll_info +- */ +- hw_engine->reference_frequency = +- (arg->reference_frequency * 2) / xtal_ref_div; +-} +- +-struct i2c_engine *dal_i2c_hw_engine_dce110_create( +- const struct i2c_hw_engine_dce110_create_arg *arg) +-{ +- struct i2c_hw_engine_dce110 *engine_dce10; +- +- if (!arg) { +- ASSERT_CRITICAL(false); +- return NULL; +- } +- if (!arg->reference_frequency) { +- ASSERT_CRITICAL(false); +- return NULL; +- } +- +- engine_dce10 = kzalloc(sizeof(struct i2c_hw_engine_dce110), +- GFP_KERNEL); +- +- if (!engine_dce10) { +- ASSERT_CRITICAL(false); +- return NULL; +- } +- +- construct(engine_dce10, arg); +- return &engine_dce10->base.base; +-} +diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.c +deleted file mode 100644 +index a9db04738724..000000000000 +--- a/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.c ++++ /dev/null +@@ -1,129 +0,0 @@ +-/* +- * Copyright 2012-15 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 "dm_services.h" +- +-#include "include/i2caux_interface.h" +-#include "../i2caux.h" +-#include "../engine.h" +-#include "../i2c_engine.h" +-#include "../i2c_sw_engine.h" +-#include "../i2c_hw_engine.h" +- +-#include "../dce110/i2caux_dce110.h" +-#include "i2caux_dce112.h" +- +-#include "../dce110/aux_engine_dce110.h" +- +-#include "../dce110/i2c_hw_engine_dce110.h" +- +-#include "dce/dce_11_2_d.h" +-#include "dce/dce_11_2_sh_mask.h" +- +-/* set register offset */ +-#define SR(reg_name)\ +- .reg_name = mm ## reg_name +- +-/* set register offset with instance */ +-#define SRI(reg_name, block, id)\ +- .reg_name = mm ## block ## id ## _ ## reg_name +- +-#define aux_regs(id)\ +-[id] = {\ +- AUX_COMMON_REG_LIST(id), \ +- .AUX_RESET_MASK = AUX_CONTROL__AUX_RESET_MASK \ +-} +- +-#define hw_engine_regs(id)\ +-{\ +- I2C_HW_ENGINE_COMMON_REG_LIST(id) \ +-} +- +-static const struct dce110_aux_registers dce112_aux_regs[] = { +- aux_regs(0), +- aux_regs(1), +- aux_regs(2), +- aux_regs(3), +- aux_regs(4), +- aux_regs(5), +-}; +- +-static const struct dce110_i2c_hw_engine_registers dce112_hw_engine_regs[] = { +- hw_engine_regs(1), +- hw_engine_regs(2), +- hw_engine_regs(3), +- hw_engine_regs(4), +- hw_engine_regs(5), +- hw_engine_regs(6) +-}; +- +-static const struct dce110_i2c_hw_engine_shift i2c_shift = { +- I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT) +-}; +- +-static const struct dce110_i2c_hw_engine_mask i2c_mask = { +- I2C_COMMON_MASK_SH_LIST_DCE110(_MASK) +-}; +- +-static void construct( +- struct i2caux_dce110 *i2caux_dce110, +- struct dc_context *ctx) +-{ +- dal_i2caux_dce110_construct(i2caux_dce110, +- ctx, +- ARRAY_SIZE(dce112_aux_regs), +- dce112_aux_regs, +- dce112_hw_engine_regs, +- &i2c_shift, +- &i2c_mask); +-} +- +-/* +- * dal_i2caux_dce110_create +- * +- * @brief +- * public interface to allocate memory for DCE11 I2CAUX +- * +- * @param +- * struct adapter_service *as - [in] +- * struct dc_context *ctx - [in] +- * +- * @return +- * pointer to the base struct of DCE11 I2CAUX +- */ +-struct i2caux *dal_i2caux_dce112_create( +- struct dc_context *ctx) +-{ +- struct i2caux_dce110 *i2caux_dce110 = +- kzalloc(sizeof(struct i2caux_dce110), GFP_KERNEL); +- +- if (!i2caux_dce110) { +- ASSERT_CRITICAL(false); +- return NULL; +- } +- +- construct(i2caux_dce110, ctx); +- return &i2caux_dce110->base; +-} +diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.h b/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.h +deleted file mode 100644 +index 8d35453c25b6..000000000000 +--- a/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.h ++++ /dev/null +@@ -1,32 +0,0 @@ +-/* +- * Copyright 2012-15 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 __DAL_I2C_AUX_DCE112_H__ +-#define __DAL_I2C_AUX_DCE112_H__ +- +-struct i2caux *dal_i2caux_dce112_create( +- struct dc_context *ctx); +- +-#endif /* __DAL_I2C_AUX_DCE112_H__ */ +diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce80/i2c_sw_engine_dce80.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce80/i2c_sw_engine_dce80.c +deleted file mode 100644 +index c9d6cf08e8ab..000000000000 +--- a/drivers/gpu/drm/amd/display/dc/i2caux/dce80/i2c_sw_engine_dce80.c ++++ /dev/null +@@ -1,163 +0,0 @@ +-/* +- * Copyright 2012-15 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 "dm_services.h" +- +-/* +- * Pre-requisites: headers required by header of this unit +- */ +-#include "include/i2caux_interface.h" +-#include "../engine.h" +-#include "../i2c_engine.h" +-#include "../i2c_sw_engine.h" +- +-/* +- * Header of this unit +- */ +- +-#include "i2c_sw_engine_dce80.h" +- +-/* +- * Post-requisites: headers required by this unit +- */ +- +-#include "dce/dce_8_0_d.h" +-#include "dce/dce_8_0_sh_mask.h" +- +-/* +- * This unit +- */ +- +-/* +- * @brief +- * Cast 'struct i2c_sw_engine *' +- * to 'struct i2c_sw_engine_dce80 *' +- */ +-#define FROM_I2C_SW_ENGINE(ptr) \ +- container_of((ptr), struct i2c_sw_engine_dce80, base) +- +-/* +- * @brief +- * Cast 'struct i2c_engine *' +- * to 'struct i2c_sw_engine_dce80 *' +- */ +-#define FROM_I2C_ENGINE(ptr) \ +- FROM_I2C_SW_ENGINE(container_of((ptr), struct i2c_sw_engine, base)) +- +-/* +- * @brief +- * Cast 'struct engine *' +- * to 'struct i2c_sw_engine_dce80 *' +- */ +-#define FROM_ENGINE(ptr) \ +- FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base)) +- +-static void release_engine( +- struct engine *engine) +-{ +- +-} +- +-static void destruct( +- struct i2c_sw_engine_dce80 *engine) +-{ +- dal_i2c_sw_engine_destruct(&engine->base); +-} +- +-static void destroy( +- struct i2c_engine **engine) +-{ +- struct i2c_sw_engine_dce80 *sw_engine = FROM_I2C_ENGINE(*engine); +- +- destruct(sw_engine); +- +- kfree(sw_engine); +- +- *engine = NULL; +-} +- +-static bool acquire_engine( +- struct i2c_engine *engine, +- struct ddc *ddc_handle) +-{ +- return dal_i2caux_i2c_sw_engine_acquire_engine(engine, ddc_handle); +-} +- +-static const struct i2c_engine_funcs i2c_engine_funcs = { +- .acquire_engine = acquire_engine, +- .destroy = destroy, +- .get_speed = dal_i2c_sw_engine_get_speed, +- .set_speed = dal_i2c_sw_engine_set_speed, +- .setup_engine = dal_i2c_engine_setup_i2c_engine, +- .submit_channel_request = dal_i2c_sw_engine_submit_channel_request, +- .process_channel_reply = dal_i2c_engine_process_channel_reply, +- .get_channel_status = dal_i2c_sw_engine_get_channel_status, +-}; +- +-static const struct engine_funcs engine_funcs = { +- .release_engine = release_engine, +- .get_engine_type = dal_i2c_sw_engine_get_engine_type, +- .acquire = dal_i2c_engine_acquire, +- .submit_request = dal_i2c_sw_engine_submit_request, +-}; +- +-static void construct( +- struct i2c_sw_engine_dce80 *engine, +- const struct i2c_sw_engine_dce80_create_arg *arg) +-{ +- struct i2c_sw_engine_create_arg arg_base; +- +- arg_base.ctx = arg->ctx; +- arg_base.default_speed = arg->default_speed; +- +- dal_i2c_sw_engine_construct(&engine->base, &arg_base); +- +- engine->base.base.base.funcs = &engine_funcs; +- engine->base.base.funcs = &i2c_engine_funcs; +- engine->base.default_speed = arg->default_speed; +- engine->engine_id = arg->engine_id; +-} +- +-struct i2c_engine *dal_i2c_sw_engine_dce80_create( +- const struct i2c_sw_engine_dce80_create_arg *arg) +-{ +- struct i2c_sw_engine_dce80 *engine; +- +- if (!arg) { +- BREAK_TO_DEBUGGER(); +- return NULL; +- } +- +- engine = kzalloc(sizeof(struct i2c_sw_engine_dce80), GFP_KERNEL); +- +- if (!engine) { +- BREAK_TO_DEBUGGER(); +- return NULL; +- } +- +- construct(engine, arg); +- return &engine->base.base; +-} +- +diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c +deleted file mode 100644 +index a18fc4fca864..000000000000 +--- a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c ++++ /dev/null +@@ -1,491 +0,0 @@ +-/* +- * Copyright 2012-15 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 "dm_services.h" +- +-/* +- * Pre-requisites: headers required by header of this unit +- */ +-#include "include/i2caux_interface.h" +-#include "dc_bios_types.h" +- +-/* +- * Header of this unit +- */ +- +-#include "i2caux.h" +- +-/* +- * Post-requisites: headers required by this unit +- */ +- +-#include "engine.h" +-#include "i2c_engine.h" +-#include "aux_engine.h" +- +-/* +- * This unit +- */ +- +-#include "dce80/i2caux_dce80.h" +- +-#include "dce100/i2caux_dce100.h" +- +-#include "dce110/i2caux_dce110.h" +- +-#include "dce112/i2caux_dce112.h" +- +-#include "dce120/i2caux_dce120.h" +- +-#ifdef CONFIG_X86 +-#include "dcn10/i2caux_dcn10.h" +-#endif +- +-#include "diagnostics/i2caux_diag.h" +- +-/* +- * @brief +- * Plain API, available publicly +- */ +- +-struct i2caux *dal_i2caux_create( +- struct dc_context *ctx) +-{ +- if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { +- return dal_i2caux_diag_fpga_create(ctx); +- } +- +- switch (ctx->dce_version) { +- case DCE_VERSION_8_0: +- case DCE_VERSION_8_1: +- case DCE_VERSION_8_3: +- return dal_i2caux_dce80_create(ctx); +- case DCE_VERSION_11_2: +- case DCE_VERSION_11_22: +- return dal_i2caux_dce112_create(ctx); +- case DCE_VERSION_11_0: +- return dal_i2caux_dce110_create(ctx); +- case DCE_VERSION_10_0: +- return dal_i2caux_dce100_create(ctx); +- case DCE_VERSION_12_0: +- case DCE_VERSION_12_1: +- return dal_i2caux_dce120_create(ctx); +-#ifdef CONFIG_X86 +- case DCN_VERSION_1_0: +- return dal_i2caux_dcn10_create(ctx); +-#endif +- +-#if defined(CONFIG_DRM_AMD_DC_DCN1_01) +- case DCN_VERSION_1_01: +- return dal_i2caux_dcn10_create(ctx); +-#endif +- default: +- BREAK_TO_DEBUGGER(); +- return NULL; +- } +-} +- +-bool dal_i2caux_submit_i2c_command( +- struct i2caux *i2caux, +- struct ddc *ddc, +- struct i2c_command *cmd) +-{ +- struct i2c_engine *engine; +- uint8_t index_of_payload = 0; +- bool result; +- +- if (!ddc) { +- BREAK_TO_DEBUGGER(); +- return false; +- } +- +- if (!cmd) { +- BREAK_TO_DEBUGGER(); +- return false; +- } +- +- /* +- * default will be SW, however there is a feature flag in adapter +- * service that determines whether SW i2c_engine will be available or +- * not, if sw i2c is not available we will fallback to hw. This feature +- * flag is set to not creating sw i2c engine for every dce except dce80 +- * currently +- */ +- switch (cmd->engine) { +- case I2C_COMMAND_ENGINE_DEFAULT: +- case I2C_COMMAND_ENGINE_SW: +- /* try to acquire SW engine first, +- * acquire HW engine if SW engine not available */ +- engine = i2caux->funcs->acquire_i2c_sw_engine(i2caux, ddc); +- +- if (!engine) +- engine = i2caux->funcs->acquire_i2c_hw_engine( +- i2caux, ddc); +- break; +- case I2C_COMMAND_ENGINE_HW: +- default: +- /* try to acquire HW engine first, +- * acquire SW engine if HW engine not available */ +- engine = i2caux->funcs->acquire_i2c_hw_engine(i2caux, ddc); +- +- if (!engine) +- engine = i2caux->funcs->acquire_i2c_sw_engine( +- i2caux, ddc); +- } +- +- if (!engine) +- return false; +- +- engine->funcs->set_speed(engine, cmd->speed); +- +- result = true; +- +- while (index_of_payload < cmd->number_of_payloads) { +- bool mot = (index_of_payload != cmd->number_of_payloads - 1); +- +- struct i2c_payload *payload = cmd->payloads + index_of_payload; +- +- struct i2caux_transaction_request request = { 0 }; +- +- request.operation = payload->write ? +- I2CAUX_TRANSACTION_WRITE : +- I2CAUX_TRANSACTION_READ; +- +- request.payload.address_space = +- I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C; +- request.payload.address = (payload->address << 1) | +- !payload->write; +- request.payload.length = payload->length; +- request.payload.data = payload->data; +- +- if (!engine->base.funcs->submit_request( +- &engine->base, &request, mot)) { +- result = false; +- break; +- } +- +- ++index_of_payload; +- } +- +- i2caux->funcs->release_engine(i2caux, &engine->base); +- +- return result; +-} +- +-bool dal_i2caux_submit_aux_command( +- struct i2caux *i2caux, +- struct ddc *ddc, +- struct aux_command *cmd) +-{ +- struct aux_engine *engine; +- uint8_t index_of_payload = 0; +- bool result; +- bool mot; +- +- if (!ddc) { +- BREAK_TO_DEBUGGER(); +- return false; +- } +- +- if (!cmd) { +- BREAK_TO_DEBUGGER(); +- return false; +- } +- +- engine = i2caux->funcs->acquire_aux_engine(i2caux, ddc); +- +- if (!engine) +- return false; +- +- engine->delay = cmd->defer_delay; +- engine->max_defer_write_retry = cmd->max_defer_write_retry; +- +- result = true; +- +- while (index_of_payload < cmd->number_of_payloads) { +- struct aux_payload *payload = cmd->payloads + index_of_payload; +- struct i2caux_transaction_request request = { 0 }; +- +- if (cmd->mot == I2C_MOT_UNDEF) +- mot = (index_of_payload != cmd->number_of_payloads - 1); +- else +- mot = (cmd->mot == I2C_MOT_TRUE); +- +- request.operation = payload->write ? +- I2CAUX_TRANSACTION_WRITE : +- I2CAUX_TRANSACTION_READ; +- +- if (payload->i2c_over_aux) { +- request.payload.address_space = +- I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C; +- +- request.payload.address = (payload->address << 1) | +- !payload->write; +- } else { +- request.payload.address_space = +- I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD; +- +- request.payload.address = payload->address; +- } +- +- request.payload.length = payload->length; +- request.payload.data = payload->data; +- +- if (!engine->base.funcs->submit_request( +- &engine->base, &request, mot)) { +- result = false; +- break; +- } +- +- ++index_of_payload; +- } +- +- i2caux->funcs->release_engine(i2caux, &engine->base); +- +- return result; +-} +- +-static bool get_hw_supported_ddc_line( +- struct ddc *ddc, +- enum gpio_ddc_line *line) +-{ +- enum gpio_ddc_line line_found; +- +- *line = GPIO_DDC_LINE_UNKNOWN; +- +- if (!ddc) { +- BREAK_TO_DEBUGGER(); +- return false; +- } +- +- if (!ddc->hw_info.hw_supported) +- return false; +- +- line_found = dal_ddc_get_line(ddc); +- +- if (line_found >= GPIO_DDC_LINE_COUNT) +- return false; +- +- *line = line_found; +- +- return true; +-} +- +-void dal_i2caux_configure_aux( +- struct i2caux *i2caux, +- struct ddc *ddc, +- union aux_config cfg) +-{ +- struct aux_engine *engine = +- i2caux->funcs->acquire_aux_engine(i2caux, ddc); +- +- if (!engine) +- return; +- +- engine->funcs->configure(engine, cfg); +- +- i2caux->funcs->release_engine(i2caux, &engine->base); +-} +- +-void dal_i2caux_destroy( +- struct i2caux **i2caux) +-{ +- if (!i2caux || !*i2caux) { +- BREAK_TO_DEBUGGER(); +- return; +- } +- +- (*i2caux)->funcs->destroy(i2caux); +- +- *i2caux = NULL; +-} +- +-/* +- * @brief +- * An utility function used by 'struct i2caux' and its descendants +- */ +- +-uint32_t dal_i2caux_get_reference_clock( +- struct dc_bios *bios) +-{ +- struct dc_firmware_info info = { { 0 } }; +- +- if (bios->funcs->get_firmware_info(bios, &info) != BP_RESULT_OK) +- return 0; +- +- return info.pll_info.crystal_frequency; +-} +- +-/* +- * @brief +- * i2caux +- */ +- +-enum { +- /* following are expressed in KHz */ +- DEFAULT_I2C_SW_SPEED = 50, +- DEFAULT_I2C_HW_SPEED = 50, +- +- DEFAULT_I2C_SW_SPEED_100KHZ = 100, +- DEFAULT_I2C_HW_SPEED_100KHZ = 100, +- +- /* This is the timeout as defined in DP 1.2a, +- * 2.3.4 "Detailed uPacket TX AUX CH State Description". */ +- AUX_TIMEOUT_PERIOD = 400, +- +- /* Ideally, the SW timeout should be just above 550usec +- * which is programmed in HW. +- * But the SW timeout of 600usec is not reliable, +- * because on some systems, delay_in_microseconds() +- * returns faster than it should. +- * EPR #379763: by trial-and-error on different systems, +- * 700usec is the minimum reliable SW timeout for polling +- * the AUX_SW_STATUS.AUX_SW_DONE bit. +- * This timeout expires *only* when there is +- * AUX Error or AUX Timeout conditions - not during normal operation. +- * During normal operation, AUX_SW_STATUS.AUX_SW_DONE bit is set +- * at most within ~240usec. That means, +- * increasing this timeout will not affect normal operation, +- * and we'll timeout after +- * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD = 1600usec. +- * This timeout is especially important for +- * resume from S3 and CTS. */ +- SW_AUX_TIMEOUT_PERIOD_MULTIPLIER = 4 +-}; +- +-struct i2c_engine *dal_i2caux_acquire_i2c_sw_engine( +- struct i2caux *i2caux, +- struct ddc *ddc) +-{ +- enum gpio_ddc_line line; +- struct i2c_engine *engine = NULL; +- +- if (get_hw_supported_ddc_line(ddc, &line)) +- engine = i2caux->i2c_sw_engines[line]; +- +- if (!engine) +- engine = i2caux->i2c_generic_sw_engine; +- +- if (!engine) +- return NULL; +- +- if (!engine->base.funcs->acquire(&engine->base, ddc)) +- return NULL; +- +- return engine; +-} +- +-struct aux_engine *dal_i2caux_acquire_aux_engine( +- struct i2caux *i2caux, +- struct ddc *ddc) +-{ +- enum gpio_ddc_line line; +- struct aux_engine *engine; +- +- if (!get_hw_supported_ddc_line(ddc, &line)) +- return NULL; +- +- engine = i2caux->aux_engines[line]; +- +- if (!engine) +- return NULL; +- +- if (!engine->base.funcs->acquire(&engine->base, ddc)) +- return NULL; +- +- return engine; +-} +- +-void dal_i2caux_release_engine( +- struct i2caux *i2caux, +- struct engine *engine) +-{ +- engine->funcs->release_engine(engine); +- +- dal_ddc_close(engine->ddc); +- +- engine->ddc = NULL; +-} +- +-void dal_i2caux_construct( +- struct i2caux *i2caux, +- struct dc_context *ctx) +-{ +- uint32_t i = 0; +- +- i2caux->ctx = ctx; +- do { +- i2caux->i2c_sw_engines[i] = NULL; +- i2caux->i2c_hw_engines[i] = NULL; +- i2caux->aux_engines[i] = NULL; +- +- ++i; +- } while (i < GPIO_DDC_LINE_COUNT); +- +- i2caux->i2c_generic_sw_engine = NULL; +- i2caux->i2c_generic_hw_engine = NULL; +- +- i2caux->aux_timeout_period = +- SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD; +- +- if (ctx->dce_version >= DCE_VERSION_11_2) { +- i2caux->default_i2c_hw_speed = DEFAULT_I2C_HW_SPEED_100KHZ; +- i2caux->default_i2c_sw_speed = DEFAULT_I2C_SW_SPEED_100KHZ; +- } else { +- i2caux->default_i2c_hw_speed = DEFAULT_I2C_HW_SPEED; +- i2caux->default_i2c_sw_speed = DEFAULT_I2C_SW_SPEED; +- } +-} +- +-void dal_i2caux_destruct( +- struct i2caux *i2caux) +-{ +- uint32_t i = 0; +- +- if (i2caux->i2c_generic_hw_engine) +- i2caux->i2c_generic_hw_engine->funcs->destroy( +- &i2caux->i2c_generic_hw_engine); +- +- if (i2caux->i2c_generic_sw_engine) +- i2caux->i2c_generic_sw_engine->funcs->destroy( +- &i2caux->i2c_generic_sw_engine); +- +- do { +- if (i2caux->aux_engines[i]) +- i2caux->aux_engines[i]->funcs->destroy( +- &i2caux->aux_engines[i]); +- +- if (i2caux->i2c_hw_engines[i]) +- i2caux->i2c_hw_engines[i]->funcs->destroy( +- &i2caux->i2c_hw_engines[i]); +- +- if (i2caux->i2c_sw_engines[i]) +- i2caux->i2c_sw_engines[i]->funcs->destroy( +- &i2caux->i2c_sw_engines[i]); +- +- ++i; +- } while (i < GPIO_DDC_LINE_COUNT); +-} +- +-- +2.17.1 + |