/*
* Samsung DP (Display port) register interface driver.
*
* Copyright (C) 2012 Samsung Electronics Co., Ltd.
* Author: Jingoo Han <jg1.han@samsung.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/device.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <video/exynos_dp.h>
#include "exynos_dp_core.h"
#include "exynos_dp_reg.h"
#define COMMON_INT_MASK_1 (0)
#define COMMON_INT_MASK_2 (0)
#define COMMON_INT_MASK_3 (0)
#define COMMON_INT_MASK_4 (0)
#define INT_STA_MASK (0)
void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
{
u32 reg;
if (enable) {
reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
reg |= HDCP_VIDEO_MUTE;
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
} else {
reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
reg &= ~HDCP_VIDEO_MUTE;
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
}
}
void exynos_dp_stop_video(struct exynos_dp_device *dp)
{
u32 reg;
reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
reg &= ~VIDEO_EN;
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
}
void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable)
{
u32 reg;
if (enable)
reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
else
reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP);
}
void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
{
u32 reg;
reg = TX_TERMINAL_CTRL_50_OHM;
writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1);
reg = SEL_24M | TX_DVDD_BIT_1_0625V;
writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2);
reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
TX_CUR1_2X | TX_CUR_8_MA;
writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
CH1_AMP_400_MV | CH0_AMP_400_MV;
writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL);
}
void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
{
/* Set interrupt pin assertion polarity as high */
writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
/* Clear pending regisers */
writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2);
writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3);
writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA);
/* 0:mask,1: unmask */
writel