[PATCH v3 21/32] drm/exynos: Move dp driver from video/ to drm/
Sean Paul
seanpaul at chromium.org
Thu Oct 31 17:05:34 CET 2013
On Thu, Oct 31, 2013 at 6:46 AM, Inki Dae <inki.dae at samsung.com> wrote:
> CCing Jingoo,
>
> Is that ok to remove eDP driver from video/exynos? Isn't this driver really
> used by Linux framebuffer driver, s3c-fb.c?
>
> Of course, now s3c-fb driver is dead code because this driver doesn't
> support device tree yet but we would need more reviews and discussions about
> moving this driver into drm side. Let's watch new rules for device tree
> bindings of DRM world. So I'd not like to merge this driver yet.
>
Hi Inki,
I don't think that the dt bindings conversation has any bearing on
this patch. IMO, the justification for doing this is:
- Suspend/resume/dpms is currently broken for boards that use the edp driver
- HDMI driver is already in drm, so it makes sense to have DP in as well
- This allows us to do things like proper hpd, and EDID in DP driver
- Allows us to remove all encoder/connector oriented code from fimd
We've been talking about this for over 10 months now, is there really
anything left to discuss?
Sean
> Thanks,
> Inki Dae
>
>> -----Original Message-----
>> From: Sean Paul [mailto:seanpaul at chromium.org]
>> Sent: Wednesday, October 30, 2013 1:13 AM
>> To: dri-devel at lists.freedesktop.org; inki.dae at samsung.com
>> Cc: airlied at linux.ie; tomasz.figa at gmail.com; marcheu at chromium.org; Sean
>> Paul
>> Subject: [PATCH v3 21/32] drm/exynos: Move dp driver from video/ to drm/
>>
>> This patch moves the code from video/ to drm/
>>
>> Signed-off-by: Sean Paul <seanpaul at chromium.org>
>> ---
>>
>> Changes in v2: None
>> Changes in v3: None
>>
>> drivers/gpu/drm/exynos/Kconfig | 7 +
>> drivers/gpu/drm/exynos/Makefile | 1 +
>> drivers/gpu/drm/exynos/exynos_dp_core.c | 1213
>> ++++++++++++++++++++++++++++++
>> drivers/gpu/drm/exynos/exynos_dp_core.h | 210 ++++++
>> drivers/gpu/drm/exynos/exynos_dp_reg.c | 1245
>> +++++++++++++++++++++++++++++++
>> drivers/gpu/drm/exynos/exynos_dp_reg.h | 366 +++++++++
>> drivers/video/exynos/Kconfig | 7 -
>> drivers/video/exynos/Makefile | 1 -
>> drivers/video/exynos/exynos_dp_core.c | 1213
> ---------------------------
>> ---
>> drivers/video/exynos/exynos_dp_core.h | 210 ------
>> drivers/video/exynos/exynos_dp_reg.c | 1245
> ---------------------------
>> ----
>> drivers/video/exynos/exynos_dp_reg.h | 366 ---------
>> 12 files changed, 3042 insertions(+), 3042 deletions(-)
>> create mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.c
>> create mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
>> create mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.c
>> create mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.h
>> delete mode 100644 drivers/video/exynos/exynos_dp_core.c
>> delete mode 100644 drivers/video/exynos/exynos_dp_core.h
>> delete mode 100644 drivers/video/exynos/exynos_dp_reg.c
>> delete mode 100644 drivers/video/exynos/exynos_dp_reg.h
>>
>> diff --git a/drivers/gpu/drm/exynos/Kconfig
>> b/drivers/gpu/drm/exynos/Kconfig
>> index 45b6ef5..3ace74f 100644
>> --- a/drivers/gpu/drm/exynos/Kconfig
>> +++ b/drivers/gpu/drm/exynos/Kconfig
>> @@ -30,6 +30,13 @@ config DRM_EXYNOS_FIMD
>> help
>> Choose this option if you want to use Exynos FIMD for DRM.
>>
>> +config DRM_EXYNOS_DP
>> + bool "EXYNOS DRM DP driver support"
>> + depends on ARCH_EXYNOS
>> + default n
>> + help
>> + This enables support for DP device.
>> +
>> config DRM_EXYNOS_HDMI
>> bool "Exynos DRM HDMI"
>> depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV
>> diff --git a/drivers/gpu/drm/exynos/Makefile
>> b/drivers/gpu/drm/exynos/Makefile
>> index afbe499..fc8555c 100644
>> --- a/drivers/gpu/drm/exynos/Makefile
>> +++ b/drivers/gpu/drm/exynos/Makefile
>> @@ -11,6 +11,7 @@ exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o
>> exynos_drm_connector.o \
>> exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
>> exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o
>> exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
>> +exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o
>> exynos_dp_reg.o
>> exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o
>> exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o
>> exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c
>> b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> new file mode 100644
>> index 0000000..089ae22
>> --- /dev/null
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> @@ -0,0 +1,1213 @@
>> +/*
>> + * Samsung SoC DP (Display Port) interface driver.
>> + *
>> + * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>> + * Author: Jingoo Han <jg1.han at samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> it
>> + * under the terms of the GNU General Public License as published by the
>> + * Free Software Foundation; either version 2 of the License, or (at your
>> + * option) any later version.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/err.h>
>> +#include <linux/clk.h>
>> +#include <linux/io.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/delay.h>
>> +#include <linux/of.h>
>> +
>> +#include <video/exynos_dp.h>
>> +
>> +#include "exynos_dp_core.h"
>> +
>> +static int exynos_dp_init_dp(struct exynos_dp_device *dp)
>> +{
>> + exynos_dp_reset(dp);
>> +
>> + exynos_dp_swreset(dp);
>> +
>> + exynos_dp_init_analog_param(dp);
>> + exynos_dp_init_interrupt(dp);
>> +
>> + /* SW defined function Normal operation */
>> + exynos_dp_enable_sw_function(dp);
>> +
>> + exynos_dp_config_interrupt(dp);
>> + exynos_dp_init_analog_func(dp);
>> +
>> + exynos_dp_init_hpd(dp);
>> + exynos_dp_init_aux(dp);
>> +
>> + return 0;
>> +}
>> +
>> +static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
>> +{
>> + int timeout_loop = 0;
>> +
>> + while (exynos_dp_get_plug_in_status(dp) != 0) {
>> + timeout_loop++;
>> + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> + dev_err(dp->dev, "failed to get hpd plug status\n");
>> + return -ETIMEDOUT;
>> + }
>> + usleep_range(10, 11);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static unsigned char exynos_dp_calc_edid_check_sum(unsigned char
>> *edid_data)
>> +{
>> + int i;
>> + unsigned char sum = 0;
>> +
>> + for (i = 0; i < EDID_BLOCK_LENGTH; i++)
>> + sum = sum + edid_data[i];
>> +
>> + return sum;
>> +}
>> +
>> +static int exynos_dp_read_edid(struct exynos_dp_device *dp)
>> +{
>> + unsigned char edid[EDID_BLOCK_LENGTH * 2];
>> + unsigned int extend_block = 0;
>> + unsigned char sum;
>> + unsigned char test_vector;
>> + int retval;
>> +
>> + /*
>> + * EDID device address is 0x50.
>> + * However, if necessary, you must have set upper address
>> + * into E-EDID in I2C device, 0x30.
>> + */
>> +
>> + /* Read Extension Flag, Number of 128-byte EDID extension blocks */
>> + retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
>> + EDID_EXTENSION_FLAG,
>> + &extend_block);
>> + if (retval)
>> + return retval;
>> +
>> + if (extend_block > 0) {
>> + dev_dbg(dp->dev, "EDID data includes a single
> extension!\n");
>> +
>> + /* Read EDID data */
>> + retval = exynos_dp_read_bytes_from_i2c(dp,
>> I2C_EDID_DEVICE_ADDR,
>> + EDID_HEADER_PATTERN,
>> + EDID_BLOCK_LENGTH,
>> + &edid[EDID_HEADER_PATTERN]);
>> + if (retval != 0) {
>> + dev_err(dp->dev, "EDID Read failed!\n");
>> + return -EIO;
>> + }
>> + sum = exynos_dp_calc_edid_check_sum(edid);
>> + if (sum != 0) {
>> + dev_err(dp->dev, "EDID bad checksum!\n");
>> + return -EIO;
>> + }
>> +
>> + /* Read additional EDID data */
>> + retval = exynos_dp_read_bytes_from_i2c(dp,
>> + I2C_EDID_DEVICE_ADDR,
>> + EDID_BLOCK_LENGTH,
>> + EDID_BLOCK_LENGTH,
>> + &edid[EDID_BLOCK_LENGTH]);
>> + if (retval != 0) {
>> + dev_err(dp->dev, "EDID Read failed!\n");
>> + return -EIO;
>> + }
>> + sum =
>> exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
>> + if (sum != 0) {
>> + dev_err(dp->dev, "EDID bad checksum!\n");
>> + return -EIO;
>> + }
>> +
>> + exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_TEST_REQUEST,
>> + &test_vector);
>> + if (test_vector & DPCD_TEST_EDID_READ) {
>> + exynos_dp_write_byte_to_dpcd(dp,
>> + DPCD_ADDR_TEST_EDID_CHECKSUM,
>> + edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
>> + exynos_dp_write_byte_to_dpcd(dp,
>> + DPCD_ADDR_TEST_RESPONSE,
>> + DPCD_TEST_EDID_CHECKSUM_WRITE);
>> + }
>> + } else {
>> + dev_info(dp->dev, "EDID data does not include any
>> extensions.\n");
>> +
>> + /* Read EDID data */
>> + retval = exynos_dp_read_bytes_from_i2c(dp,
>> + I2C_EDID_DEVICE_ADDR,
>> + EDID_HEADER_PATTERN,
>> + EDID_BLOCK_LENGTH,
>> + &edid[EDID_HEADER_PATTERN]);
>> + if (retval != 0) {
>> + dev_err(dp->dev, "EDID Read failed!\n");
>> + return -EIO;
>> + }
>> + sum = exynos_dp_calc_edid_check_sum(edid);
>> + if (sum != 0) {
>> + dev_err(dp->dev, "EDID bad checksum!\n");
>> + return -EIO;
>> + }
>> +
>> + exynos_dp_read_byte_from_dpcd(dp,
>> + DPCD_ADDR_TEST_REQUEST,
>> + &test_vector);
>> + if (test_vector & DPCD_TEST_EDID_READ) {
>> + exynos_dp_write_byte_to_dpcd(dp,
>> + DPCD_ADDR_TEST_EDID_CHECKSUM,
>> + edid[EDID_CHECKSUM]);
>> + exynos_dp_write_byte_to_dpcd(dp,
>> + DPCD_ADDR_TEST_RESPONSE,
>> + DPCD_TEST_EDID_CHECKSUM_WRITE);
>> + }
>> + }
>> +
>> + dev_err(dp->dev, "EDID Read success!\n");
>> + return 0;
>> +}
>> +
>> +static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
>> +{
>> + u8 buf[12];
>> + int i;
>> + int retval;
>> +
>> + /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */
>> + retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV,
>> + 12, buf);
>> + if (retval)
>> + return retval;
>> +
>> + /* Read EDID */
>> + for (i = 0; i < 3; i++) {
>> + retval = exynos_dp_read_edid(dp);
>> + if (!retval)
>> + break;
>> + }
>> +
>> + return retval;
>> +}
>> +
>> +static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device
>> *dp,
>> + bool enable)
>> +{
>> + u8 data;
>> +
>> + exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, &data);
>> +
>> + if (enable)
>> + exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
>> + DPCD_ENHANCED_FRAME_EN |
>> + DPCD_LANE_COUNT_SET(data));
>> + else
>> + exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
>> + DPCD_LANE_COUNT_SET(data));
>> +}
>> +
>> +static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device
>> *dp)
>> +{
>> + u8 data;
>> + int retval;
>> +
>> + exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data);
>> + retval = DPCD_ENHANCED_FRAME_CAP(data);
>> +
>> + return retval;
>> +}
>> +
>> +static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp)
>> +{
>> + u8 data;
>> +
>> + data = exynos_dp_is_enhanced_mode_available(dp);
>> + exynos_dp_enable_rx_to_enhanced_mode(dp, data);
>> + exynos_dp_enable_enhanced_mode(dp, data);
>> +}
>> +
>> +static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
>> +{
>> + exynos_dp_set_training_pattern(dp, DP_NONE);
>> +
>> + exynos_dp_write_byte_to_dpcd(dp,
>> + DPCD_ADDR_TRAINING_PATTERN_SET,
>> + DPCD_TRAINING_PATTERN_DISABLED);
>> +}
>> +
>> +static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device
>> *dp,
>> + int pre_emphasis, int lane)
>> +{
>> + switch (lane) {
>> + case 0:
>> + exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
>> + break;
>> + case 1:
>> + exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
>> + break;
>> +
>> + case 2:
>> + exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
>> + break;
>> +
>> + case 3:
>> + exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
>> + break;
>> + }
>> +}
>> +
>> +static int exynos_dp_link_start(struct exynos_dp_device *dp)
>> +{
>> + u8 buf[4];
>> + int lane, lane_count, pll_tries, retval;
>> +
>> + lane_count = dp->link_train.lane_count;
>> +
>> + dp->link_train.lt_state = CLOCK_RECOVERY;
>> + dp->link_train.eq_loop = 0;
>> +
>> + for (lane = 0; lane < lane_count; lane++)
>> + dp->link_train.cr_loop[lane] = 0;
>> +
>> + /* Set link rate and count as you want to establish*/
>> + exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
>> + exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
>> +
>> + /* Setup RX configuration */
>> + buf[0] = dp->link_train.link_rate;
>> + buf[1] = dp->link_train.lane_count;
>> + retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
>> + 2, buf);
>> + if (retval)
>> + return retval;
>> +
>> + /* Set TX pre-emphasis to minimum */
>> + for (lane = 0; lane < lane_count; lane++)
>> + exynos_dp_set_lane_lane_pre_emphasis(dp,
>> + PRE_EMPHASIS_LEVEL_0, lane);
>> +
>> + /* Wait for PLL lock */
>> + pll_tries = 0;
>> + while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
>> + if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
>> + dev_err(dp->dev, "Wait for PLL lock timed out\n");
>> + return -ETIMEDOUT;
>> + }
>> +
>> + pll_tries++;
>> + usleep_range(90, 120);
>> + }
>> +
>> + /* Set training pattern 1 */
>> + exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
>> +
>> + /* Set RX training pattern */
>> + retval = exynos_dp_write_byte_to_dpcd(dp,
>> + DPCD_ADDR_TRAINING_PATTERN_SET,
>> + DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1);
>> + if (retval)
>> + return retval;
>> +
>> + for (lane = 0; lane < lane_count; lane++)
>> + buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
>> + DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
>> +
>> + retval = exynos_dp_write_bytes_to_dpcd(dp,
>> DPCD_ADDR_TRAINING_LANE0_SET,
>> + lane_count, buf);
>> +
>> + return retval;
>> +}
>> +
>> +static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int
>> lane)
>> +{
>> + int shift = (lane & 1) * 4;
>> + u8 link_value = link_status[lane>>1];
>> +
>> + return (link_value >> shift) & 0xf;
>> +}
>> +
>> +static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
>> +{
>> + int lane;
>> + u8 lane_status;
>> +
>> + for (lane = 0; lane < lane_count; lane++) {
>> + lane_status = exynos_dp_get_lane_status(link_status, lane);
>> + if ((lane_status & DPCD_LANE_CR_DONE) == 0)
>> + return -EINVAL;
>> + }
>> + return 0;
>> +}
>> +
>> +static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
>> + int lane_count)
>> +{
>> + int lane;
>> + u8 lane_status;
>> +
>> + if ((link_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
>> + return -EINVAL;
>> +
>> + for (lane = 0; lane < lane_count; lane++) {
>> + lane_status = exynos_dp_get_lane_status(link_status, lane);
>> + lane_status &= DPCD_CHANNEL_EQ_BITS;
>> + if (lane_status != DPCD_CHANNEL_EQ_BITS)
>> + return -EINVAL;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static unsigned char exynos_dp_get_adjust_request_voltage(u8
>> adjust_request[2],
>> + int lane)
>> +{
>> + int shift = (lane & 1) * 4;
>> + u8 link_value = adjust_request[lane>>1];
>> +
>> + return (link_value >> shift) & 0x3;
>> +}
>> +
>> +static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
>> + u8 adjust_request[2],
>> + int lane)
>> +{
>> + int shift = (lane & 1) * 4;
>> + u8 link_value = adjust_request[lane>>1];
>> +
>> + return ((link_value >> shift) & 0xc) >> 2;
>> +}
>> +
>> +static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
>> + u8 training_lane_set, int lane)
>> +{
>> + switch (lane) {
>> + case 0:
>> + exynos_dp_set_lane0_link_training(dp, training_lane_set);
>> + break;
>> + case 1:
>> + exynos_dp_set_lane1_link_training(dp, training_lane_set);
>> + break;
>> +
>> + case 2:
>> + exynos_dp_set_lane2_link_training(dp, training_lane_set);
>> + break;
>> +
>> + case 3:
>> + exynos_dp_set_lane3_link_training(dp, training_lane_set);
>> + break;
>> + }
>> +}
>> +
>> +static unsigned int exynos_dp_get_lane_link_training(
>> + struct exynos_dp_device *dp,
>> + int lane)
>> +{
>> + u32 reg;
>> +
>> + switch (lane) {
>> + case 0:
>> + reg = exynos_dp_get_lane0_link_training(dp);
>> + break;
>> + case 1:
>> + reg = exynos_dp_get_lane1_link_training(dp);
>> + break;
>> + case 2:
>> + reg = exynos_dp_get_lane2_link_training(dp);
>> + break;
>> + case 3:
>> + reg = exynos_dp_get_lane3_link_training(dp);
>> + break;
>> + default:
>> + WARN_ON(1);
>> + return 0;
>> + }
>> +
>> + return reg;
>> +}
>> +
>> +static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
>> +{
>> + exynos_dp_training_pattern_dis(dp);
>> + exynos_dp_set_enhanced_mode(dp);
>> +
>> + dp->link_train.lt_state = FAILED;
>> +}
>> +
>> +static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device
>> *dp,
>> + u8 adjust_request[2])
>> +{
>> + int lane, lane_count;
>> + u8 voltage_swing, pre_emphasis, training_lane;
>> +
>> + lane_count = dp->link_train.lane_count;
>> + for (lane = 0; lane < lane_count; lane++) {
>> + voltage_swing = exynos_dp_get_adjust_request_voltage(
>> + adjust_request, lane);
>> + pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
>> + adjust_request, lane);
>> + training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
>> + DPCD_PRE_EMPHASIS_SET(pre_emphasis);
>> +
>> + if (voltage_swing == VOLTAGE_LEVEL_3)
>> + training_lane |= DPCD_MAX_SWING_REACHED;
>> + if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
>> + training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
>> +
>> + dp->link_train.training_lane[lane] = training_lane;
>> + }
>> +}
>> +
>> +static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
>> +{
>> + int lane, lane_count, retval;
>> + u8 voltage_swing, pre_emphasis, training_lane;
>> + u8 link_status[2], adjust_request[2];
>> +
>> + usleep_range(100, 101);
>> +
>> + lane_count = dp->link_train.lane_count;
>> +
>> + retval = exynos_dp_read_bytes_from_dpcd(dp,
>> + DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
>> + if (retval)
>> + return retval;
>> +
>> + retval = exynos_dp_read_bytes_from_dpcd(dp,
>> + DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2,
> adjust_request);
>> + if (retval)
>> + return retval;
>> +
>> + if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
>> + /* set training pattern 2 for EQ */
>> + exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
>> +
>> + retval = exynos_dp_write_byte_to_dpcd(dp,
>> + DPCD_ADDR_TRAINING_PATTERN_SET,
>> + DPCD_SCRAMBLING_DISABLED |
>> + DPCD_TRAINING_PATTERN_2);
>> + if (retval)
>> + return retval;
>> +
>> + dev_info(dp->dev, "Link Training Clock Recovery success\n");
>> + dp->link_train.lt_state = EQUALIZER_TRAINING;
>> + } else {
>> + for (lane = 0; lane < lane_count; lane++) {
>> + training_lane = exynos_dp_get_lane_link_training(
>> + dp, lane);
>> + voltage_swing =
> exynos_dp_get_adjust_request_voltage(
>> + adjust_request,
> lane);
>> + pre_emphasis =
>> exynos_dp_get_adjust_request_pre_emphasis(
>> + adjust_request,
> lane);
>> +
>> + if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
>> + voltage_swing &&
>> + DPCD_PRE_EMPHASIS_GET(training_lane) ==
>> + pre_emphasis)
>> + dp->link_train.cr_loop[lane]++;
>> +
>> + if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
>> + voltage_swing == VOLTAGE_LEVEL_3 ||
>> + pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
>> + dev_err(dp->dev, "CR Max reached
> (%d,%d,%d)\n",
>> + dp->link_train.cr_loop[lane],
>> + voltage_swing, pre_emphasis);
>> + exynos_dp_reduce_link_rate(dp);
>> + return -EIO;
>> + }
>> + }
>> + }
>> +
>> + exynos_dp_get_adjust_training_lane(dp, adjust_request);
>> +
>> + for (lane = 0; lane < lane_count; lane++)
>> + exynos_dp_set_lane_link_training(dp,
>> + dp->link_train.training_lane[lane], lane);
>> +
>> + retval = exynos_dp_write_bytes_to_dpcd(dp,
>> + DPCD_ADDR_TRAINING_LANE0_SET, lane_count,
>> + dp->link_train.training_lane);
>> + if (retval)
>> + return retval;
>> +
>> + return retval;
>> +}
>> +
>> +static int exynos_dp_process_equalizer_training(struct exynos_dp_device
>> *dp)
>> +{
>> + int lane, lane_count, retval;
>> + u32 reg;
>> + u8 link_align, link_status[2], adjust_request[2];
>> +
>> + usleep_range(400, 401);
>> +
>> + lane_count = dp->link_train.lane_count;
>> +
>> + retval = exynos_dp_read_bytes_from_dpcd(dp,
>> + DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
>> + if (retval)
>> + return retval;
>> +
>> + if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
>> + exynos_dp_reduce_link_rate(dp);
>> + return -EIO;
>> + }
>> +
>> + retval = exynos_dp_read_bytes_from_dpcd(dp,
>> + DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2,
> adjust_request);
>> + if (retval)
>> + return retval;
>> +
>> + retval = exynos_dp_read_byte_from_dpcd(dp,
>> + DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &link_align);
>> + if (retval)
>> + return retval;
>> +
>> + exynos_dp_get_adjust_training_lane(dp, adjust_request);
>> +
>> + if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count))
>> {
>> + /* traing pattern Set to Normal */
>> + exynos_dp_training_pattern_dis(dp);
>> +
>> + dev_info(dp->dev, "Link Training success!\n");
>> +
>> + exynos_dp_get_link_bandwidth(dp, ®);
>> + dp->link_train.link_rate = reg;
>> + dev_dbg(dp->dev, "final bandwidth = %.2x\n",
>> + dp->link_train.link_rate);
>> +
>> + exynos_dp_get_lane_count(dp, ®);
>> + dp->link_train.lane_count = reg;
>> + dev_dbg(dp->dev, "final lane count = %.2x\n",
>> + dp->link_train.lane_count);
>> +
>> + /* set enhanced mode if available */
>> + exynos_dp_set_enhanced_mode(dp);
>> + dp->link_train.lt_state = FINISHED;
>> +
>> + return 0;
>> + }
>> +
>> + /* not all locked */
>> + dp->link_train.eq_loop++;
>> +
>> + if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
>> + dev_err(dp->dev, "EQ Max loop\n");
>> + exynos_dp_reduce_link_rate(dp);
>> + return -EIO;
>> + }
>> +
>> + for (lane = 0; lane < lane_count; lane++)
>> + exynos_dp_set_lane_link_training(dp,
>> + dp->link_train.training_lane[lane], lane);
>> +
>> + retval = exynos_dp_write_bytes_to_dpcd(dp,
>> DPCD_ADDR_TRAINING_LANE0_SET,
>> + lane_count, dp->link_train.training_lane);
>> +
>> + return retval;
>> +}
>> +
>> +static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
>> + u8 *bandwidth)
>> +{
>> + u8 data;
>> +
>> + /*
>> + * For DP rev.1.1, Maximum link rate of Main Link lanes
>> + * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
>> + */
>> + exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LINK_RATE, &data);
>> + *bandwidth = data;
>> +}
>> +
>> +static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
>> + u8 *lane_count)
>> +{
>> + u8 data;
>> +
>> + /*
>> + * For DP rev.1.1, Maximum number of Main Link lanes
>> + * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
>> + */
>> + exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data);
>> + *lane_count = DPCD_MAX_LANE_COUNT(data);
>> +}
>> +
>> +static void exynos_dp_init_training(struct exynos_dp_device *dp,
>> + enum link_lane_count_type max_lane,
>> + enum link_rate_type max_rate)
>> +{
>> + /*
>> + * MACRO_RST must be applied after the PLL_LOCK to avoid
>> + * the DP inter pair skew issue for at least 10 us
>> + */
>> + exynos_dp_reset_macro(dp);
>> +
>> + /* Initialize by reading RX's DPCD */
>> + exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
>> + exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
>> +
>> + if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
>> + (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
>> + dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
>> + dp->link_train.link_rate);
>> + dp->link_train.link_rate = LINK_RATE_1_62GBPS;
>> + }
>> +
>> + if (dp->link_train.lane_count == 0) {
>> + dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n",
>> + dp->link_train.lane_count);
>> + dp->link_train.lane_count = (u8)LANE_COUNT1;
>> + }
>> +
>> + /* Setup TX lane count & rate */
>> + if (dp->link_train.lane_count > max_lane)
>> + dp->link_train.lane_count = max_lane;
>> + if (dp->link_train.link_rate > max_rate)
>> + dp->link_train.link_rate = max_rate;
>> +
>> + /* All DP analog module power up */
>> + exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
>> +}
>> +
>> +static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
>> +{
>> + int retval = 0, training_finished = 0;
>> +
>> + dp->link_train.lt_state = START;
>> +
>> + /* Process here */
>> + while (!retval && !training_finished) {
>> + switch (dp->link_train.lt_state) {
>> + case START:
>> + retval = exynos_dp_link_start(dp);
>> + if (retval)
>> + dev_err(dp->dev, "LT link start failed!\n");
>> + break;
>> + case CLOCK_RECOVERY:
>> + retval = exynos_dp_process_clock_recovery(dp);
>> + if (retval)
>> + dev_err(dp->dev, "LT CR failed!\n");
>> + break;
>> + case EQUALIZER_TRAINING:
>> + retval = exynos_dp_process_equalizer_training(dp);
>> + if (retval)
>> + dev_err(dp->dev, "LT EQ failed!\n");
>> + break;
>> + case FINISHED:
>> + training_finished = 1;
>> + break;
>> + case FAILED:
>> + return -EREMOTEIO;
>> + }
>> + }
>> + if (retval)
>> + dev_err(dp->dev, "eDP link training failed (%d)\n", retval);
>> +
>> + return retval;
>> +}
>> +
>> +static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
>> + u32 count,
>> + u32 bwtype)
>> +{
>> + int i;
>> + int retval;
>> +
>> + for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
>> + exynos_dp_init_training(dp, count, bwtype);
>> + retval = exynos_dp_sw_link_training(dp);
>> + if (retval == 0)
>> + break;
>> +
>> + usleep_range(100, 110);
>> + }
>> +
>> + return retval;
>> +}
>> +
>> +static int exynos_dp_config_video(struct exynos_dp_device *dp)
>> +{
>> + int retval = 0;
>> + int timeout_loop = 0;
>> + int done_count = 0;
>> +
>> + exynos_dp_config_video_slave_mode(dp);
>> +
>> + exynos_dp_set_video_color_format(dp);
>> +
>> + if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
>> + dev_err(dp->dev, "PLL is not locked yet.\n");
>> + return -EINVAL;
>> + }
>> +
>> + for (;;) {
>> + timeout_loop++;
>> + if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0)
>> + break;
>> + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> + dev_err(dp->dev, "Timeout of video streamclk ok\n");
>> + return -ETIMEDOUT;
>> + }
>> +
>> + usleep_range(1, 2);
>> + }
>> +
>> + /* Set to use the register calculated M/N video */
>> + exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);
>> +
>> + /* For video bist, Video timing must be generated by register */
>> + exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);
>> +
>> + /* Disable video mute */
>> + exynos_dp_enable_video_mute(dp, 0);
>> +
>> + /* Configure video slave mode */
>> + exynos_dp_enable_video_master(dp, 0);
>> +
>> + /* Enable video */
>> + exynos_dp_start_video(dp);
>> +
>> + timeout_loop = 0;
>> +
>> + for (;;) {
>> + timeout_loop++;
>> + if (exynos_dp_is_video_stream_on(dp) == 0) {
>> + done_count++;
>> + if (done_count > 10)
>> + break;
>> + } else if (done_count) {
>> + done_count = 0;
>> + }
>> + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> + dev_err(dp->dev, "Timeout of video streamclk ok\n");
>> + return -ETIMEDOUT;
>> + }
>> +
>> + usleep_range(1000, 1001);
>> + }
>> +
>> + if (retval != 0)
>> + dev_err(dp->dev, "Video stream is not detected!\n");
>> +
>> + return retval;
>> +}
>> +
>> +static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool
>> enable)
>> +{
>> + u8 data;
>> +
>> + if (enable) {
>> + exynos_dp_enable_scrambling(dp);
>> +
>> + exynos_dp_read_byte_from_dpcd(dp,
>> + DPCD_ADDR_TRAINING_PATTERN_SET,
>> + &data);
>> + exynos_dp_write_byte_to_dpcd(dp,
>> + DPCD_ADDR_TRAINING_PATTERN_SET,
>> + (u8)(data & ~DPCD_SCRAMBLING_DISABLED));
>> + } else {
>> + exynos_dp_disable_scrambling(dp);
>> +
>> + exynos_dp_read_byte_from_dpcd(dp,
>> + DPCD_ADDR_TRAINING_PATTERN_SET,
>> + &data);
>> + exynos_dp_write_byte_to_dpcd(dp,
>> + DPCD_ADDR_TRAINING_PATTERN_SET,
>> + (u8)(data | DPCD_SCRAMBLING_DISABLED));
>> + }
>> +}
>> +
>> +static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
>> +{
>> + struct exynos_dp_device *dp = arg;
>> +
>> + enum dp_irq_type irq_type;
>> +
>> + irq_type = exynos_dp_get_irq_type(dp);
>> + switch (irq_type) {
>> + case DP_IRQ_TYPE_HP_CABLE_IN:
>> + dev_dbg(dp->dev, "Received irq - cable in\n");
>> + schedule_work(&dp->hotplug_work);
>> + exynos_dp_clear_hotplug_interrupts(dp);
>> + break;
>> + case DP_IRQ_TYPE_HP_CABLE_OUT:
>> + dev_dbg(dp->dev, "Received irq - cable out\n");
>> + exynos_dp_clear_hotplug_interrupts(dp);
>> + break;
>> + case DP_IRQ_TYPE_HP_CHANGE:
>> + /*
>> + * We get these change notifications once in a while, but
>> there
>> + * is nothing we can do with them. Just ignore it for now
> and
>> + * only handle cable changes.
>> + */
>> + dev_dbg(dp->dev, "Received irq - hotplug change;
>> ignoring.\n");
>> + exynos_dp_clear_hotplug_interrupts(dp);
>> + break;
>> + default:
>> + dev_err(dp->dev, "Received irq - unknown type!\n");
>> + break;
>> + }
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static void exynos_dp_hotplug(struct work_struct *work)
>> +{
>> + struct exynos_dp_device *dp;
>> + int ret;
>> +
>> + dp = container_of(work, struct exynos_dp_device, hotplug_work);
>> +
>> + ret = exynos_dp_detect_hpd(dp);
>> + if (ret) {
>> + /* Cable has been disconnected, we're done */
>> + return;
>> + }
>> +
>> + ret = exynos_dp_handle_edid(dp);
>> + if (ret) {
>> + dev_err(dp->dev, "unable to handle edid\n");
>> + return;
>> + }
>> +
>> + ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
>> + dp->video_info->link_rate);
>> + if (ret) {
>> + dev_err(dp->dev, "unable to do link train\n");
>> + return;
>> + }
>> +
>> + exynos_dp_enable_scramble(dp, 1);
>> + exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
>> + exynos_dp_enable_enhanced_mode(dp, 1);
>> +
>> + exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
>> + exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
>> +
>> + exynos_dp_init_video(dp);
>> + ret = exynos_dp_config_video(dp);
>> + if (ret)
>> + dev_err(dp->dev, "unable to config video\n");
>> +}
>> +
>> +#ifdef CONFIG_OF
>> +static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device
>> *dev)
>> +{
>> + struct device_node *dp_node = dev->of_node;
>> + struct exynos_dp_platdata *pd;
>> + struct video_info *dp_video_config;
>> +
>> + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
>> + if (!pd) {
>> + dev_err(dev, "memory allocation for pdata failed\n");
>> + return ERR_PTR(-ENOMEM);
>> + }
>> + dp_video_config = devm_kzalloc(dev,
>> + sizeof(*dp_video_config), GFP_KERNEL);
>> +
>> + if (!dp_video_config) {
>> + dev_err(dev, "memory allocation for video config failed\n");
>> + return ERR_PTR(-ENOMEM);
>> + }
>> + pd->video_info = dp_video_config;
>> +
>> + dp_video_config->h_sync_polarity =
>> + of_property_read_bool(dp_node, "hsync-active-high");
>> +
>> + dp_video_config->v_sync_polarity =
>> + of_property_read_bool(dp_node, "vsync-active-high");
>> +
>> + dp_video_config->interlaced =
>> + of_property_read_bool(dp_node, "interlaced");
>> +
>> + if (of_property_read_u32(dp_node, "samsung,color-space",
>> + &dp_video_config->color_space)) {
>> + dev_err(dev, "failed to get color-space\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (of_property_read_u32(dp_node, "samsung,dynamic-range",
>> + &dp_video_config->dynamic_range)) {
>> + dev_err(dev, "failed to get dynamic-range\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
>> + &dp_video_config->ycbcr_coeff)) {
>> + dev_err(dev, "failed to get ycbcr-coeff\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (of_property_read_u32(dp_node, "samsung,color-depth",
>> + &dp_video_config->color_depth)) {
>> + dev_err(dev, "failed to get color-depth\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (of_property_read_u32(dp_node, "samsung,link-rate",
>> + &dp_video_config->link_rate)) {
>> + dev_err(dev, "failed to get link-rate\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (of_property_read_u32(dp_node, "samsung,lane-count",
>> + &dp_video_config->lane_count)) {
>> + dev_err(dev, "failed to get lane-count\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + return pd;
>> +}
>> +
>> +static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
>> +{
>> + struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
>> + u32 phy_base;
>> + int ret = 0;
>> +
>> + dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
>> + if (!dp_phy_node) {
>> + dev_err(dp->dev, "could not find dptx-phy node\n");
>> + return -ENODEV;
>> + }
>> +
>> + if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
>> + dev_err(dp->dev, "failed to get reg for dptx-phy\n");
>> + ret = -EINVAL;
>> + goto err;
>> + }
>> +
>> + if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
>> + &dp->enable_mask)) {
>> + dev_err(dp->dev, "failed to get enable-mask for
> dptx-phy\n");
>> + ret = -EINVAL;
>> + goto err;
>> + }
>> +
>> + dp->phy_addr = ioremap(phy_base, SZ_4);
>> + if (!dp->phy_addr) {
>> + dev_err(dp->dev, "failed to ioremap dp-phy\n");
>> + ret = -ENOMEM;
>> + goto err;
>> + }
>> +
>> +err:
>> + of_node_put(dp_phy_node);
>> +
>> + return ret;
>> +}
>> +
>> +static void exynos_dp_phy_init(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = __raw_readl(dp->phy_addr);
>> + reg |= dp->enable_mask;
>> + __raw_writel(reg, dp->phy_addr);
>> +}
>> +
>> +static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = __raw_readl(dp->phy_addr);
>> + reg &= ~(dp->enable_mask);
>> + __raw_writel(reg, dp->phy_addr);
>> +}
>> +#else
>> +static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device
>> *dev)
>> +{
>> + return NULL;
>> +}
>> +
>> +static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
>> +{
>> + return -EINVAL;
>> +}
>> +
>> +static void exynos_dp_phy_init(struct exynos_dp_device *dp)
>> +{
>> + return;
>> +}
>> +
>> +static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
>> +{
>> + return;
>> +}
>> +#endif /* CONFIG_OF */
>> +
>> +static int exynos_dp_probe(struct platform_device *pdev)
>> +{
>> + struct resource *res;
>> + struct exynos_dp_device *dp;
>> + struct exynos_dp_platdata *pdata;
>> +
>> + int ret = 0;
>> +
>> + dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
>> + GFP_KERNEL);
>> + if (!dp) {
>> + dev_err(&pdev->dev, "no memory for device data\n");
>> + return -ENOMEM;
>> + }
>> +
>> + dp->dev = &pdev->dev;
>> +
>> + if (pdev->dev.of_node) {
>> + pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
>> + if (IS_ERR(pdata))
>> + return PTR_ERR(pdata);
>> +
>> + ret = exynos_dp_dt_parse_phydata(dp);
>> + if (ret)
>> + return ret;
>> + } else {
>> + pdata = pdev->dev.platform_data;
>> + if (!pdata) {
>> + dev_err(&pdev->dev, "no platform data\n");
>> + return -EINVAL;
>> + }
>> + }
>> +
>> + dp->clock = devm_clk_get(&pdev->dev, "dp");
>> + if (IS_ERR(dp->clock)) {
>> + dev_err(&pdev->dev, "failed to get clock\n");
>> + return PTR_ERR(dp->clock);
>> + }
>> +
>> + clk_prepare_enable(dp->clock);
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +
>> + dp->reg_base = devm_ioremap_resource(&pdev->dev, res);
>> + if (IS_ERR(dp->reg_base))
>> + return PTR_ERR(dp->reg_base);
>> +
>> + dp->irq = platform_get_irq(pdev, 0);
>> + if (dp->irq == -ENXIO) {
>> + dev_err(&pdev->dev, "failed to get irq\n");
>> + return -ENODEV;
>> + }
>> +
>> + INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
>> +
>> + dp->video_info = pdata->video_info;
>> +
>> + if (pdev->dev.of_node) {
>> + if (dp->phy_addr)
>> + exynos_dp_phy_init(dp);
>> + } else {
>> + if (pdata->phy_init)
>> + pdata->phy_init();
>> + }
>> +
>> + exynos_dp_init_dp(dp);
>> +
>> + ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
>> 0,
>> + "exynos-dp", dp);
>> + if (ret) {
>> + dev_err(&pdev->dev, "failed to request irq\n");
>> + return ret;
>> + }
>> +
>> + platform_set_drvdata(pdev, dp);
>> +
>> + return 0;
>> +}
>> +
>> +static int exynos_dp_remove(struct platform_device *pdev)
>> +{
>> + struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>> + struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>> +
>> + flush_work(&dp->hotplug_work);
>> +
>> + if (pdev->dev.of_node) {
>> + if (dp->phy_addr)
>> + exynos_dp_phy_exit(dp);
>> + } else {
>> + if (pdata->phy_exit)
>> + pdata->phy_exit();
>> + }
>> +
>> + clk_disable_unprepare(dp->clock);
>> +
>> +
>> + return 0;
>> +}
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int exynos_dp_suspend(struct device *dev)
>> +{
>> + struct exynos_dp_platdata *pdata = dev->platform_data;
>> + struct exynos_dp_device *dp = dev_get_drvdata(dev);
>> +
>> + disable_irq(dp->irq);
>> +
>> + flush_work(&dp->hotplug_work);
>> +
>> + if (dev->of_node) {
>> + if (dp->phy_addr)
>> + exynos_dp_phy_exit(dp);
>> + } else {
>> + if (pdata->phy_exit)
>> + pdata->phy_exit();
>> + }
>> +
>> + clk_disable_unprepare(dp->clock);
>> +
>> + return 0;
>> +}
>> +
>> +static int exynos_dp_resume(struct device *dev)
>> +{
>> + struct exynos_dp_platdata *pdata = dev->platform_data;
>> + struct exynos_dp_device *dp = dev_get_drvdata(dev);
>> +
>> + if (dev->of_node) {
>> + if (dp->phy_addr)
>> + exynos_dp_phy_init(dp);
>> + } else {
>> + if (pdata->phy_init)
>> + pdata->phy_init();
>> + }
>> +
>> + clk_prepare_enable(dp->clock);
>> +
>> + exynos_dp_init_dp(dp);
>> +
>> + enable_irq(dp->irq);
>> +
>> + return 0;
>> +}
>> +#endif
>> +
>> +static const struct dev_pm_ops exynos_dp_pm_ops = {
>> + SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
>> +};
>> +
>> +static const struct of_device_id exynos_dp_match[] = {
>> + { .compatible = "samsung,exynos5-dp" },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, exynos_dp_match);
>> +
>> +static struct platform_driver exynos_dp_driver = {
>> + .probe = exynos_dp_probe,
>> + .remove = exynos_dp_remove,
>> + .driver = {
>> + .name = "exynos-dp",
>> + .owner = THIS_MODULE,
>> + .pm = &exynos_dp_pm_ops,
>> + .of_match_table = of_match_ptr(exynos_dp_match),
>> + },
>> +};
>> +
>> +module_platform_driver(exynos_dp_driver);
>> +
>> +MODULE_AUTHOR("Jingoo Han <jg1.han at samsung.com>");
>> +MODULE_DESCRIPTION("Samsung SoC DP Driver");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h
>> b/drivers/gpu/drm/exynos/exynos_dp_core.h
>> new file mode 100644
>> index 0000000..6c567bbf
>> --- /dev/null
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
>> @@ -0,0 +1,210 @@
>> +/*
>> + * Header file for Samsung DP (Display Port) interface driver.
>> + *
>> + * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>> + * Author: Jingoo Han <jg1.han at samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> it
>> + * under the terms of the GNU General Public License as published by the
>> + * Free Software Foundation; either version 2 of the License, or (at your
>> + * option) any later version.
>> + */
>> +
>> +#ifndef _EXYNOS_DP_CORE_H
>> +#define _EXYNOS_DP_CORE_H
>> +
>> +enum dp_irq_type {
>> + DP_IRQ_TYPE_HP_CABLE_IN,
>> + DP_IRQ_TYPE_HP_CABLE_OUT,
>> + DP_IRQ_TYPE_HP_CHANGE,
>> + DP_IRQ_TYPE_UNKNOWN,
>> +};
>> +
>> +struct link_train {
>> + int eq_loop;
>> + int cr_loop[4];
>> +
>> + u8 link_rate;
>> + u8 lane_count;
>> + u8 training_lane[4];
>> +
>> + enum link_training_state lt_state;
>> +};
>> +
>> +struct exynos_dp_device {
>> + struct device *dev;
>> + struct clk *clock;
>> + unsigned int irq;
>> + void __iomem *reg_base;
>> + void __iomem *phy_addr;
>> + unsigned int enable_mask;
>> +
>> + struct video_info *video_info;
>> + struct link_train link_train;
>> + struct work_struct hotplug_work;
>> +};
>> +
>> +/* exynos_dp_reg.c */
>> +void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool
>> enable);
>> +void exynos_dp_stop_video(struct exynos_dp_device *dp);
>> +void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable);
>> +void exynos_dp_init_analog_param(struct exynos_dp_device *dp);
>> +void exynos_dp_init_interrupt(struct exynos_dp_device *dp);
>> +void exynos_dp_reset(struct exynos_dp_device *dp);
>> +void exynos_dp_swreset(struct exynos_dp_device *dp);
>> +void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
>> +enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device
>> *dp);
>> +void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool
>> enable);
>> +void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
>> + enum analog_power_block block,
>> + bool enable);
>> +void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
>> +void exynos_dp_init_hpd(struct exynos_dp_device *dp);
>> +enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
>> +void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp);
>> +void exynos_dp_reset_aux(struct exynos_dp_device *dp);
>> +void exynos_dp_init_aux(struct exynos_dp_device *dp);
>> +int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
>> +void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
>> +int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
>> +int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
>> + unsigned int reg_addr,
>> + unsigned char data);
>> +int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
>> + unsigned int reg_addr,
>> + unsigned char *data);
>> +int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
>> + unsigned int reg_addr,
>> + unsigned int count,
>> + unsigned char data[]);
>> +int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
>> + unsigned int reg_addr,
>> + unsigned int count,
>> + unsigned char data[]);
>> +int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
>> + unsigned int device_addr,
>> + unsigned int reg_addr);
>> +int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
>> + unsigned int device_addr,
>> + unsigned int reg_addr,
>> + unsigned int *data);
>> +int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
>> + unsigned int device_addr,
>> + unsigned int reg_addr,
>> + unsigned int count,
>> + unsigned char edid[]);
>> +void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32
>> bwtype);
>> +void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32
>> *bwtype);
>> +void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
>> +void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
>> +void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool
>> enable);
>> +void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
>> + enum pattern_set pattern);
>> +void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32
>> level);
>> +void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32
>> level);
>> +void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32
>> level);
>> +void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32
>> level);
>> +void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
>> + u32 training_lane);
>> +void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
>> + u32 training_lane);
>> +void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
>> + u32 training_lane);
>> +void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
>> + u32 training_lane);
>> +u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
>> +u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
>> +u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
>> +u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
>> +void exynos_dp_reset_macro(struct exynos_dp_device *dp);
>> +void exynos_dp_init_video(struct exynos_dp_device *dp);
>> +
>> +void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
>> +int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device
> *dp);
>> +void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
>> + enum clock_recovery_m_value_type type,
>> + u32 m_value,
>> + u32 n_value);
>> +void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32
>> type);
>> +void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool
>> enable);
>> +void exynos_dp_start_video(struct exynos_dp_device *dp);
>> +int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp);
>> +void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp);
>> +void exynos_dp_enable_scrambling(struct exynos_dp_device *dp);
>> +void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
>> +
>> +/* I2C EDID Chip ID, Slave Address */
>> +#define I2C_EDID_DEVICE_ADDR 0x50
>> +#define I2C_E_EDID_DEVICE_ADDR 0x30
>> +
>> +#define EDID_BLOCK_LENGTH 0x80
>> +#define EDID_HEADER_PATTERN 0x00
>> +#define EDID_EXTENSION_FLAG 0x7e
>> +#define EDID_CHECKSUM 0x7f
>> +
>> +/* Definition for DPCD Register */
>> +#define DPCD_ADDR_DPCD_REV 0x0000
>> +#define DPCD_ADDR_MAX_LINK_RATE 0x0001
>> +#define DPCD_ADDR_MAX_LANE_COUNT 0x0002
>> +#define DPCD_ADDR_LINK_BW_SET 0x0100
>> +#define DPCD_ADDR_LANE_COUNT_SET 0x0101
>> +#define DPCD_ADDR_TRAINING_PATTERN_SET 0x0102
>> +#define DPCD_ADDR_TRAINING_LANE0_SET 0x0103
>> +#define DPCD_ADDR_LANE0_1_STATUS 0x0202
>> +#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x0204
>> +#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x0206
>> +#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x0207
>> +#define DPCD_ADDR_TEST_REQUEST 0x0218
>> +#define DPCD_ADDR_TEST_RESPONSE 0x0260
>> +#define DPCD_ADDR_TEST_EDID_CHECKSUM 0x0261
>> +#define DPCD_ADDR_SINK_POWER_STATE 0x0600
>> +
>> +/* DPCD_ADDR_MAX_LANE_COUNT */
>> +#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
>> +#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
>> +
>> +/* DPCD_ADDR_LANE_COUNT_SET */
>> +#define DPCD_ENHANCED_FRAME_EN (0x1 << 7)
>> +#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
>> +
>> +/* DPCD_ADDR_TRAINING_PATTERN_SET */
>> +#define DPCD_SCRAMBLING_DISABLED (0x1 << 5)
>> +#define DPCD_SCRAMBLING_ENABLED (0x0 << 5)
>> +#define DPCD_TRAINING_PATTERN_2 (0x2 << 0)
>> +#define DPCD_TRAINING_PATTERN_1 (0x1 << 0)
>> +#define DPCD_TRAINING_PATTERN_DISABLED (0x0 << 0)
>> +
>> +/* DPCD_ADDR_TRAINING_LANE0_SET */
>> +#define DPCD_MAX_PRE_EMPHASIS_REACHED (0x1 << 5)
>> +#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
>> +#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
>> +#define DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 (0x0 << 3)
>> +#define DPCD_MAX_SWING_REACHED (0x1 << 2)
>> +#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
>> +#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
>> +#define DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0 (0x0 << 0)
>> +
>> +/* DPCD_ADDR_LANE0_1_STATUS */
>> +#define DPCD_LANE_SYMBOL_LOCKED (0x1 << 2)
>> +#define DPCD_LANE_CHANNEL_EQ_DONE (0x1 << 1)
>> +#define DPCD_LANE_CR_DONE (0x1 << 0)
>> +#define DPCD_CHANNEL_EQ_BITS (DPCD_LANE_CR_DONE| \
>> + DPCD_LANE_CHANNEL_EQ_DONE|\
>> + DPCD_LANE_SYMBOL_LOCKED)
>> +
>> +/* DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED */
>> +#define DPCD_LINK_STATUS_UPDATED (0x1 << 7)
>> +#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED (0x1 << 6)
>> +#define DPCD_INTERLANE_ALIGN_DONE (0x1 << 0)
>> +
>> +/* DPCD_ADDR_TEST_REQUEST */
>> +#define DPCD_TEST_EDID_READ (0x1 << 2)
>> +
>> +/* DPCD_ADDR_TEST_RESPONSE */
>> +#define DPCD_TEST_EDID_CHECKSUM_WRITE (0x1 << 2)
>> +
>> +/* DPCD_ADDR_SINK_POWER_STATE */
>> +#define DPCD_SET_POWER_STATE_D0 (0x1 << 0)
>> +#define DPCD_SET_POWER_STATE_D4 (0x2 << 0)
>> +
>> +#endif /* _EXYNOS_DP_CORE_H */
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c
>> b/drivers/gpu/drm/exynos/exynos_dp_reg.c
>> new file mode 100644
>> index 0000000..29d9d03
>> --- /dev/null
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_reg.c
>> @@ -0,0 +1,1245 @@
>> +/*
>> + * Samsung DP (Display port) register interface driver.
>> + *
>> + * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>> + * Author: Jingoo Han <jg1.han at samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> it
>> + * under the terms of the GNU General Public License as published by the
>> + * Free Software Foundation; either version 2 of the License, or (at your
>> + * option) any later version.
>> + */
>> +
>> +#include <linux/device.h>
>> +#include <linux/io.h>
>> +#include <linux/delay.h>
>> +
>> +#include <video/exynos_dp.h>
>> +
>> +#include "exynos_dp_core.h"
>> +#include "exynos_dp_reg.h"
>> +
>> +#define COMMON_INT_MASK_1 0
>> +#define COMMON_INT_MASK_2 0
>> +#define COMMON_INT_MASK_3 0
>> +#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
>> +#define INT_STA_MASK INT_HPD
>> +
>> +void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool
> enable)
>> +{
>> + u32 reg;
>> +
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> + reg |= HDCP_VIDEO_MUTE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> + reg &= ~HDCP_VIDEO_MUTE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> + }
>> +}
>> +
>> +void exynos_dp_stop_video(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> + reg &= ~VIDEO_EN;
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> +}
>> +
>> +void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable)
>> +{
>> + u32 reg;
>> +
>> + if (enable)
>> + reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
>> + LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
>> + else
>> + reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
>> + LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
>> +
>> + writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP);
>> +}
>> +
>> +void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = TX_TERMINAL_CTRL_50_OHM;
>> + writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1);
>> +
>> + reg = SEL_24M | TX_DVDD_BIT_1_0625V;
>> + writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2);
>> +
>> + reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
>> + writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
>> +
>> + reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
>> + TX_CUR1_2X | TX_CUR_16_MA;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
>> +
>> + reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
>> + CH1_AMP_400_MV | CH0_AMP_400_MV;
>> + writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL);
>> +}
>> +
>> +void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
>> +{
>> + /* Set interrupt pin assertion polarity as high */
>> + writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
>> +
>> + /* Clear pending regisers */
>> + writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
>> + writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2);
>> + writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3);
>> + writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
>> + writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA);
>> +
>> + /* 0:mask,1: unmask */
>> + writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
>> + writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
>> + writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
>> + writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
>> + writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
>> +}
>> +
>> +void exynos_dp_reset(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + exynos_dp_stop_video(dp);
>> + exynos_dp_enable_video_mute(dp, 0);
>> +
>> + reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
>> + AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
>> + HDCP_FUNC_EN_N | SW_FUNC_EN_N;
>> + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> +
>> + reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
>> + SERDES_FIFO_FUNC_EN_N |
>> + LS_CLK_DOMAIN_FUNC_EN_N;
>> + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> +
>> + usleep_range(20, 30);
>> +
>> + exynos_dp_lane_swap(dp, 0);
>> +
>> + writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> + writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> + writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> + writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> +
>> + writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL);
>> + writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL);
>> +
>> + writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L);
>> + writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H);
>> +
>> + writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL);
>> +
>> + writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST);
>> +
>> + writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD);
>> + writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN);
>> +
>> + writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH);
>> + writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
>> +
>> + writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> +}
>> +
>> +void exynos_dp_swreset(struct exynos_dp_device *dp)
>> +{
>> + writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET);
>> +}
>> +
>> +void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + /* 0: mask, 1: unmask */
>> + reg = COMMON_INT_MASK_1;
>> + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
>> +
>> + reg = COMMON_INT_MASK_2;
>> + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
>> +
>> + reg = COMMON_INT_MASK_3;
>> + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
>> +
>> + reg = COMMON_INT_MASK_4;
>> + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
>> +
>> + reg = INT_STA_MASK;
>> + writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
>> +}
>> +
>> +enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device
> *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
>> + if (reg & PLL_LOCK)
>> + return PLL_LOCKED;
>> + else
>> + return PLL_UNLOCKED;
>> +}
>> +
>> +void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool
>> enable)
>> +{
>> + u32 reg;
>> +
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
>> + reg |= DP_PLL_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
>> + reg &= ~DP_PLL_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
>> + }
>> +}
>> +
>> +void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
>> + enum analog_power_block block,
>> + bool enable)
>> +{
>> + u32 reg;
>> +
>> + switch (block) {
>> + case AUX_BLOCK:
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg |= AUX_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg &= ~AUX_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + }
>> + break;
>> + case CH0_BLOCK:
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg |= CH0_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg &= ~CH0_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + }
>> + break;
>> + case CH1_BLOCK:
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg |= CH1_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg &= ~CH1_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + }
>> + break;
>> + case CH2_BLOCK:
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg |= CH2_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg &= ~CH2_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + }
>> + break;
>> + case CH3_BLOCK:
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg |= CH3_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg &= ~CH3_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + }
>> + break;
>> + case ANALOG_TOTAL:
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg |= DP_PHY_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> + reg &= ~DP_PHY_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + }
>> + break;
>> + case POWER_ALL:
>> + if (enable) {
>> + reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
>> + CH1_PD | CH0_PD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + } else {
>> + writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD);
>> + }
>> + break;
>> + default:
>> + break;
>> + }
>> +}
>> +
>> +void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> + int timeout_loop = 0;
>> +
>> + exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
>> +
>> + reg = PLL_LOCK_CHG;
>> + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
>> + reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
>> + writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL);
>> +
>> + /* Power up PLL */
>> + if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
>> + exynos_dp_set_pll_power_down(dp, 0);
>> +
>> + while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
>> + timeout_loop++;
>> + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> + dev_err(dp->dev, "failed to get pll lock
>> status\n");
>> + return;
>> + }
>> + usleep_range(10, 20);
>> + }
>> + }
>> +
>> + /* Enable Serdes FIFO function and Link symbol clock domain module
>> */
>> + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> + reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
>> + | AUX_FUNC_EN_N);
>> + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> +}
>> +
>> +void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = HOTPLUG_CHG | HPD_LOST | PLUG;
>> + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
>> +
>> + reg = INT_HPD;
>> + writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
>> +}
>> +
>> +void exynos_dp_init_hpd(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + exynos_dp_clear_hotplug_interrupts(dp);
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> + reg &= ~(F_HPD | HPD_CTRL);
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> +}
>> +
>> +enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + /* Parse hotplug interrupt status register */
>> + reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
>> +
>> + if (reg & PLUG)
>> + return DP_IRQ_TYPE_HP_CABLE_IN;
>> +
>> + if (reg & HPD_LOST)
>> + return DP_IRQ_TYPE_HP_CABLE_OUT;
>> +
>> + if (reg & HOTPLUG_CHG)
>> + return DP_IRQ_TYPE_HP_CHANGE;
>> +
>> + return DP_IRQ_TYPE_UNKNOWN;
>> +}
>> +
>> +void exynos_dp_reset_aux(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + /* Disable AUX channel module */
>> + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> + reg |= AUX_FUNC_EN_N;
>> + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> +}
>> +
>> +void exynos_dp_init_aux(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + /* Clear inerrupts related to AUX channel */
>> + reg = RPLY_RECEIV | AUX_ERR;
>> + writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
>> +
>> + exynos_dp_reset_aux(dp);
>> +
>> + /* Disable AUX transaction H/W retry */
>> + reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
>> + AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL) ;
>> +
>> + /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
>> + reg = DEFER_CTRL_EN | DEFER_COUNT(1);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL);
>> +
>> + /* Enable AUX channel module */
>> + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> + reg &= ~AUX_FUNC_EN_N;
>> + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> +}
>> +
>> +int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> + if (reg & HPD_STATUS)
>> + return 0;
>> +
>> + return -EINVAL;
>> +}
>> +
>> +void exynos_dp_enable_sw_function(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> + reg &= ~SW_FUNC_EN_N;
>> + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> +}
>> +
>> +int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
>> +{
>> + int reg;
>> + int retval = 0;
>> + int timeout_loop = 0;
>> +
>> + /* Enable AUX CH operation */
>> + reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
>> + reg |= AUX_EN;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
>> +
>> + /* Is AUX CH command reply received? */
>> + reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
>> + while (!(reg & RPLY_RECEIV)) {
>> + timeout_loop++;
>> + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> + dev_err(dp->dev, "AUX CH command reply failed!\n");
>> + return -ETIMEDOUT;
>> + }
>> + reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
>> + usleep_range(10, 11);
>> + }
>> +
>> + /* Clear interrupt source for AUX CH command reply */
>> + writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
>> +
>> + /* Clear interrupt source for AUX CH access error */
>> + reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
>> + if (reg & AUX_ERR) {
>> + writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA);
>> + return -EREMOTEIO;
>> + }
>> +
>> + /* Check AUX CH error access status */
>> + reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA);
>> + if ((reg & AUX_STATUS_MASK) != 0) {
>> + dev_err(dp->dev, "AUX CH error happens: %d\n\n",
>> + reg & AUX_STATUS_MASK);
>> + return -EREMOTEIO;
>> + }
>> +
>> + return retval;
>> +}
>> +
>> +int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
>> + unsigned int reg_addr,
>> + unsigned char data)
>> +{
>> + u32 reg;
>> + int i;
>> + int retval;
>> +
>> + for (i = 0; i < 3; i++) {
>> + /* Clear AUX CH data buffer */
>> + reg = BUF_CLR;
>> + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> +
>> + /* Select DPCD device address */
>> + reg = AUX_ADDR_7_0(reg_addr);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> + reg = AUX_ADDR_15_8(reg_addr);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> + reg = AUX_ADDR_19_16(reg_addr);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
>> +
>> + /* Write data buffer */
>> + reg = (unsigned int)data;
>> + writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
>> +
>> + /*
>> + * Set DisplayPort transaction and write 1 byte
>> + * If bit 3 is 1, DisplayPort transaction.
>> + * If Bit 3 is 0, I2C transaction.
>> + */
>> + reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> +
>> + /* Start AUX transaction */
>> + retval = exynos_dp_start_aux_transaction(dp);
>> + if (retval == 0)
>> + break;
>> + else
>> + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
>> + __func__);
>> + }
>> +
>> + return retval;
>> +}
>> +
>> +int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
>> + unsigned int reg_addr,
>> + unsigned char *data)
>> +{
>> + u32 reg;
>> + int i;
>> + int retval;
>> +
>> + for (i = 0; i < 3; i++) {
>> + /* Clear AUX CH data buffer */
>> + reg = BUF_CLR;
>> + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> +
>> + /* Select DPCD device address */
>> + reg = AUX_ADDR_7_0(reg_addr);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> + reg = AUX_ADDR_15_8(reg_addr);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> + reg = AUX_ADDR_19_16(reg_addr);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
>> +
>> + /*
>> + * Set DisplayPort transaction and read 1 byte
>> + * If bit 3 is 1, DisplayPort transaction.
>> + * If Bit 3 is 0, I2C transaction.
>> + */
>> + reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> +
>> + /* Start AUX transaction */
>> + retval = exynos_dp_start_aux_transaction(dp);
>> + if (retval == 0)
>> + break;
>> + else
>> + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
>> + __func__);
>> + }
>> +
>> + /* Read data buffer */
>> + reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
>> + *data = (unsigned char)(reg & 0xff);
>> +
>> + return retval;
>> +}
>> +
>> +int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
>> + unsigned int reg_addr,
>> + unsigned int count,
>> + unsigned char data[])
>> +{
>> + u32 reg;
>> + unsigned int start_offset;
>> + unsigned int cur_data_count;
>> + unsigned int cur_data_idx;
>> + int i;
>> + int retval = 0;
>> +
>> + /* Clear AUX CH data buffer */
>> + reg = BUF_CLR;
>> + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> +
>> + start_offset = 0;
>> + while (start_offset < count) {
>> + /* Buffer size of AUX CH is 16 * 4bytes */
>> + if ((count - start_offset) > 16)
>> + cur_data_count = 16;
>> + else
>> + cur_data_count = count - start_offset;
>> +
>> + for (i = 0; i < 3; i++) {
>> + /* Select DPCD device address */
>> + reg = AUX_ADDR_7_0(reg_addr + start_offset);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> + reg = AUX_ADDR_15_8(reg_addr + start_offset);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> + reg = AUX_ADDR_19_16(reg_addr + start_offset);
>> + writel(reg, dp->reg_base +
> EXYNOS_DP_AUX_ADDR_19_16);
>> +
>> + for (cur_data_idx = 0; cur_data_idx <
> cur_data_count;
>> + cur_data_idx++) {
>> + reg = data[start_offset + cur_data_idx];
>> + writel(reg, dp->reg_base +
> EXYNOS_DP_BUF_DATA_0
>> + + 4 *
> cur_data_idx);
>> + }
>> +
>> + /*
>> + * Set DisplayPort transaction and write
>> + * If bit 3 is 1, DisplayPort transaction.
>> + * If Bit 3 is 0, I2C transaction.
>> + */
>> + reg = AUX_LENGTH(cur_data_count) |
>> + AUX_TX_COMM_DP_TRANSACTION |
> AUX_TX_COMM_WRITE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> +
>> + /* Start AUX transaction */
>> + retval = exynos_dp_start_aux_transaction(dp);
>> + if (retval == 0)
>> + break;
>> + else
>> + dev_dbg(dp->dev, "%s: Aux Transaction
> fail!\n",
>> + __func__);
>> + }
>> +
>> + start_offset += cur_data_count;
>> + }
>> +
>> + return retval;
>> +}
>> +
>> +int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
>> + unsigned int reg_addr,
>> + unsigned int count,
>> + unsigned char data[])
>> +{
>> + u32 reg;
>> + unsigned int start_offset;
>> + unsigned int cur_data_count;
>> + unsigned int cur_data_idx;
>> + int i;
>> + int retval = 0;
>> +
>> + /* Clear AUX CH data buffer */
>> + reg = BUF_CLR;
>> + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> +
>> + start_offset = 0;
>> + while (start_offset < count) {
>> + /* Buffer size of AUX CH is 16 * 4bytes */
>> + if ((count - start_offset) > 16)
>> + cur_data_count = 16;
>> + else
>> + cur_data_count = count - start_offset;
>> +
>> + /* AUX CH Request Transaction process */
>> + for (i = 0; i < 3; i++) {
>> + /* Select DPCD device address */
>> + reg = AUX_ADDR_7_0(reg_addr + start_offset);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> + reg = AUX_ADDR_15_8(reg_addr + start_offset);
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> + reg = AUX_ADDR_19_16(reg_addr + start_offset);
>> + writel(reg, dp->reg_base +
> EXYNOS_DP_AUX_ADDR_19_16);
>> +
>> + /*
>> + * Set DisplayPort transaction and read
>> + * If bit 3 is 1, DisplayPort transaction.
>> + * If Bit 3 is 0, I2C transaction.
>> + */
>> + reg = AUX_LENGTH(cur_data_count) |
>> + AUX_TX_COMM_DP_TRANSACTION |
> AUX_TX_COMM_READ;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> +
>> + /* Start AUX transaction */
>> + retval = exynos_dp_start_aux_transaction(dp);
>> + if (retval == 0)
>> + break;
>> + else
>> + dev_dbg(dp->dev, "%s: Aux Transaction
> fail!\n",
>> + __func__);
>> + }
>> +
>> + for (cur_data_idx = 0; cur_data_idx < cur_data_count;
>> + cur_data_idx++) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
>> + + 4 * cur_data_idx);
>> + data[start_offset + cur_data_idx] =
>> + (unsigned char)reg;
>> + }
>> +
>> + start_offset += cur_data_count;
>> + }
>> +
>> + return retval;
>> +}
>> +
>> +int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
>> + unsigned int device_addr,
>> + unsigned int reg_addr)
>> +{
>> + u32 reg;
>> + int retval;
>> +
>> + /* Set EDID device address */
>> + reg = device_addr;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> + writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> + writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
>> +
>> + /* Set offset from base address of EDID device */
>> + writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
>> +
>> + /*
>> + * Set I2C transaction and write address
>> + * If bit 3 is 1, DisplayPort transaction.
>> + * If Bit 3 is 0, I2C transaction.
>> + */
>> + reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
>> + AUX_TX_COMM_WRITE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> +
>> + /* Start AUX transaction */
>> + retval = exynos_dp_start_aux_transaction(dp);
>> + if (retval != 0)
>> + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
>> +
>> + return retval;
>> +}
>> +
>> +int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
>> + unsigned int device_addr,
>> + unsigned int reg_addr,
>> + unsigned int *data)
>> +{
>> + u32 reg;
>> + int i;
>> + int retval;
>> +
>> + for (i = 0; i < 3; i++) {
>> + /* Clear AUX CH data buffer */
>> + reg = BUF_CLR;
>> + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> +
>> + /* Select EDID device */
>> + retval = exynos_dp_select_i2c_device(dp, device_addr,
>> reg_addr);
>> + if (retval != 0)
>> + continue;
>> +
>> + /*
>> + * Set I2C transaction and read data
>> + * If bit 3 is 1, DisplayPort transaction.
>> + * If Bit 3 is 0, I2C transaction.
>> + */
>> + reg = AUX_TX_COMM_I2C_TRANSACTION |
>> + AUX_TX_COMM_READ;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> +
>> + /* Start AUX transaction */
>> + retval = exynos_dp_start_aux_transaction(dp);
>> + if (retval == 0)
>> + break;
>> + else
>> + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
>> + __func__);
>> + }
>> +
>> + /* Read data */
>> + if (retval == 0)
>> + *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
>> +
>> + return retval;
>> +}
>> +
>> +int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
>> + unsigned int device_addr,
>> + unsigned int reg_addr,
>> + unsigned int count,
>> + unsigned char edid[])
>> +{
>> + u32 reg;
>> + unsigned int i, j;
>> + unsigned int cur_data_idx;
>> + unsigned int defer = 0;
>> + int retval = 0;
>> +
>> + for (i = 0; i < count; i += 16) {
>> + for (j = 0; j < 3; j++) {
>> + /* Clear AUX CH data buffer */
>> + reg = BUF_CLR;
>> + writel(reg, dp->reg_base +
> EXYNOS_DP_BUFFER_DATA_CTL);
>> +
>> + /* Set normal AUX CH command */
>> + reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
>> + reg &= ~ADDR_ONLY;
>> + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
>> +
>> + /*
>> + * If Rx sends defer, Tx sends only reads
>> + * request without sending address
>> + */
>> + if (!defer)
>> + retval = exynos_dp_select_i2c_device(dp,
>> + device_addr, reg_addr + i);
>> + else
>> + defer = 0;
>> +
>> + if (retval == 0) {
>> + /*
>> + * Set I2C transaction and write data
>> + * If bit 3 is 1, DisplayPort transaction.
>> + * If Bit 3 is 0, I2C transaction.
>> + */
>> + reg = AUX_LENGTH(16) |
>> + AUX_TX_COMM_I2C_TRANSACTION |
>> + AUX_TX_COMM_READ;
>> + writel(reg, dp->reg_base +
>> + EXYNOS_DP_AUX_CH_CTL_1);
>> +
>> + /* Start AUX transaction */
>> + retval =
> exynos_dp_start_aux_transaction(dp);
>> + if (retval == 0)
>> + break;
>> + else
>> + dev_dbg(dp->dev,
>> + "%s: Aux Transaction
> fail!\n",
>> + __func__);
>> + }
>> + /* Check if Rx sends defer */
>> + reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
>> + if (reg == AUX_RX_COMM_AUX_DEFER ||
>> + reg == AUX_RX_COMM_I2C_DEFER) {
>> + dev_err(dp->dev, "Defer: %d\n\n", reg);
>> + defer = 1;
>> + }
>> + }
>> +
>> + for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
>> + + 4 * cur_data_idx);
>> + edid[i + cur_data_idx] = (unsigned char)reg;
>> + }
>> + }
>> +
>> + return retval;
>> +}
>> +
>> +void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32
> bwtype)
>> +{
>> + u32 reg;
>> +
>> + reg = bwtype;
>> + if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype ==
>> LINK_RATE_1_62GBPS))
>> + writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET);
>> +}
>> +
>> +void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32
>> *bwtype)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET);
>> + *bwtype = reg;
>> +}
>> +
>> +void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count)
>> +{
>> + u32 reg;
>> +
>> + reg = count;
>> + writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
>> +}
>> +
>> +void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
>> + *count = reg;
>> +}
>> +
>> +void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool
>> enable)
>> +{
>> + u32 reg;
>> +
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> + reg |= ENHANCED;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> + reg &= ~ENHANCED;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> + }
>> +}
>> +
>> +void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
>> + enum pattern_set pattern)
>> +{
>> + u32 reg;
>> +
>> + switch (pattern) {
>> + case PRBS7:
>> + reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
>> + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> + break;
>> + case D10_2:
>> + reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
>> + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> + break;
>> + case TRAINING_PTN1:
>> + reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
>> + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> + break;
>> + case TRAINING_PTN2:
>> + reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
>> + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> + break;
>> + case DP_NONE:
>> + reg = SCRAMBLING_ENABLE |
>> + LINK_QUAL_PATTERN_SET_DISABLE |
>> + SW_TRAINING_PATTERN_SET_NORMAL;
>> + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> + break;
>> + default:
>> + break;
>> + }
>> +}
>> +
>> +void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32
>> level)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
>> + reg &= ~PRE_EMPHASIS_SET_MASK;
>> + reg |= level << PRE_EMPHASIS_SET_SHIFT;
>> + writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
>> +}
>> +
>> +void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32
>> level)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
>> + reg &= ~PRE_EMPHASIS_SET_MASK;
>> + reg |= level << PRE_EMPHASIS_SET_SHIFT;
>> + writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
>> +}
>> +
>> +void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32
>> level)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
>> + reg &= ~PRE_EMPHASIS_SET_MASK;
>> + reg |= level << PRE_EMPHASIS_SET_SHIFT;
>> + writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
>> +}
>> +
>> +void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32
>> level)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
>> + reg &= ~PRE_EMPHASIS_SET_MASK;
>> + reg |= level << PRE_EMPHASIS_SET_SHIFT;
>> + writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
>> +}
>> +
>> +void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
>> + u32 training_lane)
>> +{
>> + u32 reg;
>> +
>> + reg = training_lane;
>> + writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
>> +}
>> +
>> +void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
>> + u32 training_lane)
>> +{
>> + u32 reg;
>> +
>> + reg = training_lane;
>> + writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
>> +}
>> +
>> +void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
>> + u32 training_lane)
>> +{
>> + u32 reg;
>> +
>> + reg = training_lane;
>> + writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
>> +}
>> +
>> +void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
>> + u32 training_lane)
>> +{
>> + u32 reg;
>> +
>> + reg = training_lane;
>> + writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
>> +}
>> +
>> +u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
>> + return reg;
>> +}
>> +
>> +u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
>> + return reg;
>> +}
>> +
>> +u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
>> + return reg;
>> +}
>> +
>> +u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
>> + return reg;
>> +}
>> +
>> +void exynos_dp_reset_macro(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST);
>> + reg |= MACRO_RST;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
>> +
>> + /* 10 us is the minimum reset time. */
>> + usleep_range(10, 20);
>> +
>> + reg &= ~MACRO_RST;
>> + writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
>> +}
>> +
>> +void exynos_dp_init_video(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
>> + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
>> +
>> + reg = 0x0;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> +
>> + reg = CHA_CRI(4) | CHA_CTRL;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> +
>> + reg = 0x0;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> +
>> + reg = VID_HRES_TH(2) | VID_VRES_TH(0);
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
>> +}
>> +
>> +void exynos_dp_set_video_color_format(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + /* Configure the input color depth, color space, dynamic range */
>> + reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
>> + (dp->video_info->color_depth << IN_BPC_SHIFT) |
>> + (dp->video_info->color_space << IN_COLOR_F_SHIFT);
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
>> +
>> + /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
>> + reg &= ~IN_YC_COEFFI_MASK;
>> + if (dp->video_info->ycbcr_coeff)
>> + reg |= IN_YC_COEFFI_ITU709;
>> + else
>> + reg |= IN_YC_COEFFI_ITU601;
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
>> +}
>> +
>> +int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> +
>> + if (!(reg & DET_STA)) {
>> + dev_dbg(dp->dev, "Input stream clock not detected.\n");
>> + return -EINVAL;
>> + }
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> + dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
>> +
>> + if (reg & CHA_STA) {
>> + dev_dbg(dp->dev, "Input stream clk is changing\n");
>> + return -EINVAL;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
>> + enum clock_recovery_m_value_type type,
>> + u32 m_value,
>> + u32 n_value)
>> +{
>> + u32 reg;
>> +
>> + if (type == REGISTER_M) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> + reg |= FIX_M_VID;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> + reg = m_value & 0xff;
>> + writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0);
>> + reg = (m_value >> 8) & 0xff;
>> + writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1);
>> + reg = (m_value >> 16) & 0xff;
>> + writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2);
>> +
>> + reg = n_value & 0xff;
>> + writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0);
>> + reg = (n_value >> 8) & 0xff;
>> + writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1);
>> + reg = (n_value >> 16) & 0xff;
>> + writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> + reg &= ~FIX_M_VID;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> +
>> + writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0);
>> + writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1);
>> + writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2);
>> + }
>> +}
>> +
>> +void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32
>> type)
>> +{
>> + u32 reg;
>> +
>> + if (type == VIDEO_TIMING_FROM_CAPTURE) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> + reg &= ~FORMAT_SEL;
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> + reg |= FORMAT_SEL;
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> + }
>> +}
>> +
>> +void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool
>> enable)
>> +{
>> + u32 reg;
>> +
>> + if (enable) {
>> + reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> + reg &= ~VIDEO_MODE_MASK;
>> + reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> + } else {
>> + reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> + reg &= ~VIDEO_MODE_MASK;
>> + reg |= VIDEO_MODE_SLAVE_MODE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> + }
>> +}
>> +
>> +void exynos_dp_start_video(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> + reg |= VIDEO_EN;
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> +}
>> +
>> +int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> + if (!(reg & STRM_VALID)) {
>> + dev_dbg(dp->dev, "Input video stream is not detected.\n");
>> + return -EINVAL;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> + reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
>> + reg |= MASTER_VID_FUNC_EN_N;
>> + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> + reg &= ~INTERACE_SCAN_CFG;
>> + reg |= (dp->video_info->interlaced << 2);
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> + reg &= ~VSYNC_POLARITY_CFG;
>> + reg |= (dp->video_info->v_sync_polarity << 1);
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> + reg &= ~HSYNC_POLARITY_CFG;
>> + reg |= (dp->video_info->h_sync_polarity << 0);
>> + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> +
>> + reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> +}
>> +
>> +void exynos_dp_enable_scrambling(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> + reg &= ~SCRAMBLING_DISABLE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> +}
>> +
>> +void exynos_dp_disable_scrambling(struct exynos_dp_device *dp)
>> +{
>> + u32 reg;
>> +
>> + reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> + reg |= SCRAMBLING_DISABLE;
>> + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> +}
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.h
>> b/drivers/gpu/drm/exynos/exynos_dp_reg.h
>> new file mode 100644
>> index 0000000..2e9bd0e
>> --- /dev/null
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_reg.h
>> @@ -0,0 +1,366 @@
>> +/*
>> + * Register definition file for Samsung DP driver
>> + *
>> + * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>> + * Author: Jingoo Han <jg1.han at samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#ifndef _EXYNOS_DP_REG_H
>> +#define _EXYNOS_DP_REG_H
>> +
>> +#define EXYNOS_DP_TX_SW_RESET 0x14
>> +#define EXYNOS_DP_FUNC_EN_1 0x18
>> +#define EXYNOS_DP_FUNC_EN_2 0x1C
>> +#define EXYNOS_DP_VIDEO_CTL_1 0x20
>> +#define EXYNOS_DP_VIDEO_CTL_2 0x24
>> +#define EXYNOS_DP_VIDEO_CTL_3 0x28
>> +
>> +#define EXYNOS_DP_VIDEO_CTL_8 0x3C
>> +#define EXYNOS_DP_VIDEO_CTL_10 0x44
>> +
>> +#define EXYNOS_DP_LANE_MAP 0x35C
>> +
>> +#define EXYNOS_DP_ANALOG_CTL_1 0x370
>> +#define EXYNOS_DP_ANALOG_CTL_2 0x374
>> +#define EXYNOS_DP_ANALOG_CTL_3 0x378
>> +#define EXYNOS_DP_PLL_FILTER_CTL_1 0x37C
>> +#define EXYNOS_DP_TX_AMP_TUNING_CTL 0x380
>> +
>> +#define EXYNOS_DP_AUX_HW_RETRY_CTL 0x390
>> +
>> +#define EXYNOS_DP_COMMON_INT_STA_1 0x3C4
>> +#define EXYNOS_DP_COMMON_INT_STA_2 0x3C8
>> +#define EXYNOS_DP_COMMON_INT_STA_3 0x3CC
>> +#define EXYNOS_DP_COMMON_INT_STA_4 0x3D0
>> +#define EXYNOS_DP_INT_STA 0x3DC
>> +#define EXYNOS_DP_COMMON_INT_MASK_1 0x3E0
>> +#define EXYNOS_DP_COMMON_INT_MASK_2 0x3E4
>> +#define EXYNOS_DP_COMMON_INT_MASK_3 0x3E8
>> +#define EXYNOS_DP_COMMON_INT_MASK_4 0x3EC
>> +#define EXYNOS_DP_INT_STA_MASK 0x3F8
>> +#define EXYNOS_DP_INT_CTL 0x3FC
>> +
>> +#define EXYNOS_DP_SYS_CTL_1 0x600
>> +#define EXYNOS_DP_SYS_CTL_2 0x604
>> +#define EXYNOS_DP_SYS_CTL_3 0x608
>> +#define EXYNOS_DP_SYS_CTL_4 0x60C
>> +
>> +#define EXYNOS_DP_PKT_SEND_CTL 0x640
>> +#define EXYNOS_DP_HDCP_CTL 0x648
>> +
>> +#define EXYNOS_DP_LINK_BW_SET 0x680
>> +#define EXYNOS_DP_LANE_COUNT_SET 0x684
>> +#define EXYNOS_DP_TRAINING_PTN_SET 0x688
>> +#define EXYNOS_DP_LN0_LINK_TRAINING_CTL 0x68C
>> +#define EXYNOS_DP_LN1_LINK_TRAINING_CTL 0x690
>> +#define EXYNOS_DP_LN2_LINK_TRAINING_CTL 0x694
>> +#define EXYNOS_DP_LN3_LINK_TRAINING_CTL 0x698
>> +
>> +#define EXYNOS_DP_DEBUG_CTL 0x6C0
>> +#define EXYNOS_DP_HPD_DEGLITCH_L 0x6C4
>> +#define EXYNOS_DP_HPD_DEGLITCH_H 0x6C8
>> +#define EXYNOS_DP_LINK_DEBUG_CTL 0x6E0
>> +
>> +#define EXYNOS_DP_M_VID_0 0x700
>> +#define EXYNOS_DP_M_VID_1 0x704
>> +#define EXYNOS_DP_M_VID_2 0x708
>> +#define EXYNOS_DP_N_VID_0 0x70C
>> +#define EXYNOS_DP_N_VID_1 0x710
>> +#define EXYNOS_DP_N_VID_2 0x714
>> +
>> +#define EXYNOS_DP_PLL_CTL 0x71C
>> +#define EXYNOS_DP_PHY_PD 0x720
>> +#define EXYNOS_DP_PHY_TEST 0x724
>> +
>> +#define EXYNOS_DP_VIDEO_FIFO_THRD 0x730
>> +#define EXYNOS_DP_AUDIO_MARGIN 0x73C
>> +
>> +#define EXYNOS_DP_M_VID_GEN_FILTER_TH 0x764
>> +#define EXYNOS_DP_M_AUD_GEN_FILTER_TH 0x778
>> +#define EXYNOS_DP_AUX_CH_STA 0x780
>> +#define EXYNOS_DP_AUX_CH_DEFER_CTL 0x788
>> +#define EXYNOS_DP_AUX_RX_COMM 0x78C
>> +#define EXYNOS_DP_BUFFER_DATA_CTL 0x790
>> +#define EXYNOS_DP_AUX_CH_CTL_1 0x794
>> +#define EXYNOS_DP_AUX_ADDR_7_0 0x798
>> +#define EXYNOS_DP_AUX_ADDR_15_8 0x79C
>> +#define EXYNOS_DP_AUX_ADDR_19_16 0x7A0
>> +#define EXYNOS_DP_AUX_CH_CTL_2 0x7A4
>> +
>> +#define EXYNOS_DP_BUF_DATA_0 0x7C0
>> +
>> +#define EXYNOS_DP_SOC_GENERAL_CTL 0x800
>> +
>> +/* EXYNOS_DP_TX_SW_RESET */
>> +#define RESET_DP_TX (0x1 << 0)
>> +
>> +/* EXYNOS_DP_FUNC_EN_1 */
>> +#define MASTER_VID_FUNC_EN_N (0x1 << 7)
>> +#define SLAVE_VID_FUNC_EN_N (0x1 << 5)
>> +#define AUD_FIFO_FUNC_EN_N (0x1 << 4)
>> +#define AUD_FUNC_EN_N (0x1 << 3)
>> +#define HDCP_FUNC_EN_N (0x1 << 2)
>> +#define CRC_FUNC_EN_N (0x1 << 1)
>> +#define SW_FUNC_EN_N (0x1 << 0)
>> +
>> +/* EXYNOS_DP_FUNC_EN_2 */
>> +#define SSC_FUNC_EN_N (0x1 << 7)
>> +#define AUX_FUNC_EN_N (0x1 << 2)
>> +#define SERDES_FIFO_FUNC_EN_N (0x1 << 1)
>> +#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0)
>> +
>> +/* EXYNOS_DP_VIDEO_CTL_1 */
>> +#define VIDEO_EN (0x1 << 7)
>> +#define HDCP_VIDEO_MUTE (0x1 << 6)
>> +
>> +/* EXYNOS_DP_VIDEO_CTL_1 */
>> +#define IN_D_RANGE_MASK (0x1 << 7)
>> +#define IN_D_RANGE_SHIFT (7)
>> +#define IN_D_RANGE_CEA (0x1 << 7)
>> +#define IN_D_RANGE_VESA (0x0 << 7)
>> +#define IN_BPC_MASK (0x7 << 4)
>> +#define IN_BPC_SHIFT (4)
>> +#define IN_BPC_12_BITS (0x3 << 4)
>> +#define IN_BPC_10_BITS (0x2 << 4)
>> +#define IN_BPC_8_BITS (0x1 << 4)
>> +#define IN_BPC_6_BITS (0x0 << 4)
>> +#define IN_COLOR_F_MASK (0x3 << 0)
>> +#define IN_COLOR_F_SHIFT (0)
>> +#define IN_COLOR_F_YCBCR444 (0x2 << 0)
>> +#define IN_COLOR_F_YCBCR422 (0x1 << 0)
>> +#define IN_COLOR_F_RGB (0x0 << 0)
>> +
>> +/* EXYNOS_DP_VIDEO_CTL_3 */
>> +#define IN_YC_COEFFI_MASK (0x1 << 7)
>> +#define IN_YC_COEFFI_SHIFT (7)
>> +#define IN_YC_COEFFI_ITU709 (0x1 << 7)
>> +#define IN_YC_COEFFI_ITU601 (0x0 << 7)
>> +#define VID_CHK_UPDATE_TYPE_MASK (0x1 << 4)
>> +#define VID_CHK_UPDATE_TYPE_SHIFT (4)
>> +#define VID_CHK_UPDATE_TYPE_1 (0x1 << 4)
>> +#define VID_CHK_UPDATE_TYPE_0 (0x0 << 4)
>> +
>> +/* EXYNOS_DP_VIDEO_CTL_8 */
>> +#define VID_HRES_TH(x) (((x) & 0xf) << 4)
>> +#define VID_VRES_TH(x) (((x) & 0xf) << 0)
>> +
>> +/* EXYNOS_DP_VIDEO_CTL_10 */
>> +#define FORMAT_SEL (0x1 << 4)
>> +#define INTERACE_SCAN_CFG (0x1 << 2)
>> +#define VSYNC_POLARITY_CFG (0x1 << 1)
>> +#define HSYNC_POLARITY_CFG (0x1 << 0)
>> +
>> +/* EXYNOS_DP_LANE_MAP */
>> +#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
>> +#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6)
>> +#define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6)
>> +#define LANE3_MAP_LOGIC_LANE_3 (0x3 << 6)
>> +#define LANE2_MAP_LOGIC_LANE_0 (0x0 << 4)
>> +#define LANE2_MAP_LOGIC_LANE_1 (0x1 << 4)
>> +#define LANE2_MAP_LOGIC_LANE_2 (0x2 << 4)
>> +#define LANE2_MAP_LOGIC_LANE_3 (0x3 << 4)
>> +#define LANE1_MAP_LOGIC_LANE_0 (0x0 << 2)
>> +#define LANE1_MAP_LOGIC_LANE_1 (0x1 << 2)
>> +#define LANE1_MAP_LOGIC_LANE_2 (0x2 << 2)
>> +#define LANE1_MAP_LOGIC_LANE_3 (0x3 << 2)
>> +#define LANE0_MAP_LOGIC_LANE_0 (0x0 << 0)
>> +#define LANE0_MAP_LOGIC_LANE_1 (0x1 << 0)
>> +#define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0)
>> +#define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0)
>> +
>> +/* EXYNOS_DP_ANALOG_CTL_1 */
>> +#define TX_TERMINAL_CTRL_50_OHM (0x1 << 4)
>> +
>> +/* EXYNOS_DP_ANALOG_CTL_2 */
>> +#define SEL_24M (0x1 << 3)
>> +#define TX_DVDD_BIT_1_0625V (0x4 << 0)
>> +
>> +/* EXYNOS_DP_ANALOG_CTL_3 */
>> +#define DRIVE_DVDD_BIT_1_0625V (0x4 << 5)
>> +#define VCO_BIT_600_MICRO (0x5 << 0)
>> +
>> +/* EXYNOS_DP_PLL_FILTER_CTL_1 */
>> +#define PD_RING_OSC (0x1 << 6)
>> +#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
>> +#define TX_CUR1_2X (0x1 << 2)
>> +#define TX_CUR_16_MA (0x3 << 0)
>> +
>> +/* EXYNOS_DP_TX_AMP_TUNING_CTL */
>> +#define CH3_AMP_400_MV (0x0 << 24)
>> +#define CH2_AMP_400_MV (0x0 << 16)
>> +#define CH1_AMP_400_MV (0x0 << 8)
>> +#define CH0_AMP_400_MV (0x0 << 0)
>> +
>> +/* EXYNOS_DP_AUX_HW_RETRY_CTL */
>> +#define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8)
>> +#define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3)
>> +#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3)
>> +#define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS (0x1 << 3)
>> +#define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS (0x2 << 3)
>> +#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3)
>> +#define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0)
>> +
>> +/* EXYNOS_DP_COMMON_INT_STA_1 */
>> +#define VSYNC_DET (0x1 << 7)
>> +#define PLL_LOCK_CHG (0x1 << 6)
>> +#define SPDIF_ERR (0x1 << 5)
>> +#define SPDIF_UNSTBL (0x1 << 4)
>> +#define VID_FORMAT_CHG (0x1 << 3)
>> +#define AUD_CLK_CHG (0x1 << 2)
>> +#define VID_CLK_CHG (0x1 << 1)
>> +#define SW_INT (0x1 << 0)
>> +
>> +/* EXYNOS_DP_COMMON_INT_STA_2 */
>> +#define ENC_EN_CHG (0x1 << 6)
>> +#define HW_BKSV_RDY (0x1 << 3)
>> +#define HW_SHA_DONE (0x1 << 2)
>> +#define HW_AUTH_STATE_CHG (0x1 << 1)
>> +#define HW_AUTH_DONE (0x1 << 0)
>> +
>> +/* EXYNOS_DP_COMMON_INT_STA_3 */
>> +#define AFIFO_UNDER (0x1 << 7)
>> +#define AFIFO_OVER (0x1 << 6)
>> +#define R0_CHK_FLAG (0x1 << 5)
>> +
>> +/* EXYNOS_DP_COMMON_INT_STA_4 */
>> +#define PSR_ACTIVE (0x1 << 7)
>> +#define PSR_INACTIVE (0x1 << 6)
>> +#define SPDIF_BI_PHASE_ERR (0x1 << 5)
>> +#define HOTPLUG_CHG (0x1 << 2)
>> +#define HPD_LOST (0x1 << 1)
>> +#define PLUG (0x1 << 0)
>> +
>> +/* EXYNOS_DP_INT_STA */
>> +#define INT_HPD (0x1 << 6)
>> +#define HW_TRAINING_FINISH (0x1 << 5)
>> +#define RPLY_RECEIV (0x1 << 1)
>> +#define AUX_ERR (0x1 << 0)
>> +
>> +/* EXYNOS_DP_INT_CTL */
>> +#define SOFT_INT_CTRL (0x1 << 2)
>> +#define INT_POL1 (0x1 << 1)
>> +#define INT_POL0 (0x1 << 0)
>> +
>> +/* EXYNOS_DP_SYS_CTL_1 */
>> +#define DET_STA (0x1 << 2)
>> +#define FORCE_DET (0x1 << 1)
>> +#define DET_CTRL (0x1 << 0)
>> +
>> +/* EXYNOS_DP_SYS_CTL_2 */
>> +#define CHA_CRI(x) (((x) & 0xf) << 4)
>> +#define CHA_STA (0x1 << 2)
>> +#define FORCE_CHA (0x1 << 1)
>> +#define CHA_CTRL (0x1 << 0)
>> +
>> +/* EXYNOS_DP_SYS_CTL_3 */
>> +#define HPD_STATUS (0x1 << 6)
>> +#define F_HPD (0x1 << 5)
>> +#define HPD_CTRL (0x1 << 4)
>> +#define HDCP_RDY (0x1 << 3)
>> +#define STRM_VALID (0x1 << 2)
>> +#define F_VALID (0x1 << 1)
>> +#define VALID_CTRL (0x1 << 0)
>> +
>> +/* EXYNOS_DP_SYS_CTL_4 */
>> +#define FIX_M_AUD (0x1 << 4)
>> +#define ENHANCED (0x1 << 3)
>> +#define FIX_M_VID (0x1 << 2)
>> +#define M_VID_UPDATE_CTRL (0x3 << 0)
>> +
>> +/* EXYNOS_DP_TRAINING_PTN_SET */
>> +#define SCRAMBLER_TYPE (0x1 << 9)
>> +#define HW_LINK_TRAINING_PATTERN (0x1 << 8)
>> +#define SCRAMBLING_DISABLE (0x1 << 5)
>> +#define SCRAMBLING_ENABLE (0x0 << 5)
>> +#define LINK_QUAL_PATTERN_SET_MASK (0x3 << 2)
>> +#define LINK_QUAL_PATTERN_SET_PRBS7 (0x3 << 2)
>> +#define LINK_QUAL_PATTERN_SET_D10_2 (0x1 << 2)
>> +#define LINK_QUAL_PATTERN_SET_DISABLE (0x0 << 2)
>> +#define SW_TRAINING_PATTERN_SET_MASK (0x3 << 0)
>> +#define SW_TRAINING_PATTERN_SET_PTN2 (0x2 << 0)
>> +#define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0)
>> +#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0)
>> +
>> +/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
>> +#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
>> +#define PRE_EMPHASIS_SET_SHIFT (3)
>> +
>> +/* EXYNOS_DP_DEBUG_CTL */
>> +#define PLL_LOCK (0x1 << 4)
>> +#define F_PLL_LOCK (0x1 << 3)
>> +#define PLL_LOCK_CTRL (0x1 << 2)
>> +#define PN_INV (0x1 << 0)
>> +
>> +/* EXYNOS_DP_PLL_CTL */
>> +#define DP_PLL_PD (0x1 << 7)
>> +#define DP_PLL_RESET (0x1 << 6)
>> +#define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4)
>> +#define DP_PLL_REF_BIT_1_1250V (0x5 << 0)
>> +#define DP_PLL_REF_BIT_1_2500V (0x7 << 0)
>> +
>> +/* EXYNOS_DP_PHY_PD */
>> +#define DP_PHY_PD (0x1 << 5)
>> +#define AUX_PD (0x1 << 4)
>> +#define CH3_PD (0x1 << 3)
>> +#define CH2_PD (0x1 << 2)
>> +#define CH1_PD (0x1 << 1)
>> +#define CH0_PD (0x1 << 0)
>> +
>> +/* EXYNOS_DP_PHY_TEST */
>> +#define MACRO_RST (0x1 << 5)
>> +#define CH1_TEST (0x1 << 1)
>> +#define CH0_TEST (0x1 << 0)
>> +
>> +/* EXYNOS_DP_AUX_CH_STA */
>> +#define AUX_BUSY (0x1 << 4)
>> +#define AUX_STATUS_MASK (0xf << 0)
>> +
>> +/* EXYNOS_DP_AUX_CH_DEFER_CTL */
>> +#define DEFER_CTRL_EN (0x1 << 7)
>> +#define DEFER_COUNT(x) (((x) & 0x7f) << 0)
>> +
>> +/* EXYNOS_DP_AUX_RX_COMM */
>> +#define AUX_RX_COMM_I2C_DEFER (0x2 << 2)
>> +#define AUX_RX_COMM_AUX_DEFER (0x2 << 0)
>> +
>> +/* EXYNOS_DP_BUFFER_DATA_CTL */
>> +#define BUF_CLR (0x1 << 7)
>> +#define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0)
>> +
>> +/* EXYNOS_DP_AUX_CH_CTL_1 */
>> +#define AUX_LENGTH(x) (((x - 1) & 0xf) <<
> 4)
>> +#define AUX_TX_COMM_MASK (0xf << 0)
>> +#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3)
>> +#define AUX_TX_COMM_I2C_TRANSACTION (0x0 << 3)
>> +#define AUX_TX_COMM_MOT (0x1 << 2)
>> +#define AUX_TX_COMM_WRITE (0x0 << 0)
>> +#define AUX_TX_COMM_READ (0x1 << 0)
>> +
>> +/* EXYNOS_DP_AUX_ADDR_7_0 */
>> +#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff)
>> +
>> +/* EXYNOS_DP_AUX_ADDR_15_8 */
>> +#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff)
>> +
>> +/* EXYNOS_DP_AUX_ADDR_19_16 */
>> +#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f)
>> +
>> +/* EXYNOS_DP_AUX_CH_CTL_2 */
>> +#define ADDR_ONLY (0x1 << 1)
>> +#define AUX_EN (0x1 << 0)
>> +
>> +/* EXYNOS_DP_SOC_GENERAL_CTL */
>> +#define AUDIO_MODE_SPDIF_MODE (0x1 << 8)
>> +#define AUDIO_MODE_MASTER_MODE (0x0 << 8)
>> +#define MASTER_VIDEO_INTERLACE_EN (0x1 << 4)
>> +#define VIDEO_MASTER_CLK_SEL (0x1 << 2)
>> +#define VIDEO_MASTER_MODE_EN (0x1 << 1)
>> +#define VIDEO_MODE_MASK (0x1 << 0)
>> +#define VIDEO_MODE_SLAVE_MODE (0x1 << 0)
>> +#define VIDEO_MODE_MASTER_MODE (0x0 << 0)
>> +
>> +#endif /* _EXYNOS_DP_REG_H */
>> diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig
>> index 1b035b2..7032ad9 100644
>> --- a/drivers/video/exynos/Kconfig
>> +++ b/drivers/video/exynos/Kconfig
>> @@ -27,11 +27,4 @@ config EXYNOS_LCD_S6E8AX0
>> If you have an S6E8AX0 MIPI AMOLED LCD Panel, say Y to enable its
>> LCD control driver.
>>
>> -config EXYNOS_DP
>> - bool "EXYNOS DP driver support"
>> - depends on ARCH_EXYNOS
>> - default n
>> - help
>> - This enables support for DP device.
>> -
>> endif # EXYNOS_VIDEO
>> diff --git a/drivers/video/exynos/Makefile b/drivers/video/exynos/Makefile
>> index ec7772e..b5b1bd2 100644
>> --- a/drivers/video/exynos/Makefile
>> +++ b/drivers/video/exynos/Makefile
>> @@ -5,4 +5,3 @@
>> obj-$(CONFIG_EXYNOS_MIPI_DSI) += exynos_mipi_dsi.o
>> exynos_mipi_dsi_common.o \
>> exynos_mipi_dsi_lowlevel.o
>> obj-$(CONFIG_EXYNOS_LCD_S6E8AX0) += s6e8ax0.o
>> -obj-$(CONFIG_EXYNOS_DP) += exynos_dp_core.o
>> exynos_dp_reg.o
>> diff --git a/drivers/video/exynos/exynos_dp_core.c
>> b/drivers/video/exynos/exynos_dp_core.c
>> deleted file mode 100644
>> index 089ae22..0000000
>> --- a/drivers/video/exynos/exynos_dp_core.c
>> +++ /dev/null
>> @@ -1,1213 +0,0 @@
>> -/*
>> - * Samsung SoC DP (Display Port) interface driver.
>> - *
>> - * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>> - * Author: Jingoo Han <jg1.han at samsung.com>
>> - *
>> - * This program is free software; you can redistribute it and/or modify
>> it
>> - * under the terms of the GNU General Public License as published by the
>> - * Free Software Foundation; either version 2 of the License, or (at your
>> - * option) any later version.
>> - */
>> -
>> -#include <linux/module.h>
>> -#include <linux/platform_device.h>
>> -#include <linux/err.h>
>> -#include <linux/clk.h>
>> -#include <linux/io.h>
>> -#include <linux/interrupt.h>
>> -#include <linux/delay.h>
>> -#include <linux/of.h>
>> -
>> -#include <video/exynos_dp.h>
>> -
>> -#include "exynos_dp_core.h"
>> -
>> -static int exynos_dp_init_dp(struct exynos_dp_device *dp)
>> -{
>> - exynos_dp_reset(dp);
>> -
>> - exynos_dp_swreset(dp);
>> -
>> - exynos_dp_init_analog_param(dp);
>> - exynos_dp_init_interrupt(dp);
>> -
>> - /* SW defined function Normal operation */
>> - exynos_dp_enable_sw_function(dp);
>> -
>> - exynos_dp_config_interrupt(dp);
>> - exynos_dp_init_analog_func(dp);
>> -
>> - exynos_dp_init_hpd(dp);
>> - exynos_dp_init_aux(dp);
>> -
>> - return 0;
>> -}
>> -
>> -static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
>> -{
>> - int timeout_loop = 0;
>> -
>> - while (exynos_dp_get_plug_in_status(dp) != 0) {
>> - timeout_loop++;
>> - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> - dev_err(dp->dev, "failed to get hpd plug status\n");
>> - return -ETIMEDOUT;
>> - }
>> - usleep_range(10, 11);
>> - }
>> -
>> - return 0;
>> -}
>> -
>> -static unsigned char exynos_dp_calc_edid_check_sum(unsigned char
>> *edid_data)
>> -{
>> - int i;
>> - unsigned char sum = 0;
>> -
>> - for (i = 0; i < EDID_BLOCK_LENGTH; i++)
>> - sum = sum + edid_data[i];
>> -
>> - return sum;
>> -}
>> -
>> -static int exynos_dp_read_edid(struct exynos_dp_device *dp)
>> -{
>> - unsigned char edid[EDID_BLOCK_LENGTH * 2];
>> - unsigned int extend_block = 0;
>> - unsigned char sum;
>> - unsigned char test_vector;
>> - int retval;
>> -
>> - /*
>> - * EDID device address is 0x50.
>> - * However, if necessary, you must have set upper address
>> - * into E-EDID in I2C device, 0x30.
>> - */
>> -
>> - /* Read Extension Flag, Number of 128-byte EDID extension blocks */
>> - retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
>> - EDID_EXTENSION_FLAG,
>> - &extend_block);
>> - if (retval)
>> - return retval;
>> -
>> - if (extend_block > 0) {
>> - dev_dbg(dp->dev, "EDID data includes a single
> extension!\n");
>> -
>> - /* Read EDID data */
>> - retval = exynos_dp_read_bytes_from_i2c(dp,
>> I2C_EDID_DEVICE_ADDR,
>> - EDID_HEADER_PATTERN,
>> - EDID_BLOCK_LENGTH,
>> - &edid[EDID_HEADER_PATTERN]);
>> - if (retval != 0) {
>> - dev_err(dp->dev, "EDID Read failed!\n");
>> - return -EIO;
>> - }
>> - sum = exynos_dp_calc_edid_check_sum(edid);
>> - if (sum != 0) {
>> - dev_err(dp->dev, "EDID bad checksum!\n");
>> - return -EIO;
>> - }
>> -
>> - /* Read additional EDID data */
>> - retval = exynos_dp_read_bytes_from_i2c(dp,
>> - I2C_EDID_DEVICE_ADDR,
>> - EDID_BLOCK_LENGTH,
>> - EDID_BLOCK_LENGTH,
>> - &edid[EDID_BLOCK_LENGTH]);
>> - if (retval != 0) {
>> - dev_err(dp->dev, "EDID Read failed!\n");
>> - return -EIO;
>> - }
>> - sum =
>> exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
>> - if (sum != 0) {
>> - dev_err(dp->dev, "EDID bad checksum!\n");
>> - return -EIO;
>> - }
>> -
>> - exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_TEST_REQUEST,
>> - &test_vector);
>> - if (test_vector & DPCD_TEST_EDID_READ) {
>> - exynos_dp_write_byte_to_dpcd(dp,
>> - DPCD_ADDR_TEST_EDID_CHECKSUM,
>> - edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
>> - exynos_dp_write_byte_to_dpcd(dp,
>> - DPCD_ADDR_TEST_RESPONSE,
>> - DPCD_TEST_EDID_CHECKSUM_WRITE);
>> - }
>> - } else {
>> - dev_info(dp->dev, "EDID data does not include any
>> extensions.\n");
>> -
>> - /* Read EDID data */
>> - retval = exynos_dp_read_bytes_from_i2c(dp,
>> - I2C_EDID_DEVICE_ADDR,
>> - EDID_HEADER_PATTERN,
>> - EDID_BLOCK_LENGTH,
>> - &edid[EDID_HEADER_PATTERN]);
>> - if (retval != 0) {
>> - dev_err(dp->dev, "EDID Read failed!\n");
>> - return -EIO;
>> - }
>> - sum = exynos_dp_calc_edid_check_sum(edid);
>> - if (sum != 0) {
>> - dev_err(dp->dev, "EDID bad checksum!\n");
>> - return -EIO;
>> - }
>> -
>> - exynos_dp_read_byte_from_dpcd(dp,
>> - DPCD_ADDR_TEST_REQUEST,
>> - &test_vector);
>> - if (test_vector & DPCD_TEST_EDID_READ) {
>> - exynos_dp_write_byte_to_dpcd(dp,
>> - DPCD_ADDR_TEST_EDID_CHECKSUM,
>> - edid[EDID_CHECKSUM]);
>> - exynos_dp_write_byte_to_dpcd(dp,
>> - DPCD_ADDR_TEST_RESPONSE,
>> - DPCD_TEST_EDID_CHECKSUM_WRITE);
>> - }
>> - }
>> -
>> - dev_err(dp->dev, "EDID Read success!\n");
>> - return 0;
>> -}
>> -
>> -static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
>> -{
>> - u8 buf[12];
>> - int i;
>> - int retval;
>> -
>> - /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */
>> - retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV,
>> - 12, buf);
>> - if (retval)
>> - return retval;
>> -
>> - /* Read EDID */
>> - for (i = 0; i < 3; i++) {
>> - retval = exynos_dp_read_edid(dp);
>> - if (!retval)
>> - break;
>> - }
>> -
>> - return retval;
>> -}
>> -
>> -static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device
>> *dp,
>> - bool enable)
>> -{
>> - u8 data;
>> -
>> - exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, &data);
>> -
>> - if (enable)
>> - exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
>> - DPCD_ENHANCED_FRAME_EN |
>> - DPCD_LANE_COUNT_SET(data));
>> - else
>> - exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
>> - DPCD_LANE_COUNT_SET(data));
>> -}
>> -
>> -static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device
>> *dp)
>> -{
>> - u8 data;
>> - int retval;
>> -
>> - exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data);
>> - retval = DPCD_ENHANCED_FRAME_CAP(data);
>> -
>> - return retval;
>> -}
>> -
>> -static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp)
>> -{
>> - u8 data;
>> -
>> - data = exynos_dp_is_enhanced_mode_available(dp);
>> - exynos_dp_enable_rx_to_enhanced_mode(dp, data);
>> - exynos_dp_enable_enhanced_mode(dp, data);
>> -}
>> -
>> -static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
>> -{
>> - exynos_dp_set_training_pattern(dp, DP_NONE);
>> -
>> - exynos_dp_write_byte_to_dpcd(dp,
>> - DPCD_ADDR_TRAINING_PATTERN_SET,
>> - DPCD_TRAINING_PATTERN_DISABLED);
>> -}
>> -
>> -static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device
>> *dp,
>> - int pre_emphasis, int lane)
>> -{
>> - switch (lane) {
>> - case 0:
>> - exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
>> - break;
>> - case 1:
>> - exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
>> - break;
>> -
>> - case 2:
>> - exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
>> - break;
>> -
>> - case 3:
>> - exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
>> - break;
>> - }
>> -}
>> -
>> -static int exynos_dp_link_start(struct exynos_dp_device *dp)
>> -{
>> - u8 buf[4];
>> - int lane, lane_count, pll_tries, retval;
>> -
>> - lane_count = dp->link_train.lane_count;
>> -
>> - dp->link_train.lt_state = CLOCK_RECOVERY;
>> - dp->link_train.eq_loop = 0;
>> -
>> - for (lane = 0; lane < lane_count; lane++)
>> - dp->link_train.cr_loop[lane] = 0;
>> -
>> - /* Set link rate and count as you want to establish*/
>> - exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
>> - exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
>> -
>> - /* Setup RX configuration */
>> - buf[0] = dp->link_train.link_rate;
>> - buf[1] = dp->link_train.lane_count;
>> - retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
>> - 2, buf);
>> - if (retval)
>> - return retval;
>> -
>> - /* Set TX pre-emphasis to minimum */
>> - for (lane = 0; lane < lane_count; lane++)
>> - exynos_dp_set_lane_lane_pre_emphasis(dp,
>> - PRE_EMPHASIS_LEVEL_0, lane);
>> -
>> - /* Wait for PLL lock */
>> - pll_tries = 0;
>> - while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
>> - if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
>> - dev_err(dp->dev, "Wait for PLL lock timed out\n");
>> - return -ETIMEDOUT;
>> - }
>> -
>> - pll_tries++;
>> - usleep_range(90, 120);
>> - }
>> -
>> - /* Set training pattern 1 */
>> - exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
>> -
>> - /* Set RX training pattern */
>> - retval = exynos_dp_write_byte_to_dpcd(dp,
>> - DPCD_ADDR_TRAINING_PATTERN_SET,
>> - DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1);
>> - if (retval)
>> - return retval;
>> -
>> - for (lane = 0; lane < lane_count; lane++)
>> - buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
>> - DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
>> -
>> - retval = exynos_dp_write_bytes_to_dpcd(dp,
>> DPCD_ADDR_TRAINING_LANE0_SET,
>> - lane_count, buf);
>> -
>> - return retval;
>> -}
>> -
>> -static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int
>> lane)
>> -{
>> - int shift = (lane & 1) * 4;
>> - u8 link_value = link_status[lane>>1];
>> -
>> - return (link_value >> shift) & 0xf;
>> -}
>> -
>> -static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
>> -{
>> - int lane;
>> - u8 lane_status;
>> -
>> - for (lane = 0; lane < lane_count; lane++) {
>> - lane_status = exynos_dp_get_lane_status(link_status, lane);
>> - if ((lane_status & DPCD_LANE_CR_DONE) == 0)
>> - return -EINVAL;
>> - }
>> - return 0;
>> -}
>> -
>> -static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
>> - int lane_count)
>> -{
>> - int lane;
>> - u8 lane_status;
>> -
>> - if ((link_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
>> - return -EINVAL;
>> -
>> - for (lane = 0; lane < lane_count; lane++) {
>> - lane_status = exynos_dp_get_lane_status(link_status, lane);
>> - lane_status &= DPCD_CHANNEL_EQ_BITS;
>> - if (lane_status != DPCD_CHANNEL_EQ_BITS)
>> - return -EINVAL;
>> - }
>> -
>> - return 0;
>> -}
>> -
>> -static unsigned char exynos_dp_get_adjust_request_voltage(u8
>> adjust_request[2],
>> - int lane)
>> -{
>> - int shift = (lane & 1) * 4;
>> - u8 link_value = adjust_request[lane>>1];
>> -
>> - return (link_value >> shift) & 0x3;
>> -}
>> -
>> -static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
>> - u8 adjust_request[2],
>> - int lane)
>> -{
>> - int shift = (lane & 1) * 4;
>> - u8 link_value = adjust_request[lane>>1];
>> -
>> - return ((link_value >> shift) & 0xc) >> 2;
>> -}
>> -
>> -static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
>> - u8 training_lane_set, int lane)
>> -{
>> - switch (lane) {
>> - case 0:
>> - exynos_dp_set_lane0_link_training(dp, training_lane_set);
>> - break;
>> - case 1:
>> - exynos_dp_set_lane1_link_training(dp, training_lane_set);
>> - break;
>> -
>> - case 2:
>> - exynos_dp_set_lane2_link_training(dp, training_lane_set);
>> - break;
>> -
>> - case 3:
>> - exynos_dp_set_lane3_link_training(dp, training_lane_set);
>> - break;
>> - }
>> -}
>> -
>> -static unsigned int exynos_dp_get_lane_link_training(
>> - struct exynos_dp_device *dp,
>> - int lane)
>> -{
>> - u32 reg;
>> -
>> - switch (lane) {
>> - case 0:
>> - reg = exynos_dp_get_lane0_link_training(dp);
>> - break;
>> - case 1:
>> - reg = exynos_dp_get_lane1_link_training(dp);
>> - break;
>> - case 2:
>> - reg = exynos_dp_get_lane2_link_training(dp);
>> - break;
>> - case 3:
>> - reg = exynos_dp_get_lane3_link_training(dp);
>> - break;
>> - default:
>> - WARN_ON(1);
>> - return 0;
>> - }
>> -
>> - return reg;
>> -}
>> -
>> -static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
>> -{
>> - exynos_dp_training_pattern_dis(dp);
>> - exynos_dp_set_enhanced_mode(dp);
>> -
>> - dp->link_train.lt_state = FAILED;
>> -}
>> -
>> -static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device
>> *dp,
>> - u8 adjust_request[2])
>> -{
>> - int lane, lane_count;
>> - u8 voltage_swing, pre_emphasis, training_lane;
>> -
>> - lane_count = dp->link_train.lane_count;
>> - for (lane = 0; lane < lane_count; lane++) {
>> - voltage_swing = exynos_dp_get_adjust_request_voltage(
>> - adjust_request, lane);
>> - pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
>> - adjust_request, lane);
>> - training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
>> - DPCD_PRE_EMPHASIS_SET(pre_emphasis);
>> -
>> - if (voltage_swing == VOLTAGE_LEVEL_3)
>> - training_lane |= DPCD_MAX_SWING_REACHED;
>> - if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
>> - training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
>> -
>> - dp->link_train.training_lane[lane] = training_lane;
>> - }
>> -}
>> -
>> -static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
>> -{
>> - int lane, lane_count, retval;
>> - u8 voltage_swing, pre_emphasis, training_lane;
>> - u8 link_status[2], adjust_request[2];
>> -
>> - usleep_range(100, 101);
>> -
>> - lane_count = dp->link_train.lane_count;
>> -
>> - retval = exynos_dp_read_bytes_from_dpcd(dp,
>> - DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
>> - if (retval)
>> - return retval;
>> -
>> - retval = exynos_dp_read_bytes_from_dpcd(dp,
>> - DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2,
> adjust_request);
>> - if (retval)
>> - return retval;
>> -
>> - if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
>> - /* set training pattern 2 for EQ */
>> - exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
>> -
>> - retval = exynos_dp_write_byte_to_dpcd(dp,
>> - DPCD_ADDR_TRAINING_PATTERN_SET,
>> - DPCD_SCRAMBLING_DISABLED |
>> - DPCD_TRAINING_PATTERN_2);
>> - if (retval)
>> - return retval;
>> -
>> - dev_info(dp->dev, "Link Training Clock Recovery success\n");
>> - dp->link_train.lt_state = EQUALIZER_TRAINING;
>> - } else {
>> - for (lane = 0; lane < lane_count; lane++) {
>> - training_lane = exynos_dp_get_lane_link_training(
>> - dp, lane);
>> - voltage_swing =
> exynos_dp_get_adjust_request_voltage(
>> - adjust_request,
> lane);
>> - pre_emphasis =
>> exynos_dp_get_adjust_request_pre_emphasis(
>> - adjust_request,
> lane);
>> -
>> - if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
>> - voltage_swing &&
>> - DPCD_PRE_EMPHASIS_GET(training_lane) ==
>> - pre_emphasis)
>> - dp->link_train.cr_loop[lane]++;
>> -
>> - if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
>> - voltage_swing == VOLTAGE_LEVEL_3 ||
>> - pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
>> - dev_err(dp->dev, "CR Max reached
> (%d,%d,%d)\n",
>> - dp->link_train.cr_loop[lane],
>> - voltage_swing, pre_emphasis);
>> - exynos_dp_reduce_link_rate(dp);
>> - return -EIO;
>> - }
>> - }
>> - }
>> -
>> - exynos_dp_get_adjust_training_lane(dp, adjust_request);
>> -
>> - for (lane = 0; lane < lane_count; lane++)
>> - exynos_dp_set_lane_link_training(dp,
>> - dp->link_train.training_lane[lane], lane);
>> -
>> - retval = exynos_dp_write_bytes_to_dpcd(dp,
>> - DPCD_ADDR_TRAINING_LANE0_SET, lane_count,
>> - dp->link_train.training_lane);
>> - if (retval)
>> - return retval;
>> -
>> - return retval;
>> -}
>> -
>> -static int exynos_dp_process_equalizer_training(struct exynos_dp_device
>> *dp)
>> -{
>> - int lane, lane_count, retval;
>> - u32 reg;
>> - u8 link_align, link_status[2], adjust_request[2];
>> -
>> - usleep_range(400, 401);
>> -
>> - lane_count = dp->link_train.lane_count;
>> -
>> - retval = exynos_dp_read_bytes_from_dpcd(dp,
>> - DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
>> - if (retval)
>> - return retval;
>> -
>> - if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
>> - exynos_dp_reduce_link_rate(dp);
>> - return -EIO;
>> - }
>> -
>> - retval = exynos_dp_read_bytes_from_dpcd(dp,
>> - DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2,
> adjust_request);
>> - if (retval)
>> - return retval;
>> -
>> - retval = exynos_dp_read_byte_from_dpcd(dp,
>> - DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &link_align);
>> - if (retval)
>> - return retval;
>> -
>> - exynos_dp_get_adjust_training_lane(dp, adjust_request);
>> -
>> - if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count))
>> {
>> - /* traing pattern Set to Normal */
>> - exynos_dp_training_pattern_dis(dp);
>> -
>> - dev_info(dp->dev, "Link Training success!\n");
>> -
>> - exynos_dp_get_link_bandwidth(dp, ®);
>> - dp->link_train.link_rate = reg;
>> - dev_dbg(dp->dev, "final bandwidth = %.2x\n",
>> - dp->link_train.link_rate);
>> -
>> - exynos_dp_get_lane_count(dp, ®);
>> - dp->link_train.lane_count = reg;
>> - dev_dbg(dp->dev, "final lane count = %.2x\n",
>> - dp->link_train.lane_count);
>> -
>> - /* set enhanced mode if available */
>> - exynos_dp_set_enhanced_mode(dp);
>> - dp->link_train.lt_state = FINISHED;
>> -
>> - return 0;
>> - }
>> -
>> - /* not all locked */
>> - dp->link_train.eq_loop++;
>> -
>> - if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
>> - dev_err(dp->dev, "EQ Max loop\n");
>> - exynos_dp_reduce_link_rate(dp);
>> - return -EIO;
>> - }
>> -
>> - for (lane = 0; lane < lane_count; lane++)
>> - exynos_dp_set_lane_link_training(dp,
>> - dp->link_train.training_lane[lane], lane);
>> -
>> - retval = exynos_dp_write_bytes_to_dpcd(dp,
>> DPCD_ADDR_TRAINING_LANE0_SET,
>> - lane_count, dp->link_train.training_lane);
>> -
>> - return retval;
>> -}
>> -
>> -static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
>> - u8 *bandwidth)
>> -{
>> - u8 data;
>> -
>> - /*
>> - * For DP rev.1.1, Maximum link rate of Main Link lanes
>> - * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
>> - */
>> - exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LINK_RATE, &data);
>> - *bandwidth = data;
>> -}
>> -
>> -static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
>> - u8 *lane_count)
>> -{
>> - u8 data;
>> -
>> - /*
>> - * For DP rev.1.1, Maximum number of Main Link lanes
>> - * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
>> - */
>> - exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data);
>> - *lane_count = DPCD_MAX_LANE_COUNT(data);
>> -}
>> -
>> -static void exynos_dp_init_training(struct exynos_dp_device *dp,
>> - enum link_lane_count_type max_lane,
>> - enum link_rate_type max_rate)
>> -{
>> - /*
>> - * MACRO_RST must be applied after the PLL_LOCK to avoid
>> - * the DP inter pair skew issue for at least 10 us
>> - */
>> - exynos_dp_reset_macro(dp);
>> -
>> - /* Initialize by reading RX's DPCD */
>> - exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
>> - exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
>> -
>> - if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
>> - (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
>> - dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
>> - dp->link_train.link_rate);
>> - dp->link_train.link_rate = LINK_RATE_1_62GBPS;
>> - }
>> -
>> - if (dp->link_train.lane_count == 0) {
>> - dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n",
>> - dp->link_train.lane_count);
>> - dp->link_train.lane_count = (u8)LANE_COUNT1;
>> - }
>> -
>> - /* Setup TX lane count & rate */
>> - if (dp->link_train.lane_count > max_lane)
>> - dp->link_train.lane_count = max_lane;
>> - if (dp->link_train.link_rate > max_rate)
>> - dp->link_train.link_rate = max_rate;
>> -
>> - /* All DP analog module power up */
>> - exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
>> -}
>> -
>> -static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
>> -{
>> - int retval = 0, training_finished = 0;
>> -
>> - dp->link_train.lt_state = START;
>> -
>> - /* Process here */
>> - while (!retval && !training_finished) {
>> - switch (dp->link_train.lt_state) {
>> - case START:
>> - retval = exynos_dp_link_start(dp);
>> - if (retval)
>> - dev_err(dp->dev, "LT link start failed!\n");
>> - break;
>> - case CLOCK_RECOVERY:
>> - retval = exynos_dp_process_clock_recovery(dp);
>> - if (retval)
>> - dev_err(dp->dev, "LT CR failed!\n");
>> - break;
>> - case EQUALIZER_TRAINING:
>> - retval = exynos_dp_process_equalizer_training(dp);
>> - if (retval)
>> - dev_err(dp->dev, "LT EQ failed!\n");
>> - break;
>> - case FINISHED:
>> - training_finished = 1;
>> - break;
>> - case FAILED:
>> - return -EREMOTEIO;
>> - }
>> - }
>> - if (retval)
>> - dev_err(dp->dev, "eDP link training failed (%d)\n", retval);
>> -
>> - return retval;
>> -}
>> -
>> -static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
>> - u32 count,
>> - u32 bwtype)
>> -{
>> - int i;
>> - int retval;
>> -
>> - for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
>> - exynos_dp_init_training(dp, count, bwtype);
>> - retval = exynos_dp_sw_link_training(dp);
>> - if (retval == 0)
>> - break;
>> -
>> - usleep_range(100, 110);
>> - }
>> -
>> - return retval;
>> -}
>> -
>> -static int exynos_dp_config_video(struct exynos_dp_device *dp)
>> -{
>> - int retval = 0;
>> - int timeout_loop = 0;
>> - int done_count = 0;
>> -
>> - exynos_dp_config_video_slave_mode(dp);
>> -
>> - exynos_dp_set_video_color_format(dp);
>> -
>> - if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
>> - dev_err(dp->dev, "PLL is not locked yet.\n");
>> - return -EINVAL;
>> - }
>> -
>> - for (;;) {
>> - timeout_loop++;
>> - if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0)
>> - break;
>> - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> - dev_err(dp->dev, "Timeout of video streamclk ok\n");
>> - return -ETIMEDOUT;
>> - }
>> -
>> - usleep_range(1, 2);
>> - }
>> -
>> - /* Set to use the register calculated M/N video */
>> - exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);
>> -
>> - /* For video bist, Video timing must be generated by register */
>> - exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);
>> -
>> - /* Disable video mute */
>> - exynos_dp_enable_video_mute(dp, 0);
>> -
>> - /* Configure video slave mode */
>> - exynos_dp_enable_video_master(dp, 0);
>> -
>> - /* Enable video */
>> - exynos_dp_start_video(dp);
>> -
>> - timeout_loop = 0;
>> -
>> - for (;;) {
>> - timeout_loop++;
>> - if (exynos_dp_is_video_stream_on(dp) == 0) {
>> - done_count++;
>> - if (done_count > 10)
>> - break;
>> - } else if (done_count) {
>> - done_count = 0;
>> - }
>> - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> - dev_err(dp->dev, "Timeout of video streamclk ok\n");
>> - return -ETIMEDOUT;
>> - }
>> -
>> - usleep_range(1000, 1001);
>> - }
>> -
>> - if (retval != 0)
>> - dev_err(dp->dev, "Video stream is not detected!\n");
>> -
>> - return retval;
>> -}
>> -
>> -static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool
>> enable)
>> -{
>> - u8 data;
>> -
>> - if (enable) {
>> - exynos_dp_enable_scrambling(dp);
>> -
>> - exynos_dp_read_byte_from_dpcd(dp,
>> - DPCD_ADDR_TRAINING_PATTERN_SET,
>> - &data);
>> - exynos_dp_write_byte_to_dpcd(dp,
>> - DPCD_ADDR_TRAINING_PATTERN_SET,
>> - (u8)(data & ~DPCD_SCRAMBLING_DISABLED));
>> - } else {
>> - exynos_dp_disable_scrambling(dp);
>> -
>> - exynos_dp_read_byte_from_dpcd(dp,
>> - DPCD_ADDR_TRAINING_PATTERN_SET,
>> - &data);
>> - exynos_dp_write_byte_to_dpcd(dp,
>> - DPCD_ADDR_TRAINING_PATTERN_SET,
>> - (u8)(data | DPCD_SCRAMBLING_DISABLED));
>> - }
>> -}
>> -
>> -static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
>> -{
>> - struct exynos_dp_device *dp = arg;
>> -
>> - enum dp_irq_type irq_type;
>> -
>> - irq_type = exynos_dp_get_irq_type(dp);
>> - switch (irq_type) {
>> - case DP_IRQ_TYPE_HP_CABLE_IN:
>> - dev_dbg(dp->dev, "Received irq - cable in\n");
>> - schedule_work(&dp->hotplug_work);
>> - exynos_dp_clear_hotplug_interrupts(dp);
>> - break;
>> - case DP_IRQ_TYPE_HP_CABLE_OUT:
>> - dev_dbg(dp->dev, "Received irq - cable out\n");
>> - exynos_dp_clear_hotplug_interrupts(dp);
>> - break;
>> - case DP_IRQ_TYPE_HP_CHANGE:
>> - /*
>> - * We get these change notifications once in a while, but
>> there
>> - * is nothing we can do with them. Just ignore it for now
> and
>> - * only handle cable changes.
>> - */
>> - dev_dbg(dp->dev, "Received irq - hotplug change;
>> ignoring.\n");
>> - exynos_dp_clear_hotplug_interrupts(dp);
>> - break;
>> - default:
>> - dev_err(dp->dev, "Received irq - unknown type!\n");
>> - break;
>> - }
>> - return IRQ_HANDLED;
>> -}
>> -
>> -static void exynos_dp_hotplug(struct work_struct *work)
>> -{
>> - struct exynos_dp_device *dp;
>> - int ret;
>> -
>> - dp = container_of(work, struct exynos_dp_device, hotplug_work);
>> -
>> - ret = exynos_dp_detect_hpd(dp);
>> - if (ret) {
>> - /* Cable has been disconnected, we're done */
>> - return;
>> - }
>> -
>> - ret = exynos_dp_handle_edid(dp);
>> - if (ret) {
>> - dev_err(dp->dev, "unable to handle edid\n");
>> - return;
>> - }
>> -
>> - ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
>> - dp->video_info->link_rate);
>> - if (ret) {
>> - dev_err(dp->dev, "unable to do link train\n");
>> - return;
>> - }
>> -
>> - exynos_dp_enable_scramble(dp, 1);
>> - exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
>> - exynos_dp_enable_enhanced_mode(dp, 1);
>> -
>> - exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
>> - exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
>> -
>> - exynos_dp_init_video(dp);
>> - ret = exynos_dp_config_video(dp);
>> - if (ret)
>> - dev_err(dp->dev, "unable to config video\n");
>> -}
>> -
>> -#ifdef CONFIG_OF
>> -static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device
>> *dev)
>> -{
>> - struct device_node *dp_node = dev->of_node;
>> - struct exynos_dp_platdata *pd;
>> - struct video_info *dp_video_config;
>> -
>> - pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
>> - if (!pd) {
>> - dev_err(dev, "memory allocation for pdata failed\n");
>> - return ERR_PTR(-ENOMEM);
>> - }
>> - dp_video_config = devm_kzalloc(dev,
>> - sizeof(*dp_video_config), GFP_KERNEL);
>> -
>> - if (!dp_video_config) {
>> - dev_err(dev, "memory allocation for video config failed\n");
>> - return ERR_PTR(-ENOMEM);
>> - }
>> - pd->video_info = dp_video_config;
>> -
>> - dp_video_config->h_sync_polarity =
>> - of_property_read_bool(dp_node, "hsync-active-high");
>> -
>> - dp_video_config->v_sync_polarity =
>> - of_property_read_bool(dp_node, "vsync-active-high");
>> -
>> - dp_video_config->interlaced =
>> - of_property_read_bool(dp_node, "interlaced");
>> -
>> - if (of_property_read_u32(dp_node, "samsung,color-space",
>> - &dp_video_config->color_space)) {
>> - dev_err(dev, "failed to get color-space\n");
>> - return ERR_PTR(-EINVAL);
>> - }
>> -
>> - if (of_property_read_u32(dp_node, "samsung,dynamic-range",
>> - &dp_video_config->dynamic_range)) {
>> - dev_err(dev, "failed to get dynamic-range\n");
>> - return ERR_PTR(-EINVAL);
>> - }
>> -
>> - if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
>> - &dp_video_config->ycbcr_coeff)) {
>> - dev_err(dev, "failed to get ycbcr-coeff\n");
>> - return ERR_PTR(-EINVAL);
>> - }
>> -
>> - if (of_property_read_u32(dp_node, "samsung,color-depth",
>> - &dp_video_config->color_depth)) {
>> - dev_err(dev, "failed to get color-depth\n");
>> - return ERR_PTR(-EINVAL);
>> - }
>> -
>> - if (of_property_read_u32(dp_node, "samsung,link-rate",
>> - &dp_video_config->link_rate)) {
>> - dev_err(dev, "failed to get link-rate\n");
>> - return ERR_PTR(-EINVAL);
>> - }
>> -
>> - if (of_property_read_u32(dp_node, "samsung,lane-count",
>> - &dp_video_config->lane_count)) {
>> - dev_err(dev, "failed to get lane-count\n");
>> - return ERR_PTR(-EINVAL);
>> - }
>> -
>> - return pd;
>> -}
>> -
>> -static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
>> -{
>> - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
>> - u32 phy_base;
>> - int ret = 0;
>> -
>> - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
>> - if (!dp_phy_node) {
>> - dev_err(dp->dev, "could not find dptx-phy node\n");
>> - return -ENODEV;
>> - }
>> -
>> - if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
>> - dev_err(dp->dev, "failed to get reg for dptx-phy\n");
>> - ret = -EINVAL;
>> - goto err;
>> - }
>> -
>> - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
>> - &dp->enable_mask)) {
>> - dev_err(dp->dev, "failed to get enable-mask for
> dptx-phy\n");
>> - ret = -EINVAL;
>> - goto err;
>> - }
>> -
>> - dp->phy_addr = ioremap(phy_base, SZ_4);
>> - if (!dp->phy_addr) {
>> - dev_err(dp->dev, "failed to ioremap dp-phy\n");
>> - ret = -ENOMEM;
>> - goto err;
>> - }
>> -
>> -err:
>> - of_node_put(dp_phy_node);
>> -
>> - return ret;
>> -}
>> -
>> -static void exynos_dp_phy_init(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = __raw_readl(dp->phy_addr);
>> - reg |= dp->enable_mask;
>> - __raw_writel(reg, dp->phy_addr);
>> -}
>> -
>> -static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = __raw_readl(dp->phy_addr);
>> - reg &= ~(dp->enable_mask);
>> - __raw_writel(reg, dp->phy_addr);
>> -}
>> -#else
>> -static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device
>> *dev)
>> -{
>> - return NULL;
>> -}
>> -
>> -static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
>> -{
>> - return -EINVAL;
>> -}
>> -
>> -static void exynos_dp_phy_init(struct exynos_dp_device *dp)
>> -{
>> - return;
>> -}
>> -
>> -static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
>> -{
>> - return;
>> -}
>> -#endif /* CONFIG_OF */
>> -
>> -static int exynos_dp_probe(struct platform_device *pdev)
>> -{
>> - struct resource *res;
>> - struct exynos_dp_device *dp;
>> - struct exynos_dp_platdata *pdata;
>> -
>> - int ret = 0;
>> -
>> - dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
>> - GFP_KERNEL);
>> - if (!dp) {
>> - dev_err(&pdev->dev, "no memory for device data\n");
>> - return -ENOMEM;
>> - }
>> -
>> - dp->dev = &pdev->dev;
>> -
>> - if (pdev->dev.of_node) {
>> - pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
>> - if (IS_ERR(pdata))
>> - return PTR_ERR(pdata);
>> -
>> - ret = exynos_dp_dt_parse_phydata(dp);
>> - if (ret)
>> - return ret;
>> - } else {
>> - pdata = pdev->dev.platform_data;
>> - if (!pdata) {
>> - dev_err(&pdev->dev, "no platform data\n");
>> - return -EINVAL;
>> - }
>> - }
>> -
>> - dp->clock = devm_clk_get(&pdev->dev, "dp");
>> - if (IS_ERR(dp->clock)) {
>> - dev_err(&pdev->dev, "failed to get clock\n");
>> - return PTR_ERR(dp->clock);
>> - }
>> -
>> - clk_prepare_enable(dp->clock);
>> -
>> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> -
>> - dp->reg_base = devm_ioremap_resource(&pdev->dev, res);
>> - if (IS_ERR(dp->reg_base))
>> - return PTR_ERR(dp->reg_base);
>> -
>> - dp->irq = platform_get_irq(pdev, 0);
>> - if (dp->irq == -ENXIO) {
>> - dev_err(&pdev->dev, "failed to get irq\n");
>> - return -ENODEV;
>> - }
>> -
>> - INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
>> -
>> - dp->video_info = pdata->video_info;
>> -
>> - if (pdev->dev.of_node) {
>> - if (dp->phy_addr)
>> - exynos_dp_phy_init(dp);
>> - } else {
>> - if (pdata->phy_init)
>> - pdata->phy_init();
>> - }
>> -
>> - exynos_dp_init_dp(dp);
>> -
>> - ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
>> 0,
>> - "exynos-dp", dp);
>> - if (ret) {
>> - dev_err(&pdev->dev, "failed to request irq\n");
>> - return ret;
>> - }
>> -
>> - platform_set_drvdata(pdev, dp);
>> -
>> - return 0;
>> -}
>> -
>> -static int exynos_dp_remove(struct platform_device *pdev)
>> -{
>> - struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>> - struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>> -
>> - flush_work(&dp->hotplug_work);
>> -
>> - if (pdev->dev.of_node) {
>> - if (dp->phy_addr)
>> - exynos_dp_phy_exit(dp);
>> - } else {
>> - if (pdata->phy_exit)
>> - pdata->phy_exit();
>> - }
>> -
>> - clk_disable_unprepare(dp->clock);
>> -
>> -
>> - return 0;
>> -}
>> -
>> -#ifdef CONFIG_PM_SLEEP
>> -static int exynos_dp_suspend(struct device *dev)
>> -{
>> - struct exynos_dp_platdata *pdata = dev->platform_data;
>> - struct exynos_dp_device *dp = dev_get_drvdata(dev);
>> -
>> - disable_irq(dp->irq);
>> -
>> - flush_work(&dp->hotplug_work);
>> -
>> - if (dev->of_node) {
>> - if (dp->phy_addr)
>> - exynos_dp_phy_exit(dp);
>> - } else {
>> - if (pdata->phy_exit)
>> - pdata->phy_exit();
>> - }
>> -
>> - clk_disable_unprepare(dp->clock);
>> -
>> - return 0;
>> -}
>> -
>> -static int exynos_dp_resume(struct device *dev)
>> -{
>> - struct exynos_dp_platdata *pdata = dev->platform_data;
>> - struct exynos_dp_device *dp = dev_get_drvdata(dev);
>> -
>> - if (dev->of_node) {
>> - if (dp->phy_addr)
>> - exynos_dp_phy_init(dp);
>> - } else {
>> - if (pdata->phy_init)
>> - pdata->phy_init();
>> - }
>> -
>> - clk_prepare_enable(dp->clock);
>> -
>> - exynos_dp_init_dp(dp);
>> -
>> - enable_irq(dp->irq);
>> -
>> - return 0;
>> -}
>> -#endif
>> -
>> -static const struct dev_pm_ops exynos_dp_pm_ops = {
>> - SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
>> -};
>> -
>> -static const struct of_device_id exynos_dp_match[] = {
>> - { .compatible = "samsung,exynos5-dp" },
>> - {},
>> -};
>> -MODULE_DEVICE_TABLE(of, exynos_dp_match);
>> -
>> -static struct platform_driver exynos_dp_driver = {
>> - .probe = exynos_dp_probe,
>> - .remove = exynos_dp_remove,
>> - .driver = {
>> - .name = "exynos-dp",
>> - .owner = THIS_MODULE,
>> - .pm = &exynos_dp_pm_ops,
>> - .of_match_table = of_match_ptr(exynos_dp_match),
>> - },
>> -};
>> -
>> -module_platform_driver(exynos_dp_driver);
>> -
>> -MODULE_AUTHOR("Jingoo Han <jg1.han at samsung.com>");
>> -MODULE_DESCRIPTION("Samsung SoC DP Driver");
>> -MODULE_LICENSE("GPL");
>> diff --git a/drivers/video/exynos/exynos_dp_core.h
>> b/drivers/video/exynos/exynos_dp_core.h
>> deleted file mode 100644
>> index 6c567bbf..0000000
>> --- a/drivers/video/exynos/exynos_dp_core.h
>> +++ /dev/null
>> @@ -1,210 +0,0 @@
>> -/*
>> - * Header file for Samsung DP (Display Port) interface driver.
>> - *
>> - * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>> - * Author: Jingoo Han <jg1.han at samsung.com>
>> - *
>> - * This program is free software; you can redistribute it and/or modify
>> it
>> - * under the terms of the GNU General Public License as published by the
>> - * Free Software Foundation; either version 2 of the License, or (at your
>> - * option) any later version.
>> - */
>> -
>> -#ifndef _EXYNOS_DP_CORE_H
>> -#define _EXYNOS_DP_CORE_H
>> -
>> -enum dp_irq_type {
>> - DP_IRQ_TYPE_HP_CABLE_IN,
>> - DP_IRQ_TYPE_HP_CABLE_OUT,
>> - DP_IRQ_TYPE_HP_CHANGE,
>> - DP_IRQ_TYPE_UNKNOWN,
>> -};
>> -
>> -struct link_train {
>> - int eq_loop;
>> - int cr_loop[4];
>> -
>> - u8 link_rate;
>> - u8 lane_count;
>> - u8 training_lane[4];
>> -
>> - enum link_training_state lt_state;
>> -};
>> -
>> -struct exynos_dp_device {
>> - struct device *dev;
>> - struct clk *clock;
>> - unsigned int irq;
>> - void __iomem *reg_base;
>> - void __iomem *phy_addr;
>> - unsigned int enable_mask;
>> -
>> - struct video_info *video_info;
>> - struct link_train link_train;
>> - struct work_struct hotplug_work;
>> -};
>> -
>> -/* exynos_dp_reg.c */
>> -void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool
>> enable);
>> -void exynos_dp_stop_video(struct exynos_dp_device *dp);
>> -void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable);
>> -void exynos_dp_init_analog_param(struct exynos_dp_device *dp);
>> -void exynos_dp_init_interrupt(struct exynos_dp_device *dp);
>> -void exynos_dp_reset(struct exynos_dp_device *dp);
>> -void exynos_dp_swreset(struct exynos_dp_device *dp);
>> -void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
>> -enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device
>> *dp);
>> -void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool
>> enable);
>> -void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
>> - enum analog_power_block block,
>> - bool enable);
>> -void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
>> -void exynos_dp_init_hpd(struct exynos_dp_device *dp);
>> -enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
>> -void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp);
>> -void exynos_dp_reset_aux(struct exynos_dp_device *dp);
>> -void exynos_dp_init_aux(struct exynos_dp_device *dp);
>> -int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
>> -void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
>> -int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
>> -int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
>> - unsigned int reg_addr,
>> - unsigned char data);
>> -int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
>> - unsigned int reg_addr,
>> - unsigned char *data);
>> -int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
>> - unsigned int reg_addr,
>> - unsigned int count,
>> - unsigned char data[]);
>> -int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
>> - unsigned int reg_addr,
>> - unsigned int count,
>> - unsigned char data[]);
>> -int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
>> - unsigned int device_addr,
>> - unsigned int reg_addr);
>> -int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
>> - unsigned int device_addr,
>> - unsigned int reg_addr,
>> - unsigned int *data);
>> -int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
>> - unsigned int device_addr,
>> - unsigned int reg_addr,
>> - unsigned int count,
>> - unsigned char edid[]);
>> -void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32
>> bwtype);
>> -void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32
>> *bwtype);
>> -void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
>> -void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
>> -void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool
>> enable);
>> -void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
>> - enum pattern_set pattern);
>> -void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32
>> level);
>> -void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32
>> level);
>> -void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32
>> level);
>> -void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32
>> level);
>> -void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
>> - u32 training_lane);
>> -void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
>> - u32 training_lane);
>> -void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
>> - u32 training_lane);
>> -void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
>> - u32 training_lane);
>> -u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
>> -u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
>> -u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
>> -u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
>> -void exynos_dp_reset_macro(struct exynos_dp_device *dp);
>> -void exynos_dp_init_video(struct exynos_dp_device *dp);
>> -
>> -void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
>> -int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device
> *dp);
>> -void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
>> - enum clock_recovery_m_value_type type,
>> - u32 m_value,
>> - u32 n_value);
>> -void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32
>> type);
>> -void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool
>> enable);
>> -void exynos_dp_start_video(struct exynos_dp_device *dp);
>> -int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp);
>> -void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp);
>> -void exynos_dp_enable_scrambling(struct exynos_dp_device *dp);
>> -void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
>> -
>> -/* I2C EDID Chip ID, Slave Address */
>> -#define I2C_EDID_DEVICE_ADDR 0x50
>> -#define I2C_E_EDID_DEVICE_ADDR 0x30
>> -
>> -#define EDID_BLOCK_LENGTH 0x80
>> -#define EDID_HEADER_PATTERN 0x00
>> -#define EDID_EXTENSION_FLAG 0x7e
>> -#define EDID_CHECKSUM 0x7f
>> -
>> -/* Definition for DPCD Register */
>> -#define DPCD_ADDR_DPCD_REV 0x0000
>> -#define DPCD_ADDR_MAX_LINK_RATE 0x0001
>> -#define DPCD_ADDR_MAX_LANE_COUNT 0x0002
>> -#define DPCD_ADDR_LINK_BW_SET 0x0100
>> -#define DPCD_ADDR_LANE_COUNT_SET 0x0101
>> -#define DPCD_ADDR_TRAINING_PATTERN_SET 0x0102
>> -#define DPCD_ADDR_TRAINING_LANE0_SET 0x0103
>> -#define DPCD_ADDR_LANE0_1_STATUS 0x0202
>> -#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x0204
>> -#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x0206
>> -#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x0207
>> -#define DPCD_ADDR_TEST_REQUEST 0x0218
>> -#define DPCD_ADDR_TEST_RESPONSE 0x0260
>> -#define DPCD_ADDR_TEST_EDID_CHECKSUM 0x0261
>> -#define DPCD_ADDR_SINK_POWER_STATE 0x0600
>> -
>> -/* DPCD_ADDR_MAX_LANE_COUNT */
>> -#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
>> -#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
>> -
>> -/* DPCD_ADDR_LANE_COUNT_SET */
>> -#define DPCD_ENHANCED_FRAME_EN (0x1 << 7)
>> -#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
>> -
>> -/* DPCD_ADDR_TRAINING_PATTERN_SET */
>> -#define DPCD_SCRAMBLING_DISABLED (0x1 << 5)
>> -#define DPCD_SCRAMBLING_ENABLED (0x0 << 5)
>> -#define DPCD_TRAINING_PATTERN_2 (0x2 << 0)
>> -#define DPCD_TRAINING_PATTERN_1 (0x1 << 0)
>> -#define DPCD_TRAINING_PATTERN_DISABLED (0x0 << 0)
>> -
>> -/* DPCD_ADDR_TRAINING_LANE0_SET */
>> -#define DPCD_MAX_PRE_EMPHASIS_REACHED (0x1 << 5)
>> -#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
>> -#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
>> -#define DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 (0x0 << 3)
>> -#define DPCD_MAX_SWING_REACHED (0x1 << 2)
>> -#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
>> -#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
>> -#define DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0 (0x0 << 0)
>> -
>> -/* DPCD_ADDR_LANE0_1_STATUS */
>> -#define DPCD_LANE_SYMBOL_LOCKED (0x1 << 2)
>> -#define DPCD_LANE_CHANNEL_EQ_DONE (0x1 << 1)
>> -#define DPCD_LANE_CR_DONE (0x1 << 0)
>> -#define DPCD_CHANNEL_EQ_BITS (DPCD_LANE_CR_DONE| \
>> - DPCD_LANE_CHANNEL_EQ_DONE|\
>> - DPCD_LANE_SYMBOL_LOCKED)
>> -
>> -/* DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED */
>> -#define DPCD_LINK_STATUS_UPDATED (0x1 << 7)
>> -#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED (0x1 << 6)
>> -#define DPCD_INTERLANE_ALIGN_DONE (0x1 << 0)
>> -
>> -/* DPCD_ADDR_TEST_REQUEST */
>> -#define DPCD_TEST_EDID_READ (0x1 << 2)
>> -
>> -/* DPCD_ADDR_TEST_RESPONSE */
>> -#define DPCD_TEST_EDID_CHECKSUM_WRITE (0x1 << 2)
>> -
>> -/* DPCD_ADDR_SINK_POWER_STATE */
>> -#define DPCD_SET_POWER_STATE_D0 (0x1 << 0)
>> -#define DPCD_SET_POWER_STATE_D4 (0x2 << 0)
>> -
>> -#endif /* _EXYNOS_DP_CORE_H */
>> diff --git a/drivers/video/exynos/exynos_dp_reg.c
>> b/drivers/video/exynos/exynos_dp_reg.c
>> deleted file mode 100644
>> index 29d9d03..0000000
>> --- a/drivers/video/exynos/exynos_dp_reg.c
>> +++ /dev/null
>> @@ -1,1245 +0,0 @@
>> -/*
>> - * Samsung DP (Display port) register interface driver.
>> - *
>> - * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>> - * Author: Jingoo Han <jg1.han at samsung.com>
>> - *
>> - * This program is free software; you can redistribute it and/or modify
>> it
>> - * under the terms of the GNU General Public License as published by the
>> - * Free Software Foundation; either version 2 of the License, or (at your
>> - * option) any later version.
>> - */
>> -
>> -#include <linux/device.h>
>> -#include <linux/io.h>
>> -#include <linux/delay.h>
>> -
>> -#include <video/exynos_dp.h>
>> -
>> -#include "exynos_dp_core.h"
>> -#include "exynos_dp_reg.h"
>> -
>> -#define COMMON_INT_MASK_1 0
>> -#define COMMON_INT_MASK_2 0
>> -#define COMMON_INT_MASK_3 0
>> -#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
>> -#define INT_STA_MASK INT_HPD
>> -
>> -void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool
> enable)
>> -{
>> - u32 reg;
>> -
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> - reg |= HDCP_VIDEO_MUTE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> - reg &= ~HDCP_VIDEO_MUTE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> - }
>> -}
>> -
>> -void exynos_dp_stop_video(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> - reg &= ~VIDEO_EN;
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> -}
>> -
>> -void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable)
>> -{
>> - u32 reg;
>> -
>> - if (enable)
>> - reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
>> - LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
>> - else
>> - reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
>> - LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
>> -
>> - writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP);
>> -}
>> -
>> -void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = TX_TERMINAL_CTRL_50_OHM;
>> - writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1);
>> -
>> - reg = SEL_24M | TX_DVDD_BIT_1_0625V;
>> - writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2);
>> -
>> - reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
>> - writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
>> -
>> - reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
>> - TX_CUR1_2X | TX_CUR_16_MA;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
>> -
>> - reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
>> - CH1_AMP_400_MV | CH0_AMP_400_MV;
>> - writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL);
>> -}
>> -
>> -void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
>> -{
>> - /* Set interrupt pin assertion polarity as high */
>> - writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
>> -
>> - /* Clear pending regisers */
>> - writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
>> - writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2);
>> - writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3);
>> - writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
>> - writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA);
>> -
>> - /* 0:mask,1: unmask */
>> - writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
>> - writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
>> - writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
>> - writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
>> - writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
>> -}
>> -
>> -void exynos_dp_reset(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - exynos_dp_stop_video(dp);
>> - exynos_dp_enable_video_mute(dp, 0);
>> -
>> - reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
>> - AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
>> - HDCP_FUNC_EN_N | SW_FUNC_EN_N;
>> - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> -
>> - reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
>> - SERDES_FIFO_FUNC_EN_N |
>> - LS_CLK_DOMAIN_FUNC_EN_N;
>> - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> -
>> - usleep_range(20, 30);
>> -
>> - exynos_dp_lane_swap(dp, 0);
>> -
>> - writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> - writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> - writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> - writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> -
>> - writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL);
>> - writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL);
>> -
>> - writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L);
>> - writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H);
>> -
>> - writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL);
>> -
>> - writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST);
>> -
>> - writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD);
>> - writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN);
>> -
>> - writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH);
>> - writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
>> -
>> - writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> -}
>> -
>> -void exynos_dp_swreset(struct exynos_dp_device *dp)
>> -{
>> - writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET);
>> -}
>> -
>> -void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - /* 0: mask, 1: unmask */
>> - reg = COMMON_INT_MASK_1;
>> - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
>> -
>> - reg = COMMON_INT_MASK_2;
>> - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
>> -
>> - reg = COMMON_INT_MASK_3;
>> - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
>> -
>> - reg = COMMON_INT_MASK_4;
>> - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
>> -
>> - reg = INT_STA_MASK;
>> - writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
>> -}
>> -
>> -enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device
> *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
>> - if (reg & PLL_LOCK)
>> - return PLL_LOCKED;
>> - else
>> - return PLL_UNLOCKED;
>> -}
>> -
>> -void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool
>> enable)
>> -{
>> - u32 reg;
>> -
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
>> - reg |= DP_PLL_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
>> - reg &= ~DP_PLL_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
>> - }
>> -}
>> -
>> -void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
>> - enum analog_power_block block,
>> - bool enable)
>> -{
>> - u32 reg;
>> -
>> - switch (block) {
>> - case AUX_BLOCK:
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg |= AUX_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg &= ~AUX_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - }
>> - break;
>> - case CH0_BLOCK:
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg |= CH0_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg &= ~CH0_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - }
>> - break;
>> - case CH1_BLOCK:
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg |= CH1_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg &= ~CH1_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - }
>> - break;
>> - case CH2_BLOCK:
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg |= CH2_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg &= ~CH2_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - }
>> - break;
>> - case CH3_BLOCK:
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg |= CH3_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg &= ~CH3_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - }
>> - break;
>> - case ANALOG_TOTAL:
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg |= DP_PHY_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
>> - reg &= ~DP_PHY_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - }
>> - break;
>> - case POWER_ALL:
>> - if (enable) {
>> - reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
>> - CH1_PD | CH0_PD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - } else {
>> - writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD);
>> - }
>> - break;
>> - default:
>> - break;
>> - }
>> -}
>> -
>> -void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> - int timeout_loop = 0;
>> -
>> - exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
>> -
>> - reg = PLL_LOCK_CHG;
>> - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
>> - reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
>> - writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL);
>> -
>> - /* Power up PLL */
>> - if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
>> - exynos_dp_set_pll_power_down(dp, 0);
>> -
>> - while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
>> - timeout_loop++;
>> - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> - dev_err(dp->dev, "failed to get pll lock
>> status\n");
>> - return;
>> - }
>> - usleep_range(10, 20);
>> - }
>> - }
>> -
>> - /* Enable Serdes FIFO function and Link symbol clock domain module
>> */
>> - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> - reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
>> - | AUX_FUNC_EN_N);
>> - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> -}
>> -
>> -void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = HOTPLUG_CHG | HPD_LOST | PLUG;
>> - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
>> -
>> - reg = INT_HPD;
>> - writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
>> -}
>> -
>> -void exynos_dp_init_hpd(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - exynos_dp_clear_hotplug_interrupts(dp);
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> - reg &= ~(F_HPD | HPD_CTRL);
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> -}
>> -
>> -enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - /* Parse hotplug interrupt status register */
>> - reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
>> -
>> - if (reg & PLUG)
>> - return DP_IRQ_TYPE_HP_CABLE_IN;
>> -
>> - if (reg & HPD_LOST)
>> - return DP_IRQ_TYPE_HP_CABLE_OUT;
>> -
>> - if (reg & HOTPLUG_CHG)
>> - return DP_IRQ_TYPE_HP_CHANGE;
>> -
>> - return DP_IRQ_TYPE_UNKNOWN;
>> -}
>> -
>> -void exynos_dp_reset_aux(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - /* Disable AUX channel module */
>> - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> - reg |= AUX_FUNC_EN_N;
>> - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> -}
>> -
>> -void exynos_dp_init_aux(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - /* Clear inerrupts related to AUX channel */
>> - reg = RPLY_RECEIV | AUX_ERR;
>> - writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
>> -
>> - exynos_dp_reset_aux(dp);
>> -
>> - /* Disable AUX transaction H/W retry */
>> - reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
>> - AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL) ;
>> -
>> - /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
>> - reg = DEFER_CTRL_EN | DEFER_COUNT(1);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL);
>> -
>> - /* Enable AUX channel module */
>> - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> - reg &= ~AUX_FUNC_EN_N;
>> - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>> -}
>> -
>> -int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> - if (reg & HPD_STATUS)
>> - return 0;
>> -
>> - return -EINVAL;
>> -}
>> -
>> -void exynos_dp_enable_sw_function(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> - reg &= ~SW_FUNC_EN_N;
>> - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> -}
>> -
>> -int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
>> -{
>> - int reg;
>> - int retval = 0;
>> - int timeout_loop = 0;
>> -
>> - /* Enable AUX CH operation */
>> - reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
>> - reg |= AUX_EN;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
>> -
>> - /* Is AUX CH command reply received? */
>> - reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
>> - while (!(reg & RPLY_RECEIV)) {
>> - timeout_loop++;
>> - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
>> - dev_err(dp->dev, "AUX CH command reply failed!\n");
>> - return -ETIMEDOUT;
>> - }
>> - reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
>> - usleep_range(10, 11);
>> - }
>> -
>> - /* Clear interrupt source for AUX CH command reply */
>> - writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
>> -
>> - /* Clear interrupt source for AUX CH access error */
>> - reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
>> - if (reg & AUX_ERR) {
>> - writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA);
>> - return -EREMOTEIO;
>> - }
>> -
>> - /* Check AUX CH error access status */
>> - reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA);
>> - if ((reg & AUX_STATUS_MASK) != 0) {
>> - dev_err(dp->dev, "AUX CH error happens: %d\n\n",
>> - reg & AUX_STATUS_MASK);
>> - return -EREMOTEIO;
>> - }
>> -
>> - return retval;
>> -}
>> -
>> -int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
>> - unsigned int reg_addr,
>> - unsigned char data)
>> -{
>> - u32 reg;
>> - int i;
>> - int retval;
>> -
>> - for (i = 0; i < 3; i++) {
>> - /* Clear AUX CH data buffer */
>> - reg = BUF_CLR;
>> - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> -
>> - /* Select DPCD device address */
>> - reg = AUX_ADDR_7_0(reg_addr);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> - reg = AUX_ADDR_15_8(reg_addr);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> - reg = AUX_ADDR_19_16(reg_addr);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
>> -
>> - /* Write data buffer */
>> - reg = (unsigned int)data;
>> - writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
>> -
>> - /*
>> - * Set DisplayPort transaction and write 1 byte
>> - * If bit 3 is 1, DisplayPort transaction.
>> - * If Bit 3 is 0, I2C transaction.
>> - */
>> - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> -
>> - /* Start AUX transaction */
>> - retval = exynos_dp_start_aux_transaction(dp);
>> - if (retval == 0)
>> - break;
>> - else
>> - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
>> - __func__);
>> - }
>> -
>> - return retval;
>> -}
>> -
>> -int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
>> - unsigned int reg_addr,
>> - unsigned char *data)
>> -{
>> - u32 reg;
>> - int i;
>> - int retval;
>> -
>> - for (i = 0; i < 3; i++) {
>> - /* Clear AUX CH data buffer */
>> - reg = BUF_CLR;
>> - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> -
>> - /* Select DPCD device address */
>> - reg = AUX_ADDR_7_0(reg_addr);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> - reg = AUX_ADDR_15_8(reg_addr);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> - reg = AUX_ADDR_19_16(reg_addr);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
>> -
>> - /*
>> - * Set DisplayPort transaction and read 1 byte
>> - * If bit 3 is 1, DisplayPort transaction.
>> - * If Bit 3 is 0, I2C transaction.
>> - */
>> - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> -
>> - /* Start AUX transaction */
>> - retval = exynos_dp_start_aux_transaction(dp);
>> - if (retval == 0)
>> - break;
>> - else
>> - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
>> - __func__);
>> - }
>> -
>> - /* Read data buffer */
>> - reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
>> - *data = (unsigned char)(reg & 0xff);
>> -
>> - return retval;
>> -}
>> -
>> -int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
>> - unsigned int reg_addr,
>> - unsigned int count,
>> - unsigned char data[])
>> -{
>> - u32 reg;
>> - unsigned int start_offset;
>> - unsigned int cur_data_count;
>> - unsigned int cur_data_idx;
>> - int i;
>> - int retval = 0;
>> -
>> - /* Clear AUX CH data buffer */
>> - reg = BUF_CLR;
>> - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> -
>> - start_offset = 0;
>> - while (start_offset < count) {
>> - /* Buffer size of AUX CH is 16 * 4bytes */
>> - if ((count - start_offset) > 16)
>> - cur_data_count = 16;
>> - else
>> - cur_data_count = count - start_offset;
>> -
>> - for (i = 0; i < 3; i++) {
>> - /* Select DPCD device address */
>> - reg = AUX_ADDR_7_0(reg_addr + start_offset);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> - reg = AUX_ADDR_15_8(reg_addr + start_offset);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> - reg = AUX_ADDR_19_16(reg_addr + start_offset);
>> - writel(reg, dp->reg_base +
> EXYNOS_DP_AUX_ADDR_19_16);
>> -
>> - for (cur_data_idx = 0; cur_data_idx <
> cur_data_count;
>> - cur_data_idx++) {
>> - reg = data[start_offset + cur_data_idx];
>> - writel(reg, dp->reg_base +
> EXYNOS_DP_BUF_DATA_0
>> - + 4 *
> cur_data_idx);
>> - }
>> -
>> - /*
>> - * Set DisplayPort transaction and write
>> - * If bit 3 is 1, DisplayPort transaction.
>> - * If Bit 3 is 0, I2C transaction.
>> - */
>> - reg = AUX_LENGTH(cur_data_count) |
>> - AUX_TX_COMM_DP_TRANSACTION |
> AUX_TX_COMM_WRITE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> -
>> - /* Start AUX transaction */
>> - retval = exynos_dp_start_aux_transaction(dp);
>> - if (retval == 0)
>> - break;
>> - else
>> - dev_dbg(dp->dev, "%s: Aux Transaction
> fail!\n",
>> - __func__);
>> - }
>> -
>> - start_offset += cur_data_count;
>> - }
>> -
>> - return retval;
>> -}
>> -
>> -int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
>> - unsigned int reg_addr,
>> - unsigned int count,
>> - unsigned char data[])
>> -{
>> - u32 reg;
>> - unsigned int start_offset;
>> - unsigned int cur_data_count;
>> - unsigned int cur_data_idx;
>> - int i;
>> - int retval = 0;
>> -
>> - /* Clear AUX CH data buffer */
>> - reg = BUF_CLR;
>> - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> -
>> - start_offset = 0;
>> - while (start_offset < count) {
>> - /* Buffer size of AUX CH is 16 * 4bytes */
>> - if ((count - start_offset) > 16)
>> - cur_data_count = 16;
>> - else
>> - cur_data_count = count - start_offset;
>> -
>> - /* AUX CH Request Transaction process */
>> - for (i = 0; i < 3; i++) {
>> - /* Select DPCD device address */
>> - reg = AUX_ADDR_7_0(reg_addr + start_offset);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> - reg = AUX_ADDR_15_8(reg_addr + start_offset);
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> - reg = AUX_ADDR_19_16(reg_addr + start_offset);
>> - writel(reg, dp->reg_base +
> EXYNOS_DP_AUX_ADDR_19_16);
>> -
>> - /*
>> - * Set DisplayPort transaction and read
>> - * If bit 3 is 1, DisplayPort transaction.
>> - * If Bit 3 is 0, I2C transaction.
>> - */
>> - reg = AUX_LENGTH(cur_data_count) |
>> - AUX_TX_COMM_DP_TRANSACTION |
> AUX_TX_COMM_READ;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> -
>> - /* Start AUX transaction */
>> - retval = exynos_dp_start_aux_transaction(dp);
>> - if (retval == 0)
>> - break;
>> - else
>> - dev_dbg(dp->dev, "%s: Aux Transaction
> fail!\n",
>> - __func__);
>> - }
>> -
>> - for (cur_data_idx = 0; cur_data_idx < cur_data_count;
>> - cur_data_idx++) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
>> - + 4 * cur_data_idx);
>> - data[start_offset + cur_data_idx] =
>> - (unsigned char)reg;
>> - }
>> -
>> - start_offset += cur_data_count;
>> - }
>> -
>> - return retval;
>> -}
>> -
>> -int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
>> - unsigned int device_addr,
>> - unsigned int reg_addr)
>> -{
>> - u32 reg;
>> - int retval;
>> -
>> - /* Set EDID device address */
>> - reg = device_addr;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
>> - writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
>> - writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
>> -
>> - /* Set offset from base address of EDID device */
>> - writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
>> -
>> - /*
>> - * Set I2C transaction and write address
>> - * If bit 3 is 1, DisplayPort transaction.
>> - * If Bit 3 is 0, I2C transaction.
>> - */
>> - reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
>> - AUX_TX_COMM_WRITE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> -
>> - /* Start AUX transaction */
>> - retval = exynos_dp_start_aux_transaction(dp);
>> - if (retval != 0)
>> - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
>> -
>> - return retval;
>> -}
>> -
>> -int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
>> - unsigned int device_addr,
>> - unsigned int reg_addr,
>> - unsigned int *data)
>> -{
>> - u32 reg;
>> - int i;
>> - int retval;
>> -
>> - for (i = 0; i < 3; i++) {
>> - /* Clear AUX CH data buffer */
>> - reg = BUF_CLR;
>> - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
>> -
>> - /* Select EDID device */
>> - retval = exynos_dp_select_i2c_device(dp, device_addr,
>> reg_addr);
>> - if (retval != 0)
>> - continue;
>> -
>> - /*
>> - * Set I2C transaction and read data
>> - * If bit 3 is 1, DisplayPort transaction.
>> - * If Bit 3 is 0, I2C transaction.
>> - */
>> - reg = AUX_TX_COMM_I2C_TRANSACTION |
>> - AUX_TX_COMM_READ;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
>> -
>> - /* Start AUX transaction */
>> - retval = exynos_dp_start_aux_transaction(dp);
>> - if (retval == 0)
>> - break;
>> - else
>> - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
>> - __func__);
>> - }
>> -
>> - /* Read data */
>> - if (retval == 0)
>> - *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
>> -
>> - return retval;
>> -}
>> -
>> -int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
>> - unsigned int device_addr,
>> - unsigned int reg_addr,
>> - unsigned int count,
>> - unsigned char edid[])
>> -{
>> - u32 reg;
>> - unsigned int i, j;
>> - unsigned int cur_data_idx;
>> - unsigned int defer = 0;
>> - int retval = 0;
>> -
>> - for (i = 0; i < count; i += 16) {
>> - for (j = 0; j < 3; j++) {
>> - /* Clear AUX CH data buffer */
>> - reg = BUF_CLR;
>> - writel(reg, dp->reg_base +
> EXYNOS_DP_BUFFER_DATA_CTL);
>> -
>> - /* Set normal AUX CH command */
>> - reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
>> - reg &= ~ADDR_ONLY;
>> - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
>> -
>> - /*
>> - * If Rx sends defer, Tx sends only reads
>> - * request without sending address
>> - */
>> - if (!defer)
>> - retval = exynos_dp_select_i2c_device(dp,
>> - device_addr, reg_addr + i);
>> - else
>> - defer = 0;
>> -
>> - if (retval == 0) {
>> - /*
>> - * Set I2C transaction and write data
>> - * If bit 3 is 1, DisplayPort transaction.
>> - * If Bit 3 is 0, I2C transaction.
>> - */
>> - reg = AUX_LENGTH(16) |
>> - AUX_TX_COMM_I2C_TRANSACTION |
>> - AUX_TX_COMM_READ;
>> - writel(reg, dp->reg_base +
>> - EXYNOS_DP_AUX_CH_CTL_1);
>> -
>> - /* Start AUX transaction */
>> - retval =
> exynos_dp_start_aux_transaction(dp);
>> - if (retval == 0)
>> - break;
>> - else
>> - dev_dbg(dp->dev,
>> - "%s: Aux Transaction
> fail!\n",
>> - __func__);
>> - }
>> - /* Check if Rx sends defer */
>> - reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
>> - if (reg == AUX_RX_COMM_AUX_DEFER ||
>> - reg == AUX_RX_COMM_I2C_DEFER) {
>> - dev_err(dp->dev, "Defer: %d\n\n", reg);
>> - defer = 1;
>> - }
>> - }
>> -
>> - for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
>> - + 4 * cur_data_idx);
>> - edid[i + cur_data_idx] = (unsigned char)reg;
>> - }
>> - }
>> -
>> - return retval;
>> -}
>> -
>> -void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32
> bwtype)
>> -{
>> - u32 reg;
>> -
>> - reg = bwtype;
>> - if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype ==
>> LINK_RATE_1_62GBPS))
>> - writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET);
>> -}
>> -
>> -void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32
>> *bwtype)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET);
>> - *bwtype = reg;
>> -}
>> -
>> -void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count)
>> -{
>> - u32 reg;
>> -
>> - reg = count;
>> - writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
>> -}
>> -
>> -void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
>> - *count = reg;
>> -}
>> -
>> -void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool
>> enable)
>> -{
>> - u32 reg;
>> -
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> - reg |= ENHANCED;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> - reg &= ~ENHANCED;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> - }
>> -}
>> -
>> -void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
>> - enum pattern_set pattern)
>> -{
>> - u32 reg;
>> -
>> - switch (pattern) {
>> - case PRBS7:
>> - reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
>> - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> - break;
>> - case D10_2:
>> - reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
>> - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> - break;
>> - case TRAINING_PTN1:
>> - reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
>> - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> - break;
>> - case TRAINING_PTN2:
>> - reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
>> - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> - break;
>> - case DP_NONE:
>> - reg = SCRAMBLING_ENABLE |
>> - LINK_QUAL_PATTERN_SET_DISABLE |
>> - SW_TRAINING_PATTERN_SET_NORMAL;
>> - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> - break;
>> - default:
>> - break;
>> - }
>> -}
>> -
>> -void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32
>> level)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
>> - reg &= ~PRE_EMPHASIS_SET_MASK;
>> - reg |= level << PRE_EMPHASIS_SET_SHIFT;
>> - writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
>> -}
>> -
>> -void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32
>> level)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
>> - reg &= ~PRE_EMPHASIS_SET_MASK;
>> - reg |= level << PRE_EMPHASIS_SET_SHIFT;
>> - writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
>> -}
>> -
>> -void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32
>> level)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
>> - reg &= ~PRE_EMPHASIS_SET_MASK;
>> - reg |= level << PRE_EMPHASIS_SET_SHIFT;
>> - writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
>> -}
>> -
>> -void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32
>> level)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
>> - reg &= ~PRE_EMPHASIS_SET_MASK;
>> - reg |= level << PRE_EMPHASIS_SET_SHIFT;
>> - writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
>> -}
>> -
>> -void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
>> - u32 training_lane)
>> -{
>> - u32 reg;
>> -
>> - reg = training_lane;
>> - writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
>> -}
>> -
>> -void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
>> - u32 training_lane)
>> -{
>> - u32 reg;
>> -
>> - reg = training_lane;
>> - writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
>> -}
>> -
>> -void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
>> - u32 training_lane)
>> -{
>> - u32 reg;
>> -
>> - reg = training_lane;
>> - writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
>> -}
>> -
>> -void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
>> - u32 training_lane)
>> -{
>> - u32 reg;
>> -
>> - reg = training_lane;
>> - writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
>> -}
>> -
>> -u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
>> - return reg;
>> -}
>> -
>> -u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
>> - return reg;
>> -}
>> -
>> -u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
>> - return reg;
>> -}
>> -
>> -u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
>> - return reg;
>> -}
>> -
>> -void exynos_dp_reset_macro(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST);
>> - reg |= MACRO_RST;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
>> -
>> - /* 10 us is the minimum reset time. */
>> - usleep_range(10, 20);
>> -
>> - reg &= ~MACRO_RST;
>> - writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
>> -}
>> -
>> -void exynos_dp_init_video(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
>> - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
>> -
>> - reg = 0x0;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> -
>> - reg = CHA_CRI(4) | CHA_CTRL;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> -
>> - reg = 0x0;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> -
>> - reg = VID_HRES_TH(2) | VID_VRES_TH(0);
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
>> -}
>> -
>> -void exynos_dp_set_video_color_format(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - /* Configure the input color depth, color space, dynamic range */
>> - reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
>> - (dp->video_info->color_depth << IN_BPC_SHIFT) |
>> - (dp->video_info->color_space << IN_COLOR_F_SHIFT);
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
>> -
>> - /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
>> - reg &= ~IN_YC_COEFFI_MASK;
>> - if (dp->video_info->ycbcr_coeff)
>> - reg |= IN_YC_COEFFI_ITU709;
>> - else
>> - reg |= IN_YC_COEFFI_ITU601;
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
>> -}
>> -
>> -int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
>> -
>> - if (!(reg & DET_STA)) {
>> - dev_dbg(dp->dev, "Input stream clock not detected.\n");
>> - return -EINVAL;
>> - }
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
>> - dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
>> -
>> - if (reg & CHA_STA) {
>> - dev_dbg(dp->dev, "Input stream clk is changing\n");
>> - return -EINVAL;
>> - }
>> -
>> - return 0;
>> -}
>> -
>> -void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
>> - enum clock_recovery_m_value_type type,
>> - u32 m_value,
>> - u32 n_value)
>> -{
>> - u32 reg;
>> -
>> - if (type == REGISTER_M) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> - reg |= FIX_M_VID;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> - reg = m_value & 0xff;
>> - writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0);
>> - reg = (m_value >> 8) & 0xff;
>> - writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1);
>> - reg = (m_value >> 16) & 0xff;
>> - writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2);
>> -
>> - reg = n_value & 0xff;
>> - writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0);
>> - reg = (n_value >> 8) & 0xff;
>> - writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1);
>> - reg = (n_value >> 16) & 0xff;
>> - writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> - reg &= ~FIX_M_VID;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
>> -
>> - writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0);
>> - writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1);
>> - writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2);
>> - }
>> -}
>> -
>> -void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32
>> type)
>> -{
>> - u32 reg;
>> -
>> - if (type == VIDEO_TIMING_FROM_CAPTURE) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> - reg &= ~FORMAT_SEL;
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> - reg |= FORMAT_SEL;
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> - }
>> -}
>> -
>> -void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool
>> enable)
>> -{
>> - u32 reg;
>> -
>> - if (enable) {
>> - reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> - reg &= ~VIDEO_MODE_MASK;
>> - reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> - } else {
>> - reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> - reg &= ~VIDEO_MODE_MASK;
>> - reg |= VIDEO_MODE_SLAVE_MODE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> - }
>> -}
>> -
>> -void exynos_dp_start_video(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> - reg |= VIDEO_EN;
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
>> -}
>> -
>> -int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
>> - if (!(reg & STRM_VALID)) {
>> - dev_dbg(dp->dev, "Input video stream is not detected.\n");
>> - return -EINVAL;
>> - }
>> -
>> - return 0;
>> -}
>> -
>> -void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> - reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
>> - reg |= MASTER_VID_FUNC_EN_N;
>> - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> - reg &= ~INTERACE_SCAN_CFG;
>> - reg |= (dp->video_info->interlaced << 2);
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> - reg &= ~VSYNC_POLARITY_CFG;
>> - reg |= (dp->video_info->v_sync_polarity << 1);
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> - reg &= ~HSYNC_POLARITY_CFG;
>> - reg |= (dp->video_info->h_sync_polarity << 0);
>> - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
>> -
>> - reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
>> -}
>> -
>> -void exynos_dp_enable_scrambling(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> - reg &= ~SCRAMBLING_DISABLE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> -}
>> -
>> -void exynos_dp_disable_scrambling(struct exynos_dp_device *dp)
>> -{
>> - u32 reg;
>> -
>> - reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> - reg |= SCRAMBLING_DISABLE;
>> - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
>> -}
>> diff --git a/drivers/video/exynos/exynos_dp_reg.h
>> b/drivers/video/exynos/exynos_dp_reg.h
>> deleted file mode 100644
>> index 2e9bd0e..0000000
>> --- a/drivers/video/exynos/exynos_dp_reg.h
>> +++ /dev/null
>> @@ -1,366 +0,0 @@
>> -/*
>> - * Register definition file for Samsung DP driver
>> - *
>> - * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>> - * Author: Jingoo Han <jg1.han at samsung.com>
>> - *
>> - * This program is free software; you can redistribute it and/or modify
>> - * it under the terms of the GNU General Public License version 2 as
>> - * published by the Free Software Foundation.
>> - */
>> -
>> -#ifndef _EXYNOS_DP_REG_H
>> -#define _EXYNOS_DP_REG_H
>> -
>> -#define EXYNOS_DP_TX_SW_RESET 0x14
>> -#define EXYNOS_DP_FUNC_EN_1 0x18
>> -#define EXYNOS_DP_FUNC_EN_2 0x1C
>> -#define EXYNOS_DP_VIDEO_CTL_1 0x20
>> -#define EXYNOS_DP_VIDEO_CTL_2 0x24
>> -#define EXYNOS_DP_VIDEO_CTL_3 0x28
>> -
>> -#define EXYNOS_DP_VIDEO_CTL_8 0x3C
>> -#define EXYNOS_DP_VIDEO_CTL_10 0x44
>> -
>> -#define EXYNOS_DP_LANE_MAP 0x35C
>> -
>> -#define EXYNOS_DP_ANALOG_CTL_1 0x370
>> -#define EXYNOS_DP_ANALOG_CTL_2 0x374
>> -#define EXYNOS_DP_ANALOG_CTL_3 0x378
>> -#define EXYNOS_DP_PLL_FILTER_CTL_1 0x37C
>> -#define EXYNOS_DP_TX_AMP_TUNING_CTL 0x380
>> -
>> -#define EXYNOS_DP_AUX_HW_RETRY_CTL 0x390
>> -
>> -#define EXYNOS_DP_COMMON_INT_STA_1 0x3C4
>> -#define EXYNOS_DP_COMMON_INT_STA_2 0x3C8
>> -#define EXYNOS_DP_COMMON_INT_STA_3 0x3CC
>> -#define EXYNOS_DP_COMMON_INT_STA_4 0x3D0
>> -#define EXYNOS_DP_INT_STA 0x3DC
>> -#define EXYNOS_DP_COMMON_INT_MASK_1 0x3E0
>> -#define EXYNOS_DP_COMMON_INT_MASK_2 0x3E4
>> -#define EXYNOS_DP_COMMON_INT_MASK_3 0x3E8
>> -#define EXYNOS_DP_COMMON_INT_MASK_4 0x3EC
>> -#define EXYNOS_DP_INT_STA_MASK 0x3F8
>> -#define EXYNOS_DP_INT_CTL 0x3FC
>> -
>> -#define EXYNOS_DP_SYS_CTL_1 0x600
>> -#define EXYNOS_DP_SYS_CTL_2 0x604
>> -#define EXYNOS_DP_SYS_CTL_3 0x608
>> -#define EXYNOS_DP_SYS_CTL_4 0x60C
>> -
>> -#define EXYNOS_DP_PKT_SEND_CTL 0x640
>> -#define EXYNOS_DP_HDCP_CTL 0x648
>> -
>> -#define EXYNOS_DP_LINK_BW_SET 0x680
>> -#define EXYNOS_DP_LANE_COUNT_SET 0x684
>> -#define EXYNOS_DP_TRAINING_PTN_SET 0x688
>> -#define EXYNOS_DP_LN0_LINK_TRAINING_CTL 0x68C
>> -#define EXYNOS_DP_LN1_LINK_TRAINING_CTL 0x690
>> -#define EXYNOS_DP_LN2_LINK_TRAINING_CTL 0x694
>> -#define EXYNOS_DP_LN3_LINK_TRAINING_CTL 0x698
>> -
>> -#define EXYNOS_DP_DEBUG_CTL 0x6C0
>> -#define EXYNOS_DP_HPD_DEGLITCH_L 0x6C4
>> -#define EXYNOS_DP_HPD_DEGLITCH_H 0x6C8
>> -#define EXYNOS_DP_LINK_DEBUG_CTL 0x6E0
>> -
>> -#define EXYNOS_DP_M_VID_0 0x700
>> -#define EXYNOS_DP_M_VID_1 0x704
>> -#define EXYNOS_DP_M_VID_2 0x708
>> -#define EXYNOS_DP_N_VID_0 0x70C
>> -#define EXYNOS_DP_N_VID_1 0x710
>> -#define EXYNOS_DP_N_VID_2 0x714
>> -
>> -#define EXYNOS_DP_PLL_CTL 0x71C
>> -#define EXYNOS_DP_PHY_PD 0x720
>> -#define EXYNOS_DP_PHY_TEST 0x724
>> -
>> -#define EXYNOS_DP_VIDEO_FIFO_THRD 0x730
>> -#define EXYNOS_DP_AUDIO_MARGIN 0x73C
>> -
>> -#define EXYNOS_DP_M_VID_GEN_FILTER_TH 0x764
>> -#define EXYNOS_DP_M_AUD_GEN_FILTER_TH 0x778
>> -#define EXYNOS_DP_AUX_CH_STA 0x780
>> -#define EXYNOS_DP_AUX_CH_DEFER_CTL 0x788
>> -#define EXYNOS_DP_AUX_RX_COMM 0x78C
>> -#define EXYNOS_DP_BUFFER_DATA_CTL 0x790
>> -#define EXYNOS_DP_AUX_CH_CTL_1 0x794
>> -#define EXYNOS_DP_AUX_ADDR_7_0 0x798
>> -#define EXYNOS_DP_AUX_ADDR_15_8 0x79C
>> -#define EXYNOS_DP_AUX_ADDR_19_16 0x7A0
>> -#define EXYNOS_DP_AUX_CH_CTL_2 0x7A4
>> -
>> -#define EXYNOS_DP_BUF_DATA_0 0x7C0
>> -
>> -#define EXYNOS_DP_SOC_GENERAL_CTL 0x800
>> -
>> -/* EXYNOS_DP_TX_SW_RESET */
>> -#define RESET_DP_TX (0x1 << 0)
>> -
>> -/* EXYNOS_DP_FUNC_EN_1 */
>> -#define MASTER_VID_FUNC_EN_N (0x1 << 7)
>> -#define SLAVE_VID_FUNC_EN_N (0x1 << 5)
>> -#define AUD_FIFO_FUNC_EN_N (0x1 << 4)
>> -#define AUD_FUNC_EN_N (0x1 << 3)
>> -#define HDCP_FUNC_EN_N (0x1 << 2)
>> -#define CRC_FUNC_EN_N (0x1 << 1)
>> -#define SW_FUNC_EN_N (0x1 << 0)
>> -
>> -/* EXYNOS_DP_FUNC_EN_2 */
>> -#define SSC_FUNC_EN_N (0x1 << 7)
>> -#define AUX_FUNC_EN_N (0x1 << 2)
>> -#define SERDES_FIFO_FUNC_EN_N (0x1 << 1)
>> -#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0)
>> -
>> -/* EXYNOS_DP_VIDEO_CTL_1 */
>> -#define VIDEO_EN (0x1 << 7)
>> -#define HDCP_VIDEO_MUTE (0x1 << 6)
>> -
>> -/* EXYNOS_DP_VIDEO_CTL_1 */
>> -#define IN_D_RANGE_MASK (0x1 << 7)
>> -#define IN_D_RANGE_SHIFT (7)
>> -#define IN_D_RANGE_CEA (0x1 << 7)
>> -#define IN_D_RANGE_VESA (0x0 << 7)
>> -#define IN_BPC_MASK (0x7 << 4)
>> -#define IN_BPC_SHIFT (4)
>> -#define IN_BPC_12_BITS (0x3 << 4)
>> -#define IN_BPC_10_BITS (0x2 << 4)
>> -#define IN_BPC_8_BITS (0x1 << 4)
>> -#define IN_BPC_6_BITS (0x0 << 4)
>> -#define IN_COLOR_F_MASK (0x3 << 0)
>> -#define IN_COLOR_F_SHIFT (0)
>> -#define IN_COLOR_F_YCBCR444 (0x2 << 0)
>> -#define IN_COLOR_F_YCBCR422 (0x1 << 0)
>> -#define IN_COLOR_F_RGB (0x0 << 0)
>> -
>> -/* EXYNOS_DP_VIDEO_CTL_3 */
>> -#define IN_YC_COEFFI_MASK (0x1 << 7)
>> -#define IN_YC_COEFFI_SHIFT (7)
>> -#define IN_YC_COEFFI_ITU709 (0x1 << 7)
>> -#define IN_YC_COEFFI_ITU601 (0x0 << 7)
>> -#define VID_CHK_UPDATE_TYPE_MASK (0x1 << 4)
>> -#define VID_CHK_UPDATE_TYPE_SHIFT (4)
>> -#define VID_CHK_UPDATE_TYPE_1 (0x1 << 4)
>> -#define VID_CHK_UPDATE_TYPE_0 (0x0 << 4)
>> -
>> -/* EXYNOS_DP_VIDEO_CTL_8 */
>> -#define VID_HRES_TH(x) (((x) & 0xf) << 4)
>> -#define VID_VRES_TH(x) (((x) & 0xf) << 0)
>> -
>> -/* EXYNOS_DP_VIDEO_CTL_10 */
>> -#define FORMAT_SEL (0x1 << 4)
>> -#define INTERACE_SCAN_CFG (0x1 << 2)
>> -#define VSYNC_POLARITY_CFG (0x1 << 1)
>> -#define HSYNC_POLARITY_CFG (0x1 << 0)
>> -
>> -/* EXYNOS_DP_LANE_MAP */
>> -#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
>> -#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6)
>> -#define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6)
>> -#define LANE3_MAP_LOGIC_LANE_3 (0x3 << 6)
>> -#define LANE2_MAP_LOGIC_LANE_0 (0x0 << 4)
>> -#define LANE2_MAP_LOGIC_LANE_1 (0x1 << 4)
>> -#define LANE2_MAP_LOGIC_LANE_2 (0x2 << 4)
>> -#define LANE2_MAP_LOGIC_LANE_3 (0x3 << 4)
>> -#define LANE1_MAP_LOGIC_LANE_0 (0x0 << 2)
>> -#define LANE1_MAP_LOGIC_LANE_1 (0x1 << 2)
>> -#define LANE1_MAP_LOGIC_LANE_2 (0x2 << 2)
>> -#define LANE1_MAP_LOGIC_LANE_3 (0x3 << 2)
>> -#define LANE0_MAP_LOGIC_LANE_0 (0x0 << 0)
>> -#define LANE0_MAP_LOGIC_LANE_1 (0x1 << 0)
>> -#define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0)
>> -#define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0)
>> -
>> -/* EXYNOS_DP_ANALOG_CTL_1 */
>> -#define TX_TERMINAL_CTRL_50_OHM (0x1 << 4)
>> -
>> -/* EXYNOS_DP_ANALOG_CTL_2 */
>> -#define SEL_24M (0x1 << 3)
>> -#define TX_DVDD_BIT_1_0625V (0x4 << 0)
>> -
>> -/* EXYNOS_DP_ANALOG_CTL_3 */
>> -#define DRIVE_DVDD_BIT_1_0625V (0x4 << 5)
>> -#define VCO_BIT_600_MICRO (0x5 << 0)
>> -
>> -/* EXYNOS_DP_PLL_FILTER_CTL_1 */
>> -#define PD_RING_OSC (0x1 << 6)
>> -#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
>> -#define TX_CUR1_2X (0x1 << 2)
>> -#define TX_CUR_16_MA (0x3 << 0)
>> -
>> -/* EXYNOS_DP_TX_AMP_TUNING_CTL */
>> -#define CH3_AMP_400_MV (0x0 << 24)
>> -#define CH2_AMP_400_MV (0x0 << 16)
>> -#define CH1_AMP_400_MV (0x0 << 8)
>> -#define CH0_AMP_400_MV (0x0 << 0)
>> -
>> -/* EXYNOS_DP_AUX_HW_RETRY_CTL */
>> -#define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8)
>> -#define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3)
>> -#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3)
>> -#define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS (0x1 << 3)
>> -#define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS (0x2 << 3)
>> -#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3)
>> -#define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0)
>> -
>> -/* EXYNOS_DP_COMMON_INT_STA_1 */
>> -#define VSYNC_DET (0x1 << 7)
>> -#define PLL_LOCK_CHG (0x1 << 6)
>> -#define SPDIF_ERR (0x1 << 5)
>> -#define SPDIF_UNSTBL (0x1 << 4)
>> -#define VID_FORMAT_CHG (0x1 << 3)
>> -#define AUD_CLK_CHG (0x1 << 2)
>> -#define VID_CLK_CHG (0x1 << 1)
>> -#define SW_INT (0x1 << 0)
>> -
>> -/* EXYNOS_DP_COMMON_INT_STA_2 */
>> -#define ENC_EN_CHG (0x1 << 6)
>> -#define HW_BKSV_RDY (0x1 << 3)
>> -#define HW_SHA_DONE (0x1 << 2)
>> -#define HW_AUTH_STATE_CHG (0x1 << 1)
>> -#define HW_AUTH_DONE (0x1 << 0)
>> -
>> -/* EXYNOS_DP_COMMON_INT_STA_3 */
>> -#define AFIFO_UNDER (0x1 << 7)
>> -#define AFIFO_OVER (0x1 << 6)
>> -#define R0_CHK_FLAG (0x1 << 5)
>> -
>> -/* EXYNOS_DP_COMMON_INT_STA_4 */
>> -#define PSR_ACTIVE (0x1 << 7)
>> -#define PSR_INACTIVE (0x1 << 6)
>> -#define SPDIF_BI_PHASE_ERR (0x1 << 5)
>> -#define HOTPLUG_CHG (0x1 << 2)
>> -#define HPD_LOST (0x1 << 1)
>> -#define PLUG (0x1 << 0)
>> -
>> -/* EXYNOS_DP_INT_STA */
>> -#define INT_HPD (0x1 << 6)
>> -#define HW_TRAINING_FINISH (0x1 << 5)
>> -#define RPLY_RECEIV (0x1 << 1)
>> -#define AUX_ERR (0x1 << 0)
>> -
>> -/* EXYNOS_DP_INT_CTL */
>> -#define SOFT_INT_CTRL (0x1 << 2)
>> -#define INT_POL1 (0x1 << 1)
>> -#define INT_POL0 (0x1 << 0)
>> -
>> -/* EXYNOS_DP_SYS_CTL_1 */
>> -#define DET_STA (0x1 << 2)
>> -#define FORCE_DET (0x1 << 1)
>> -#define DET_CTRL (0x1 << 0)
>> -
>> -/* EXYNOS_DP_SYS_CTL_2 */
>> -#define CHA_CRI(x) (((x) & 0xf) << 4)
>> -#define CHA_STA (0x1 << 2)
>> -#define FORCE_CHA (0x1 << 1)
>> -#define CHA_CTRL (0x1 << 0)
>> -
>> -/* EXYNOS_DP_SYS_CTL_3 */
>> -#define HPD_STATUS (0x1 << 6)
>> -#define F_HPD (0x1 << 5)
>> -#define HPD_CTRL (0x1 << 4)
>> -#define HDCP_RDY (0x1 << 3)
>> -#define STRM_VALID (0x1 << 2)
>> -#define F_VALID (0x1 << 1)
>> -#define VALID_CTRL (0x1 << 0)
>> -
>> -/* EXYNOS_DP_SYS_CTL_4 */
>> -#define FIX_M_AUD (0x1 << 4)
>> -#define ENHANCED (0x1 << 3)
>> -#define FIX_M_VID (0x1 << 2)
>> -#define M_VID_UPDATE_CTRL (0x3 << 0)
>> -
>> -/* EXYNOS_DP_TRAINING_PTN_SET */
>> -#define SCRAMBLER_TYPE (0x1 << 9)
>> -#define HW_LINK_TRAINING_PATTERN (0x1 << 8)
>> -#define SCRAMBLING_DISABLE (0x1 << 5)
>> -#define SCRAMBLING_ENABLE (0x0 << 5)
>> -#define LINK_QUAL_PATTERN_SET_MASK (0x3 << 2)
>> -#define LINK_QUAL_PATTERN_SET_PRBS7 (0x3 << 2)
>> -#define LINK_QUAL_PATTERN_SET_D10_2 (0x1 << 2)
>> -#define LINK_QUAL_PATTERN_SET_DISABLE (0x0 << 2)
>> -#define SW_TRAINING_PATTERN_SET_MASK (0x3 << 0)
>> -#define SW_TRAINING_PATTERN_SET_PTN2 (0x2 << 0)
>> -#define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0)
>> -#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0)
>> -
>> -/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
>> -#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
>> -#define PRE_EMPHASIS_SET_SHIFT (3)
>> -
>> -/* EXYNOS_DP_DEBUG_CTL */
>> -#define PLL_LOCK (0x1 << 4)
>> -#define F_PLL_LOCK (0x1 << 3)
>> -#define PLL_LOCK_CTRL (0x1 << 2)
>> -#define PN_INV (0x1 << 0)
>> -
>> -/* EXYNOS_DP_PLL_CTL */
>> -#define DP_PLL_PD (0x1 << 7)
>> -#define DP_PLL_RESET (0x1 << 6)
>> -#define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4)
>> -#define DP_PLL_REF_BIT_1_1250V (0x5 << 0)
>> -#define DP_PLL_REF_BIT_1_2500V (0x7 << 0)
>> -
>> -/* EXYNOS_DP_PHY_PD */
>> -#define DP_PHY_PD (0x1 << 5)
>> -#define AUX_PD (0x1 << 4)
>> -#define CH3_PD (0x1 << 3)
>> -#define CH2_PD (0x1 << 2)
>> -#define CH1_PD (0x1 << 1)
>> -#define CH0_PD (0x1 << 0)
>> -
>> -/* EXYNOS_DP_PHY_TEST */
>> -#define MACRO_RST (0x1 << 5)
>> -#define CH1_TEST (0x1 << 1)
>> -#define CH0_TEST (0x1 << 0)
>> -
>> -/* EXYNOS_DP_AUX_CH_STA */
>> -#define AUX_BUSY (0x1 << 4)
>> -#define AUX_STATUS_MASK (0xf << 0)
>> -
>> -/* EXYNOS_DP_AUX_CH_DEFER_CTL */
>> -#define DEFER_CTRL_EN (0x1 << 7)
>> -#define DEFER_COUNT(x) (((x) & 0x7f) << 0)
>> -
>> -/* EXYNOS_DP_AUX_RX_COMM */
>> -#define AUX_RX_COMM_I2C_DEFER (0x2 << 2)
>> -#define AUX_RX_COMM_AUX_DEFER (0x2 << 0)
>> -
>> -/* EXYNOS_DP_BUFFER_DATA_CTL */
>> -#define BUF_CLR (0x1 << 7)
>> -#define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0)
>> -
>> -/* EXYNOS_DP_AUX_CH_CTL_1 */
>> -#define AUX_LENGTH(x) (((x - 1) & 0xf) <<
> 4)
>> -#define AUX_TX_COMM_MASK (0xf << 0)
>> -#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3)
>> -#define AUX_TX_COMM_I2C_TRANSACTION (0x0 << 3)
>> -#define AUX_TX_COMM_MOT (0x1 << 2)
>> -#define AUX_TX_COMM_WRITE (0x0 << 0)
>> -#define AUX_TX_COMM_READ (0x1 << 0)
>> -
>> -/* EXYNOS_DP_AUX_ADDR_7_0 */
>> -#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff)
>> -
>> -/* EXYNOS_DP_AUX_ADDR_15_8 */
>> -#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff)
>> -
>> -/* EXYNOS_DP_AUX_ADDR_19_16 */
>> -#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f)
>> -
>> -/* EXYNOS_DP_AUX_CH_CTL_2 */
>> -#define ADDR_ONLY (0x1 << 1)
>> -#define AUX_EN (0x1 << 0)
>> -
>> -/* EXYNOS_DP_SOC_GENERAL_CTL */
>> -#define AUDIO_MODE_SPDIF_MODE (0x1 << 8)
>> -#define AUDIO_MODE_MASTER_MODE (0x0 << 8)
>> -#define MASTER_VIDEO_INTERLACE_EN (0x1 << 4)
>> -#define VIDEO_MASTER_CLK_SEL (0x1 << 2)
>> -#define VIDEO_MASTER_MODE_EN (0x1 << 1)
>> -#define VIDEO_MODE_MASK (0x1 << 0)
>> -#define VIDEO_MODE_SLAVE_MODE (0x1 << 0)
>> -#define VIDEO_MODE_MASTER_MODE (0x0 << 0)
>> -
>> -#endif /* _EXYNOS_DP_REG_H */
>> --
>> 1.8.4
>
More information about the dri-devel
mailing list