cregit-Linux how code gets into the kernel

Release 4.17 drivers/gpu/drm/amd/display/dc/i2caux/i2c_hw_engine.c

/*
 * 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"

/*
 * Header of this unit
 */

#include "i2c_hw_engine.h"

/*
 * Post-requisites: headers required by this unit
 */

/*
 * This unit
 */

/*
 * @brief
 * Cast 'struct i2c_engine *'
 * to 'struct i2c_hw_engine *'
 */

#define FROM_I2C_ENGINE(ptr) \
	container_of((ptr), struct i2c_hw_engine, base)

/*
 * @brief
 * Cast 'struct engine *'
 * to 'struct i2c_hw_engine *'
 */

#define FROM_ENGINE(ptr) \
	FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base))


enum i2caux_engine_type dal_i2c_hw_engine_get_engine_type( const struct engine *engine) { return I2CAUX_ENGINE_TYPE_I2C_DDC_HW; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland15100.00%1100.00%
Total15100.00%1100.00%


bool dal_i2c_hw_engine_submit_request( struct engine *engine, struct i2caux_transaction_request *i2caux_request, bool middle_of_transaction) { struct i2c_hw_engine *hw_engine = FROM_ENGINE(engine); struct i2c_request_transaction_data request; uint32_t transaction_timeout; enum i2c_channel_operation_result operation_result; bool result = false; /* We need following: * transaction length will not exceed * the number of free bytes in HW buffer (minus one for address)*/ if (i2caux_request->payload.length >= hw_engine->funcs->get_hw_buffer_available_size(hw_engine)) { i2caux_request->status = I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW; return false; } if (i2caux_request->operation == I2CAUX_TRANSACTION_READ) request.action = middle_of_transaction ? I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT : I2CAUX_TRANSACTION_ACTION_I2C_READ; else if (i2caux_request->operation == I2CAUX_TRANSACTION_WRITE) request.action = middle_of_transaction ? I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT : I2CAUX_TRANSACTION_ACTION_I2C_WRITE; else { i2caux_request->status = I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION; /* [anaumov] in DAL2, there was no "return false" */ return false; } request.address = (uint8_t)i2caux_request->payload.address; request.length = i2caux_request->payload.length; request.data = i2caux_request->payload.data; /* obtain timeout value before submitting request */ transaction_timeout = hw_engine->funcs->get_transaction_timeout( hw_engine, i2caux_request->payload.length + 1); hw_engine->base.funcs->submit_channel_request( &hw_engine->base, &request); if ((request.status == I2C_CHANNEL_OPERATION_FAILED) || (request.status == I2C_CHANNEL_OPERATION_ENGINE_BUSY)) { i2caux_request->status = I2CAUX_TRANSACTION_STATUS_FAILED_CHANNEL_BUSY; return false; } /* wait until transaction proceed */ operation_result = hw_engine->funcs->wait_on_operation_result( hw_engine, transaction_timeout, I2C_CHANNEL_OPERATION_ENGINE_BUSY); /* update transaction status */ switch (operation_result) { case I2C_CHANNEL_OPERATION_SUCCEEDED: i2caux_request->status = I2CAUX_TRANSACTION_STATUS_SUCCEEDED; result = true; break; case I2C_CHANNEL_OPERATION_NO_RESPONSE: i2caux_request->status = I2CAUX_TRANSACTION_STATUS_FAILED_NACK; break; case I2C_CHANNEL_OPERATION_TIMEOUT: i2caux_request->status = I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT; break; case I2C_CHANNEL_OPERATION_FAILED: i2caux_request->status = I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE; break; default: i2caux_request->status = I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION; } if (result && (i2caux_request->operation == I2CAUX_TRANSACTION_READ)) { struct i2c_reply_transaction_data reply; reply.data = i2caux_request->payload.data; reply.length = i2caux_request->payload.length; hw_engine->base.funcs-> process_channel_reply(&hw_engine->base, &reply); } return result; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland354100.00%1100.00%
Total354100.00%1100.00%


bool dal_i2c_hw_engine_acquire_engine( struct i2c_engine *engine, struct ddc *ddc) { enum gpio_result result; uint32_t current_speed; result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE, GPIO_DDC_CONFIG_TYPE_MODE_I2C); if (result != GPIO_RESULT_OK) return false; engine->base.ddc = ddc; current_speed = engine->funcs->get_speed(engine); if (current_speed) FROM_I2C_ENGINE(engine)->original_speed = current_speed; return true; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland77100.00%1100.00%
Total77100.00%1100.00%

/* * @brief * Queries in a loop for current engine status * until retrieved status matches 'expected_result', or timeout occurs. * Timeout given in microseconds * and the status query frequency is also one per microsecond. */
enum i2c_channel_operation_result dal_i2c_hw_engine_wait_on_operation_result( struct i2c_hw_engine *engine, uint32_t timeout, enum i2c_channel_operation_result expected_result) { enum i2c_channel_operation_result result; uint32_t i = 0; if (!timeout) return I2C_CHANNEL_OPERATION_SUCCEEDED; do { result = engine->base.funcs->get_channel_status( &engine->base, NULL); if (result != expected_result) break; udelay(1); ++i; } while (i < timeout); return result; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland81100.00%1100.00%
Total81100.00%1100.00%


void dal_i2c_hw_engine_construct( struct i2c_hw_engine *engine, struct dc_context *ctx) { dal_i2c_engine_construct(&engine->base, ctx); engine->original_speed = I2CAUX_DEFAULT_I2C_HW_SPEED; engine->default_speed = I2CAUX_DEFAULT_I2C_HW_SPEED; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland3594.59%150.00%
Dave Airlie25.41%150.00%
Total37100.00%2100.00%


void dal_i2c_hw_engine_destruct( struct i2c_hw_engine *engine) { dal_i2c_engine_destruct(&engine->base); }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland18100.00%1100.00%
Total18100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland61999.68%150.00%
Dave Airlie20.32%150.00%
Total621100.00%2100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.