summaryrefslogtreecommitdiff
path: root/drivers/mxc/hdp/API_DPTX.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/hdp/API_DPTX.c')
-rw-r--r--drivers/mxc/hdp/API_DPTX.c936
1 files changed, 936 insertions, 0 deletions
diff --git a/drivers/mxc/hdp/API_DPTX.c b/drivers/mxc/hdp/API_DPTX.c
new file mode 100644
index 000000000000..4bd74bd4156d
--- /dev/null
+++ b/drivers/mxc/hdp/API_DPTX.c
@@ -0,0 +1,936 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Copyright 2017-2018 NXP
+ *
+ ******************************************************************************
+ *
+ * API_DPTX.c
+ *
+ ******************************************************************************
+ */
+#include "API_DPTX.h"
+#include "util.h"
+#include "opcodes.h"
+#include "address.h"
+#include "dptx_stream.h"
+#include "dptx_framer.h"
+#include "source_vif.h"
+
+CDN_API_STATUS CDN_API_DPTX_Read_DPCD(state_struct *state, int numOfBytes,
+ int addr, DPTX_Read_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_READ_DPCD,
+ 2, 2, numOfBytes, 3, addr);
+ state->bus_type = bus_type;
+ state->rxEnable = 1;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_DPCD_READ_RESP);
+ if (ret != CDN_OK) {
+ state->running = 0;
+ return ret;
+ }
+ /* Clean most significant bytes in members of structure used for response. */
+ resp->size = 0;
+ resp->addr = 0;
+ internal_readmsg(state, 3,
+ 2, &resp->size, 3, &resp->addr, 0, &resp->buff);
+ state->running = 0;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_DPCD_blocking(state_struct *state,
+ int numOfBytes, int addr,
+ DPTX_Read_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Read_DPCD
+ (state, numOfBytes, addr, resp, bus_type));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_EDID(state_struct *state, u8 segment,
+ u8 extension,
+ DPTX_Read_EDID_response *resp)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_GET_EDID,
+ 2, 1, segment, 1, extension);
+ state->rxEnable = 1;
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_GET_EDID);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 3,
+ 1, &resp->size, 1, &resp->blockNo, 0, &resp->buff);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_EDID_blocking(state_struct *state, u8 segment,
+ u8 extension,
+ DPTX_Read_EDID_response *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Read_EDID
+ (state, segment, extension, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetHostCap(state_struct *state, u8 maxLinkRate,
+ u8 lanesCount_SSC,
+ u8 maxVoltageSwing,
+ u8 maxPreemphasis,
+ u8 testPatternsSupported,
+ u8 fastLinkTraining,
+ u8 laneMapping, u8 enchanced)
+{
+ /* fifth bit of lanesCount_SSC is used to declare eDP. */
+ state->edp = ((lanesCount_SSC >> 5) & 1);
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_SET_HOST_CAPABILITIES, 8, 1,
+ maxLinkRate, 1, lanesCount_SSC, 1,
+ maxVoltageSwing, 1, maxPreemphasis, 1,
+ testPatternsSupported, 1,
+ fastLinkTraining, 1, laneMapping, 1,
+ enchanced);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetHostCap_blocking(state_struct *state,
+ u8 maxLinkRate,
+ u8 lanesCount_SSC,
+ u8 maxVoltageSwing,
+ u8 maxPreemphasis,
+ u8 testPatternsSupported,
+ u8 fastLinkTraining,
+ u8 laneMapping, u8 enchanced)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_SetHostCap
+ (state, maxLinkRate, lanesCount_SSC,
+ maxVoltageSwing, maxPreemphasis,
+ testPatternsSupported, fastLinkTraining,
+ laneMapping, enchanced));
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetPowerMode(state_struct *state,
+ CDN_API_PWR_MODE mode)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_SET_POWER_MNG, 1, 1, mode);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetPowerMode_blocking(state_struct *state,
+ CDN_API_PWR_MODE mode)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_SetPowerMode(state, mode));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Control(state_struct *state, u32 mode)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_TRAINING_CONTROL, 1, 1, mode);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Control_blocking(state_struct *state, u32 mode)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Control(state, mode));
+}
+
+CDN_API_STATUS CDN_API_DPTX_EDP_Training(state_struct *state,
+ u8 mode, ENUM_AFE_LINK_RATE linkRate,
+ u8 rateId)
+{
+ if (AFE_check_rate_supported(linkRate) == 0)
+ return CDN_ERROR_NOT_SUPPORTED;
+
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_EDP_RATE_TRAINING, 3,
+ 1, mode,
+ 1, (u8)linkRate,
+ 1, rateId);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_EDP_Training_blocking(state_struct *state,
+ u8 mode,
+ ENUM_AFE_LINK_RATE linkRate,
+ u8 rateId)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_EDP_Training(state, mode, linkRate, rateId));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_DPCD(state_struct *state, u32 numOfBytes,
+ u32 addr, u8 *buff,
+ DPTX_Write_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_WRITE_DPCD, 3, 2, numOfBytes, 3,
+ addr, -numOfBytes, buff);
+ state->rxEnable = 1;
+ state->bus_type = bus_type;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_DPCD_WRITE_RESP);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 2, 2, &resp->size, 3, &resp->addr);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_DPCD_blocking(state_struct *state,
+ u32 numOfBytes, u32 addr,
+ u8 *buff,
+ DPTX_Write_DPCD_response *resp,
+ CDN_BUS_TYPE bus_type)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Write_DPCD
+ (state, numOfBytes, addr, buff, resp,
+ bus_type));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_Register(state_struct *state, u8 base,
+ u8 regNo,
+ DPTX_Read_Register_response *resp)
+{
+ u16 addr = (base << 8) + (regNo << 2);
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_REGISTER, 1, 2, addr);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ state->rxEnable = 1;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_REGISTER_RESP);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 3,
+ 1, &resp->base, 1, &resp->regNo, 4, &resp->val);
+ resp->regNo >>= 2;
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Read_Register_blocking(state_struct *state,
+ u8 base, u8 regNo,
+ DPTX_Read_Register_response *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Read_Register
+ (state, base, regNo, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_Register(state_struct *state, u8 base,
+ u8 regNo, u32 val)
+{
+ u16 addr = (base << 8) + (regNo << 2);
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_WRITE_REGISTER, 2, 2, addr, 4, val);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_Register_blocking(state_struct *state,
+ u8 base, u8 regNo, u32 val)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Write_Register
+ (state, base, regNo, val));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_Field(state_struct *state, u8 base, u8 regNo,
+ u8 startBit, u8 bitsNo, u32 val)
+{
+ u16 addr = (base << 8) + (regNo << 2);
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_WRITE_FIELD, 4, 2, addr, 1, startBit,
+ 1, bitsNo, 4, val);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Write_Field_blocking(state_struct *state, u8 base,
+ u8 regNo,
+ u8 startBit,
+ u8 bitsNo, u32 val)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Write_Field
+ (state, base, regNo, startBit, bitsNo, val));
+}
+
+CDN_API_STATUS CDN_API_DPTX_EnableEvent(state_struct *state, bool hpd,
+ bool training)
+{
+ uint8_t events = 0;
+
+ if (!state->running) {
+ if (!internal_apb_available(state)) {
+ return CDN_BSY;
+ }
+
+ events |= (hpd ? 1 << DP_TX_EVENT_ENABLE_HPD_BIT : 0);
+ events |= (training ? 1 << DP_TX_EVENT_ENABLE_TRAINING_BIT : 0);
+
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_ENABLE_EVENT, 2, 1, events, 4, 0);
+
+ state->bus_type = CDN_BUS_TYPE_APB;
+
+ return CDN_STARTED;
+ }
+
+ internal_process_messages(state);
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_EnableEvent_blocking(state_struct *state, bool hpd,
+ bool training)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_EnableEvent(state, hpd, training));
+}
+
+CDN_API_STATUS CDN_API_DPTX_ReadEvent(state_struct *state, u8 *LinkeventId,
+ u8 *HPDevents)
+{
+ CDN_API_STATUS ret;
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_EVENT, 0);
+ state->rxEnable = 1;
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ ret = internal_test_rx_head(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_EVENT);
+ if (ret != CDN_OK)
+ return ret;
+ internal_readmsg(state, 2, 1, HPDevents, 1, LinkeventId);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_ReadEvent_blocking(state_struct *state,
+ u8 *LinkeventId, u8 *HPDevents)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_ReadEvent
+ (state, LinkeventId, HPDevents));
+}
+
+CDN_API_STATUS CDN_API_DPTX_Set_VIC(state_struct *state,
+ struct drm_display_mode *mode,
+ int bitsPerPixel,
+ VIC_NUM_OF_LANES NumOfLanes,
+ VIC_SYMBOL_RATE rate,
+ VIC_PXL_ENCODING_FORMAT pxlencformat,
+ STEREO_VIDEO_ATTR steroVidAttr,
+ BT_TYPE bt_type, int TU)
+{
+ int min_link_rate;
+ int bitsPerPixelCalc;
+ int TU_SIZE_reg = 34;
+ int val, val_f, val2, val2_f;
+ u32 lineThresh;
+ u32 pixelClockFreq;
+ u32 MSA_MISC_Param, tempForMisc, tempForMisc2;
+ u32 oddEvenV_Total;
+ u32 DP_FRAMER_SP_Param;
+ u32 DP_FRONT_BACK_PORCH_Param;
+ u32 DP_BYTE_COUNT_Param;
+ u32 MSA_HORIZONTAL_0_Param;
+ u32 MSA_HORIZONTAL_1_Param;
+ u32 MSA_VERTICAL_0_Param;
+ u32 MSA_VERTICAL_1_Param;
+ u32 DP_HORIZONTAL_ADDR_Param;
+ u32 DP_VERTICAL_0_ADDR_Param;
+ u32 DP_VERTICAL_1_ADDR_Param;
+ u32 DP_FRAMER_PXL_REPR_Param;
+ u32 HSYNC2VSYNC_POL_CTRL_Param = 0;
+ u32 BND_HSYNC2VSYNC_Param = 0;
+ u32 DP_FRAMER_TU_Param;
+ u32 tu_vs_diff = 0;
+ VIC_COLOR_DEPTH colorDepth;
+ CDN_API_STATUS ret = CDN_OK;
+
+ if (pxlencformat == YCBCR_4_2_2)
+ bitsPerPixelCalc = bitsPerPixel * 2;
+ else if (pxlencformat == YCBCR_4_2_0)
+ bitsPerPixelCalc = bitsPerPixel * 3 / 2;
+ else
+ bitsPerPixelCalc = bitsPerPixel * 3;
+
+ /* KHz */
+ pixelClockFreq = mode->clock;
+
+ /* KHz */
+ min_link_rate = rate * 995;
+ rate *= 1000;
+
+ val = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val_f = val / (NumOfLanes * rate * 8);
+ val /= NumOfLanes * rate * 8;
+
+ val2 = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val2_f = val2 / (NumOfLanes * min_link_rate * 8);
+ val2 /= NumOfLanes * min_link_rate * 8;
+
+ /* find optimum value for the TU_SIZE */
+
+ while (((val == 1) || (TU_SIZE_reg - val < 2) || (val != val2)
+ || (val_f % 1000 > 850) || (val2_f % 1000 > 850)
+ || (val_f % 1000 < 100) || (val2_f % 1000 < 100))
+ && (TU_SIZE_reg < 64)) {
+ TU_SIZE_reg += 2;
+
+ val = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val_f = val / (NumOfLanes * rate * 8);
+ val /= NumOfLanes * rate * 8;
+
+ val2 = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val2_f = val2 / (NumOfLanes * min_link_rate * 8);
+ val2 /= NumOfLanes * min_link_rate * 8;
+ }
+
+ /* calculate the fixed valid symbols */
+ val = TU_SIZE_reg * pixelClockFreq * bitsPerPixelCalc;
+ val /= NumOfLanes * rate * 8;
+
+ if (val > 64) {
+ return CDN_ERROR_NOT_SUPPORTED;
+ }
+ DP_FRAMER_TU_Param = (TU_SIZE_reg << 8) + val + (1 << 15);
+
+ tu_vs_diff = 0;
+ if ((TU_SIZE_reg - val) <= 3) {
+ tu_vs_diff = TU_SIZE_reg - val;
+ }
+
+ /* LINE_THRESH set according to zeev presantation */
+ lineThresh =
+ ((val + 1) * NumOfLanes - ((pixelClockFreq / rate) * (val + 1) *
+ (bitsPerPixelCalc / 8) -
+ (bitsPerPixelCalc / 8))) /
+ ((bitsPerPixelCalc * NumOfLanes) / 8);
+ lineThresh += 2;
+
+ DP_FRAMER_SP_Param =
+ ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 4 : 0) +
+ ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 2 : 0) +
+ ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
+
+ DP_FRONT_BACK_PORCH_Param =
+ mode->htotal - mode->hsync_end + ((mode->hsync_start - mode->hdisplay) << 16);
+
+ DP_BYTE_COUNT_Param = mode->hdisplay * (bitsPerPixelCalc) / 8;
+
+ MSA_HORIZONTAL_0_Param =
+ mode->htotal + ((mode->htotal - mode->hsync_start) << 16);
+
+ MSA_HORIZONTAL_1_Param =
+ mode->hsync_end - mode->hsync_start +
+ ((mode->flags & DRM_MODE_FLAG_NHSYNC ? 0 : 1) << 15) + (mode->hdisplay << 16);
+
+ MSA_VERTICAL_0_Param =
+ (mode->flags & DRM_MODE_FLAG_INTERLACE ? (mode->vtotal / 2) : mode->vtotal) +
+ ((mode->vtotal - mode->vsync_start) << 16);
+
+ MSA_VERTICAL_1_Param =
+ (mode->vsync_end - mode->vsync_start +
+ ((mode->flags & DRM_MODE_FLAG_NVSYNC ? 0 : 1) << 15)) +
+ ((mode->flags & DRM_MODE_FLAG_INTERLACE ? mode->vdisplay / 2 : mode->vdisplay) << 16);
+
+ DP_HORIZONTAL_ADDR_Param = (mode->hdisplay << 16) + mode->hsync;
+
+ DP_VERTICAL_0_ADDR_Param =
+ (mode->flags & DRM_MODE_FLAG_INTERLACE ? (mode->vtotal / 2) : mode->vtotal) -
+ (mode->vtotal - mode->vdisplay) + ((mode->vtotal - mode->vsync_start) << 16);
+
+ DP_VERTICAL_1_ADDR_Param =
+ mode->flags & DRM_MODE_FLAG_INTERLACE ? (mode->vtotal / 2) : mode->vtotal;
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ BND_HSYNC2VSYNC_Param = 0x3020;
+ else
+ BND_HSYNC2VSYNC_Param = 0x2000;
+
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ HSYNC2VSYNC_POL_CTRL_Param |= F_HPOL(1);
+
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ HSYNC2VSYNC_POL_CTRL_Param |= F_VPOL(1);
+
+ switch (bitsPerPixel) {
+ case 6:
+ colorDepth = BCS_6;
+ break;
+ case 8:
+ colorDepth = BCS_8;
+ break;
+ case 10:
+ colorDepth = BCS_10;
+ break;
+ case 12:
+ colorDepth = BCS_12;
+ break;
+ case 16:
+ colorDepth = BCS_16;
+ break;
+ default:
+ colorDepth = BCS_8;
+ };
+
+ DP_FRAMER_PXL_REPR_Param = (pxlencformat << 8) + colorDepth;
+
+ switch (pxlencformat) {
+ case PXL_RGB: /*0x1 */
+ tempForMisc = 0;
+ break;
+ case YCBCR_4_4_4: /*0x2 */
+ tempForMisc = 6 + 8 * (bt_type);
+ break;
+ case YCBCR_4_2_2: /*0x4 */
+ tempForMisc = 5 + 8 * (bt_type);
+ break;
+ case YCBCR_4_2_0: /*0x8 */
+ tempForMisc = 5;
+ break;
+
+ case Y_ONLY: /*0x10 */
+ tempForMisc = 0;
+ break;
+ default:
+ tempForMisc = 0;
+ };
+
+ switch (bitsPerPixel) {
+ case 6:
+ tempForMisc2 = 0;
+ break;
+
+ case 8:
+ tempForMisc2 = 1;
+ break;
+
+ case 10:
+ tempForMisc2 = 2;
+ break;
+
+ case 12:
+ tempForMisc2 = 3;
+ break;
+
+ case 16:
+ tempForMisc2 = 4;
+ break;
+ default:
+ tempForMisc2 = 1;
+
+ };
+
+ oddEvenV_Total = mode->vtotal % 2;
+ oddEvenV_Total = 1 - oddEvenV_Total;
+ oddEvenV_Total = oddEvenV_Total << 8;
+ MSA_MISC_Param =
+ ((tempForMisc * 2) + (32 * tempForMisc2) +
+ ((pxlencformat == Y_ONLY ? 1 : 0) << 14) +
+ ((oddEvenV_Total) * (mode->flags & DRM_MODE_FLAG_INTERLACE ? 1 : 0)));
+
+ /* 420 has diffrent parameters, enable VSS SDP */
+ if (pxlencformat == YCBCR_4_2_0)
+ MSA_MISC_Param = 1 << 14;
+
+ switch (state->tmp) {
+ case 0:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_SOURCE_VIF,
+ BND_HSYNC2VSYNC,
+ BND_HSYNC2VSYNC_Param);
+ break;
+ case 1:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_SOURCE_VIF,
+ HSYNC2VSYNC_POL_CTRL,
+ HSYNC2VSYNC_POL_CTRL_Param);
+ break;
+ case 2:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_FRAMER_TU,
+ DP_FRAMER_TU_Param);
+ break;
+ case 3:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_FRAMER_PXL_REPR,
+ DP_FRAMER_PXL_REPR_Param);
+ break;
+ case 4:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_FRAMER_SP,
+ DP_FRAMER_SP_Param);
+ break;
+ case 5:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_FRONT_BACK_PORCH,
+ DP_FRONT_BACK_PORCH_Param);
+ break;
+ case 6:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_BYTE_COUNT,
+ DP_BYTE_COUNT_Param);
+ break;
+ case 7:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_HORIZONTAL_0,
+ MSA_HORIZONTAL_0_Param);
+ break;
+ case 8:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_HORIZONTAL_1,
+ MSA_HORIZONTAL_1_Param);
+ break;
+ case 9:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_VERTICAL_0,
+ MSA_VERTICAL_0_Param);
+ break;
+ case 10:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_VERTICAL_1,
+ MSA_VERTICAL_1_Param);
+ break;
+ case 11:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ MSA_MISC, MSA_MISC_Param);
+ break;
+ case 12:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ STREAM_CONFIG, 1);
+ break;
+ case 13:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_HORIZONTAL,
+ DP_HORIZONTAL_ADDR_Param);
+ break;
+ case 14:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_VERTICAL_0,
+ DP_VERTICAL_0_ADDR_Param);
+ break;
+ case 15:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ DP_VERTICAL_1,
+ DP_VERTICAL_1_ADDR_Param);
+ break;
+ case 16:
+ ret =
+ CDN_API_DPTX_Write_Field(state, BASE_DPTX_STREAM, DP_VB_ID,
+ 2, 1,
+ ((mode->flags & DRM_MODE_FLAG_INTERLACE ? 1 : 0) << 2));
+ break;
+ case 17:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ LINE_THRESH, lineThresh);
+ break;
+ case 18:
+ ret =
+ CDN_API_DPTX_Write_Register(state, BASE_DPTX_STREAM,
+ RATE_GOVERNOR_STATUS,
+ tu_vs_diff << 8);
+ break;
+ }
+ if (!state->tmp && ret == CDN_STARTED)
+ return CDN_STARTED;
+ switch (ret) {
+ case CDN_OK:
+ state->tmp++;
+ break;
+ case CDN_STARTED:
+ return CDN_BSY;
+ break;
+ default:
+ return ret;
+ }
+ if (state->tmp == 19) {
+ state->tmp = 0;
+ return CDN_OK;
+ }
+ return CDN_BSY;
+}
+
+CDN_API_STATUS CDN_API_DPTX_Set_VIC_blocking(state_struct *state,
+ struct drm_display_mode *mode,
+ int bitsPerPixel,
+ VIC_NUM_OF_LANES NumOfLanes,
+ VIC_SYMBOL_RATE rate,
+ VIC_PXL_ENCODING_FORMAT
+ pxlencformat,
+ STEREO_VIDEO_ATTR steroVidAttr,
+ BT_TYPE bt_type, int TU)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_Set_VIC
+ (state, mode, bitsPerPixel, NumOfLanes, rate,
+ pxlencformat, steroVidAttr, bt_type, TU));
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetVideo(state_struct *state, u8 mode)
+{
+ internal_macro_command_tx(state, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
+ CDN_BUS_TYPE_APB, 1, 1, mode);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetVideo_blocking(state_struct *state, u8 mode)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_SetVideo(state, mode));
+}
+
+CDN_API_STATUS CDN_API_DPTX_ReadLinkStat(state_struct *state,
+ S_LINK_STAT *stat)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_DP_TX,
+ DPTX_READ_LINK_STAT, CDN_BUS_TYPE_APB, 0);
+ internal_readmsg(state, 10, 1, &stat->rate, 1, &stat->lanes, 1,
+ &stat->swing[0], 1, &stat->preemphasis[0], 1,
+ &stat->swing[1], 1, &stat->preemphasis[1], 1,
+ &stat->swing[2], 1, &stat->preemphasis[2], 1,
+ &stat->swing[3], 1, &stat->preemphasis[3]);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_ReadLinkStat_blocking(state_struct *state,
+ S_LINK_STAT *stat)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_ReadLinkStat(state, stat));
+}
+
+CDN_API_STATUS CDN_API_DPTX_TrainingControl(state_struct *state, u8 val)
+{
+ internal_macro_command_tx(state, MB_MODULE_ID_DP_TX,
+ DPTX_TRAINING_CONTROL, CDN_BUS_TYPE_APB, 1, 1,
+ val);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_TrainingControl_blocking(state_struct *state,
+ u8 val)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_TrainingControl(state, val));
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetLastAuxStatus(state_struct *state, u8 *resp)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_DP_TX,
+ DPTX_GET_LAST_AUX_STAUS, CDN_BUS_TYPE_APB,
+ 0);
+ internal_readmsg(state, 1, 1, resp);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetLastAuxStatus_blocking(state_struct *state,
+ u8 *resp)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_GetLastAuxStatus(state, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetHpdStatus(state_struct *state, u8 *resp)
+{
+ internal_macro_command_txrx(state, MB_MODULE_ID_DP_TX, DPTX_HPD_STATE,
+ CDN_BUS_TYPE_APB, 0);
+ internal_readmsg(state, 1, 1, resp);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_GetHpdStatus_blocking(state_struct *state,
+ u8 *resp)
+{
+
+ internal_block_function(&state->mutex, CDN_API_DPTX_GetHpdStatus(state, resp));
+}
+
+CDN_API_STATUS CDN_API_DPTX_ForceLanes(state_struct *state, u8 linkRate,
+ u8 numOfLanes,
+ u8 voltageSwing_l0,
+ u8 preemphasis_l0,
+ u8 voltageSwing_l1,
+ u8 preemphasis_l1,
+ u8 voltageSwing_l2,
+ u8 preemphasis_l2,
+ u8 voltageSwing_l3,
+ u8 preemphasis_l3, u8 pattern, u8 ssc)
+{
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX,
+ DPTX_FORCE_LANES, 12, 1, linkRate, 1,
+ numOfLanes, 1, voltageSwing_l0, 1,
+ preemphasis_l0, 1, voltageSwing_l1, 1,
+ preemphasis_l1, 1, voltageSwing_l2, 1,
+ preemphasis_l2, 1, voltageSwing_l3, 1,
+ preemphasis_l3, 1, pattern, 1, ssc);
+ state->bus_type = CDN_BUS_TYPE_APB;
+ return CDN_STARTED;
+ }
+ internal_process_messages(state);
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_ForceLanes_blocking(state_struct *state,
+ u8 linkRate, u8 numOfLanes,
+ u8 voltageSwing_l0,
+ u8 preemphasis_l0,
+ u8 voltageSwing_l1,
+ u8 preemphasis_l1,
+ u8 voltageSwing_l2,
+ u8 preemphasis_l2,
+ u8 voltageSwing_l3,
+ u8 preemphasis_l3, u8 pattern,
+ u8 ssc)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_ForceLanes_blocking
+ (state, linkRate, numOfLanes, voltageSwing_l0,
+ preemphasis_l0, voltageSwing_l1,
+ preemphasis_l1, voltageSwing_l2,
+ preemphasis_l2, voltageSwing_l3,
+ preemphasis_l3, pattern, ssc));
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetDbg(state_struct *state, uint32_t dbg_cfg)
+{
+ uint8_t buf[sizeof(uint32_t)];
+
+ if (!state->running) {
+ if (!internal_apb_available(state))
+ return CDN_BSY;
+
+ buf[0] = (uint8_t) (dbg_cfg);
+ buf[1] = (uint8_t) (dbg_cfg >> 8);
+ buf[2] = (uint8_t) (dbg_cfg >> 16);
+ buf[3] = (uint8_t) (dbg_cfg >> 24);
+
+ internal_tx_mkfullmsg(state, MB_MODULE_ID_DP_TX, DPTX_DBG_SET,
+ 1, -sizeof(buf), buf);
+
+ state->bus_type = CDN_BUS_TYPE_APB;
+
+ return CDN_STARTED;
+ }
+
+ internal_process_messages(state);
+
+ return CDN_OK;
+}
+
+CDN_API_STATUS CDN_API_DPTX_SetDbg_blocking(state_struct *state,
+ uint32_t dbg_cfg)
+{
+ internal_block_function(&state->mutex, CDN_API_DPTX_SetDbg(state, dbg_cfg));
+}