1e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han/* 2e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Samsung DP (Display port) register interface driver. 3e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * 4e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Author: Jingoo Han <jg1.han@samsung.com> 6e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * 7e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * This program is free software; you can redistribute it and/or modify it 8e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * under the terms of the GNU General Public License as published by the 9e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Free Software Foundation; either version 2 of the License, or (at your 10e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * option) any later version. 11e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han */ 12e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 13e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han#include <linux/device.h> 14e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han#include <linux/io.h> 15e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han#include <linux/delay.h> 16b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker#include <linux/gpio.h> 17e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 18e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han#include "exynos_dp_core.h" 19e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han#include "exynos_dp_reg.h" 20e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 21c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul#define COMMON_INT_MASK_1 0 22c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul#define COMMON_INT_MASK_2 0 23c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul#define COMMON_INT_MASK_3 0 24c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG) 25c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul#define INT_STA_MASK INT_HPD 26e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 27e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable) 28e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 29e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 30e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 31e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 32e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 33e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= HDCP_VIDEO_MUTE; 34e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 35e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 36e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 37e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~HDCP_VIDEO_MUTE; 38e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 39e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 40e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 41e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 42e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_stop_video(struct exynos_dp_device *dp) 43e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 44e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 45e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 46e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 47e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~VIDEO_EN; 48e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 49e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 50e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 51e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable) 52e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 53e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 54e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 55e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) 56e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 | 57e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3; 58e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 59e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 | 60e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0; 61e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 62e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP); 63e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 64e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 658affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Hanvoid exynos_dp_init_analog_param(struct exynos_dp_device *dp) 668affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han{ 678affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han u32 reg; 688affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han 698affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han reg = TX_TERMINAL_CTRL_50_OHM; 708affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1); 718affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han 728affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han reg = SEL_24M | TX_DVDD_BIT_1_0625V; 738affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2); 748affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han 758affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO; 768affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3); 778affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han 788affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | 795fdc62ca62d7e896ef8ad64b68127e81eb3bdc3fJingoo Han TX_CUR1_2X | TX_CUR_16_MA; 808affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1); 818affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han 828affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han reg = CH3_AMP_400_MV | CH2_AMP_400_MV | 838affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han CH1_AMP_400_MV | CH0_AMP_400_MV; 848affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL); 858affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han} 868affaf5c7698c627b133bfcafd9869ef17faff31Jingoo Han 87e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_init_interrupt(struct exynos_dp_device *dp) 88e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 89e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Set interrupt pin assertion polarity as high */ 902f85f97e460a4bcfad678151fcc13dbf0b8181b3Ajay Kumar writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL); 91e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 92e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear pending regisers */ 93e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 94e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2); 95e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3); 96e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 97e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA); 98e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 99e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 0:mask,1: unmask */ 100e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); 101e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); 102e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); 103e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); 104e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK); 105e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 106e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 107e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_reset(struct exynos_dp_device *dp) 108e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 109e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 110e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 111e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han exynos_dp_stop_video(dp); 112e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han exynos_dp_enable_video_mute(dp, 0); 113e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 114e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | 115e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | 116e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han HDCP_FUNC_EN_N | SW_FUNC_EN_N; 117e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); 118e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 119e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N | 120e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han SERDES_FIFO_FUNC_EN_N | 121e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han LS_CLK_DOMAIN_FUNC_EN_N; 122e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 123e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 124a2c81bc12c81189928a03a94da1565d0c14e32ebJingoo Han usleep_range(20, 30); 125e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 126e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han exynos_dp_lane_swap(dp, 0); 127e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 128e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1); 129e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2); 130e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 131e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 132e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 133e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL); 134e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL); 135e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 136e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L); 137e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H); 138e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 139e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL); 140e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 141e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST); 142e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 143e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD); 144e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN); 145e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 146e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH); 147e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH); 148e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 149e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 150e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 151e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 15224db03a834089a3600780ea1c7abe08e483e5d29Jingoo Hanvoid exynos_dp_swreset(struct exynos_dp_device *dp) 15324db03a834089a3600780ea1c7abe08e483e5d29Jingoo Han{ 15424db03a834089a3600780ea1c7abe08e483e5d29Jingoo Han writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET); 15524db03a834089a3600780ea1c7abe08e483e5d29Jingoo Han} 15624db03a834089a3600780ea1c7abe08e483e5d29Jingoo Han 157e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_config_interrupt(struct exynos_dp_device *dp) 158e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 159e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 160e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 161e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 0: mask, 1: unmask */ 162e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = COMMON_INT_MASK_1; 163e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); 164e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 165e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = COMMON_INT_MASK_2; 166e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); 167e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 168e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = COMMON_INT_MASK_3; 169e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); 170e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 171e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = COMMON_INT_MASK_4; 172e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); 173e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 174e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = INT_STA_MASK; 175e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK); 176e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 177e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 17809d00d170f8da388761cc29de1cf8c12c69c1300Sean Paulenum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp) 179e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 180e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 181e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 182e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); 183e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (reg & PLL_LOCK) 184e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return PLL_LOCKED; 185e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 186e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return PLL_UNLOCKED; 187e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 188e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 189e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable) 190e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 191e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 192e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 193e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 194e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); 195e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= DP_PLL_PD; 196e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); 197e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 198e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); 199e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~DP_PLL_PD; 200e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); 201e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 202e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 203e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 204e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_analog_power_down(struct exynos_dp_device *dp, 205e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han enum analog_power_block block, 206e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han bool enable) 207e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 208e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 209e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 210e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han switch (block) { 211e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case AUX_BLOCK: 212e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 213e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 214e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= AUX_PD; 215e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 216e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 217e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 218e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~AUX_PD; 219e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 220e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 221e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 222e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case CH0_BLOCK: 223e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 224e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 225e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= CH0_PD; 226e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 227e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 228e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 229e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~CH0_PD; 230e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 231e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 232e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 233e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case CH1_BLOCK: 234e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 235e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 236e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= CH1_PD; 237e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 238e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 239e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 240e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~CH1_PD; 241e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 242e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 243e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 244e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case CH2_BLOCK: 245e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 246e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 247e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= CH2_PD; 248e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 249e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 250e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 251e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~CH2_PD; 252e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 253e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 254e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 255e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case CH3_BLOCK: 256e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 257e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 258e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= CH3_PD; 259e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 260e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 261e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 262e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~CH3_PD; 263e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 264e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 265e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 266e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case ANALOG_TOTAL: 267e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 268e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 269e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= DP_PHY_PD; 270e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 271e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 272e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 273e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~DP_PHY_PD; 274e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 275e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 276e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 277e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case POWER_ALL: 278e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 279e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD | 280e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han CH1_PD | CH0_PD; 281e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 282e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 283e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD); 284e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 285e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 286e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han default: 287e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 288e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 289e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 290e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 291e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_init_analog_func(struct exynos_dp_device *dp) 292e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 293e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 294b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han int timeout_loop = 0; 295e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 296e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); 297e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 298e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = PLL_LOCK_CHG; 299e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 300e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 301e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); 302e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); 303e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL); 304e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 305e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Power up PLL */ 306b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 307e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han exynos_dp_set_pll_power_down(dp, 0); 308e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 309b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 310b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han timeout_loop++; 311b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 312b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han dev_err(dp->dev, "failed to get pll lock status\n"); 313b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han return; 314b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han } 315b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han usleep_range(10, 20); 316b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han } 317b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han } 318b5cfeed6cf90a4bb619b7ac640ba1a6dd002364dJingoo Han 319e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Enable Serdes FIFO function and Link symbol clock domain module */ 320e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); 321e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N 322e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han | AUX_FUNC_EN_N); 323e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 324e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 325e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 326c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paulvoid exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp) 327e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 328e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 329e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 330b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (gpio_is_valid(dp->hpd_gpio)) 331b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return; 332b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker 333e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = HOTPLUG_CHG | HPD_LOST | PLUG; 334e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 335e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 336e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = INT_HPD; 337e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); 338c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul} 339c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul 340c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paulvoid exynos_dp_init_hpd(struct exynos_dp_device *dp) 341c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul{ 342c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul u32 reg; 343c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul 344b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (gpio_is_valid(dp->hpd_gpio)) 345b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return; 346b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker 347c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul exynos_dp_clear_hotplug_interrupts(dp); 348e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 349e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 350e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~(F_HPD | HPD_CTRL); 351e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 352e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 353e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 354c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paulenum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp) 355c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul{ 356c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul u32 reg; 357c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul 358b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (gpio_is_valid(dp->hpd_gpio)) { 359b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker reg = gpio_get_value(dp->hpd_gpio); 360b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (reg) 361b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return DP_IRQ_TYPE_HP_CABLE_IN; 362b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker else 363b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return DP_IRQ_TYPE_HP_CABLE_OUT; 364b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker } else { 365b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker /* Parse hotplug interrupt status register */ 366b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 367c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul 368b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (reg & PLUG) 369b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return DP_IRQ_TYPE_HP_CABLE_IN; 370c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul 371b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (reg & HPD_LOST) 372b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return DP_IRQ_TYPE_HP_CABLE_OUT; 373c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul 374b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (reg & HOTPLUG_CHG) 375b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return DP_IRQ_TYPE_HP_CHANGE; 376c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul 377b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return DP_IRQ_TYPE_UNKNOWN; 378b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker } 379c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul} 380c30ffb904cff819dc2423b1c3edd4f2e48f7acb0Sean Paul 381e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_reset_aux(struct exynos_dp_device *dp) 382e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 383e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 384e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 385e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Disable AUX channel module */ 386e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); 387e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= AUX_FUNC_EN_N; 388e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 389e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 390e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 391e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_init_aux(struct exynos_dp_device *dp) 392e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 393e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 394e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 395e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear inerrupts related to AUX channel */ 396e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = RPLY_RECEIV | AUX_ERR; 397e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); 398e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 399e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han exynos_dp_reset_aux(dp); 400e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 401e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Disable AUX transaction H/W retry */ 402e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)| 403e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; 4047a80ec79f0328cc8829c901666adca968026f82dSachin Kamat writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL); 405e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 406e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ 407e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = DEFER_CTRL_EN | DEFER_COUNT(1); 408e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL); 409e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 410e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Enable AUX channel module */ 411e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); 412e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~AUX_FUNC_EN_N; 413e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 414e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 415e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 416e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_get_plug_in_status(struct exynos_dp_device *dp) 417e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 418e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 419e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 420b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (gpio_is_valid(dp->hpd_gpio)) { 421b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (gpio_get_value(dp->hpd_gpio)) 422b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return 0; 423b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker } else { 424b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 425b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker if (reg & HPD_STATUS) 426b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker return 0; 427b8b52471e87a713e61d26fa2f546fda0fb04e8fdAndrew Bresticker } 428e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 429e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return -EINVAL; 430e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 431e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 432e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_enable_sw_function(struct exynos_dp_device *dp) 433e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 434e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 435e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 436e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); 437e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~SW_FUNC_EN_N; 438e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); 439e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 440e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 441e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_start_aux_transaction(struct exynos_dp_device *dp) 442e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 443e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int reg; 444e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int retval = 0; 445bada55371fb2b3615983ba231cad61ef21bdf9c3Jingoo Han int timeout_loop = 0; 446e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 447e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Enable AUX CH operation */ 448e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 449e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= AUX_EN; 450e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 451e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 452e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Is AUX CH command reply received? */ 453e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); 454bada55371fb2b3615983ba231cad61ef21bdf9c3Jingoo Han while (!(reg & RPLY_RECEIV)) { 455bada55371fb2b3615983ba231cad61ef21bdf9c3Jingoo Han timeout_loop++; 456bada55371fb2b3615983ba231cad61ef21bdf9c3Jingoo Han if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 457bada55371fb2b3615983ba231cad61ef21bdf9c3Jingoo Han dev_err(dp->dev, "AUX CH command reply failed!\n"); 458bada55371fb2b3615983ba231cad61ef21bdf9c3Jingoo Han return -ETIMEDOUT; 459bada55371fb2b3615983ba231cad61ef21bdf9c3Jingoo Han } 460e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); 461bada55371fb2b3615983ba231cad61ef21bdf9c3Jingoo Han usleep_range(10, 11); 462bada55371fb2b3615983ba231cad61ef21bdf9c3Jingoo Han } 463e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 464e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear interrupt source for AUX CH command reply */ 465e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA); 466e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 467e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear interrupt source for AUX CH access error */ 468e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); 469e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (reg & AUX_ERR) { 470e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA); 471e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return -EREMOTEIO; 472e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 473e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 474e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Check AUX CH error access status */ 475e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA); 476e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if ((reg & AUX_STATUS_MASK) != 0) { 477e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han dev_err(dp->dev, "AUX CH error happens: %d\n\n", 478e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg & AUX_STATUS_MASK); 479e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return -EREMOTEIO; 480e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 481e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 482e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return retval; 483e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 484e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 485e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp, 486e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int reg_addr, 487e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned char data) 488e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 489e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 490e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int i; 491e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int retval; 492e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 493e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han for (i = 0; i < 3; i++) { 494e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear AUX CH data buffer */ 495e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = BUF_CLR; 496e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 497e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 498e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Select DPCD device address */ 499e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_7_0(reg_addr); 500e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 501e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_15_8(reg_addr); 502e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 503e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_19_16(reg_addr); 504e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 505e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 506e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Write data buffer */ 507e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = (unsigned int)data; 508e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0); 509e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 510e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 511e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Set DisplayPort transaction and write 1 byte 512e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If bit 3 is 1, DisplayPort transaction. 513e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If Bit 3 is 0, I2C transaction. 514e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han */ 515e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; 516e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 517e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 518e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Start AUX transaction */ 519e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han retval = exynos_dp_start_aux_transaction(dp); 520e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (retval == 0) 521e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 522e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 5238fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 5248fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul __func__); 525e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 526e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 527e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return retval; 528e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 529e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 530e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, 531e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int reg_addr, 532e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned char *data) 533e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 534e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 535e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int i; 536e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int retval; 537e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 53899f541524c8cd7b54a4f64a1c225de940e950833Sean Paul for (i = 0; i < 3; i++) { 539e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear AUX CH data buffer */ 540e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = BUF_CLR; 541e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 542e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 543e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Select DPCD device address */ 544e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_7_0(reg_addr); 545e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 546e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_15_8(reg_addr); 547e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 548e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_19_16(reg_addr); 549e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 550e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 551e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 552e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Set DisplayPort transaction and read 1 byte 553e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If bit 3 is 1, DisplayPort transaction. 554e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If Bit 3 is 0, I2C transaction. 555e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han */ 556e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 557e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 558e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 559e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Start AUX transaction */ 560e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han retval = exynos_dp_start_aux_transaction(dp); 561e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (retval == 0) 562e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 563e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 5648fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 5658fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul __func__); 566e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 567e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 568e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Read data buffer */ 569e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); 570e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han *data = (unsigned char)(reg & 0xff); 571e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 572e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return retval; 573e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 574e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 575e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, 576e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int reg_addr, 577e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int count, 578e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned char data[]) 579e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 580e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 581e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int start_offset; 582e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int cur_data_count; 583e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int cur_data_idx; 584e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int i; 585e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int retval = 0; 586e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 587e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear AUX CH data buffer */ 588e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = BUF_CLR; 589e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 590e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 591e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han start_offset = 0; 592e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han while (start_offset < count) { 593e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Buffer size of AUX CH is 16 * 4bytes */ 594e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if ((count - start_offset) > 16) 595e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han cur_data_count = 16; 596e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 597e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han cur_data_count = count - start_offset; 598e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 59999f541524c8cd7b54a4f64a1c225de940e950833Sean Paul for (i = 0; i < 3; i++) { 600e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Select DPCD device address */ 601e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_7_0(reg_addr + start_offset); 602e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 603e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_15_8(reg_addr + start_offset); 604e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 605e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_19_16(reg_addr + start_offset); 606e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 607e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 608e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han for (cur_data_idx = 0; cur_data_idx < cur_data_count; 609e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han cur_data_idx++) { 610e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = data[start_offset + cur_data_idx]; 611e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0 612e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han + 4 * cur_data_idx); 613e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 614e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 615e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 616e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Set DisplayPort transaction and write 617e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If bit 3 is 1, DisplayPort transaction. 618e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If Bit 3 is 0, I2C transaction. 619e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han */ 620e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_LENGTH(cur_data_count) | 621e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; 622e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 623e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 624e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Start AUX transaction */ 625e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han retval = exynos_dp_start_aux_transaction(dp); 626e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (retval == 0) 627e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 628e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 6298fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 6308fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul __func__); 631e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 632e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 633e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han start_offset += cur_data_count; 634e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 635e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 636e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return retval; 637e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 638e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 639e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, 640e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int reg_addr, 641e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int count, 642e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned char data[]) 643e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 644e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 645e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int start_offset; 646e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int cur_data_count; 647e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int cur_data_idx; 648e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int i; 649e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int retval = 0; 650e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 651e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear AUX CH data buffer */ 652e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = BUF_CLR; 653e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 654e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 655e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han start_offset = 0; 656e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han while (start_offset < count) { 657e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Buffer size of AUX CH is 16 * 4bytes */ 658e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if ((count - start_offset) > 16) 659e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han cur_data_count = 16; 660e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 661e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han cur_data_count = count - start_offset; 662e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 663e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* AUX CH Request Transaction process */ 66499f541524c8cd7b54a4f64a1c225de940e950833Sean Paul for (i = 0; i < 3; i++) { 665e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Select DPCD device address */ 666e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_7_0(reg_addr + start_offset); 667e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 668e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_15_8(reg_addr + start_offset); 669e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 670e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_ADDR_19_16(reg_addr + start_offset); 671e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 672e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 673e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 674e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Set DisplayPort transaction and read 675e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If bit 3 is 1, DisplayPort transaction. 676e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If Bit 3 is 0, I2C transaction. 677e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han */ 678e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_LENGTH(cur_data_count) | 679e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 680e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 681e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 682e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Start AUX transaction */ 683e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han retval = exynos_dp_start_aux_transaction(dp); 684e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (retval == 0) 685e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 686e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 6878fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 6888fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul __func__); 689e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 690e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 691e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han for (cur_data_idx = 0; cur_data_idx < cur_data_count; 692e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han cur_data_idx++) { 693e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 694e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han + 4 * cur_data_idx); 695e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han data[start_offset + cur_data_idx] = 696e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han (unsigned char)reg; 697e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 698e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 699e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han start_offset += cur_data_count; 700e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 701e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 702e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return retval; 703e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 704e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 705e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_select_i2c_device(struct exynos_dp_device *dp, 706e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int device_addr, 707e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int reg_addr) 708e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 709e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 710e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int retval; 711e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 712e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Set EDID device address */ 713e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = device_addr; 714e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 715e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 716e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 717e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 718e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Set offset from base address of EDID device */ 719e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0); 720e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 721e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 722e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Set I2C transaction and write address 723e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If bit 3 is 1, DisplayPort transaction. 724e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If Bit 3 is 0, I2C transaction. 725e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han */ 726e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT | 727e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han AUX_TX_COMM_WRITE; 728e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 729e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 730e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Start AUX transaction */ 731e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han retval = exynos_dp_start_aux_transaction(dp); 732e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (retval != 0) 7338fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 734e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 735e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return retval; 736e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 737e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 738e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, 739e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int device_addr, 740e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int reg_addr, 741e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int *data) 742e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 743e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 744e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int i; 745e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int retval; 746e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 74799f541524c8cd7b54a4f64a1c225de940e950833Sean Paul for (i = 0; i < 3; i++) { 748e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear AUX CH data buffer */ 749e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = BUF_CLR; 750e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 751e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 752e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Select EDID device */ 753e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); 75499f541524c8cd7b54a4f64a1c225de940e950833Sean Paul if (retval != 0) 755e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han continue; 756e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 757e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 758e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Set I2C transaction and read data 759e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If bit 3 is 1, DisplayPort transaction. 760e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If Bit 3 is 0, I2C transaction. 761e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han */ 762e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_TX_COMM_I2C_TRANSACTION | 763e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han AUX_TX_COMM_READ; 764e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 765e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 766e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Start AUX transaction */ 767e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han retval = exynos_dp_start_aux_transaction(dp); 768e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (retval == 0) 769e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 770e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 7718fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 7728fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul __func__); 773e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 774e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 775e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Read data */ 776e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (retval == 0) 777e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); 778e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 779e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return retval; 780e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 781e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 782e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, 783e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int device_addr, 784e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int reg_addr, 785e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int count, 786e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned char edid[]) 787e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 788e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 789e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int i, j; 790e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int cur_data_idx; 791e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han unsigned int defer = 0; 792e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han int retval = 0; 793e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 794e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han for (i = 0; i < count; i += 16) { 79599f541524c8cd7b54a4f64a1c225de940e950833Sean Paul for (j = 0; j < 3; j++) { 796e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Clear AUX CH data buffer */ 797e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = BUF_CLR; 798e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 799e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 800e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Set normal AUX CH command */ 801e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 802e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~ADDR_ONLY; 803e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 804e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 805e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 806e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If Rx sends defer, Tx sends only reads 807ff0c26424c1d993d8d1e04f72f1d428e935798daMasanari Iida * request without sending address 808e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han */ 809e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (!defer) 810e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han retval = exynos_dp_select_i2c_device(dp, 811e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han device_addr, reg_addr + i); 812e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 813e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han defer = 0; 814e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 815e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (retval == 0) { 816e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 817e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * Set I2C transaction and write data 818e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If bit 3 is 1, DisplayPort transaction. 819e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han * If Bit 3 is 0, I2C transaction. 820e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han */ 821e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUX_LENGTH(16) | 822e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han AUX_TX_COMM_I2C_TRANSACTION | 823e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han AUX_TX_COMM_READ; 824e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + 825e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han EXYNOS_DP_AUX_CH_CTL_1); 826e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 827e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Start AUX transaction */ 828e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han retval = exynos_dp_start_aux_transaction(dp); 829e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (retval == 0) 830e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 831e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 8328fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul dev_dbg(dp->dev, 8338fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul "%s: Aux Transaction fail!\n", 8348fefbb7519a37ad6c0752da1f939607d73a04edeSean Paul __func__); 835e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 836e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Check if Rx sends defer */ 837e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM); 838e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (reg == AUX_RX_COMM_AUX_DEFER || 839e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg == AUX_RX_COMM_I2C_DEFER) { 840e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han dev_err(dp->dev, "Defer: %d\n\n", reg); 841e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han defer = 1; 842e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 843e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 844e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 845e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) { 846e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 847e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han + 4 * cur_data_idx); 848e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han edid[i + cur_data_idx] = (unsigned char)reg; 849e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 850e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 851e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 852e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return retval; 853e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 854e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 855e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype) 856e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 857e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 858e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 859e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = bwtype; 860e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS)) 861e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET); 862e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 863e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 864e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype) 865e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 866e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 867e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 868e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET); 869e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han *bwtype = reg; 870e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 871e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 872e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count) 873e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 874e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 875e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 876e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = count; 877e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); 878e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 879e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 880e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count) 881e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 882e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 883e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 884e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); 885e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han *count = reg; 886e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 887e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 888e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable) 889e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 890e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 891e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 892e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 893e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 894e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= ENHANCED; 895e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 896e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 897e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 898e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~ENHANCED; 899e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 900e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 901e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 902e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 903e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_training_pattern(struct exynos_dp_device *dp, 904e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han enum pattern_set pattern) 905e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 906e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 907e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 908e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han switch (pattern) { 909e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case PRBS7: 910e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7; 911e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 912e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 913e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case D10_2: 914e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2; 915e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 916e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 917e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case TRAINING_PTN1: 918e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1; 919e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 920e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 921e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case TRAINING_PTN2: 922e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2; 923e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 924e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 925e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han case DP_NONE: 926e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = SCRAMBLING_ENABLE | 927e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han LINK_QUAL_PATTERN_SET_DISABLE | 928e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han SW_TRAINING_PATTERN_SET_NORMAL; 929e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 930e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 931e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han default: 932e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han break; 933e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 934e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 935e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 936e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level) 937e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 938e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 939e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 940e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 941e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg &= ~PRE_EMPHASIS_SET_MASK; 942e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg |= level << PRE_EMPHASIS_SET_SHIFT; 943e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 944e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 945e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 946e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level) 947e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 948e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 949e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 950e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 951e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg &= ~PRE_EMPHASIS_SET_MASK; 952e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg |= level << PRE_EMPHASIS_SET_SHIFT; 953e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 954e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 955e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 956e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level) 957e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 958e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 959e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 960e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 961e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg &= ~PRE_EMPHASIS_SET_MASK; 962e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg |= level << PRE_EMPHASIS_SET_SHIFT; 963e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 964e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 965e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 966e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level) 967e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 968e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 969e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 970e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 971e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg &= ~PRE_EMPHASIS_SET_MASK; 972e3c02009003eebf84f7c56c7f330521553c8d299Jingoo Han reg |= level << PRE_EMPHASIS_SET_SHIFT; 973e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 974e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 975e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 976e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp, 977e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 training_lane) 978e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 979e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 980e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 981e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = training_lane; 982e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 983e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 984e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 985e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp, 986e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 training_lane) 987e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 988e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 989e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 990e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = training_lane; 991e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 992e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 993e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 994e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp, 995e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 training_lane) 996e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 997e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 998e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 999e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = training_lane; 1000e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 1001e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1002e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1003e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp, 1004e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 training_lane) 1005e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1006e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1007e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1008e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = training_lane; 1009e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 1010e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1011e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1012e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanu32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp) 1013e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1014e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1015e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1016e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 1017e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return reg; 1018e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1019e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1020e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanu32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp) 1021e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1022e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1023e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1024e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 1025e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return reg; 1026e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1027e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1028e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanu32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp) 1029e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1030e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1031e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1032e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 1033e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return reg; 1034e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1035e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1036e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanu32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp) 1037e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1038e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1039e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1040e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 1041e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return reg; 1042e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1043e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1044e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_reset_macro(struct exynos_dp_device *dp) 1045e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1046e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1047e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1048e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST); 1049e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= MACRO_RST; 1050e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); 1051e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1052e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* 10 us is the minimum reset time. */ 1053a2c81bc12c81189928a03a94da1565d0c14e32ebJingoo Han usleep_range(10, 20); 1054e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1055e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~MACRO_RST; 1056e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); 1057e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1058e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 10591ec7be9c9f3ee416d5c97c1c649f3cba9e41ee1dJingoo Hanvoid exynos_dp_init_video(struct exynos_dp_device *dp) 1060e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1061e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1062e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1063e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG; 1064e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 1065e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1066e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = 0x0; 1067e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1068e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1069e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = CHA_CRI(4) | CHA_CTRL; 1070e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1071e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1072e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = 0x0; 1073e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1074e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1075e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = VID_HRES_TH(2) | VID_VRES_TH(0); 1076e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); 1077e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1078e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 10793fcb6eb4063ab4eef05601c266afa2af667c8e1fAjay Kumarvoid exynos_dp_set_video_color_format(struct exynos_dp_device *dp) 1080e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1081e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1082e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1083e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Configure the input color depth, color space, dynamic range */ 10843fcb6eb4063ab4eef05601c266afa2af667c8e1fAjay Kumar reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) | 10853fcb6eb4063ab4eef05601c266afa2af667c8e1fAjay Kumar (dp->video_info->color_depth << IN_BPC_SHIFT) | 10863fcb6eb4063ab4eef05601c266afa2af667c8e1fAjay Kumar (dp->video_info->color_space << IN_COLOR_F_SHIFT); 1087e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2); 1088e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1089e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ 1090e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); 1091e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~IN_YC_COEFFI_MASK; 10923fcb6eb4063ab4eef05601c266afa2af667c8e1fAjay Kumar if (dp->video_info->ycbcr_coeff) 1093e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= IN_YC_COEFFI_ITU709; 1094e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han else 1095e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= IN_YC_COEFFI_ITU601; 1096e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); 1097e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1098e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1099e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp) 1100e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1101e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1102e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1103e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1104e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1105e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1106e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1107e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1108e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (!(reg & DET_STA)) { 1109e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han dev_dbg(dp->dev, "Input stream clock not detected.\n"); 1110e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return -EINVAL; 1111e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 1112e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1113e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1114e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1115e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1116e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1117e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han dev_dbg(dp->dev, "wait SYS_CTL_2.\n"); 1118e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1119e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (reg & CHA_STA) { 1120e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han dev_dbg(dp->dev, "Input stream clk is changing\n"); 1121e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return -EINVAL; 1122e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 1123e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1124e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return 0; 1125e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1126e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1127e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, 1128e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han enum clock_recovery_m_value_type type, 1129e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 m_value, 1130e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 n_value) 1131e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1132e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1133e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1134e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (type == REGISTER_M) { 1135e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1136e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= FIX_M_VID; 1137e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1138e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = m_value & 0xff; 1139e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0); 1140e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = (m_value >> 8) & 0xff; 1141e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1); 1142e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = (m_value >> 16) & 0xff; 1143e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2); 1144e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1145e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = n_value & 0xff; 1146e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0); 1147e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = (n_value >> 8) & 0xff; 1148e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1); 1149e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = (n_value >> 16) & 0xff; 1150e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2); 1151e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 1152e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1153e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~FIX_M_VID; 1154e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1155e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1156e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0); 1157e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1); 1158e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2); 1159e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 1160e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1161e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1162e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type) 1163e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1164e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1165e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1166e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (type == VIDEO_TIMING_FROM_CAPTURE) { 1167e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1168e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~FORMAT_SEL; 1169e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1170e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 1171e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1172e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= FORMAT_SEL; 1173e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1174e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 1175e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1176e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1177e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable) 1178e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1179e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1180e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1181e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (enable) { 1182e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1183e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~VIDEO_MODE_MASK; 1184e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE; 1185e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1186e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } else { 1187e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1188e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~VIDEO_MODE_MASK; 1189e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= VIDEO_MODE_SLAVE_MODE; 1190e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1191e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 1192e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1193e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1194e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_start_video(struct exynos_dp_device *dp) 1195e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1196e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1197e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1198e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 1199e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= VIDEO_EN; 1200e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 1201e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1202e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1203e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanint exynos_dp_is_video_stream_on(struct exynos_dp_device *dp) 1204e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1205e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1206e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1207e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1208e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1209e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1210e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1211e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han if (!(reg & STRM_VALID)) { 1212e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han dev_dbg(dp->dev, "Input video stream is not detected.\n"); 1213e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return -EINVAL; 1214e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han } 1215e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1216e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han return 0; 1217e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1218e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 12193fcb6eb4063ab4eef05601c266afa2af667c8e1fAjay Kumarvoid exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp) 1220e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1221e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1222e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1223e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); 1224e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N); 1225e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= MASTER_VID_FUNC_EN_N; 1226e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); 1227e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1228e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1229e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~INTERACE_SCAN_CFG; 12303fcb6eb4063ab4eef05601c266afa2af667c8e1fAjay Kumar reg |= (dp->video_info->interlaced << 2); 1231e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1232e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1233e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1234e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~VSYNC_POLARITY_CFG; 12353fcb6eb4063ab4eef05601c266afa2af667c8e1fAjay Kumar reg |= (dp->video_info->v_sync_polarity << 1); 1236e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1237e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1238e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1239e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~HSYNC_POLARITY_CFG; 12403fcb6eb4063ab4eef05601c266afa2af667c8e1fAjay Kumar reg |= (dp->video_info->h_sync_polarity << 0); 1241e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1242e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1243e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; 1244e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1245e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1246e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1247e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_enable_scrambling(struct exynos_dp_device *dp) 1248e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1249e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1250e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1251e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1252e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg &= ~SCRAMBLING_DISABLE; 1253e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1254e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1255e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1256e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Hanvoid exynos_dp_disable_scrambling(struct exynos_dp_device *dp) 1257e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han{ 1258e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han u32 reg; 1259e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han 1260e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1261e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han reg |= SCRAMBLING_DISABLE; 1262e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1263e9474be4eb6918c91cb0d296f9744e8ec0e08c11Jingoo Han} 1264