aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeon Woestenberg <leon@sidebranch.com>2017-01-09 13:54:02 +0100
committerChristian Kohn <christian.kohn@xilinx.com>2017-01-31 19:03:28 -0800
commit36871e80e2ba27d48dd91644252612dd889db78d (patch)
tree08d386ebab6fb0c88e228e58dcb37cc81be1ca48
parentaf152057f7566b14ec9f49cf66fb8852a9dc21f4 (diff)
downloadlinux-36871e80e2ba27d48dd91644252612dd889db78d.tar.gz
Move DP159 retimer driver from V4L2 to misc. as it does not relate to V4L2.
Signed-off-by: Leon Woestenberg <leon@sidebranch.com>
-rw-r--r--drivers/gpu/drm/xilinx/xilinx_drm_hdmi.c3
-rw-r--r--drivers/media/i2c/Kconfig8
-rw-r--r--drivers/media/i2c/Makefile1
-rw-r--r--drivers/media/i2c/dp159.c495
-rw-r--r--drivers/media/platform/xilinx/xilinx-hdmirx.c142
-rw-r--r--drivers/misc/Kconfig9
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/dp159.c436
-rw-r--r--drivers/phy/phy-vphy.c3
9 files changed, 569 insertions, 529 deletions
diff --git a/drivers/gpu/drm/xilinx/xilinx_drm_hdmi.c b/drivers/gpu/drm/xilinx/xilinx_drm_hdmi.c
index aa2c11381a3d57..8ca1bab755d116 100644
--- a/drivers/gpu/drm/xilinx/xilinx_drm_hdmi.c
+++ b/drivers/gpu/drm/xilinx/xilinx_drm_hdmi.c
@@ -991,7 +991,7 @@ static int xilinx_drm_hdmi_encoder_init(struct platform_device *pdev,
xvphy_mutex_lock(hdmi->phy[0]);
/* the callback is not specific to a single lane, but we need to
- * provide one of the phy's as reference */
+ * provide one of the phys as reference */
XVphy_SetHdmiCallback(hdmi->xvphy, XVPHY_HDMI_HANDLER_TXINIT,
VphyHdmiTxInitCallback, (void *)hdmi);
@@ -1129,7 +1129,6 @@ XV_axi4s_remap_Config* XV_axi4s_remap_LookupConfig_TX(u16 DeviceId) {
return NULL;
}
-
static void xilinx_drm_hdmi_config_init(XV_HdmiTxSs_Config *config, void __iomem *iomem)
{
config->BaseAddress = (uintptr_t)iomem;
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 071fc4d6dd5950..fa8accd8281ac4 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -731,14 +731,6 @@ config VIDEO_M52790
To compile this driver as a module, choose M here: the
module will be called m52790.
-config VIDEO_DP159
- tristate "Texas Instruments DP159 Redriver/retimer"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Texas Instruments DP159 Redriver/retimer.
-
- To compile this driver as a module, choose M here: the
- module will be called m52790.
endmenu
menu "Sensors used on soc_camera driver"
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 78dcc2f426b05d..94f2c99e890da8 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -80,4 +80,3 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
-obj-$(CONFIG_VIDEO_DP159) += dp159.o
diff --git a/drivers/media/i2c/dp159.c b/drivers/media/i2c/dp159.c
deleted file mode 100644
index c6b97d5f9026a2..00000000000000
--- a/drivers/media/i2c/dp159.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * dp159 redriver and retimer
- * Copyright (C) 2016 Leon Woestenberg <leon@sidebranch.com>
- *
- * based on dp159.c
- * Copyright (C) 2007 Hans Verkuil
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/of.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-#include <linux/of.h>
-
-MODULE_DESCRIPTION("i2c device driver for dp159 redriver and retimer");
-MODULE_AUTHOR("Leon Woestenberg");
-MODULE_LICENSE("GPL");
-
-static bool debug;
-
-module_param(debug, bool, 0644);
-
-MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
-
-struct dp159_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
-};
-
-//static int dp159_program(struct v4l2_subdev *sd, int mode);
-
-static inline struct dp159_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct dp159_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct dp159_state, hdl)->sd;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static inline int dp159_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline int dp159_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int dp159_program(struct v4l2_subdev *sd, int mode)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int r;
- if (client->addr == 0x2C) {
- switch (mode) {
- /* HDMI 1.4 (250Mbps - 1.2Gbps) */
- case 0 :
- // Select page 1
- r = dp159_write(sd, 0xff, 0x01);
-
- // PLL_FBDIV is 280
- r = dp159_write(sd, 0x04, 0x80);
- r = dp159_write(sd, 0x05, 0x02);
-
- // PLL_PREDIV is 2
- r = dp159_write(sd, 0x08, 0x02);
-
- // CDR_CONFIG[4:0]
- r = dp159_write(sd, 0x0e, 0x10);
-
- // CP_CURRENT
- r = dp159_write(sd, 0x01, 0x81);
- usleep_range(10000, 11000);
-
- // Enable Bandgap
- r = dp159_write(sd, 0x00, 0x02);
- usleep_range(10000, 11000);
- // Enable PLL
- r = dp159_write(sd, 0x00, 0x03);
-
- // Enable TX
- r = dp159_write(sd, 0x10, 0x0f);
-
- // HDMI_TWPST1
- r = dp159_write(sd, 0x14, 0x10);
-
- // DP_TWPST1
- r = dp159_write(sd, 0x16, 0x10);
-
- // DP_TWPST2
- r = dp159_write(sd, 0x17, 0x00);
-
- // Slew CTRL
- r = dp159_write(sd, 0x12, 0x28);
-
- // FIR_UPD
- r = dp159_write(sd, 0x13, 0x0f);
- r = dp159_write(sd, 0x13, 0x00);
-
- // TX_RATE
- r = dp159_write(sd, 0x11, 0xC0);
-
- // Enable receivers
- r = dp159_write(sd, 0x30, 0x0f);
-
- // PD_RXINT
- r = dp159_write(sd, 0x32, 0x00);
-
- // RX_RATE
- r = dp159_write(sd, 0x31, 0xC0);
-
- // Disable offset correction
- r = dp159_write(sd, 0x34, 0x00);
-
- // Change default of CDR_STL
- r = dp159_write(sd, 0x3c, 0x04);
-
- // Change default of CDR_SO_TR
- r = dp159_write(sd, 0x3D, 0x06);
-
- // EQFTC
- r = dp159_write(sd, 0x4D, 0x38);
-
- // Enable Adaptive EQ
- r = dp159_write(sd, 0x4c, 0x03);
-
- // Select page 0
- r = dp159_write(sd, 0xff, 0x00);
-
- // Gate HPD_SNK
- r = dp159_write(sd, 0x09, 0x01);
-
- // Set GPIO
- r = dp159_write(sd, 0xe0, 0x01);
-
- // Un gate HPD_SNK
- r = dp159_write(sd, 0x09, 0x00);
- return 0;
- break;
-
- case 1 : // HDMI 1.4 (1.2Gbps - 3Gbps)
- // Select page 1
- r = dp159_write(sd, 0xff, 0x01);
-
- // PLL_FBDIV is 140
- r = dp159_write(sd, 0x04, 0x40);
- r = dp159_write(sd, 0x05, 0x01);
-
- // PLL_PREDIV is 4
- r = dp159_write(sd, 0x08, 0x04);
-
- // CDR_CONFIG[4:0]
- r = dp159_write(sd, 0x0e, 0x10);
-
- // CP_CURRENT
- r = dp159_write(sd, 0x01, 0x81);
- usleep_range(10000, 11000);
- // Enable Bandgap
- r = dp159_write(sd, 0x00, 0x02);
- usleep_range(10000, 11000);
- // Enable PLL
- r = dp159_write(sd, 0x00, 0x03);
-
- // Enable TX
- r = dp159_write(sd, 0x10, 0x0f);
-
- // HDMI_TWPST1
- r = dp159_write(sd, 0x14, 0x10);
-
- // DP_TWPST1
- r = dp159_write(sd, 0x16, 0x10);
-
- // DP_TWPST2
- r = dp159_write(sd, 0x17, 0x00);
-
- // Slew CTRL
- r = dp159_write(sd, 0x12, 0x28);
-
- // FIR_UPD
- r = dp159_write(sd, 0x13, 0x0f);
- r = dp159_write(sd, 0x13, 0x00);
-
- // TX_RATE
- r = dp159_write(sd, 0x11, 0x70);
-
- // Enable receivers
- r = dp159_write(sd, 0x30, 0x0f);
-
- // PD_RXINT
- r = dp159_write(sd, 0x32, 0x00);
-
- // RX_RATE
- r = dp159_write(sd, 0x31, 0x40);
-
- // Disable offset correction
- r = dp159_write(sd, 0x34, 0x00);
-
- // Change default of CDR_STL
- r = dp159_write(sd, 0x3c, 0x04);
-
- // Change default of CDR_SO_TR
- r = dp159_write(sd, 0x3D, 0x06);
-
- // EQFTC
- r = dp159_write(sd, 0x4D, 0x28);
-
- // Enable Adaptive EQ
- r = dp159_write(sd, 0x4c, 0x03);
-
- // Select page 0
- r = dp159_write(sd, 0xff, 0x00);
-
- // Gate HPD_SNK
- r = dp159_write(sd, 0x09, 0x01);
-
- // Set GPIO
- r = dp159_write(sd, 0xe0, 0x01);
-
- // Un gate HPD_SNK
- r = dp159_write(sd, 0x09, 0x00);
- return 0;
- break;
-
- case 2 : // HDMI 2.0 (3.4Gbps - 6 Gbps)
-
- // Select page 1
- r = dp159_write(sd, 0xff, 0x01);
-
- // PLL_FBDIV is 280
- r = dp159_write(sd, 0x04, 0x80);
- r = dp159_write(sd, 0x05, 0x02);
-
- // PLL_PREDIV is 4
- r = dp159_write(sd, 0x08, 0x04);
-
- // CDR_CONFIG[4:0]
- r = dp159_write(sd, 0x0e, 0x10);
-
- // CP_CURRENT
- r = dp159_write(sd, 0x01, 0x81);
- usleep_range(10000, 11000);
- // Enable Bandgap
- r = dp159_write(sd, 0x00, 0x02);
- usleep_range(10000, 11000);
- // Enable PLL
- r = dp159_write(sd, 0x00, 0x03);
-
- // Enable TX
- r = dp159_write(sd, 0x10, 0x0f);
-
- // HDMI_TWPST1
- r = dp159_write(sd, 0x14, 0x10);
-
- // DP_TWPST1
- r = dp159_write(sd, 0x16, 0x10);
-
- // DP_TWPST2
- r = dp159_write(sd, 0x17, 0x00);
-
- // Slew CTRL
- r = dp159_write(sd, 0x12, 0x28);
-
- // FIR_UPD
- r = dp159_write(sd, 0x13, 0x0f);
- r = dp159_write(sd, 0x13, 0x00);
-
- // TX_RATE
- r = dp159_write(sd, 0x11, 0x30);
-
- // Enable receivers
- r = dp159_write(sd, 0x30, 0x0f);
-
- // PD_RXINT
- r = dp159_write(sd, 0x32, 0x00);
-
- // RX_RATE
- r = dp159_write(sd, 0x31, 0x00);
-
- // Disable offset correction
- r = dp159_write(sd, 0x34, 0x00);
-
- // Change default of CDR_STL
- r = dp159_write(sd, 0x3c, 0x04);
-
- // Change default of CDR_SO_TR
- r = dp159_write(sd, 0x3D, 0x06);
-
- // EQFTC
- r = dp159_write(sd, 0x4D, 0x18);
-
- // Enable Adaptive EQ
- r = dp159_write(sd, 0x4c, 0x03);
-
- // Select page 0
- r = dp159_write(sd, 0xff, 0x00);
-
- // Gate HPD_SNK
- r = dp159_write(sd, 0x09, 0x01);
-
- // Set GPIO
- r = dp159_write(sd, 0xe0, 0x01);
-
- // Un gate HPD_SNK
- r = dp159_write(sd, 0x09, 0x00);
- return 0;
- break;
- } /* switch (mode) */
- /* DP159 ES? */
- } else if (client->addr == 0x5C) {
- if (mode == 2) {
- r = dp159_write(sd, 0x0A, 0x36); // Automatic retimer for HDMI 2.0
- r = dp159_write(sd, 0x0B, 0x1a);
-
- r = dp159_write(sd, 0x0C, 0xa1);
- r = dp159_write(sd, 0x0D, 0x00);
- } else {
- r = dp159_write(sd, 0x0A, 0x35); // Automatic redriver to retimer crossover at 1.0 Gbps
- //r = dp159_write(sd, 0x0A, 0x34); // The redriver mode must be selected to support low video rates
- r = dp159_write(sd, 0x0B, 0x01);
- r = dp159_write(sd, 0x0C, 0xA0); // Set VSWING data decrease by 24%
- r = dp159_write(sd, 0x0D, 0x00);
- }
- }
-}
-
-static int dp159_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- int mode = 0;
- switch (ctrl->id) {
- case V4L2_CID_LINK_FREQ:
- if ((ctrl->val / 1000000) > 3400) {
- mode = 2;
- } else if ((ctrl->val / 1000000) > 1200) {
- mode = 1;
- }
- return dp159_program(sd, mode);
- }
- return -EINVAL;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int dp159_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- reg->size = 1;
- reg->val = dp159_read(sd, reg->reg);
- return 0;
-}
-
-static int dp159_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
-{
- dp159_write(sd, reg->reg, reg->val & 0xff);
- return 0;
-}
-#endif
-
-static int dp159_log_status(struct v4l2_subdev *sd)
-{
-#if 0
- u8 v = dp159_read(sd, 0x09) & 7;
- u8 m = dp159_read(sd, 0x04);
- int vol = dp159_read(sd, 0x08) & 0x3f;
-
- v4l2_info(sd, "Input: %d%s\n", v,
- (m & 0x80) ? " (muted)" : "");
- if (vol >= 32)
- vol = vol - 64;
- v4l2_info(sd, "Volume: %d dB\n", vol);
-#endif
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops dp159_ctrl_ops = {
- .s_ctrl = dp159_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops dp159_core_ops = {
- .log_status = dp159_log_status,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = dp159_g_register,
- .s_register = dp159_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_ops dp159_ops = {
- .core = &dp159_core_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int dp159_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct dp159_state *state;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &dp159_ops);
-
- v4l2_ctrl_handler_init(&state->hdl, 1);
- v4l2_ctrl_new_std(&state->hdl, &dp159_ctrl_ops,
- V4L2_CID_LINK_FREQ, 0, 8000*1000*1000LL, 1, 0);
- sd->ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- return err;
- }
- /* set volume/mute */
- v4l2_ctrl_handler_setup(&state->hdl);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int dp159_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct dp159_state *state = to_state(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&state->hdl);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id dp159_id[] = {
- { "dp159", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, dp159_id);
-
-#if IS_ENABLED(CONFIG_OF)
-static const struct of_device_id dp159_of_match[] = {
- { .compatible = "ti,dp159", },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, dp159_of_match);
-#endif
-
-static struct i2c_driver dp159_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "dp159",
-//#if IS_ENABLED(CONFIG_OF)
- .of_match_table = of_match_ptr(dp159_of_match),
-//#endif
- },
- .probe = dp159_probe,
- .remove = dp159_remove,
- .id_table = dp159_id,
-};
-
-module_i2c_driver(dp159_driver);
diff --git a/drivers/media/platform/xilinx/xilinx-hdmirx.c b/drivers/media/platform/xilinx/xilinx-hdmirx.c
index afd4a4f397b5d8..2f39d26e59da06 100644
--- a/drivers/media/platform/xilinx/xilinx-hdmirx.c
+++ b/drivers/media/platform/xilinx/xilinx-hdmirx.c
@@ -1,8 +1,8 @@
/*
- * Xilinx Video HDMI RX Subsystem driver (Early Access Release)
+ * Xilinx Video HDMI RX Subsystem driver
*
- * Copyright (C) 2016 Leon Woestenberg <leon@sidebranch.com>
- * Copyright (C) 2016 Xilinx, Inc.
+ * Copyright (C) 2016-2017 Leon Woestenberg <leon@sidebranch.com>
+ * Copyright (C) 2016-2017 Xilinx, Inc.
*
* Authors: Leon Woestenberg <leon@sidebranch.com>
* Rohit Consul <rohitco@xilinx.com>
@@ -29,9 +29,9 @@
#include <media/v4l2-subdev.h>
#include <media/v4l2-dv-timings.h>
-#include "xilinx-vip.h"
+#include <linux/phy/phy-vphy.h>
-#include "linux/phy/phy-vphy.h"
+#include "xilinx-vip.h"
/* baseline driver includes */
#include "xilinx-hdmi-rx/xv_hdmirxss.h"
@@ -220,8 +220,9 @@ static int xhdmirx_get_edid(struct v4l2_subdev *subdev, struct v4l2_edid *edid)
static void xhdmirx_set_hpd(struct xhdmirx_device *xhdmirx, int enable)
{
+ XV_HdmiRxSs *HdmiRxSsPtr;
BUG_ON(!xhdmirx);
- XV_HdmiRxSs *HdmiRxSsPtr = &xhdmirx->xv_hdmirxss;
+ HdmiRxSsPtr = &xhdmirx->xv_hdmirxss;
XV_HdmiRx_SetHpd(HdmiRxSsPtr->HdmiRxPtr, enable);
}
@@ -349,7 +350,6 @@ static int xhdmirx_query_dv_timings(struct v4l2_subdev *subdev,
struct v4l2_dv_timings *timings)
{
struct xhdmirx_device *xhdmirx = to_xhdmirx(subdev);
- printk(KERN_INFO "xhdmirx_set_format\n");
struct v4l2_bt_timings *bt = &timings->bt;
if (!timings)
@@ -996,28 +996,124 @@ static int xhdmirx_parse_of(struct xhdmirx_device *xhdmirx, XV_HdmiRxSs_Config *
{
struct device *dev = xhdmirx->dev;
struct device_node *node = dev->of_node;
- (void)dev;
- (void)node;
-#if 0
- struct device_node *ports;
- struct device_node *port;
- unsigned int nports = 0;
- bool has_endpoint = false;
-#endif
+// struct device_node *ports;
+ int ret;
-#if 0 // example bool
- bool has_dre = false;
- has_dre = of_property_read_bool(node, "xlnx,include-dre");
-#endif
-#if 0 // example u32
- u32 value;
- int err;
- err = of_property_read_u32(node, "xlnx,datawidth", &value);
+ printk(KERN_INFO "Reading HDMI Rx Device Tree Info\n");
+
+// ports = of_get_child_by_name(node, "ports");
+// if (ports == NULL)
+// ports = node;
+
+ ret = of_property_read_u32(node, "xlnx,input-pixels-per-clock", (u32 *)&config->Ppc);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,max-bits-per-component", (u32 *)&config->MaxBitsPerPixel);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,include-hdmi-rx", (u32 *)&config->HdmiRx.IsPresent);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,devid-hdmi-rx", (u32 *)&config->HdmiRx.DeviceId);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,offset-hdmi-rx", (u32 *)&config->HdmiRx.AddrOffset);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,include-remapper", (u32 *)&config->Remapper.IsPresent);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,devid-remapper", (u32 *)&config->Remapper.DeviceId);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,offset-remapper", (u32 *)&config->Remapper.AddrOffset);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,include-remap-gpio", (u32 *)&config->RemapperReset.IsPresent);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,devid-remap-gpio", (u32 *)&config->RemapperReset.DeviceId);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,offset-remap-gpio", (u32 *)&config->RemapperReset.AddrOffset);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,include-timer", (u32 *)&config->HdcpTimer.IsPresent);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,devid-timer", (u32 *)&config->HdcpTimer.DeviceId);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,offset-timer", (u32 *)&config->HdcpTimer.AddrOffset);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,include-hdcp-1-4", (u32 *)&config->Hdcp14.IsPresent);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,devid-hdcp-1-4", (u32 *)&config->Hdcp14.DeviceId);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,offset-hdcp-1-4", (u32 *)&config->Hdcp14.AddrOffset);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,include-hdcp-2-2", (u32 *)&config->Hdcp22.IsPresent);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,devid-hdcp-2-2", (u32 *)&config->Hdcp22.DeviceId);
+ if (ret < 0) {
+ goto error_dt;
+ }
+ ret = of_property_read_u32(node, "xlnx,offset-hdcp-2-2", (u32 *)&config->Hdcp22.AddrOffset);
+ if (ret < 0) {
+ goto error_dt;
+ }
+#if 1
+ printk(KERN_INFO "Config.PPC %d\n", config->Ppc);
+ printk(KERN_INFO "Config.BPC %d\n", config->MaxBitsPerPixel);
+ printk(KERN_INFO "Config.IsHdmiRx %d\n", config->HdmiRx.IsPresent);
+ printk(KERN_INFO "Config.IsHdcp14 %d\n", config->Hdcp14.IsPresent);
+ printk(KERN_INFO "Config.IsHdcp22 %d\n", config->Hdcp22.IsPresent);
+ printk(KERN_INFO "Config.IsRemapper %lx\n", config->Remapper.IsPresent);
+ printk(KERN_INFO "Config.IsGpio %d\n", config->RemapperReset.IsPresent);
+ printk(KERN_INFO "Config.IsHdcpTimer %d\n", config->HdcpTimer.IsPresent);
+ printk(KERN_INFO "Config.Remap-devid %d\n", config->Remapper.DeviceId);
+ printk(KERN_INFO "Config.Remap-offset %lx\n", config->Remapper.AddrOffset);
+ printk(KERN_INFO "Config.gpio-devid %d\n", config->RemapperReset.DeviceId);
+ printk(KERN_INFO "Config.gpio-offset %p\n", config->RemapperReset.AddrOffset);
+ printk(KERN_INFO "Config.timer-devid %d\n", config->HdcpTimer.DeviceId);
+ printk(KERN_INFO "Config.timer-offset %lx\n", config->HdcpTimer.AddrOffset);
+ printk(KERN_INFO "Config.hdcp14-devid %d\n", config->Hdcp14.DeviceId);
+ printk(KERN_INFO "Config.hdcp14-offset %lx\n", config->Hdcp14.AddrOffset);
+ printk(KERN_INFO "Config.hdcp22-devid %d\n", config->Hdcp22.DeviceId);
+ printk(KERN_INFO "Config.hdcp22-offset %lx\n", config->Hdcp22.AddrOffset);
#endif
return 0;
+
+error_dt:
+ dev_err(dev, "Error Reading Xilinx Hdmi Rx Device Tree");
+ return ret;
}
+
static int xhdmirx_probe(struct platform_device *pdev)
{
struct v4l2_subdev *subdev;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b84d4ed650a79f..25689a9e4198cd 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -816,6 +816,15 @@ config XILINX_TRAFGEN
If unsure, say N
+config RETIMER_DP159
+ tristate "Texas Instruments DP159 Redriver/retimer"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Texas Instruments DP159 Redriver/retimer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called dp159.
+
source "drivers/misc/jesd204b/Kconfig"
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b9523ce5da5f23..66ff27c8adba68 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -59,3 +59,4 @@ obj-$(CONFIG_ECHO) += echo/
obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
obj-$(CONFIG_CXL_BASE) += cxl/
obj-$(CONFIG_PANEL) += panel.o
+obj-$(CONFIG_RETIMER_DP159) += dp159.o
diff --git a/drivers/misc/dp159.c b/drivers/misc/dp159.c
new file mode 100644
index 00000000000000..f55a1ad5e4ac0b
--- /dev/null
+++ b/drivers/misc/dp159.c
@@ -0,0 +1,436 @@
+/*
+ * dp159 redriver and retimer
+ * Copyright (C) 2016 Leon Woestenberg <leon@sidebranch.com>
+ *
+ * based on dp159.c
+ * Copyright (C) 2007 Hans Verkuil
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of.h>
+#include <linux/clk-provider.h>
+
+MODULE_DESCRIPTION("i2c device driver for dp159 redriver and retimer");
+MODULE_AUTHOR("Leon Woestenberg");
+MODULE_LICENSE("GPL");
+
+static bool debug;
+
+module_param(debug, bool, 0644);
+
+MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
+
+struct clk_tx_linerate {
+ struct clk_hw hw;
+ struct i2c_client *client;
+};
+
+static inline int dp159_write(struct i2c_client *client, u8 reg, u8 value)
+{
+
+#if 0
+ struct i2c_client *client = v4l2_get_subdevdata(client);
+#endif
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static inline int dp159_read(struct i2c_client *client, u8 reg)
+{
+
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int dp159_program(struct i2c_client *client, int mode)
+{
+ int r;
+ if (client->addr == 0x2C) {
+ switch (mode) {
+ /* HDMI 1.4 (250Mbps - 1.2Gbps) */
+ case 0 :
+ // Select page 1
+ r = dp159_write(client, 0xff, 0x01);
+
+ // PLL_FBDIV is 280
+ r = dp159_write(client, 0x04, 0x80);
+ r = dp159_write(client, 0x05, 0x02);
+
+ // PLL_PREDIV is 2
+ r = dp159_write(client, 0x08, 0x02);
+
+ // CDR_CONFIG[4:0]
+ r = dp159_write(client, 0x0e, 0x10);
+
+ // CP_CURRENT
+ r = dp159_write(client, 0x01, 0x81);
+ usleep_range(10000, 11000);
+
+ // Enable Bandgap
+ r = dp159_write(client, 0x00, 0x02);
+ usleep_range(10000, 11000);
+ // Enable PLL
+ r = dp159_write(client, 0x00, 0x03);
+
+ // Enable TX
+ r = dp159_write(client, 0x10, 0x0f);
+
+ // HDMI_TWPST1
+ r = dp159_write(client, 0x14, 0x10);
+
+ // DP_TWPST1
+ r = dp159_write(client, 0x16, 0x10);
+
+ // DP_TWPST2
+ r = dp159_write(client, 0x17, 0x00);
+
+ // Slew CTRL
+ r = dp159_write(client, 0x12, 0x28);
+
+ // FIR_UPD
+ r = dp159_write(client, 0x13, 0x0f);
+ r = dp159_write(client, 0x13, 0x00);
+
+ // TX_RATE
+ r = dp159_write(client, 0x11, 0xC0);
+
+ // Enable receivers
+ r = dp159_write(client, 0x30, 0x0f);
+
+ // PD_RXINT
+ r = dp159_write(client, 0x32, 0x00);
+
+ // RX_RATE
+ r = dp159_write(client, 0x31, 0xC0);
+
+ // Disable offset correction
+ r = dp159_write(client, 0x34, 0x00);
+
+ // Change default of CDR_STL
+ r = dp159_write(client, 0x3c, 0x04);
+
+ // Change default of CDR_SO_TR
+ r = dp159_write(client, 0x3D, 0x06);
+
+ // EQFTC
+ r = dp159_write(client, 0x4D, 0x38);
+
+ // Enable Adaptive EQ
+ r = dp159_write(client, 0x4c, 0x03);
+
+ // Select page 0
+ r = dp159_write(client, 0xff, 0x00);
+
+ // Gate HPD_SNK
+ r = dp159_write(client, 0x09, 0x01);
+
+ // Set GPIO
+ r = dp159_write(client, 0xe0, 0x01);
+
+ // Un gate HPD_SNK
+ r = dp159_write(client, 0x09, 0x00);
+ return 0;
+ break;
+
+ case 1 : // HDMI 1.4 (1.2Gbps - 3Gbps)
+ // Select page 1
+ r = dp159_write(client, 0xff, 0x01);
+
+ // PLL_FBDIV is 140
+ r = dp159_write(client, 0x04, 0x40);
+ r = dp159_write(client, 0x05, 0x01);
+
+ // PLL_PREDIV is 4
+ r = dp159_write(client, 0x08, 0x04);
+
+ // CDR_CONFIG[4:0]
+ r = dp159_write(client, 0x0e, 0x10);
+
+ // CP_CURRENT
+ r = dp159_write(client, 0x01, 0x81);
+ usleep_range(10000, 11000);
+ // Enable Bandgap
+ r = dp159_write(client, 0x00, 0x02);
+ usleep_range(10000, 11000);
+ // Enable PLL
+ r = dp159_write(client, 0x00, 0x03);
+
+ // Enable TX
+ r = dp159_write(client, 0x10, 0x0f);
+
+ // HDMI_TWPST1
+ r = dp159_write(client, 0x14, 0x10);
+
+ // DP_TWPST1
+ r = dp159_write(client, 0x16, 0x10);
+
+ // DP_TWPST2
+ r = dp159_write(client, 0x17, 0x00);
+
+ // Slew CTRL
+ r = dp159_write(client, 0x12, 0x28);
+
+ // FIR_UPD
+ r = dp159_write(client, 0x13, 0x0f);
+ r = dp159_write(client, 0x13, 0x00);
+
+ // TX_RATE
+ r = dp159_write(client, 0x11, 0x70);
+
+ // Enable receivers
+ r = dp159_write(client, 0x30, 0x0f);
+
+ // PD_RXINT
+ r = dp159_write(client, 0x32, 0x00);
+
+ // RX_RATE
+ r = dp159_write(client, 0x31, 0x40);
+
+ // Disable offset correction
+ r = dp159_write(client, 0x34, 0x00);
+
+ // Change default of CDR_STL
+ r = dp159_write(client, 0x3c, 0x04);
+
+ // Change default of CDR_SO_TR
+ r = dp159_write(client, 0x3D, 0x06);
+
+ // EQFTC
+ r = dp159_write(client, 0x4D, 0x28);
+
+ // Enable Adaptive EQ
+ r = dp159_write(client, 0x4c, 0x03);
+
+ // Select page 0
+ r = dp159_write(client, 0xff, 0x00);
+
+ // Gate HPD_SNK
+ r = dp159_write(client, 0x09, 0x01);
+
+ // Set GPIO
+ r = dp159_write(client, 0xe0, 0x01);
+
+ // Un gate HPD_SNK
+ r = dp159_write(client, 0x09, 0x00);
+ return 0;
+ break;
+
+ case 2 : // HDMI 2.0 (3.4Gbps - 6 Gbps)
+
+ // Select page 1
+ r = dp159_write(client, 0xff, 0x01);
+
+ // PLL_FBDIV is 280
+ r = dp159_write(client, 0x04, 0x80);
+ r = dp159_write(client, 0x05, 0x02);
+
+ // PLL_PREDIV is 4
+ r = dp159_write(client, 0x08, 0x04);
+
+ // CDR_CONFIG[4:0]
+ r = dp159_write(client, 0x0e, 0x10);
+
+ // CP_CURRENT
+ r = dp159_write(client, 0x01, 0x81);
+ usleep_range(10000, 11000);
+ // Enable Bandgap
+ r = dp159_write(client, 0x00, 0x02);
+ usleep_range(10000, 11000);
+ // Enable PLL
+ r = dp159_write(client, 0x00, 0x03);
+
+ // Enable TX
+ r = dp159_write(client, 0x10, 0x0f);
+
+ // HDMI_TWPST1
+ r = dp159_write(client, 0x14, 0x10);
+
+ // DP_TWPST1
+ r = dp159_write(client, 0x16, 0x10);
+
+ // DP_TWPST2
+ r = dp159_write(client, 0x17, 0x00);
+
+ // Slew CTRL
+ r = dp159_write(client, 0x12, 0x28);
+
+ // FIR_UPD
+ r = dp159_write(client, 0x13, 0x0f);
+ r = dp159_write(client, 0x13, 0x00);
+
+ // TX_RATE
+ r = dp159_write(client, 0x11, 0x30);
+
+ // Enable receivers
+ r = dp159_write(client, 0x30, 0x0f);
+
+ // PD_RXINT
+ r = dp159_write(client, 0x32, 0x00);
+
+ // RX_RATE
+ r = dp159_write(client, 0x31, 0x00);
+
+ // Disable offset correction
+ r = dp159_write(client, 0x34, 0x00);
+
+ // Change default of CDR_STL
+ r = dp159_write(client, 0x3c, 0x04);
+
+ // Change default of CDR_SO_TR
+ r = dp159_write(client, 0x3D, 0x06);
+
+ // EQFTC
+ r = dp159_write(client, 0x4D, 0x18);
+
+ // Enable Adaptive EQ
+ r = dp159_write(client, 0x4c, 0x03);
+
+ // Select page 0
+ r = dp159_write(client, 0xff, 0x00);
+
+ // Gate HPD_SNK
+ r = dp159_write(client, 0x09, 0x01);
+
+ // Set GPIO
+ r = dp159_write(client, 0xe0, 0x01);
+
+ // Un gate HPD_SNK
+ r = dp159_write(client, 0x09, 0x00);
+ return 0;
+ break;
+ } /* switch (mode) */
+ /* DP159 ES? */
+ } else if (client->addr == 0x5C) {
+ if (mode == 2) {
+ r = dp159_write(client, 0x0A, 0x36); // Automatic retimer for HDMI 2.0
+ r = dp159_write(client, 0x0B, 0x1a);
+
+ r = dp159_write(client, 0x0C, 0xa1);
+ r = dp159_write(client, 0x0D, 0x00);
+ } else {
+ r = dp159_write(client, 0x0A, 0x35); // Automatic redriver to retimer crossover at 1.0 Gbps
+ //r = dp159_write(client, 0x0A, 0x34); // The redriver mode must be selected to support low video rates
+ r = dp159_write(client, 0x0B, 0x01);
+ r = dp159_write(client, 0x0C, 0xA0); // Set VSWING data decrease by 24%
+ r = dp159_write(client, 0x0D, 0x00);
+ }
+ }
+}
+
+#define to_clk_tx_linerate(_hw) container_of(_hw, struct clk_tx_linerate, hw)
+
+int clk_tx_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+ struct clk_tx_linerate *clk;
+ clk = to_clk_tx_linerate(hw);
+ return 0;
+};
+
+int clk_tx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct clk_tx_linerate *clk;
+ clk = to_clk_tx_linerate(hw);
+ return 0;
+};
+
+long clk_tx_round_rate(struct clk_hw *hw,
+ unsigned long rate, unsigned long *parent_rate)
+{
+ struct clk_tx_linerate *clk;
+ clk = to_clk_tx_linerate(hw);
+ return 0;
+};
+
+struct clk_ops clk_tx_rate_ops = {
+ .set_rate = &clk_tx_set_rate,
+ .recalc_rate = &clk_tx_recalc_rate,
+ .round_rate = &clk_tx_round_rate,
+};
+
+static int dp159_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct clk_tx_linerate *clk_tx;
+ struct clk_init_data init;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ /* allocate fixed-rate clock */
+ clk_tx = kzalloc(sizeof(*clk_tx), GFP_KERNEL);
+ if (!clk_tx)
+ return -ENOMEM;
+
+ init.name = "clk_tx_linerate";
+ init.ops = &clk_tx_rate_ops;
+ init.flags = /*flags |*/ CLK_IS_BASIC;
+ init.parent_names = NULL;
+ init.num_parents = 0;
+
+ /* register the clock */
+ clk_tx = clk_register(&client->dev, &clk_tx->hw);
+ if (IS_ERR(clk_tx)) {
+ kfree(clk_tx);
+ return ERR_PTR(clk_tx);
+ }
+ /* reference to client in clock */
+ clk_tx->client = client;
+ /* reference to clk in client */
+ i2c_set_clientdata(client, (void *)clk_tx);
+
+ return 0;
+}
+
+static int dp159_remove(struct i2c_client *client)
+{
+ struct clk_tx_linerate *clk_tx;
+ clk_tx = (struct clk_tx_linerate *)i2c_get_clientdata(client);
+ if (clk_tx)
+ clk_unregister(clk_tx);
+ return 0;
+}
+
+static const struct i2c_device_id dp159_id[] = {
+ { "dp159", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, dp159_id);
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id dp159_of_match[] = {
+ { .compatible = "ti,dp159", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, dp159_of_match);
+#endif
+
+static struct i2c_driver dp159_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "dp159",
+ .of_match_table = of_match_ptr(dp159_of_match),
+ },
+ .probe = dp159_probe,
+ .remove = dp159_remove,
+ .id_table = dp159_id,
+};
+
+module_i2c_driver(dp159_driver);
diff --git a/drivers/phy/phy-vphy.c b/drivers/phy/phy-vphy.c
index 525d4c6c3d310d..bb48f75d25ff94 100644
--- a/drivers/phy/phy-vphy.c
+++ b/drivers/phy/phy-vphy.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <dt-bindings/phy/phy.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include "linux/phy/phy-vphy.h"
@@ -475,6 +476,8 @@ static int xvphy_probe(struct platform_device *pdev)
struct xvphy_dev *vphydev;
struct phy_provider *provider;
struct phy *phy;
+ struct clk *clk;
+
struct resource *res;
int lanecount, port = 0, index = 0;
int ret;