Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,50 @@
# SPDX-License-Identifier: GPL-2.0-only
config DRM_ANALOGIX_ANX6345
tristate "Analogix ANX6345 bridge"
depends on OF
select DRM_ANALOGIX_DP
select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select REGMAP_I2C
help
ANX6345 is an ultra-low power Full-HD DisplayPort/eDP
transmitter designed for portable devices. The
ANX6345 transforms the LVTTL RGB output of an
application processor to eDP or DisplayPort.
config DRM_ANALOGIX_ANX78XX
tristate "Analogix ANX78XX bridge"
depends on OF
select DRM_ANALOGIX_DP
select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select REGMAP_I2C
help
ANX78XX is an ultra-low power Full-HD SlimPort transmitter
designed for portable devices. The ANX78XX transforms
the HDMI output of an application processor to MyDP
or DisplayPort.
config DRM_ANALOGIX_DP
tristate
depends on DRM
depends on OF
select DRM_DISPLAY_DP_AUX_BUS
config DRM_ANALOGIX_ANX7625
tristate "Analogix Anx7625 MIPI to DP interface support"
depends on DRM
depends on OF
depends on TYPEC
depends on USB_ROLE_SWITCH
select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
select DRM_DISPLAY_DP_AUX_BUS
select DRM_MIPI_DSI
help
ANX7625 is an ultra-low power 4K mobile HD transmitter
designed for portable devices. It converts MIPI/DPI to
DisplayPort1.3 4K.
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o analogix-i2c-dptx.o
obj-$(CONFIG_DRM_ANALOGIX_ANX6345) += analogix-anx6345.o
obj-$(CONFIG_DRM_ANALOGIX_ANX7625) += anx7625.o
obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o
@@ -0,0 +1,793 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2016, Analogix Semiconductor.
* Copyright(c) 2017, Icenowy Zheng <icenowy@aosc.io>
*
* Based on anx7808 driver obtained from chromeos with copyright:
* Copyright(c) 2013, Google Inc.
*/
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>
#include <drm/display/drm_dp_helper.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include "analogix-i2c-dptx.h"
#include "analogix-i2c-txcommon.h"
#define POLL_DELAY 50000 /* us */
#define POLL_TIMEOUT 5000000 /* us */
#define I2C_IDX_DPTX 0
#define I2C_IDX_TXCOM 1
static const u8 anx6345_i2c_addresses[] = {
[I2C_IDX_DPTX] = 0x70,
[I2C_IDX_TXCOM] = 0x72,
};
#define I2C_NUM_ADDRESSES ARRAY_SIZE(anx6345_i2c_addresses)
struct anx6345 {
struct drm_dp_aux aux;
struct drm_bridge bridge;
struct i2c_client *client;
const struct drm_edid *drm_edid;
struct drm_connector connector;
struct drm_panel *panel;
struct regulator *dvdd12;
struct regulator *dvdd25;
struct gpio_desc *gpiod_reset;
struct mutex lock; /* protect EDID access */
/* I2C Slave addresses of ANX6345 are mapped as DPTX and SYS */
struct i2c_client *i2c_clients[I2C_NUM_ADDRESSES];
struct regmap *map[I2C_NUM_ADDRESSES];
u16 chipid;
u8 dpcd[DP_RECEIVER_CAP_SIZE];
bool powered;
};
static inline struct anx6345 *connector_to_anx6345(struct drm_connector *c)
{
return container_of(c, struct anx6345, connector);
}
static inline struct anx6345 *bridge_to_anx6345(struct drm_bridge *bridge)
{
return container_of(bridge, struct anx6345, bridge);
}
static int anx6345_set_bits(struct regmap *map, u8 reg, u8 mask)
{
return regmap_update_bits(map, reg, mask, mask);
}
static int anx6345_clear_bits(struct regmap *map, u8 reg, u8 mask)
{
return regmap_update_bits(map, reg, mask, 0);
}
static ssize_t anx6345_aux_transfer(struct drm_dp_aux *aux,
struct drm_dp_aux_msg *msg)
{
struct anx6345 *anx6345 = container_of(aux, struct anx6345, aux);
return anx_dp_aux_transfer(anx6345->map[I2C_IDX_DPTX], msg);
}
static int anx6345_dp_link_training(struct anx6345 *anx6345)
{
unsigned int value;
u8 dp_bw, dpcd[2];
int err;
err = anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM],
SP_POWERDOWN_CTRL_REG,
SP_TOTAL_PD);
if (err)
return err;
err = drm_dp_dpcd_readb(&anx6345->aux, DP_MAX_LINK_RATE, &dp_bw);
if (err < 0)
return err;
switch (dp_bw) {
case DP_LINK_BW_1_62:
case DP_LINK_BW_2_7:
break;
default:
DRM_DEBUG_KMS("DP bandwidth (%#02x) not supported\n", dp_bw);
return -EINVAL;
}
err = anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM], SP_VID_CTRL1_REG,
SP_VIDEO_MUTE);
if (err)
return err;
err = anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM],
SP_VID_CTRL1_REG, SP_VIDEO_EN);
if (err)
return err;
/* Get DPCD info */
err = drm_dp_dpcd_read(&anx6345->aux, DP_DPCD_REV,
&anx6345->dpcd, DP_RECEIVER_CAP_SIZE);
if (err < 0) {
DRM_ERROR("Failed to read DPCD: %d\n", err);
return err;
}
/* Clear channel x SERDES power down */
err = anx6345_clear_bits(anx6345->map[I2C_IDX_DPTX],
SP_DP_ANALOG_POWER_DOWN_REG, SP_CH0_PD);
if (err)
return err;
drm_dp_link_power_up(&anx6345->aux, anx6345->dpcd[DP_DPCD_REV]);
/* Possibly enable downspread on the sink */
err = regmap_write(anx6345->map[I2C_IDX_DPTX],
SP_DP_DOWNSPREAD_CTRL1_REG, 0);
if (err)
return err;
if (anx6345->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5) {
DRM_DEBUG("Enable downspread on the sink\n");
/* 4000PPM */
err = regmap_write(anx6345->map[I2C_IDX_DPTX],
SP_DP_DOWNSPREAD_CTRL1_REG, 8);
if (err)
return err;
err = drm_dp_dpcd_writeb(&anx6345->aux, DP_DOWNSPREAD_CTRL,
DP_SPREAD_AMP_0_5);
if (err < 0)
return err;
} else {
err = drm_dp_dpcd_writeb(&anx6345->aux, DP_DOWNSPREAD_CTRL, 0);
if (err < 0)
return err;
}
/* Set the lane count and the link rate on the sink */
if (drm_dp_enhanced_frame_cap(anx6345->dpcd))
err = anx6345_set_bits(anx6345->map[I2C_IDX_DPTX],
SP_DP_SYSTEM_CTRL_BASE + 4,
SP_ENHANCED_MODE);
else
err = anx6345_clear_bits(anx6345->map[I2C_IDX_DPTX],
SP_DP_SYSTEM_CTRL_BASE + 4,
SP_ENHANCED_MODE);
if (err)
return err;
dpcd[0] = dp_bw;
err = regmap_write(anx6345->map[I2C_IDX_DPTX],
SP_DP_MAIN_LINK_BW_SET_REG, dpcd[0]);
if (err)
return err;
dpcd[1] = drm_dp_max_lane_count(anx6345->dpcd);
err = regmap_write(anx6345->map[I2C_IDX_DPTX],
SP_DP_LANE_COUNT_SET_REG, dpcd[1]);
if (err)
return err;
if (drm_dp_enhanced_frame_cap(anx6345->dpcd))
dpcd[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
err = drm_dp_dpcd_write(&anx6345->aux, DP_LINK_BW_SET, dpcd,
sizeof(dpcd));
if (err < 0) {
DRM_ERROR("Failed to configure link: %d\n", err);
return err;
}
/* Start training on the source */
err = regmap_write(anx6345->map[I2C_IDX_DPTX], SP_DP_LT_CTRL_REG,
SP_LT_EN);
if (err)
return err;
return regmap_read_poll_timeout(anx6345->map[I2C_IDX_DPTX],
SP_DP_LT_CTRL_REG,
value, !(value & SP_DP_LT_INPROGRESS),
POLL_DELAY, POLL_TIMEOUT);
}
static int anx6345_tx_initialization(struct anx6345 *anx6345)
{
int err, i;
/* FIXME: colordepth is hardcoded for now */
err = regmap_write(anx6345->map[I2C_IDX_TXCOM], SP_VID_CTRL2_REG,
SP_IN_BPC_6BIT << SP_IN_BPC_SHIFT);
if (err)
return err;
err = regmap_write(anx6345->map[I2C_IDX_DPTX], SP_DP_PLL_CTRL_REG, 0);
if (err)
return err;
err = regmap_write(anx6345->map[I2C_IDX_TXCOM],
SP_ANALOG_DEBUG1_REG, 0);
if (err)
return err;
err = regmap_write(anx6345->map[I2C_IDX_DPTX],
SP_DP_LINK_DEBUG_CTRL_REG,
SP_NEW_PRBS7 | SP_M_VID_DEBUG);
if (err)
return err;
err = regmap_write(anx6345->map[I2C_IDX_DPTX],
SP_DP_ANALOG_POWER_DOWN_REG, 0);
if (err)
return err;
/* Force HPD */
err = anx6345_set_bits(anx6345->map[I2C_IDX_DPTX],
SP_DP_SYSTEM_CTRL_BASE + 3,
SP_HPD_FORCE | SP_HPD_CTRL);
if (err)
return err;
for (i = 0; i < 4; i++) {
/* 4 lanes */
err = regmap_write(anx6345->map[I2C_IDX_DPTX],
SP_DP_LANE0_LT_CTRL_REG + i, 0);
if (err)
return err;
}
/* Reset AUX */
err = anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM],
SP_RESET_CTRL2_REG, SP_AUX_RST);
if (err)
return err;
return anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM],
SP_RESET_CTRL2_REG, SP_AUX_RST);
}
static void anx6345_poweron(struct anx6345 *anx6345)
{
int err;
/* Ensure reset is asserted before starting power on sequence */
gpiod_set_value_cansleep(anx6345->gpiod_reset, 1);
usleep_range(1000, 2000);
err = regulator_enable(anx6345->dvdd12);
if (err) {
DRM_ERROR("Failed to enable dvdd12 regulator: %d\n",
err);
return;
}
/* T1 - delay between VDD12 and VDD25 should be 0-2ms */
usleep_range(1000, 2000);
err = regulator_enable(anx6345->dvdd25);
if (err) {
DRM_ERROR("Failed to enable dvdd25 regulator: %d\n",
err);
return;
}
/* T2 - delay between RESETN and all power rail stable,
* should be 2-5ms
*/
usleep_range(2000, 5000);
gpiod_set_value_cansleep(anx6345->gpiod_reset, 0);
/* Power on registers module */
anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM], SP_POWERDOWN_CTRL_REG,
SP_HDCP_PD | SP_AUDIO_PD | SP_VIDEO_PD | SP_LINK_PD);
anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM], SP_POWERDOWN_CTRL_REG,
SP_REGISTER_PD | SP_TOTAL_PD);
if (anx6345->panel)
drm_panel_prepare(anx6345->panel);
anx6345->powered = true;
}
static void anx6345_poweroff(struct anx6345 *anx6345)
{
int err;
gpiod_set_value_cansleep(anx6345->gpiod_reset, 1);
usleep_range(1000, 2000);
if (anx6345->panel)
drm_panel_unprepare(anx6345->panel);
err = regulator_disable(anx6345->dvdd25);
if (err) {
DRM_ERROR("Failed to disable dvdd25 regulator: %d\n",
err);
return;
}
usleep_range(5000, 10000);
err = regulator_disable(anx6345->dvdd12);
if (err) {
DRM_ERROR("Failed to disable dvdd12 regulator: %d\n",
err);
return;
}
usleep_range(1000, 2000);
anx6345->powered = false;
}
static int anx6345_start(struct anx6345 *anx6345)
{
int err;
if (!anx6345->powered)
anx6345_poweron(anx6345);
/* Power on needed modules */
err = anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM],
SP_POWERDOWN_CTRL_REG,
SP_VIDEO_PD | SP_LINK_PD);
err = anx6345_tx_initialization(anx6345);
if (err) {
DRM_ERROR("Failed eDP transmitter initialization: %d\n", err);
anx6345_poweroff(anx6345);
return err;
}
err = anx6345_dp_link_training(anx6345);
if (err) {
DRM_ERROR("Failed link training: %d\n", err);
anx6345_poweroff(anx6345);
return err;
}
/*
* This delay seems to help keep the hardware in a good state. Without
* it, there are times where it fails silently.
*/
usleep_range(10000, 15000);
return 0;
}
static int anx6345_config_dp_output(struct anx6345 *anx6345)
{
int err;
err = anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM], SP_VID_CTRL1_REG,
SP_VIDEO_MUTE);
if (err)
return err;
/* Enable DP output */
err = anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM], SP_VID_CTRL1_REG,
SP_VIDEO_EN);
if (err)
return err;
/* Force stream valid */
return anx6345_set_bits(anx6345->map[I2C_IDX_DPTX],
SP_DP_SYSTEM_CTRL_BASE + 3,
SP_STRM_FORCE | SP_STRM_CTRL);
}
static int anx6345_get_downstream_info(struct anx6345 *anx6345)
{
u8 value;
int err;
err = drm_dp_dpcd_readb(&anx6345->aux, DP_SINK_COUNT, &value);
if (err < 0) {
DRM_ERROR("Get sink count failed %d\n", err);
return err;
}
if (!DP_GET_SINK_COUNT(value)) {
DRM_ERROR("Downstream disconnected\n");
return -EIO;
}
return 0;
}
static int anx6345_get_modes(struct drm_connector *connector)
{
struct anx6345 *anx6345 = connector_to_anx6345(connector);
int err, num_modes = 0;
bool power_off = false;
mutex_lock(&anx6345->lock);
if (!anx6345->drm_edid) {
if (!anx6345->powered) {
anx6345_poweron(anx6345);
power_off = true;
}
err = anx6345_get_downstream_info(anx6345);
if (err) {
DRM_ERROR("Failed to get downstream info: %d\n", err);
goto unlock;
}
anx6345->drm_edid = drm_edid_read_ddc(connector, &anx6345->aux.ddc);
if (!anx6345->drm_edid)
DRM_ERROR("Failed to read EDID from panel\n");
err = drm_edid_connector_update(connector, anx6345->drm_edid);
if (err) {
DRM_ERROR("Failed to update EDID property: %d\n", err);
goto unlock;
}
}
num_modes += drm_edid_connector_add_modes(connector);
/* Driver currently supports only 6bpc */
connector->display_info.bpc = 6;
unlock:
if (power_off)
anx6345_poweroff(anx6345);
mutex_unlock(&anx6345->lock);
if (!num_modes && anx6345->panel)
num_modes += drm_panel_get_modes(anx6345->panel, connector);
return num_modes;
}
static const struct drm_connector_helper_funcs anx6345_connector_helper_funcs = {
.get_modes = anx6345_get_modes,
};
static void
anx6345_connector_destroy(struct drm_connector *connector)
{
drm_connector_cleanup(connector);
}
static const struct drm_connector_funcs anx6345_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = anx6345_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static int anx6345_bridge_attach(struct drm_bridge *bridge,
struct drm_encoder *encoder,
enum drm_bridge_attach_flags flags)
{
struct anx6345 *anx6345 = bridge_to_anx6345(bridge);
int err;
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
DRM_ERROR("Fix bridge driver to make connector optional!");
return -EINVAL;
}
/* Register aux channel */
anx6345->aux.name = "DP-AUX";
anx6345->aux.dev = &anx6345->client->dev;
anx6345->aux.drm_dev = bridge->dev;
anx6345->aux.transfer = anx6345_aux_transfer;
err = drm_dp_aux_register(&anx6345->aux);
if (err < 0) {
DRM_ERROR("Failed to register aux channel: %d\n", err);
return err;
}
err = drm_connector_init(bridge->dev, &anx6345->connector,
&anx6345_connector_funcs,
DRM_MODE_CONNECTOR_eDP);
if (err) {
DRM_ERROR("Failed to initialize connector: %d\n", err);
goto aux_unregister;
}
drm_connector_helper_add(&anx6345->connector,
&anx6345_connector_helper_funcs);
anx6345->connector.polled = DRM_CONNECTOR_POLL_HPD;
err = drm_connector_attach_encoder(&anx6345->connector,
encoder);
if (err) {
DRM_ERROR("Failed to link up connector to encoder: %d\n", err);
goto connector_cleanup;
}
err = drm_connector_register(&anx6345->connector);
if (err) {
DRM_ERROR("Failed to register connector: %d\n", err);
goto connector_cleanup;
}
return 0;
connector_cleanup:
drm_connector_cleanup(&anx6345->connector);
aux_unregister:
drm_dp_aux_unregister(&anx6345->aux);
return err;
}
static void anx6345_bridge_detach(struct drm_bridge *bridge)
{
drm_dp_aux_unregister(&bridge_to_anx6345(bridge)->aux);
}
static enum drm_mode_status
anx6345_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
return MODE_NO_INTERLACE;
/* Max 1200p at 5.4 Ghz, one lane */
if (mode->clock > 154000)
return MODE_CLOCK_HIGH;
return MODE_OK;
}
static void anx6345_bridge_disable(struct drm_bridge *bridge)
{
struct anx6345 *anx6345 = bridge_to_anx6345(bridge);
/* Power off all modules except configuration registers access */
anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM], SP_POWERDOWN_CTRL_REG,
SP_HDCP_PD | SP_AUDIO_PD | SP_VIDEO_PD | SP_LINK_PD);
if (anx6345->panel)
drm_panel_disable(anx6345->panel);
if (anx6345->powered)
anx6345_poweroff(anx6345);
}
static void anx6345_bridge_enable(struct drm_bridge *bridge)
{
struct anx6345 *anx6345 = bridge_to_anx6345(bridge);
int err;
if (anx6345->panel)
drm_panel_enable(anx6345->panel);
err = anx6345_start(anx6345);
if (err) {
DRM_ERROR("Failed to initialize: %d\n", err);
return;
}
err = anx6345_config_dp_output(anx6345);
if (err)
DRM_ERROR("Failed to enable DP output: %d\n", err);
}
static const struct drm_bridge_funcs anx6345_bridge_funcs = {
.attach = anx6345_bridge_attach,
.detach = anx6345_bridge_detach,
.mode_valid = anx6345_bridge_mode_valid,
.disable = anx6345_bridge_disable,
.enable = anx6345_bridge_enable,
};
static void unregister_i2c_dummy_clients(struct anx6345 *anx6345)
{
unsigned int i;
for (i = 1; i < ARRAY_SIZE(anx6345->i2c_clients); i++)
if (anx6345->i2c_clients[i] &&
anx6345->i2c_clients[i]->addr != anx6345->client->addr)
i2c_unregister_device(anx6345->i2c_clients[i]);
}
static const struct regmap_config anx6345_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
};
static const u16 anx6345_chipid_list[] = {
0x6345,
};
static bool anx6345_get_chip_id(struct anx6345 *anx6345)
{
unsigned int i, idl, idh, version;
if (regmap_read(anx6345->map[I2C_IDX_TXCOM], SP_DEVICE_IDL_REG, &idl))
return false;
if (regmap_read(anx6345->map[I2C_IDX_TXCOM], SP_DEVICE_IDH_REG, &idh))
return false;
anx6345->chipid = (u8)idl | ((u8)idh << 8);
if (regmap_read(anx6345->map[I2C_IDX_TXCOM], SP_DEVICE_VERSION_REG,
&version))
return false;
for (i = 0; i < ARRAY_SIZE(anx6345_chipid_list); i++) {
if (anx6345->chipid == anx6345_chipid_list[i]) {
DRM_INFO("Found ANX%x (ver. %d) eDP Transmitter\n",
anx6345->chipid, version);
return true;
}
}
DRM_ERROR("ANX%x (ver. %d) not supported by this driver\n",
anx6345->chipid, version);
return false;
}
static int anx6345_i2c_probe(struct i2c_client *client)
{
struct anx6345 *anx6345;
struct device *dev;
int i, err;
anx6345 = devm_drm_bridge_alloc(&client->dev, struct anx6345, bridge,
&anx6345_bridge_funcs);
if (IS_ERR(anx6345))
return PTR_ERR(anx6345);
mutex_init(&anx6345->lock);
anx6345->bridge.of_node = client->dev.of_node;
anx6345->client = client;
i2c_set_clientdata(client, anx6345);
dev = &anx6345->client->dev;
err = drm_of_find_panel_or_bridge(client->dev.of_node, 1, 0,
&anx6345->panel, NULL);
if (err == -EPROBE_DEFER)
return err;
if (err)
DRM_DEBUG("No panel found\n");
/* 1.2V digital core power regulator */
anx6345->dvdd12 = devm_regulator_get(dev, "dvdd12");
if (IS_ERR(anx6345->dvdd12)) {
if (PTR_ERR(anx6345->dvdd12) != -EPROBE_DEFER)
DRM_ERROR("Failed to get dvdd12 supply (%ld)\n",
PTR_ERR(anx6345->dvdd12));
return PTR_ERR(anx6345->dvdd12);
}
/* 2.5V digital core power regulator */
anx6345->dvdd25 = devm_regulator_get(dev, "dvdd25");
if (IS_ERR(anx6345->dvdd25)) {
if (PTR_ERR(anx6345->dvdd25) != -EPROBE_DEFER)
DRM_ERROR("Failed to get dvdd25 supply (%ld)\n",
PTR_ERR(anx6345->dvdd25));
return PTR_ERR(anx6345->dvdd25);
}
/* GPIO for chip reset */
anx6345->gpiod_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(anx6345->gpiod_reset)) {
DRM_ERROR("Reset gpio not found\n");
return PTR_ERR(anx6345->gpiod_reset);
}
/* Map slave addresses of ANX6345 */
for (i = 0; i < I2C_NUM_ADDRESSES; i++) {
if (anx6345_i2c_addresses[i] >> 1 != client->addr)
anx6345->i2c_clients[i] = i2c_new_dummy_device(client->adapter,
anx6345_i2c_addresses[i] >> 1);
else
anx6345->i2c_clients[i] = client;
if (IS_ERR(anx6345->i2c_clients[i])) {
err = PTR_ERR(anx6345->i2c_clients[i]);
DRM_ERROR("Failed to reserve I2C bus %02x\n",
anx6345_i2c_addresses[i]);
goto err_unregister_i2c;
}
anx6345->map[i] = devm_regmap_init_i2c(anx6345->i2c_clients[i],
&anx6345_regmap_config);
if (IS_ERR(anx6345->map[i])) {
err = PTR_ERR(anx6345->map[i]);
DRM_ERROR("Failed regmap initialization %02x\n",
anx6345_i2c_addresses[i]);
goto err_unregister_i2c;
}
}
/* Look for supported chip ID */
anx6345_poweron(anx6345);
if (anx6345_get_chip_id(anx6345)) {
drm_bridge_add(&anx6345->bridge);
return 0;
} else {
anx6345_poweroff(anx6345);
err = -ENODEV;
}
err_unregister_i2c:
unregister_i2c_dummy_clients(anx6345);
return err;
}
static void anx6345_i2c_remove(struct i2c_client *client)
{
struct anx6345 *anx6345 = i2c_get_clientdata(client);
drm_bridge_remove(&anx6345->bridge);
unregister_i2c_dummy_clients(anx6345);
drm_edid_free(anx6345->drm_edid);
mutex_destroy(&anx6345->lock);
}
static const struct i2c_device_id anx6345_id[] = {
{ "anx6345" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, anx6345_id);
static const struct of_device_id anx6345_match_table[] = {
{ .compatible = "analogix,anx6345", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, anx6345_match_table);
static struct i2c_driver anx6345_driver = {
.driver = {
.name = "anx6345",
.of_match_table = anx6345_match_table,
},
.probe = anx6345_i2c_probe,
.remove = anx6345_i2c_remove,
.id_table = anx6345_id,
};
module_i2c_driver(anx6345_driver);
MODULE_DESCRIPTION("ANX6345 eDP Transmitter driver");
MODULE_AUTHOR("Icenowy Zheng <icenowy@aosc.io>");
MODULE_LICENSE("GPL v2");
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,249 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2016, Analogix Semiconductor. All rights reserved.
*/
#ifndef __ANX78xx_H
#define __ANX78xx_H
#include "analogix-i2c-dptx.h"
#include "analogix-i2c-txcommon.h"
/***************************************************************/
/* Register definitions for RX_PO */
/***************************************************************/
/*
* System Control and Status
*/
/* Software Reset Register 1 */
#define SP_SOFTWARE_RESET1_REG 0x11
#define SP_VIDEO_RST BIT(4)
#define SP_HDCP_MAN_RST BIT(2)
#define SP_TMDS_RST BIT(1)
#define SP_SW_MAN_RST BIT(0)
/* System Status Register */
#define SP_SYSTEM_STATUS_REG 0x14
#define SP_TMDS_CLOCK_DET BIT(1)
#define SP_TMDS_DE_DET BIT(0)
/* HDMI Status Register */
#define SP_HDMI_STATUS_REG 0x15
#define SP_HDMI_AUD_LAYOUT BIT(3)
#define SP_HDMI_DET BIT(0)
# define SP_DVI_MODE 0
# define SP_HDMI_MODE 1
/* HDMI Mute Control Register */
#define SP_HDMI_MUTE_CTRL_REG 0x16
#define SP_AUD_MUTE BIT(1)
#define SP_VID_MUTE BIT(0)
/* System Power Down Register 1 */
#define SP_SYSTEM_POWER_DOWN1_REG 0x18
#define SP_PWDN_CTRL BIT(0)
/*
* Audio and Video Auto Control
*/
/* Auto Audio and Video Control register */
#define SP_AUDVID_CTRL_REG 0x20
#define SP_AVC_OE BIT(7)
#define SP_AAC_OE BIT(6)
#define SP_AVC_EN BIT(1)
#define SP_AAC_EN BIT(0)
/* Audio Exception Enable Registers */
#define SP_AUD_EXCEPTION_ENABLE_BASE (0x24 - 1)
/* Bits for Audio Exception Enable Register 3 */
#define SP_AEC_EN21 BIT(5)
/*
* Interrupt
*/
/* Interrupt Status Register 1 */
#define SP_INT_STATUS1_REG 0x31
/* Bits for Interrupt Status Register 1 */
#define SP_HDMI_DVI BIT(7)
#define SP_CKDT_CHG BIT(6)
#define SP_SCDT_CHG BIT(5)
#define SP_PCLK_CHG BIT(4)
#define SP_PLL_UNLOCK BIT(3)
#define SP_CABLE_PLUG_CHG BIT(2)
#define SP_SET_MUTE BIT(1)
#define SP_SW_INTR BIT(0)
/* Bits for Interrupt Status Register 2 */
#define SP_HDCP_ERR BIT(5)
#define SP_AUDIO_SAMPLE_CHG BIT(0) /* undocumented */
/* Bits for Interrupt Status Register 3 */
#define SP_AUD_MODE_CHG BIT(0)
/* Bits for Interrupt Status Register 5 */
#define SP_AUDIO_RCV BIT(0)
/* Bits for Interrupt Status Register 6 */
#define SP_INT_STATUS6_REG 0x36
#define SP_CTS_RCV BIT(7)
#define SP_NEW_AUD_PKT BIT(4)
#define SP_NEW_AVI_PKT BIT(1)
#define SP_NEW_CP_PKT BIT(0)
/* Bits for Interrupt Status Register 7 */
#define SP_NO_VSI BIT(7)
#define SP_NEW_VS BIT(4)
/* Interrupt Mask 1 Status Registers */
#define SP_INT_MASK1_REG 0x41
/* HDMI US TIMER Control Register */
#define SP_HDMI_US_TIMER_CTRL_REG 0x49
#define SP_MS_TIMER_MARGIN_10_8_MASK 0x07
/*
* TMDS Control
*/
/* TMDS Control Registers */
#define SP_TMDS_CTRL_BASE (0x50 - 1)
/* Bits for TMDS Control Register 7 */
#define SP_PD_RT BIT(0)
/*
* Video Control
*/
/* Video Status Register */
#define SP_VIDEO_STATUS_REG 0x70
#define SP_COLOR_DEPTH_MASK 0xf0
#define SP_COLOR_DEPTH_SHIFT 4
# define SP_COLOR_DEPTH_MODE_LEGACY 0x00
# define SP_COLOR_DEPTH_MODE_24BIT 0x04
# define SP_COLOR_DEPTH_MODE_30BIT 0x05
# define SP_COLOR_DEPTH_MODE_36BIT 0x06
# define SP_COLOR_DEPTH_MODE_48BIT 0x07
/* Video Data Range Control Register */
#define SP_VID_DATA_RANGE_CTRL_REG 0x83
#define SP_R2Y_INPUT_LIMIT BIT(1)
/* Pixel Clock High Resolution Counter Registers */
#define SP_PCLK_HIGHRES_CNT_BASE (0x8c - 1)
/*
* Audio Control
*/
/* Number of Audio Channels Status Registers */
#define SP_AUD_CH_STATUS_REG_NUM 6
/* Audio IN S/PDIF Channel Status Registers */
#define SP_AUD_SPDIF_CH_STATUS_BASE 0xc7
/* Audio IN S/PDIF Channel Status Register 4 */
#define SP_FS_FREQ_MASK 0x0f
# define SP_FS_FREQ_44100HZ 0x00
# define SP_FS_FREQ_48000HZ 0x02
# define SP_FS_FREQ_32000HZ 0x03
# define SP_FS_FREQ_88200HZ 0x08
# define SP_FS_FREQ_96000HZ 0x0a
# define SP_FS_FREQ_176400HZ 0x0c
# define SP_FS_FREQ_192000HZ 0x0e
/*
* Micellaneous Control Block
*/
/* CHIP Control Register */
#define SP_CHIP_CTRL_REG 0xe3
#define SP_MAN_HDMI5V_DET BIT(3)
#define SP_PLLLOCK_CKDT_EN BIT(2)
#define SP_ANALOG_CKDT_EN BIT(1)
#define SP_DIGITAL_CKDT_EN BIT(0)
/* Packet Receiving Status Register */
#define SP_PACKET_RECEIVING_STATUS_REG 0xf3
#define SP_AVI_RCVD BIT(5)
#define SP_VSI_RCVD BIT(1)
/***************************************************************/
/* Register definitions for RX_P1 */
/***************************************************************/
/* HDCP BCAPS Shadow Register */
#define SP_HDCP_BCAPS_SHADOW_REG 0x2a
#define SP_BCAPS_REPEATER BIT(5)
/* HDCP Status Register */
#define SP_RX_HDCP_STATUS_REG 0x3f
#define SP_AUTH_EN BIT(4)
/*
* InfoFrame and Control Packet Registers
*/
/* AVI InfoFrame packet checksum */
#define SP_AVI_INFOFRAME_CHECKSUM 0xa3
/* AVI InfoFrame Registers */
#define SP_AVI_INFOFRAME_DATA_BASE 0xa4
#define SP_AVI_COLOR_F_MASK 0x60
#define SP_AVI_COLOR_F_SHIFT 5
/* Audio InfoFrame Registers */
#define SP_AUD_INFOFRAME_DATA_BASE 0xc4
#define SP_AUD_INFOFRAME_LAYOUT_MASK 0x0f
/* MPEG/HDMI Vendor Specific InfoFrame Packet type code */
#define SP_MPEG_VS_INFOFRAME_TYPE_REG 0xe0
/* MPEG/HDMI Vendor Specific InfoFrame Packet length */
#define SP_MPEG_VS_INFOFRAME_LEN_REG 0xe2
/* MPEG/HDMI Vendor Specific InfoFrame Packet version number */
#define SP_MPEG_VS_INFOFRAME_VER_REG 0xe1
/* MPEG/HDMI Vendor Specific InfoFrame Packet content */
#define SP_MPEG_VS_INFOFRAME_DATA_BASE 0xe4
/* General Control Packet Register */
#define SP_GENERAL_CTRL_PACKET_REG 0x9f
#define SP_CLEAR_AVMUTE BIT(4)
#define SP_SET_AVMUTE BIT(0)
/***************************************************************/
/* Register definitions for TX_P1 */
/***************************************************************/
/* DP TX Link Training Control Register */
#define SP_DP_TX_LT_CTRL0_REG 0x30
/* PD 1.2 Lint Training 80bit Pattern Register */
#define SP_DP_LT_80BIT_PATTERN0_REG 0x80
#define SP_DP_LT_80BIT_PATTERN_REG_NUM 10
/* Audio Interface Control Register 0 */
#define SP_AUD_INTERFACE_CTRL0_REG 0x5f
#define SP_AUD_INTERFACE_DISABLE 0x80
/* Audio Interface Control Register 2 */
#define SP_AUD_INTERFACE_CTRL2_REG 0x60
#define SP_M_AUD_ADJUST_ST 0x04
/* Audio Interface Control Register 3 */
#define SP_AUD_INTERFACE_CTRL3_REG 0x62
/* Audio Interface Control Register 4 */
#define SP_AUD_INTERFACE_CTRL4_REG 0x67
/* Audio Interface Control Register 5 */
#define SP_AUD_INTERFACE_CTRL5_REG 0x68
/* Audio Interface Control Register 6 */
#define SP_AUD_INTERFACE_CTRL6_REG 0x69
/* Firmware Version Register */
#define SP_FW_VER_REG 0xb7
#endif
@@ -0,0 +1,167 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2016, Analogix Semiconductor.
*
* Based on anx7808 driver obtained from chromeos with copyright:
* Copyright(c) 2013, Google Inc.
*/
#include <linux/export.h>
#include <linux/regmap.h>
#include <drm/display/drm_dp_helper.h>
#include <drm/drm.h>
#include <drm/drm_print.h>
#include "analogix-i2c-dptx.h"
#define AUX_WAIT_TIMEOUT_MS 15
#define AUX_CH_BUFFER_SIZE 16
static int anx_i2c_dp_clear_bits(struct regmap *map, u8 reg, u8 mask)
{
return regmap_update_bits(map, reg, mask, 0);
}
static bool anx_dp_aux_op_finished(struct regmap *map_dptx)
{
unsigned int value;
int err;
err = regmap_read(map_dptx, SP_DP_AUX_CH_CTRL2_REG, &value);
if (err < 0)
return false;
return (value & SP_AUX_EN) == 0;
}
static int anx_dp_aux_wait(struct regmap *map_dptx)
{
unsigned long timeout;
unsigned int status;
int err;
timeout = jiffies + msecs_to_jiffies(AUX_WAIT_TIMEOUT_MS) + 1;
while (!anx_dp_aux_op_finished(map_dptx)) {
if (time_after(jiffies, timeout)) {
if (!anx_dp_aux_op_finished(map_dptx)) {
DRM_ERROR("Timed out waiting AUX to finish\n");
return -ETIMEDOUT;
}
break;
}
usleep_range(1000, 2000);
}
/* Read the AUX channel access status */
err = regmap_read(map_dptx, SP_AUX_CH_STATUS_REG, &status);
if (err < 0) {
DRM_ERROR("Failed to read from AUX channel: %d\n", err);
return err;
}
if (status & SP_AUX_STATUS) {
DRM_ERROR("Failed to wait for AUX channel (status: %02x)\n",
status);
return -ETIMEDOUT;
}
return 0;
}
static int anx_dp_aux_address(struct regmap *map_dptx, unsigned int addr)
{
int err;
err = regmap_write(map_dptx, SP_AUX_ADDR_7_0_REG, addr & 0xff);
if (err)
return err;
err = regmap_write(map_dptx, SP_AUX_ADDR_15_8_REG,
(addr & 0xff00) >> 8);
if (err)
return err;
/*
* DP AUX CH Address Register #2, only update bits[3:0]
* [7:4] RESERVED
* [3:0] AUX_ADDR[19:16], Register control AUX CH address.
*/
err = regmap_update_bits(map_dptx, SP_AUX_ADDR_19_16_REG,
SP_AUX_ADDR_19_16_MASK,
(addr & 0xf0000) >> 16);
if (err)
return err;
return 0;
}
ssize_t anx_dp_aux_transfer(struct regmap *map_dptx,
struct drm_dp_aux_msg *msg)
{
u8 ctrl1 = msg->request;
u8 ctrl2 = SP_AUX_EN;
u8 *buffer = msg->buffer;
int err;
/* The DP AUX transmit and receive buffer has 16 bytes. */
if (WARN_ON(msg->size > AUX_CH_BUFFER_SIZE))
return -E2BIG;
/* Zero-sized messages specify address-only transactions. */
if (msg->size < 1)
ctrl2 |= SP_ADDR_ONLY;
else /* For non-zero-sized set the length field. */
ctrl1 |= (msg->size - 1) << SP_AUX_LENGTH_SHIFT;
if ((msg->size > 0) && ((msg->request & DP_AUX_I2C_READ) == 0)) {
/* When WRITE | MOT write values to data buffer */
err = regmap_bulk_write(map_dptx,
SP_DP_BUF_DATA0_REG, buffer,
msg->size);
if (err)
return err;
}
/* Write address and request */
err = anx_dp_aux_address(map_dptx, msg->address);
if (err)
return err;
err = regmap_write(map_dptx, SP_DP_AUX_CH_CTRL1_REG, ctrl1);
if (err)
return err;
/* Start transaction */
err = regmap_update_bits(map_dptx, SP_DP_AUX_CH_CTRL2_REG,
SP_ADDR_ONLY | SP_AUX_EN, ctrl2);
if (err)
return err;
err = anx_dp_aux_wait(map_dptx);
if (err)
return err;
msg->reply = DP_AUX_I2C_REPLY_ACK;
if ((msg->size > 0) && (msg->request & DP_AUX_I2C_READ)) {
/* Read values from data buffer */
err = regmap_bulk_read(map_dptx,
SP_DP_BUF_DATA0_REG, buffer,
msg->size);
if (err)
return err;
}
err = anx_i2c_dp_clear_bits(map_dptx, SP_DP_AUX_CH_CTRL2_REG,
SP_ADDR_ONLY);
if (err)
return err;
return msg->size;
}
EXPORT_SYMBOL_GPL(anx_dp_aux_transfer);
@@ -0,0 +1,256 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2016, Analogix Semiconductor.
*
* Based on anx7808 driver obtained from chromeos with copyright:
* Copyright(c) 2013, Google Inc.
*/
#ifndef _ANALOGIX_I2C_DPTX_H_
#define _ANALOGIX_I2C_DPTX_H_
/***************************************************************/
/* Register definitions for TX_P0 */
/***************************************************************/
/* HDCP Status Register */
#define SP_TX_HDCP_STATUS_REG 0x00
#define SP_AUTH_FAIL BIT(5)
#define SP_AUTHEN_PASS BIT(1)
/* HDCP Control Register 0 */
#define SP_HDCP_CTRL0_REG 0x01
#define SP_RX_REPEATER BIT(6)
#define SP_RE_AUTH BIT(5)
#define SP_SW_AUTH_OK BIT(4)
#define SP_HARD_AUTH_EN BIT(3)
#define SP_HDCP_ENC_EN BIT(2)
#define SP_BKSV_SRM_PASS BIT(1)
#define SP_KSVLIST_VLD BIT(0)
/* HDCP Function Enabled */
#define SP_HDCP_FUNCTION_ENABLED (BIT(0) | BIT(1) | BIT(2) | BIT(3))
/* HDCP Receiver BSTATUS Register 0 */
#define SP_HDCP_RX_BSTATUS0_REG 0x1b
/* HDCP Receiver BSTATUS Register 1 */
#define SP_HDCP_RX_BSTATUS1_REG 0x1c
/* HDCP Embedded "Blue Screen" Content Registers */
#define SP_HDCP_VID0_BLUE_SCREEN_REG 0x2c
#define SP_HDCP_VID1_BLUE_SCREEN_REG 0x2d
#define SP_HDCP_VID2_BLUE_SCREEN_REG 0x2e
/* HDCP Wait R0 Timing Register */
#define SP_HDCP_WAIT_R0_TIME_REG 0x40
/* HDCP Link Integrity Check Timer Register */
#define SP_HDCP_LINK_CHECK_TIMER_REG 0x41
/* HDCP Repeater Ready Wait Timer Register */
#define SP_HDCP_RPTR_RDY_WAIT_TIME_REG 0x42
/* HDCP Auto Timer Register */
#define SP_HDCP_AUTO_TIMER_REG 0x51
/* HDCP Key Status Register */
#define SP_HDCP_KEY_STATUS_REG 0x5e
/* HDCP Key Command Register */
#define SP_HDCP_KEY_COMMAND_REG 0x5f
#define SP_DISABLE_SYNC_HDCP BIT(2)
/* OTP Memory Key Protection Registers */
#define SP_OTP_KEY_PROTECT1_REG 0x60
#define SP_OTP_KEY_PROTECT2_REG 0x61
#define SP_OTP_KEY_PROTECT3_REG 0x62
#define SP_OTP_PSW1 0xa2
#define SP_OTP_PSW2 0x7e
#define SP_OTP_PSW3 0xc6
/* DP System Control Registers */
#define SP_DP_SYSTEM_CTRL_BASE (0x80 - 1)
/* Bits for DP System Control Register 2 */
#define SP_CHA_STA BIT(2)
/* Bits for DP System Control Register 3 */
#define SP_HPD_STATUS BIT(6)
#define SP_HPD_FORCE BIT(5)
#define SP_HPD_CTRL BIT(4)
#define SP_STRM_VALID BIT(2)
#define SP_STRM_FORCE BIT(1)
#define SP_STRM_CTRL BIT(0)
/* Bits for DP System Control Register 4 */
#define SP_ENHANCED_MODE BIT(3)
/* DP Video Control Register */
#define SP_DP_VIDEO_CTRL_REG 0x84
#define SP_COLOR_F_MASK 0x06
#define SP_COLOR_F_SHIFT 1
#define SP_BPC_MASK 0xe0
#define SP_BPC_SHIFT 5
# define SP_BPC_6BITS 0x00
# define SP_BPC_8BITS 0x01
# define SP_BPC_10BITS 0x02
# define SP_BPC_12BITS 0x03
/* DP Audio Control Register */
#define SP_DP_AUDIO_CTRL_REG 0x87
#define SP_AUD_EN BIT(0)
/* 10us Pulse Generate Timer Registers */
#define SP_I2C_GEN_10US_TIMER0_REG 0x88
#define SP_I2C_GEN_10US_TIMER1_REG 0x89
/* Packet Send Control Register */
#define SP_PACKET_SEND_CTRL_REG 0x90
#define SP_AUD_IF_UP BIT(7)
#define SP_AVI_IF_UD BIT(6)
#define SP_MPEG_IF_UD BIT(5)
#define SP_SPD_IF_UD BIT(4)
#define SP_AUD_IF_EN BIT(3)
#define SP_AVI_IF_EN BIT(2)
#define SP_MPEG_IF_EN BIT(1)
#define SP_SPD_IF_EN BIT(0)
/* DP HDCP Control Register */
#define SP_DP_HDCP_CTRL_REG 0x92
#define SP_AUTO_EN BIT(7)
#define SP_AUTO_START BIT(5)
#define SP_LINK_POLLING BIT(1)
/* DP Main Link Bandwidth Setting Register */
#define SP_DP_MAIN_LINK_BW_SET_REG 0xa0
#define SP_LINK_BW_SET_MASK 0x1f
#define SP_INITIAL_SLIM_M_AUD_SEL BIT(5)
/* DP Lane Count Setting Register */
#define SP_DP_LANE_COUNT_SET_REG 0xa1
/* DP Training Pattern Set Register */
#define SP_DP_TRAINING_PATTERN_SET_REG 0xa2
/* DP Lane 0 Link Training Control Register */
#define SP_DP_LANE0_LT_CTRL_REG 0xa3
#define SP_TX_SW_SET_MASK 0x1b
#define SP_MAX_PRE_REACH BIT(5)
#define SP_MAX_DRIVE_REACH BIT(4)
#define SP_PRE_EMP_LEVEL1 BIT(3)
#define SP_DRVIE_CURRENT_LEVEL1 BIT(0)
/* DP Link Training Control Register */
#define SP_DP_LT_CTRL_REG 0xa8
#define SP_DP_LT_INPROGRESS 0x80
#define SP_LT_ERROR_TYPE_MASK 0x70
# define SP_LT_NO_ERROR 0x00
# define SP_LT_AUX_WRITE_ERROR 0x01
# define SP_LT_MAX_DRIVE_REACHED 0x02
# define SP_LT_WRONG_LANE_COUNT_SET 0x03
# define SP_LT_LOOP_SAME_5_TIME 0x04
# define SP_LT_CR_FAIL_IN_EQ 0x05
# define SP_LT_EQ_LOOP_5_TIME 0x06
#define SP_LT_EN BIT(0)
/* DP CEP Training Control Registers */
#define SP_DP_CEP_TRAINING_CTRL0_REG 0xa9
#define SP_DP_CEP_TRAINING_CTRL1_REG 0xaa
/* DP Debug Register 1 */
#define SP_DP_DEBUG1_REG 0xb0
#define SP_DEBUG_PLL_LOCK BIT(4)
#define SP_POLLING_EN BIT(1)
/* DP Polling Control Register */
#define SP_DP_POLLING_CTRL_REG 0xb4
#define SP_AUTO_POLLING_DISABLE BIT(0)
/* DP Link Debug Control Register */
#define SP_DP_LINK_DEBUG_CTRL_REG 0xb8
#define SP_M_VID_DEBUG BIT(5)
#define SP_NEW_PRBS7 BIT(4)
#define SP_INSERT_ER BIT(1)
#define SP_PRBS31_EN BIT(0)
/* AUX Misc control Register */
#define SP_AUX_MISC_CTRL_REG 0xbf
/* DP PLL control Register */
#define SP_DP_PLL_CTRL_REG 0xc7
#define SP_PLL_RST BIT(6)
/* DP Analog Power Down Register */
#define SP_DP_ANALOG_POWER_DOWN_REG 0xc8
#define SP_CH0_PD BIT(0)
/* DP Misc Control Register */
#define SP_DP_MISC_CTRL_REG 0xcd
#define SP_EQ_TRAINING_LOOP BIT(6)
/* DP Extra I2C Device Address Register */
#define SP_DP_EXTRA_I2C_DEV_ADDR_REG 0xce
#define SP_I2C_STRETCH_DISABLE BIT(7)
#define SP_I2C_EXTRA_ADDR 0x50
/* DP Downspread Control Register 1 */
#define SP_DP_DOWNSPREAD_CTRL1_REG 0xd0
/* DP M Value Calculation Control Register */
#define SP_DP_M_CALCULATION_CTRL_REG 0xd9
#define SP_M_GEN_CLK_SEL BIT(0)
/* AUX Channel Access Status Register */
#define SP_AUX_CH_STATUS_REG 0xe0
#define SP_AUX_STATUS 0x0f
/* AUX Channel DEFER Control Register */
#define SP_AUX_DEFER_CTRL_REG 0xe2
#define SP_DEFER_CTRL_EN BIT(7)
/* DP Buffer Data Count Register */
#define SP_BUF_DATA_COUNT_REG 0xe4
#define SP_BUF_DATA_COUNT_MASK 0x1f
#define SP_BUF_CLR BIT(7)
/* DP AUX Channel Control Register 1 */
#define SP_DP_AUX_CH_CTRL1_REG 0xe5
#define SP_AUX_TX_COMM_MASK 0x0f
#define SP_AUX_LENGTH_MASK 0xf0
#define SP_AUX_LENGTH_SHIFT 4
/* DP AUX CH Address Register 0 */
#define SP_AUX_ADDR_7_0_REG 0xe6
/* DP AUX CH Address Register 1 */
#define SP_AUX_ADDR_15_8_REG 0xe7
/* DP AUX CH Address Register 2 */
#define SP_AUX_ADDR_19_16_REG 0xe8
#define SP_AUX_ADDR_19_16_MASK 0x0f
/* DP AUX Channel Control Register 2 */
#define SP_DP_AUX_CH_CTRL2_REG 0xe9
#define SP_AUX_SEL_RXCM BIT(6)
#define SP_AUX_CHSEL BIT(3)
#define SP_AUX_PN_INV BIT(2)
#define SP_ADDR_ONLY BIT(1)
#define SP_AUX_EN BIT(0)
/* DP Video Stream Control InfoFrame Register */
#define SP_DP_3D_VSC_CTRL_REG 0xea
#define SP_INFO_FRAME_VSC_EN BIT(0)
/* DP Video Stream Data Byte 1 Register */
#define SP_DP_VSC_DB1_REG 0xeb
/* DP AUX Channel Control Register 3 */
#define SP_DP_AUX_CH_CTRL3_REG 0xec
#define SP_WAIT_COUNTER_7_0_MASK 0xff
/* DP AUX Channel Control Register 4 */
#define SP_DP_AUX_CH_CTRL4_REG 0xed
/* DP AUX Buffer Data Registers */
#define SP_DP_BUF_DATA0_REG 0xf0
ssize_t anx_dp_aux_transfer(struct regmap *map_dptx,
struct drm_dp_aux_msg *msg);
#endif
@@ -0,0 +1,234 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2016, Analogix Semiconductor. All rights reserved.
*/
#ifndef _ANALOGIX_I2C_TXCOMMON_H_
#define _ANALOGIX_I2C_TXCOMMON_H_
/***************************************************************/
/* Register definitions for TX_P2 */
/***************************************************************/
/*
* Core Register Definitions
*/
/* Device ID Low Byte Register */
#define SP_DEVICE_IDL_REG 0x02
/* Device ID High Byte Register */
#define SP_DEVICE_IDH_REG 0x03
/* Device version register */
#define SP_DEVICE_VERSION_REG 0x04
/* Power Down Control Register */
#define SP_POWERDOWN_CTRL_REG 0x05
#define SP_REGISTER_PD BIT(7)
#define SP_HDCP_PD BIT(5)
#define SP_AUDIO_PD BIT(4)
#define SP_VIDEO_PD BIT(3)
#define SP_LINK_PD BIT(2)
#define SP_TOTAL_PD BIT(1)
/* Reset Control Register 1 */
#define SP_RESET_CTRL1_REG 0x06
#define SP_MISC_RST BIT(7)
#define SP_VIDCAP_RST BIT(6)
#define SP_VIDFIF_RST BIT(5)
#define SP_AUDFIF_RST BIT(4)
#define SP_AUDCAP_RST BIT(3)
#define SP_HDCP_RST BIT(2)
#define SP_SW_RST BIT(1)
#define SP_HW_RST BIT(0)
/* Reset Control Register 2 */
#define SP_RESET_CTRL2_REG 0x07
#define SP_AUX_RST BIT(2)
#define SP_SERDES_FIFO_RST BIT(1)
#define SP_I2C_REG_RST BIT(0)
/* Video Control Register 1 */
#define SP_VID_CTRL1_REG 0x08
#define SP_VIDEO_EN BIT(7)
#define SP_VIDEO_MUTE BIT(2)
#define SP_DE_GEN BIT(1)
#define SP_DEMUX BIT(0)
/* Video Control Register 2 */
#define SP_VID_CTRL2_REG 0x09
#define SP_IN_COLOR_F_MASK 0x03
#define SP_IN_YC_BIT_SEL BIT(2)
#define SP_IN_BPC_MASK 0x70
#define SP_IN_BPC_SHIFT 4
# define SP_IN_BPC_12BIT 0x03
# define SP_IN_BPC_10BIT 0x02
# define SP_IN_BPC_8BIT 0x01
# define SP_IN_BPC_6BIT 0x00
#define SP_IN_D_RANGE BIT(7)
/* Video Control Register 3 */
#define SP_VID_CTRL3_REG 0x0a
#define SP_HPD_OUT BIT(6)
/* Video Control Register 5 */
#define SP_VID_CTRL5_REG 0x0c
#define SP_CSC_STD_SEL BIT(7)
#define SP_XVYCC_RNG_LMT BIT(6)
#define SP_RANGE_Y2R BIT(5)
#define SP_CSPACE_Y2R BIT(4)
#define SP_RGB_RNG_LMT BIT(3)
#define SP_Y_RNG_LMT BIT(2)
#define SP_RANGE_R2Y BIT(1)
#define SP_CSPACE_R2Y BIT(0)
/* Video Control Register 6 */
#define SP_VID_CTRL6_REG 0x0d
#define SP_TEST_PATTERN_EN BIT(7)
#define SP_VIDEO_PROCESS_EN BIT(6)
#define SP_VID_US_MODE BIT(3)
#define SP_VID_DS_MODE BIT(2)
#define SP_UP_SAMPLE BIT(1)
#define SP_DOWN_SAMPLE BIT(0)
/* Video Control Register 8 */
#define SP_VID_CTRL8_REG 0x0f
#define SP_VID_VRES_TH BIT(0)
/* Total Line Status Low Byte Register */
#define SP_TOTAL_LINE_STAL_REG 0x24
/* Total Line Status High Byte Register */
#define SP_TOTAL_LINE_STAH_REG 0x25
/* Active Line Status Low Byte Register */
#define SP_ACT_LINE_STAL_REG 0x26
/* Active Line Status High Byte Register */
#define SP_ACT_LINE_STAH_REG 0x27
/* Vertical Front Porch Status Register */
#define SP_V_F_PORCH_STA_REG 0x28
/* Vertical SYNC Width Status Register */
#define SP_V_SYNC_STA_REG 0x29
/* Vertical Back Porch Status Register */
#define SP_V_B_PORCH_STA_REG 0x2a
/* Total Pixel Status Low Byte Register */
#define SP_TOTAL_PIXEL_STAL_REG 0x2b
/* Total Pixel Status High Byte Register */
#define SP_TOTAL_PIXEL_STAH_REG 0x2c
/* Active Pixel Status Low Byte Register */
#define SP_ACT_PIXEL_STAL_REG 0x2d
/* Active Pixel Status High Byte Register */
#define SP_ACT_PIXEL_STAH_REG 0x2e
/* Horizontal Front Porch Status Low Byte Register */
#define SP_H_F_PORCH_STAL_REG 0x2f
/* Horizontal Front Porch Statys High Byte Register */
#define SP_H_F_PORCH_STAH_REG 0x30
/* Horizontal SYNC Width Status Low Byte Register */
#define SP_H_SYNC_STAL_REG 0x31
/* Horizontal SYNC Width Status High Byte Register */
#define SP_H_SYNC_STAH_REG 0x32
/* Horizontal Back Porch Status Low Byte Register */
#define SP_H_B_PORCH_STAL_REG 0x33
/* Horizontal Back Porch Status High Byte Register */
#define SP_H_B_PORCH_STAH_REG 0x34
/* InfoFrame AVI Packet DB1 Register */
#define SP_INFOFRAME_AVI_DB1_REG 0x70
/* Bit Control Specific Register */
#define SP_BIT_CTRL_SPECIFIC_REG 0x80
#define SP_BIT_CTRL_SELECT_SHIFT 1
#define SP_ENABLE_BIT_CTRL BIT(0)
/* InfoFrame Audio Packet DB1 Register */
#define SP_INFOFRAME_AUD_DB1_REG 0x83
/* InfoFrame MPEG Packet DB1 Register */
#define SP_INFOFRAME_MPEG_DB1_REG 0xb0
/* Audio Channel Status Registers */
#define SP_AUD_CH_STATUS_BASE 0xd0
/* Audio Channel Num Register 5 */
#define SP_I2S_CHANNEL_NUM_MASK 0xe0
# define SP_I2S_CH_NUM_1 (0x00 << 5)
# define SP_I2S_CH_NUM_2 (0x01 << 5)
# define SP_I2S_CH_NUM_3 (0x02 << 5)
# define SP_I2S_CH_NUM_4 (0x03 << 5)
# define SP_I2S_CH_NUM_5 (0x04 << 5)
# define SP_I2S_CH_NUM_6 (0x05 << 5)
# define SP_I2S_CH_NUM_7 (0x06 << 5)
# define SP_I2S_CH_NUM_8 (0x07 << 5)
#define SP_EXT_VUCP BIT(2)
#define SP_VBIT BIT(1)
#define SP_AUDIO_LAYOUT BIT(0)
/* Analog Debug Register 1 */
#define SP_ANALOG_DEBUG1_REG 0xdc
/* Analog Debug Register 2 */
#define SP_ANALOG_DEBUG2_REG 0xdd
#define SP_FORCE_SW_OFF_BYPASS 0x20
#define SP_XTAL_FRQ 0x1c
# define SP_XTAL_FRQ_19M2 (0x00 << 2)
# define SP_XTAL_FRQ_24M (0x01 << 2)
# define SP_XTAL_FRQ_25M (0x02 << 2)
# define SP_XTAL_FRQ_26M (0x03 << 2)
# define SP_XTAL_FRQ_27M (0x04 << 2)
# define SP_XTAL_FRQ_38M4 (0x05 << 2)
# define SP_XTAL_FRQ_52M (0x06 << 2)
#define SP_POWERON_TIME_1P5MS 0x03
/* Analog Control 0 Register */
#define SP_ANALOG_CTRL0_REG 0xe1
/* Common Interrupt Status Register 1 */
#define SP_COMMON_INT_STATUS_BASE (0xf1 - 1)
#define SP_PLL_LOCK_CHG 0x40
/* Common Interrupt Status Register 2 */
#define SP_COMMON_INT_STATUS2 0xf2
#define SP_HDCP_AUTH_CHG BIT(1)
#define SP_HDCP_AUTH_DONE BIT(0)
#define SP_HDCP_LINK_CHECK_FAIL BIT(0)
/* Common Interrupt Status Register 4 */
#define SP_COMMON_INT_STATUS4_REG 0xf4
#define SP_HPD_IRQ BIT(6)
#define SP_HPD_ESYNC_ERR BIT(4)
#define SP_HPD_CHG BIT(2)
#define SP_HPD_LOST BIT(1)
#define SP_HPD_PLUG BIT(0)
/* DP Interrupt Status Register */
#define SP_DP_INT_STATUS1_REG 0xf7
#define SP_TRAINING_FINISH BIT(5)
#define SP_POLLING_ERR BIT(4)
/* Common Interrupt Mask Register */
#define SP_COMMON_INT_MASK_BASE (0xf8 - 1)
#define SP_COMMON_INT_MASK4_REG 0xfb
/* DP Interrupts Mask Register */
#define SP_DP_INT_MASK1_REG 0xfe
/* Interrupt Control Register */
#define SP_INT_CTRL_REG 0xff
#endif /* _ANALOGIX_I2C_TXCOMMON_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,233 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Header file for Analogix DP (Display Port) core interface driver.
*
* Copyright (C) 2012 Samsung Electronics Co., Ltd.
* Author: Jingoo Han <jg1.han@samsung.com>
*/
#ifndef _ANALOGIX_DP_CORE_H
#define _ANALOGIX_DP_CORE_H
#include <drm/display/drm_dp_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_bridge.h>
#define DP_TIMEOUT_LOOP_COUNT 100
#define MAX_CR_LOOP 5
#define MAX_EQ_LOOP 5
#define MAX_PLL_LOCK_LOOP 5
/* Training takes 22ms if AUX channel comm fails. Use this as retry interval */
#define DP_TIMEOUT_TRAINING_US 22000
#define DP_TIMEOUT_PSR_LOOP_MS 300
/* DP_MAX_LANE_COUNT */
#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
/* DP_LANE_COUNT_SET */
#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
/* DP_TRAINING_LANE0_SET */
#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
struct gpio_desc;
enum link_lane_count_type {
LANE_COUNT1 = 1,
LANE_COUNT2 = 2,
LANE_COUNT4 = 4
};
enum link_training_state {
START,
CLOCK_RECOVERY,
EQUALIZER_TRAINING,
FINISHED,
FAILED
};
enum voltage_swing_level {
VOLTAGE_LEVEL_0,
VOLTAGE_LEVEL_1,
VOLTAGE_LEVEL_2,
VOLTAGE_LEVEL_3,
};
enum pre_emphasis_level {
PRE_EMPHASIS_LEVEL_0,
PRE_EMPHASIS_LEVEL_1,
PRE_EMPHASIS_LEVEL_2,
PRE_EMPHASIS_LEVEL_3,
};
enum pattern_set {
PRBS7,
D10_2,
TRAINING_PTN1,
TRAINING_PTN2,
DP_NONE
};
enum color_space {
COLOR_RGB,
COLOR_YCBCR422,
COLOR_YCBCR444
};
enum color_depth {
COLOR_6,
COLOR_8,
COLOR_10,
COLOR_12
};
enum color_coefficient {
COLOR_YCBCR601,
COLOR_YCBCR709
};
enum dynamic_range {
VESA,
CEA
};
enum clock_recovery_m_value_type {
CALCULATED_M,
REGISTER_M
};
enum video_timing_recognition_type {
VIDEO_TIMING_FROM_CAPTURE,
VIDEO_TIMING_FROM_REGISTER
};
enum analog_power_block {
AUX_BLOCK,
CH0_BLOCK,
CH1_BLOCK,
CH2_BLOCK,
CH3_BLOCK,
ANALOG_TOTAL,
POWER_ALL
};
enum dp_irq_type {
DP_IRQ_TYPE_HP_CABLE_IN = BIT(0),
DP_IRQ_TYPE_HP_CABLE_OUT = BIT(1),
DP_IRQ_TYPE_HP_CHANGE = BIT(2),
DP_IRQ_TYPE_UNKNOWN = BIT(3),
};
struct video_info {
char *name;
bool h_sync_polarity;
bool v_sync_polarity;
bool interlaced;
enum color_space color_space;
enum dynamic_range dynamic_range;
enum color_coefficient ycbcr_coeff;
enum color_depth color_depth;
int max_link_rate;
enum link_lane_count_type max_lane_count;
};
struct link_train {
int eq_loop;
int cr_loop[4];
u8 link_rate;
u8 lane_count;
u8 training_lane[4];
enum link_training_state lt_state;
};
struct analogix_dp_device {
struct drm_encoder *encoder;
struct device *dev;
struct drm_device *drm_dev;
struct drm_bridge bridge;
struct drm_dp_aux aux;
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
struct video_info video_info;
struct link_train link_train;
struct phy *phy;
int dpms_mode;
struct gpio_desc *hpd_gpiod;
bool force_hpd;
bool fast_train_enable;
bool psr_supported;
struct analogix_dp_plat_data *plat_data;
};
/* analogix_dp_reg.c */
void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable);
void analogix_dp_stop_video(struct analogix_dp_device *dp);
void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable);
void analogix_dp_init_analog_param(struct analogix_dp_device *dp);
void analogix_dp_init_interrupt(struct analogix_dp_device *dp);
void analogix_dp_reset(struct analogix_dp_device *dp);
void analogix_dp_swreset(struct analogix_dp_device *dp);
void analogix_dp_config_interrupt(struct analogix_dp_device *dp);
void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp);
void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp);
int analogix_dp_wait_pll_locked(struct analogix_dp_device *dp);
void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable);
void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
enum analog_power_block block,
bool enable);
int analogix_dp_init_analog_func(struct analogix_dp_device *dp);
void analogix_dp_init_hpd(struct analogix_dp_device *dp);
void analogix_dp_force_hpd(struct analogix_dp_device *dp);
enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp);
void analogix_dp_reset_aux(struct analogix_dp_device *dp);
void analogix_dp_init_aux(struct analogix_dp_device *dp);
int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp);
void analogix_dp_enable_sw_function(struct analogix_dp_device *dp);
void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype);
void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype);
void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count);
void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count);
void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
bool enable);
void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
enum pattern_set pattern);
void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp);
u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane);
void analogix_dp_reset_macro(struct analogix_dp_device *dp);
void analogix_dp_init_video(struct analogix_dp_device *dp);
void analogix_dp_set_video_color_format(struct analogix_dp_device *dp);
int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp);
void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
enum clock_recovery_m_value_type type,
u32 m_value,
u32 n_value);
void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type);
void analogix_dp_enable_video_master(struct analogix_dp_device *dp,
bool enable);
void analogix_dp_start_video(struct analogix_dp_device *dp);
int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp);
void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp);
void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
struct dp_sdp *vsc, bool blocking);
ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
struct drm_dp_aux_msg *msg);
#endif /* _ANALOGIX_DP_CORE_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,426 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Register definition file for Analogix DP core driver
*
* Copyright (C) 2012 Samsung Electronics Co., Ltd.
* Author: Jingoo Han <jg1.han@samsung.com>
*/
#ifndef _ANALOGIX_DP_REG_H
#define _ANALOGIX_DP_REG_H
#define ANALOGIX_DP_TX_SW_RESET 0x14
#define ANALOGIX_DP_FUNC_EN_1 0x18
#define ANALOGIX_DP_FUNC_EN_2 0x1C
#define ANALOGIX_DP_VIDEO_CTL_1 0x20
#define ANALOGIX_DP_VIDEO_CTL_2 0x24
#define ANALOGIX_DP_VIDEO_CTL_3 0x28
#define ANALOGIX_DP_VIDEO_CTL_8 0x3C
#define ANALOGIX_DP_VIDEO_CTL_10 0x44
#define ANALOGIX_DP_SPDIF_AUDIO_CTL_0 0xD8
#define ANALOGIX_DP_PLL_REG_1 0xfc
#define ANALOGIX_DP_PLL_REG_2 0x9e4
#define ANALOGIX_DP_PLL_REG_3 0x9e8
#define ANALOGIX_DP_PLL_REG_4 0x9ec
#define ANALOGIX_DP_PLL_REG_5 0xa00
#define ANALOGIX_DP_PD 0x12c
#define ANALOGIX_DP_IF_TYPE 0x244
#define ANALOGIX_DP_IF_PKT_DB1 0x254
#define ANALOGIX_DP_IF_PKT_DB2 0x258
#define ANALOGIX_DP_SPD_HB0 0x2F8
#define ANALOGIX_DP_SPD_HB1 0x2FC
#define ANALOGIX_DP_SPD_HB2 0x300
#define ANALOGIX_DP_SPD_HB3 0x304
#define ANALOGIX_DP_SPD_PB0 0x308
#define ANALOGIX_DP_SPD_PB1 0x30C
#define ANALOGIX_DP_SPD_PB2 0x310
#define ANALOGIX_DP_SPD_PB3 0x314
#define ANALOGIX_DP_PSR_FRAME_UPDATE_CTRL 0x318
#define ANALOGIX_DP_VSC_SHADOW_DB0 0x31C
#define ANALOGIX_DP_VSC_SHADOW_DB1 0x320
#define ANALOGIX_DP_LANE_MAP 0x35C
#define ANALOGIX_DP_ANALOG_CTL_1 0x370
#define ANALOGIX_DP_ANALOG_CTL_2 0x374
#define ANALOGIX_DP_ANALOG_CTL_3 0x378
#define ANALOGIX_DP_PLL_FILTER_CTL_1 0x37C
#define ANALOGIX_DP_TX_AMP_TUNING_CTL 0x380
#define ANALOGIX_DP_AUX_HW_RETRY_CTL 0x390
#define ANALOGIX_DP_COMMON_INT_STA_1 0x3C4
#define ANALOGIX_DP_COMMON_INT_STA_2 0x3C8
#define ANALOGIX_DP_COMMON_INT_STA_3 0x3CC
#define ANALOGIX_DP_COMMON_INT_STA_4 0x3D0
#define ANALOGIX_DP_INT_STA 0x3DC
#define ANALOGIX_DP_COMMON_INT_MASK_1 0x3E0
#define ANALOGIX_DP_COMMON_INT_MASK_2 0x3E4
#define ANALOGIX_DP_COMMON_INT_MASK_3 0x3E8
#define ANALOGIX_DP_COMMON_INT_MASK_4 0x3EC
#define ANALOGIX_DP_INT_STA_MASK 0x3F8
#define ANALOGIX_DP_INT_CTL 0x3FC
#define ANALOGIX_DP_SYS_CTL_1 0x600
#define ANALOGIX_DP_SYS_CTL_2 0x604
#define ANALOGIX_DP_SYS_CTL_3 0x608
#define ANALOGIX_DP_SYS_CTL_4 0x60C
#define ANALOGIX_DP_PKT_SEND_CTL 0x640
#define ANALOGIX_DP_HDCP_CTL 0x648
#define ANALOGIX_DP_LINK_BW_SET 0x680
#define ANALOGIX_DP_LANE_COUNT_SET 0x684
#define ANALOGIX_DP_TRAINING_PTN_SET 0x688
#define ANALOGIX_DP_LN0_LINK_TRAINING_CTL 0x68C
#define ANALOGIX_DP_LN1_LINK_TRAINING_CTL 0x690
#define ANALOGIX_DP_LN2_LINK_TRAINING_CTL 0x694
#define ANALOGIX_DP_LN3_LINK_TRAINING_CTL 0x698
#define ANALOGIX_DP_DEBUG_CTL 0x6C0
#define ANALOGIX_DP_HPD_DEGLITCH_L 0x6C4
#define ANALOGIX_DP_HPD_DEGLITCH_H 0x6C8
#define ANALOGIX_DP_LINK_DEBUG_CTL 0x6E0
#define ANALOGIX_DP_M_VID_0 0x700
#define ANALOGIX_DP_M_VID_1 0x704
#define ANALOGIX_DP_M_VID_2 0x708
#define ANALOGIX_DP_N_VID_0 0x70C
#define ANALOGIX_DP_N_VID_1 0x710
#define ANALOGIX_DP_N_VID_2 0x714
#define ANALOGIX_DP_PLL_CTL 0x71C
#define ANALOGIX_DP_PHY_PD 0x720
#define ANALOGIX_DP_PHY_TEST 0x724
#define ANALOGIX_DP_VIDEO_FIFO_THRD 0x730
#define ANALOGIX_DP_AUDIO_MARGIN 0x73C
#define ANALOGIX_DP_M_VID_GEN_FILTER_TH 0x764
#define ANALOGIX_DP_M_AUD_GEN_FILTER_TH 0x778
#define ANALOGIX_DP_AUX_CH_STA 0x780
#define ANALOGIX_DP_AUX_CH_DEFER_CTL 0x788
#define ANALOGIX_DP_AUX_RX_COMM 0x78C
#define ANALOGIX_DP_BUFFER_DATA_CTL 0x790
#define ANALOGIX_DP_AUX_CH_CTL_1 0x794
#define ANALOGIX_DP_AUX_ADDR_7_0 0x798
#define ANALOGIX_DP_AUX_ADDR_15_8 0x79C
#define ANALOGIX_DP_AUX_ADDR_19_16 0x7A0
#define ANALOGIX_DP_AUX_CH_CTL_2 0x7A4
#define ANALOGIX_DP_BUF_DATA_0 0x7C0
#define ANALOGIX_DP_SOC_GENERAL_CTL 0x800
#define ANALOGIX_DP_CRC_CON 0x890
/* ANALOGIX_DP_TX_SW_RESET */
#define RESET_DP_TX (0x1 << 0)
/* ANALOGIX_DP_FUNC_EN_1 */
#define MASTER_VID_FUNC_EN_N (0x1 << 7)
#define RK_VID_CAP_FUNC_EN_N (0x1 << 6)
#define SLAVE_VID_FUNC_EN_N (0x1 << 5)
#define RK_VID_FIFO_FUNC_EN_N (0x1 << 5)
#define AUD_FIFO_FUNC_EN_N (0x1 << 4)
#define AUD_FUNC_EN_N (0x1 << 3)
#define HDCP_FUNC_EN_N (0x1 << 2)
#define CRC_FUNC_EN_N (0x1 << 1)
#define SW_FUNC_EN_N (0x1 << 0)
/* ANALOGIX_DP_FUNC_EN_2 */
#define SSC_FUNC_EN_N (0x1 << 7)
#define AUX_FUNC_EN_N (0x1 << 2)
#define SERDES_FIFO_FUNC_EN_N (0x1 << 1)
#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0)
/* ANALOGIX_DP_VIDEO_CTL_1 */
#define VIDEO_EN (0x1 << 7)
#define HDCP_VIDEO_MUTE (0x1 << 6)
/* ANALOGIX_DP_VIDEO_CTL_1 */
#define IN_D_RANGE_MASK (0x1 << 7)
#define IN_D_RANGE_SHIFT (7)
#define IN_D_RANGE_CEA (0x1 << 7)
#define IN_D_RANGE_VESA (0x0 << 7)
#define IN_BPC_MASK (0x7 << 4)
#define IN_BPC_SHIFT (4)
#define IN_BPC_12_BITS (0x3 << 4)
#define IN_BPC_10_BITS (0x2 << 4)
#define IN_BPC_8_BITS (0x1 << 4)
#define IN_BPC_6_BITS (0x0 << 4)
#define IN_COLOR_F_MASK (0x3 << 0)
#define IN_COLOR_F_SHIFT (0)
#define IN_COLOR_F_YCBCR444 (0x2 << 0)
#define IN_COLOR_F_YCBCR422 (0x1 << 0)
#define IN_COLOR_F_RGB (0x0 << 0)
/* ANALOGIX_DP_VIDEO_CTL_3 */
#define IN_YC_COEFFI_MASK (0x1 << 7)
#define IN_YC_COEFFI_SHIFT (7)
#define IN_YC_COEFFI_ITU709 (0x1 << 7)
#define IN_YC_COEFFI_ITU601 (0x0 << 7)
#define VID_CHK_UPDATE_TYPE_MASK (0x1 << 4)
#define VID_CHK_UPDATE_TYPE_SHIFT (4)
#define VID_CHK_UPDATE_TYPE_1 (0x1 << 4)
#define VID_CHK_UPDATE_TYPE_0 (0x0 << 4)
#define REUSE_SPD_EN (0x1 << 3)
/* ANALOGIX_DP_VIDEO_CTL_8 */
#define VID_HRES_TH(x) (((x) & 0xf) << 4)
#define VID_VRES_TH(x) (((x) & 0xf) << 0)
/* ANALOGIX_DP_VIDEO_CTL_10 */
#define FORMAT_SEL (0x1 << 4)
#define INTERACE_SCAN_CFG (0x1 << 2)
#define VSYNC_POLARITY_CFG (0x1 << 1)
#define HSYNC_POLARITY_CFG (0x1 << 0)
/* ANALOGIX_DP_PLL_REG_1 */
#define REF_CLK_24M (0x1 << 0)
#define REF_CLK_27M (0x0 << 0)
#define REF_CLK_MASK (0x1 << 0)
/* ANALOGIX_DP_PSR_FRAME_UPDATE_CTRL */
#define PSR_FRAME_UP_TYPE_BURST (0x1 << 0)
#define PSR_FRAME_UP_TYPE_SINGLE (0x0 << 0)
#define PSR_CRC_SEL_HARDWARE (0x1 << 1)
#define PSR_CRC_SEL_MANUALLY (0x0 << 1)
/* ANALOGIX_DP_LANE_MAP */
#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6)
#define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6)
#define LANE3_MAP_LOGIC_LANE_3 (0x3 << 6)
#define LANE2_MAP_LOGIC_LANE_0 (0x0 << 4)
#define LANE2_MAP_LOGIC_LANE_1 (0x1 << 4)
#define LANE2_MAP_LOGIC_LANE_2 (0x2 << 4)
#define LANE2_MAP_LOGIC_LANE_3 (0x3 << 4)
#define LANE1_MAP_LOGIC_LANE_0 (0x0 << 2)
#define LANE1_MAP_LOGIC_LANE_1 (0x1 << 2)
#define LANE1_MAP_LOGIC_LANE_2 (0x2 << 2)
#define LANE1_MAP_LOGIC_LANE_3 (0x3 << 2)
#define LANE0_MAP_LOGIC_LANE_0 (0x0 << 0)
#define LANE0_MAP_LOGIC_LANE_1 (0x1 << 0)
#define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0)
#define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0)
/* ANALOGIX_DP_ANALOG_CTL_1 */
#define TX_TERMINAL_CTRL_50_OHM (0x1 << 4)
/* ANALOGIX_DP_ANALOG_CTL_2 */
#define SEL_24M (0x1 << 3)
#define TX_DVDD_BIT_1_0625V (0x4 << 0)
/* ANALOGIX_DP_ANALOG_CTL_3 */
#define DRIVE_DVDD_BIT_1_0625V (0x4 << 5)
#define VCO_BIT_600_MICRO (0x5 << 0)
/* ANALOGIX_DP_PLL_FILTER_CTL_1 */
#define PD_RING_OSC (0x1 << 6)
#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
#define TX_CUR1_2X (0x1 << 2)
#define TX_CUR_16_MA (0x3 << 0)
/* ANALOGIX_DP_TX_AMP_TUNING_CTL */
#define CH3_AMP_400_MV (0x0 << 24)
#define CH2_AMP_400_MV (0x0 << 16)
#define CH1_AMP_400_MV (0x0 << 8)
#define CH0_AMP_400_MV (0x0 << 0)
/* ANALOGIX_DP_AUX_HW_RETRY_CTL */
#define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8)
#define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3)
#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3)
#define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS (0x1 << 3)
#define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS (0x2 << 3)
#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3)
#define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0)
/* ANALOGIX_DP_COMMON_INT_STA_1 */
#define VSYNC_DET (0x1 << 7)
#define PLL_LOCK_CHG (0x1 << 6)
#define SPDIF_ERR (0x1 << 5)
#define SPDIF_UNSTBL (0x1 << 4)
#define VID_FORMAT_CHG (0x1 << 3)
#define AUD_CLK_CHG (0x1 << 2)
#define VID_CLK_CHG (0x1 << 1)
#define SW_INT (0x1 << 0)
/* ANALOGIX_DP_COMMON_INT_STA_2 */
#define ENC_EN_CHG (0x1 << 6)
#define HW_BKSV_RDY (0x1 << 3)
#define HW_SHA_DONE (0x1 << 2)
#define HW_AUTH_STATE_CHG (0x1 << 1)
#define HW_AUTH_DONE (0x1 << 0)
/* ANALOGIX_DP_COMMON_INT_STA_3 */
#define AFIFO_UNDER (0x1 << 7)
#define AFIFO_OVER (0x1 << 6)
#define R0_CHK_FLAG (0x1 << 5)
/* ANALOGIX_DP_COMMON_INT_STA_4 */
#define PSR_ACTIVE (0x1 << 7)
#define PSR_INACTIVE (0x1 << 6)
#define SPDIF_BI_PHASE_ERR (0x1 << 5)
#define HOTPLUG_CHG (0x1 << 2)
#define HPD_LOST (0x1 << 1)
#define PLUG (0x1 << 0)
/* ANALOGIX_DP_INT_STA */
#define INT_HPD (0x1 << 6)
#define HW_TRAINING_FINISH (0x1 << 5)
#define RPLY_RECEIV (0x1 << 1)
#define AUX_ERR (0x1 << 0)
/* ANALOGIX_DP_INT_CTL */
#define SOFT_INT_CTRL (0x1 << 2)
#define INT_POL1 (0x1 << 1)
#define INT_POL0 (0x1 << 0)
/* ANALOGIX_DP_SYS_CTL_1 */
#define DET_STA (0x1 << 2)
#define FORCE_DET (0x1 << 1)
#define DET_CTRL (0x1 << 0)
/* ANALOGIX_DP_SYS_CTL_2 */
#define CHA_CRI(x) (((x) & 0xf) << 4)
#define CHA_STA (0x1 << 2)
#define FORCE_CHA (0x1 << 1)
#define CHA_CTRL (0x1 << 0)
/* ANALOGIX_DP_SYS_CTL_3 */
#define HPD_STATUS (0x1 << 6)
#define F_HPD (0x1 << 5)
#define HPD_CTRL (0x1 << 4)
#define HDCP_RDY (0x1 << 3)
#define STRM_VALID (0x1 << 2)
#define F_VALID (0x1 << 1)
#define VALID_CTRL (0x1 << 0)
/* ANALOGIX_DP_SYS_CTL_4 */
#define FIX_M_AUD (0x1 << 4)
#define ENHANCED (0x1 << 3)
#define FIX_M_VID (0x1 << 2)
#define M_VID_UPDATE_CTRL (0x3 << 0)
/* ANALOGIX_DP_TRAINING_PTN_SET */
#define SCRAMBLER_TYPE (0x1 << 9)
#define HW_LINK_TRAINING_PATTERN (0x1 << 8)
#define SCRAMBLING_DISABLE (0x1 << 5)
#define SCRAMBLING_ENABLE (0x0 << 5)
#define LINK_QUAL_PATTERN_SET_MASK (0x3 << 2)
#define LINK_QUAL_PATTERN_SET_PRBS7 (0x3 << 2)
#define LINK_QUAL_PATTERN_SET_D10_2 (0x1 << 2)
#define LINK_QUAL_PATTERN_SET_DISABLE (0x0 << 2)
#define SW_TRAINING_PATTERN_SET_MASK (0x3 << 0)
#define SW_TRAINING_PATTERN_SET_PTN2 (0x2 << 0)
#define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0)
#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0)
/* ANALOGIX_DP_LN0_LINK_TRAINING_CTL */
#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
#define PRE_EMPHASIS_SET_SHIFT (3)
/* ANALOGIX_DP_DEBUG_CTL */
#define PLL_LOCK (0x1 << 4)
#define F_PLL_LOCK (0x1 << 3)
#define PLL_LOCK_CTRL (0x1 << 2)
#define PN_INV (0x1 << 0)
/* ANALOGIX_DP_PLL_CTL */
#define DP_PLL_PD (0x1 << 7)
#define DP_PLL_RESET (0x1 << 6)
#define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4)
#define DP_PLL_REF_BIT_1_1250V (0x5 << 0)
#define DP_PLL_REF_BIT_1_2500V (0x7 << 0)
/* ANALOGIX_DP_PHY_PD */
#define DP_INC_BG (0x1 << 7)
#define DP_EXP_BG (0x1 << 6)
#define DP_PHY_PD (0x1 << 5)
#define RK_AUX_PD (0x1 << 5)
#define AUX_PD (0x1 << 4)
#define RK_PLL_PD (0x1 << 4)
#define CH3_PD (0x1 << 3)
#define CH2_PD (0x1 << 2)
#define CH1_PD (0x1 << 1)
#define CH0_PD (0x1 << 0)
#define DP_ALL_PD (0xff)
/* ANALOGIX_DP_PHY_TEST */
#define MACRO_RST (0x1 << 5)
#define CH1_TEST (0x1 << 1)
#define CH0_TEST (0x1 << 0)
/* ANALOGIX_DP_AUX_CH_STA */
#define AUX_BUSY (0x1 << 4)
#define AUX_STATUS_MASK (0xf << 0)
#define AUX_STATUS_OK (0x0 << 0)
#define AUX_STATUS_NACK_ERROR (0x1 << 0)
#define AUX_STATUS_TIMEOUT_ERROR (0x2 << 0)
#define AUX_STATUS_UNKNOWN_ERROR (0x3 << 0)
#define AUX_STATUS_MUCH_DEFER_ERROR (0x4 << 0)
#define AUX_STATUS_TX_SHORT_ERROR (0x5 << 0)
#define AUX_STATUS_RX_SHORT_ERROR (0x6 << 0)
#define AUX_STATUS_NACK_WITHOUT_M_ERROR (0x7 << 0)
#define AUX_STATUS_I2C_NACK_ERROR (0x8 << 0)
/* ANALOGIX_DP_AUX_CH_DEFER_CTL */
#define DEFER_CTRL_EN (0x1 << 7)
#define DEFER_COUNT(x) (((x) & 0x7f) << 0)
/* ANALOGIX_DP_AUX_RX_COMM */
#define AUX_RX_COMM_I2C_DEFER (0x2 << 2)
#define AUX_RX_COMM_AUX_DEFER (0x2 << 0)
/* ANALOGIX_DP_BUFFER_DATA_CTL */
#define BUF_CLR (0x1 << 7)
#define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0)
/* ANALOGIX_DP_AUX_CH_CTL_1 */
#define AUX_LENGTH(x) (((x - 1) & 0xf) << 4)
#define AUX_TX_COMM_MASK (0xf << 0)
#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3)
#define AUX_TX_COMM_I2C_TRANSACTION (0x0 << 3)
#define AUX_TX_COMM_MOT (0x1 << 2)
#define AUX_TX_COMM_WRITE (0x0 << 0)
#define AUX_TX_COMM_READ (0x1 << 0)
/* ANALOGIX_DP_AUX_ADDR_7_0 */
#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff)
/* ANALOGIX_DP_AUX_ADDR_15_8 */
#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff)
/* ANALOGIX_DP_AUX_ADDR_19_16 */
#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f)
/* ANALOGIX_DP_AUX_CH_CTL_2 */
#define ADDR_ONLY (0x1 << 1)
#define AUX_EN (0x1 << 0)
/* ANALOGIX_DP_SOC_GENERAL_CTL */
#define AUDIO_MODE_SPDIF_MODE (0x1 << 8)
#define AUDIO_MODE_MASTER_MODE (0x0 << 8)
#define MASTER_VIDEO_INTERLACE_EN (0x1 << 4)
#define VIDEO_MASTER_CLK_SEL (0x1 << 2)
#define VIDEO_MASTER_MODE_EN (0x1 << 1)
#define VIDEO_MODE_MASK (0x1 << 0)
#define VIDEO_MODE_SLAVE_MODE (0x1 << 0)
#define VIDEO_MODE_MASTER_MODE (0x0 << 0)
/* ANALOGIX_DP_PKT_SEND_CTL */
#define IF_UP (0x1 << 4)
#define IF_EN (0x1 << 0)
/* ANALOGIX_DP_CRC_CON */
#define PSR_VID_CRC_FLUSH (0x1 << 2)
#define PSR_VID_CRC_ENABLE (0x1 << 0)
#endif /* _ANALOGIX_DP_REG_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,514 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2020, Analogix Semiconductor. All rights reserved.
*
*/
#ifndef __ANX7625_H__
#define __ANX7625_H__
#define ANX7625_DRV_VERSION "0.1.04"
/* Loading OCM re-trying times */
#define OCM_LOADING_TIME 10
/********* ANX7625 Register **********/
#define TX_P0_ADDR 0x70
#define TX_P1_ADDR 0x7A
#define TX_P2_ADDR 0x72
#define RX_P0_ADDR 0x7e
#define RX_P1_ADDR 0x84
#define RX_P2_ADDR 0x54
#define RSVD_00_ADDR 0x00
#define RSVD_D1_ADDR 0xD1
#define RSVD_60_ADDR 0x60
#define RSVD_39_ADDR 0x39
#define RSVD_7F_ADDR 0x7F
#define TCPC_INTERFACE_ADDR 0x58
/* Clock frequency in Hz */
#define XTAL_FRQ (27 * 1000000)
#define POST_DIVIDER_MIN 1
#define POST_DIVIDER_MAX 16
#define PLL_OUT_FREQ_MIN 520000000UL
#define PLL_OUT_FREQ_MAX 730000000UL
#define PLL_OUT_FREQ_ABS_MIN 300000000UL
#define PLL_OUT_FREQ_ABS_MAX 800000000UL
#define MAX_UNSIGNED_24BIT 16777215UL
/***************************************************************/
/* Register definition of device address 0x58 */
#define PRODUCT_ID_L 0x02
#define PRODUCT_ID_H 0x03
#define INTR_ALERT_1 0xCC
#define INTR_SOFTWARE_INT BIT(3)
#define INTR_RECEIVED_MSG BIT(5)
#define SYSTEM_STSTUS 0x45
#define INTERFACE_CHANGE_INT_MASK 0x43
#define INTERFACE_CHANGE_INT 0x44
#define VCONN_STATUS BIT(2)
#define VBUS_STATUS BIT(3)
#define CC_STATUS BIT(4)
#define DATA_ROLE_STATUS BIT(5)
#define HPD_STATUS BIT(7)
#define NEW_CC_STATUS 0x46
#define CC1_RD BIT(0)
#define CC1_RA BIT(1)
#define CC1_RP (BIT(2) | BIT(3))
#define CC2_RD BIT(4)
#define CC2_RA BIT(5)
#define CC2_RP (BIT(6) | BIT(7))
#define CMD_SEND_BUF 0xC0
#define CMD_RECV_BUF 0xE0
/******** END of I2C Address 0x58 ********/
/***************************************************************/
/* Register definition of device address 0x70 */
#define TX_HDCP_CTRL0 0x01
#define STORE_AN BIT(7)
#define RX_REPEATER BIT(6)
#define RE_AUTHEN BIT(5)
#define SW_AUTH_OK BIT(4)
#define HARD_AUTH_EN BIT(3)
#define ENC_EN BIT(2)
#define BKSV_SRM_PASS BIT(1)
#define KSVLIST_VLD BIT(0)
#define SP_TX_WAIT_R0_TIME 0x40
#define SP_TX_WAIT_KSVR_TIME 0x42
#define SP_TX_SYS_CTRL1_REG 0x80
#define HDCP2TX_FW_EN BIT(4)
#define SP_TX_LINK_BW_SET_REG 0xA0
#define SP_TX_LANE_COUNT_SET_REG 0xA1
#define M_VID_0 0xC0
#define M_VID_1 0xC1
#define M_VID_2 0xC2
#define N_VID_0 0xC3
#define N_VID_1 0xC4
#define N_VID_2 0xC5
#define KEY_START_ADDR 0x9000
#define KEY_RESERVED 416
#define HDCP14KEY_START_ADDR (KEY_START_ADDR + KEY_RESERVED)
#define HDCP14KEY_SIZE 624
/***************************************************************/
/* Register definition of device address 0x72 */
#define AUX_RST 0x04
#define RST_CTRL2 0x07
#define SP_TX_TOTAL_LINE_STA_L 0x24
#define SP_TX_TOTAL_LINE_STA_H 0x25
#define SP_TX_ACT_LINE_STA_L 0x26
#define SP_TX_ACT_LINE_STA_H 0x27
#define SP_TX_V_F_PORCH_STA 0x28
#define SP_TX_V_SYNC_STA 0x29
#define SP_TX_V_B_PORCH_STA 0x2A
#define SP_TX_TOTAL_PIXEL_STA_L 0x2B
#define SP_TX_TOTAL_PIXEL_STA_H 0x2C
#define SP_TX_ACT_PIXEL_STA_L 0x2D
#define SP_TX_ACT_PIXEL_STA_H 0x2E
#define SP_TX_H_F_PORCH_STA_L 0x2F
#define SP_TX_H_F_PORCH_STA_H 0x30
#define SP_TX_H_SYNC_STA_L 0x31
#define SP_TX_H_SYNC_STA_H 0x32
#define SP_TX_H_B_PORCH_STA_L 0x33
#define SP_TX_H_B_PORCH_STA_H 0x34
#define SP_TX_VID_CTRL 0x84
#define SP_TX_BPC_MASK 0xE0
#define SP_TX_BPC_6 0x00
#define SP_TX_BPC_8 0x20
#define SP_TX_BPC_10 0x40
#define SP_TX_BPC_12 0x60
#define VIDEO_BIT_MATRIX_12 0x4c
#define AUDIO_CHANNEL_STATUS_1 0xd0
#define AUDIO_CHANNEL_STATUS_2 0xd1
#define AUDIO_CHANNEL_STATUS_3 0xd2
#define AUDIO_CHANNEL_STATUS_4 0xd3
#define AUDIO_CHANNEL_STATUS_5 0xd4
#define AUDIO_CHANNEL_STATUS_6 0xd5
#define TDM_SLAVE_MODE 0x10
#define I2S_SLAVE_MODE 0x08
#define AUDIO_LAYOUT 0x01
#define HPD_DET_TIMER_BIT0_7 0xea
#define HPD_DET_TIMER_BIT8_15 0xeb
#define HPD_DET_TIMER_BIT16_23 0xec
/* HPD debounce time 2ms for 27M clock */
#define HPD_TIME 54000
#define AUDIO_CONTROL_REGISTER 0xe6
#define TDM_TIMING_MODE 0x08
#define I2C_ADDR_72_DPTX 0x72
#define HP_MIN 8
#define HBLANKING_MIN 80
#define SYNC_LEN_DEF 32
#define HFP_HBP_DEF ((HBLANKING_MIN - SYNC_LEN_DEF) / 2)
#define VIDEO_CONTROL_0 0x08
#define ACTIVE_LINES_L 0x14
#define ACTIVE_LINES_H 0x15 /* Bit[7:6] are reserved */
#define VERTICAL_FRONT_PORCH 0x16
#define VERTICAL_SYNC_WIDTH 0x17
#define VERTICAL_BACK_PORCH 0x18
#define HORIZONTAL_TOTAL_PIXELS_L 0x19
#define HORIZONTAL_TOTAL_PIXELS_H 0x1A /* Bit[7:6] are reserved */
#define HORIZONTAL_ACTIVE_PIXELS_L 0x1B
#define HORIZONTAL_ACTIVE_PIXELS_H 0x1C /* Bit[7:6] are reserved */
#define HORIZONTAL_FRONT_PORCH_L 0x1D
#define HORIZONTAL_FRONT_PORCH_H 0x1E /* Bit[7:4] are reserved */
#define HORIZONTAL_SYNC_WIDTH_L 0x1F
#define HORIZONTAL_SYNC_WIDTH_H 0x20 /* Bit[7:4] are reserved */
#define HORIZONTAL_BACK_PORCH_L 0x21
#define HORIZONTAL_BACK_PORCH_H 0x22 /* Bit[7:4] are reserved */
/******** END of I2C Address 0x72 *********/
/***************************************************************/
/* Register definition of device address 0x7a */
#define DP_TX_SWING_REG_CNT 0x14
#define DP_TX_LANE0_SWING_REG0 0x00
#define DP_TX_LANE1_SWING_REG0 0x14
/******** END of I2C Address 0x7a *********/
/***************************************************************/
/* Register definition of device address 0x7e */
#define I2C_ADDR_7E_FLASH_CONTROLLER 0x7E
#define R_BOOT_RETRY 0x00
#define R_RAM_ADDR_H 0x01
#define R_RAM_ADDR_L 0x02
#define R_RAM_LEN_H 0x03
#define R_RAM_LEN_L 0x04
#define FLASH_LOAD_STA 0x05
#define FLASH_LOAD_STA_CHK BIT(7)
#define R_RAM_CTRL 0x05
/* bit positions */
#define FLASH_DONE BIT(7)
#define BOOT_LOAD_DONE BIT(6)
#define CRC_OK BIT(5)
#define LOAD_DONE BIT(4)
#define O_RW_DONE BIT(3)
#define FUSE_BUSY BIT(2)
#define DECRYPT_EN BIT(1)
#define LOAD_START BIT(0)
#define FLASH_ADDR_HIGH 0x0F
#define FLASH_ADDR_LOW 0x10
#define FLASH_LEN_HIGH 0x31
#define FLASH_LEN_LOW 0x32
#define R_FLASH_RW_CTRL 0x33
/* bit positions */
#define READ_DELAY_SELECT BIT(7)
#define GENERAL_INSTRUCTION_EN BIT(6)
#define FLASH_ERASE_EN BIT(5)
#define RDID_READ_EN BIT(4)
#define REMS_READ_EN BIT(3)
#define WRITE_STATUS_EN BIT(2)
#define FLASH_READ BIT(1)
#define FLASH_WRITE BIT(0)
#define FLASH_BUF_BASE_ADDR 0x60
#define FLASH_BUF_LEN 0x20
#define XTAL_FRQ_SEL 0x3F
/* bit field positions */
#define XTAL_FRQ_SEL_POS 5
/* bit field values */
#define XTAL_FRQ_19M2 (0 << XTAL_FRQ_SEL_POS)
#define XTAL_FRQ_27M (4 << XTAL_FRQ_SEL_POS)
#define R_DSC_CTRL_0 0x40
#define READ_STATUS_EN 7
#define CLK_1MEG_RB 6 /* 1MHz clock reset; 0=reset, 0=reset release */
#define DSC_BIST_DONE 1 /* Bit[5:1]: 1=DSC MBIST pass */
#define DSC_EN 0x01 /* 1=DSC enabled, 0=DSC disabled */
#define OCM_FW_VERSION 0x31
#define OCM_FW_REVERSION 0x32
#define AP_AUX_ADDR_7_0 0x11
#define AP_AUX_ADDR_15_8 0x12
#define AP_AUX_ADDR_19_16 0x13
/* Bit[0:3] AUX status, bit 4 op_en, bit 5 address only */
#define AP_AUX_CTRL_STATUS 0x14
#define AP_AUX_CTRL_OP_EN 0x10
#define AP_AUX_CTRL_ADDRONLY 0x20
#define AP_AUX_BUFF_START 0x15
#define PIXEL_CLOCK_L 0x25
#define PIXEL_CLOCK_H 0x26
#define AP_AUX_COMMAND 0x27 /* com+len */
#define LENGTH_SHIFT 4
#define DPCD_CMD(len, cmd) ((((len) - 1) << LENGTH_SHIFT) | (cmd))
/* Bit 0&1: 3D video structure */
/* 0x01: frame packing, 0x02:Line alternative, 0x03:Side-by-side(full) */
#define AP_AV_STATUS 0x28
#define AP_VIDEO_CHG BIT(2)
#define AP_AUDIO_CHG BIT(3)
#define AP_MIPI_MUTE BIT(4) /* 1:MIPI input mute, 0: ummute */
#define AP_MIPI_RX_EN BIT(5) /* 1: MIPI RX input in 0: no RX in */
#define AP_DISABLE_PD BIT(6)
#define AP_DISABLE_DISPLAY BIT(7)
#define GPIO_CTRL_2 0x49
#define HPD_SOURCE BIT(6)
/***************************************************************/
/* Register definition of device address 0x84 */
#define MIPI_PHY_CONTROL_3 0x03
#define MIPI_HS_PWD_CLK 7
#define MIPI_HS_RT_CLK 6
#define MIPI_PD_CLK 5
#define MIPI_CLK_RT_MANUAL_PD_EN 4
#define MIPI_CLK_HS_MANUAL_PD_EN 3
#define MIPI_CLK_DET_DET_BYPASS 2
#define MIPI_CLK_MISS_CTRL 1
#define MIPI_PD_LPTX_CH_MANUAL_PD_EN 0
#define MIPI_LANE_CTRL_0 0x05
#define MIPI_TIME_HS_PRPR 0x08
/*
* After MIPI RX protocol layer received video frames,
* Protocol layer starts to reconstruct video stream from PHY
*/
#define MIPI_VIDEO_STABLE_CNT 0x0A
#define MIPI_LANE_CTRL_10 0x0F
#define MIPI_DIGITAL_ADJ_1 0x1B
#define IVO_MID 0x26CF
#define MIPI_PLL_M_NUM_23_16 0x1E
#define MIPI_PLL_M_NUM_15_8 0x1F
#define MIPI_PLL_M_NUM_7_0 0x20
#define MIPI_PLL_N_NUM_23_16 0x21
#define MIPI_PLL_N_NUM_15_8 0x22
#define MIPI_PLL_N_NUM_7_0 0x23
#define MIPI_DIGITAL_PLL_6 0x2A
/* Bit[7:6]: VCO band control, only effective */
#define MIPI_M_NUM_READY 0x10
#define MIPI_N_NUM_READY 0x08
#define STABLE_INTEGER_CNT_EN 0x04
#define MIPI_PLL_TEST_BIT 0
/* Bit[1:0]: test point output select - */
/* 00: VCO power, 01: dvdd_pdt, 10: dvdd, 11: vcox */
#define MIPI_DIGITAL_PLL_7 0x2B
#define MIPI_PLL_FORCE_N_EN 7
#define MIPI_PLL_FORCE_BAND_EN 6
#define MIPI_PLL_VCO_TUNE_REG 4
/* Bit[5:4]: VCO metal capacitance - */
/* 00: +20% fast, 01: +10% fast (default), 10: typical, 11: -10% slow */
#define MIPI_PLL_VCO_TUNE_REG_VAL 0x30
#define MIPI_PLL_PLL_LDO_BIT 2
/* Bit[3:2]: vco_v2i power - */
/* 00: 1.40V, 01: 1.45V (default), 10: 1.50V, 11: 1.55V */
#define MIPI_PLL_RESET_N 0x02
#define MIPI_FRQ_FORCE_NDET 0
#define MIPI_ALERT_CLR_0 0x2D
#define HS_link_error_clear 7
/* This bit itself is S/C, and it clears 0x84:0x31[7] */
#define MIPI_ALERT_OUT_0 0x31
#define check_sum_err_hs_sync 7
/* This bit is cleared by 0x84:0x2D[7] */
#define MIPI_DIGITAL_PLL_8 0x33
#define MIPI_POST_DIV_VAL 4
/* N means divided by (n+1), n = 0~15 */
#define MIPI_EN_LOCK_FRZ 3
#define MIPI_FRQ_COUNTER_RST 2
#define MIPI_FRQ_SET_REG_8 1
/* Bit 0 is reserved */
#define MIPI_DIGITAL_PLL_9 0x34
#define MIPI_DIGITAL_PLL_16 0x3B
#define MIPI_FRQ_FREEZE_NDET 7
#define MIPI_FRQ_REG_SET_ENABLE 6
#define MIPI_REG_FORCE_SEL_EN 5
#define MIPI_REG_SEL_DIV_REG 4
#define MIPI_REG_FORCE_PRE_DIV_EN 3
/* Bit 2 is reserved */
#define MIPI_FREF_D_IND 1
#define REF_CLK_27000KHZ 1
#define REF_CLK_19200KHZ 0
#define MIPI_REG_PLL_PLL_TEST_ENABLE 0
#define MIPI_DIGITAL_PLL_18 0x3D
#define FRQ_COUNT_RB_SEL 7
#define REG_FORCE_POST_DIV_EN 6
#define MIPI_DPI_SELECT 5
#define SELECT_DSI 1
#define SELECT_DPI 0
#define REG_BAUD_DIV_RATIO 0
#define H_BLANK_L 0x3E
/* For DSC only */
#define H_BLANK_H 0x3F
/* For DSC only; note: bit[7:6] are reserved */
#define MIPI_SWAP 0x4A
#define MIPI_SWAP_CH0 7
#define MIPI_SWAP_CH1 6
#define MIPI_SWAP_CH2 5
#define MIPI_SWAP_CH3 4
#define MIPI_SWAP_CLK 3
/* Bit[2:0] are reserved */
/******** END of I2C Address 0x84 *********/
/* DPCD regs */
#define DPCD_DPCD_REV 0x00
#define DPCD_MAX_LINK_RATE 0x01
#define DPCD_MAX_LANE_COUNT 0x02
/********* ANX7625 Register End **********/
/***************** Display *****************/
enum audio_fs {
AUDIO_FS_441K = 0x00,
AUDIO_FS_48K = 0x02,
AUDIO_FS_32K = 0x03,
AUDIO_FS_882K = 0x08,
AUDIO_FS_96K = 0x0a,
AUDIO_FS_1764K = 0x0c,
AUDIO_FS_192K = 0x0e
};
enum audio_wd_len {
AUDIO_W_LEN_16_20MAX = 0x02,
AUDIO_W_LEN_18_20MAX = 0x04,
AUDIO_W_LEN_17_20MAX = 0x0c,
AUDIO_W_LEN_19_20MAX = 0x08,
AUDIO_W_LEN_20_20MAX = 0x0a,
AUDIO_W_LEN_20_24MAX = 0x03,
AUDIO_W_LEN_22_24MAX = 0x05,
AUDIO_W_LEN_21_24MAX = 0x0d,
AUDIO_W_LEN_23_24MAX = 0x09,
AUDIO_W_LEN_24_24MAX = 0x0b
};
#define I2S_CH_2 0x01
#define TDM_CH_4 0x03
#define TDM_CH_6 0x05
#define TDM_CH_8 0x07
#define MAX_DPCD_BUFFER_SIZE 16
#define ONE_BLOCK_SIZE 128
#define FOUR_BLOCK_SIZE (128 * 4)
#define MAX_EDID_BLOCK 3
#define EDID_TRY_CNT 3
#define SUPPORT_PIXEL_CLOCK 300000
/***************** Display End *****************/
#define MAX_LANES_SUPPORT 4
struct anx7625_platform_data {
struct gpio_desc *gpio_p_on;
struct gpio_desc *gpio_reset;
struct regulator_bulk_data supplies[3];
struct drm_bridge *panel_bridge;
int intp_irq;
int is_dpi;
int mipi_lanes;
int audio_en;
int dp_lane0_swing_reg_cnt;
u8 lane0_reg_data[DP_TX_SWING_REG_CNT];
int dp_lane1_swing_reg_cnt;
u8 lane1_reg_data[DP_TX_SWING_REG_CNT];
u32 low_power_mode;
struct device_node *mipi_host_node;
};
struct anx7625_i2c_client {
struct i2c_client *tx_p0_client;
struct i2c_client *tx_p1_client;
struct i2c_client *tx_p2_client;
struct i2c_client *rx_p0_client;
struct i2c_client *rx_p1_client;
struct i2c_client *rx_p2_client;
struct i2c_client *tcpc_client;
};
struct typec_port;
struct usb_role_switch;
#define MAX_BUF_LEN 30
struct fw_msg {
u8 msg_len;
u8 msg_type;
u8 buf[MAX_BUF_LEN];
} __packed;
#define HEADER_LEN 2
struct anx7625_data {
struct anx7625_platform_data pdata;
struct platform_device *audio_pdev;
struct typec_port *typec_port;
struct usb_role_switch *role_sw;
int typec_data_role;
int hpd_status;
int hpd_high_cnt;
int dp_en;
int hdcp_cp;
/* Lock for work queue */
struct mutex lock;
struct device *dev;
struct anx7625_i2c_client i2c;
struct i2c_client *last_client;
struct timer_list hdcp_timer;
const struct drm_edid *cached_drm_edid;
struct device *codec_dev;
hdmi_codec_plugged_cb plugged_cb;
struct work_struct work;
struct workqueue_struct *workqueue;
struct delayed_work hdcp_work;
struct workqueue_struct *hdcp_workqueue;
/* Lock for hdcp work queue */
struct mutex hdcp_wq_lock;
/* Lock for aux transfer and disable */
struct mutex aux_lock;
char edid_block;
struct display_timing dt;
u8 display_timing_valid;
struct drm_bridge bridge;
u8 bridge_attached;
struct drm_connector *connector;
struct mipi_dsi_device *dsi;
struct drm_dp_aux aux;
struct fw_msg send_msg;
};
#endif /* __ANX7625_H__ */