mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
mfd: rkx110_x120: change video packet length
The serdes version 1 have a bug when enable video suspend function, which is target to enhance the i2c frequency when transfer video stream. In order to enhance i2c frequency as far as possible, a workaround ways is provided to do this thing, which is to reduce the video packet length. the formula as follow: length = ((hactive x 24 / 32 / 16) + 15) / 16 * 16 It should be noted that reducing video packet length will consume more link bandwidth. Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com> Change-Id: I23b679ec12ff3e2801bfb13cc1836094b6fd4ff9
This commit is contained in:
@@ -428,9 +428,11 @@ static int rk_serdes_link_tx_ctrl_enable(struct rk_serdes *serdes,
|
||||
{
|
||||
struct hwclk *hwclk = serdes->chip[remote_id].hwclk;
|
||||
struct i2c_client *client;
|
||||
struct videomode *vm = &route->vm;
|
||||
u32 ctrl_val, val;
|
||||
u32 rx_src;
|
||||
u32 stream_type;
|
||||
u32 length;
|
||||
|
||||
if (route->stream_type == STREAM_DISPLAY) {
|
||||
client = serdes->chip[DEVICE_LOCAL].client;
|
||||
@@ -459,6 +461,18 @@ static int rk_serdes_link_tx_ctrl_enable(struct rk_serdes *serdes,
|
||||
serdes->i2c_read_reg(client, RKLINK_TX_VIDEO_CTRL, &val);
|
||||
rx_src = rk_serdes_get_stream_source(serdes, route->local_port0);
|
||||
val |= rx_src;
|
||||
if (serdes->version == SERDES_V1) {
|
||||
/*
|
||||
* The serdes v1 have a bug when enable video suspend function, which
|
||||
* is used to enhance the i2c frequency. A workaround ways to do it is
|
||||
* reducing the video packet length:
|
||||
* length = ((hactive x 24 / 32 / 16) + 15) / 16 * 16
|
||||
*/
|
||||
length = vm->hactive * 24 / 32 / 16;
|
||||
length = (length + 15) / 16 * 16;
|
||||
val &= ~VIDEO_REPKT_LENGTH(0xffff);
|
||||
val |= VIDEO_REPKT_LENGTH(length);
|
||||
}
|
||||
serdes->i2c_write_reg(client, RKLINK_TX_VIDEO_CTRL, val);
|
||||
|
||||
if (route->local_port0 & RK_SERDES_DUAL_LVDS_RX) {
|
||||
|
||||
@@ -104,6 +104,9 @@
|
||||
#define LANE0_LANE_ID(x) UPDATE(x, 1, 1)
|
||||
#define LNAE0_ID_SEL(x) UPDATE(x, 0, 0)
|
||||
|
||||
#define DES_RKLINK_REC01_PKT_LENGTH LINK_REG(0x0028)
|
||||
#define E1_REPKT_LENGTH(x) UPDATE(x, 29, 16)
|
||||
#define E0_REPKT_LENGTH(x) UPDATE(x, 13, 0)
|
||||
#define RKLINK_DES_REG01_ENGIN_DEL 0x0030
|
||||
#define E1_ENGINE_DELAY(x) UPDATE(x, 31, 16)
|
||||
#define E0_ENGINE_DELAY(x) UPDATE(x, 15, 0)
|
||||
@@ -476,12 +479,14 @@ static int rk120_link_rx_cfg(struct rk_serdes *serdes, struct rk_serdes_route *r
|
||||
{
|
||||
struct hwclk *hwclk = serdes->chip[remote_id].hwclk;
|
||||
struct i2c_client *client;
|
||||
struct videomode *vm = &route->vm;
|
||||
u32 stream_type;
|
||||
u32 rx_src;
|
||||
u32 ctrl_val, mask, val;
|
||||
u32 lane0_dsource_id, lane1_dsource_id;
|
||||
bool is_rx_dual_lanes;
|
||||
bool is_rx_dual_channels;
|
||||
u32 length;
|
||||
|
||||
if (route->stream_type == STREAM_DISPLAY) {
|
||||
client = serdes->chip[remote_id].client;
|
||||
@@ -530,6 +535,19 @@ static int rk120_link_rx_cfg(struct rk_serdes *serdes, struct rk_serdes_route *r
|
||||
|
||||
serdes->i2c_update_bits(client, RKLINK_DES_LANE_ENGINE_DST, mask, val);
|
||||
|
||||
if (serdes->version == SERDES_V1) {
|
||||
/*
|
||||
* The serdes v1 have a bug when enable video suspend function, which
|
||||
* is used to enhance the i2c frequency. A workaround ways to do it is
|
||||
* reducing the video packet length:
|
||||
* length = ((hactive x 24 / 32 / 16) + 15) / 16 * 16
|
||||
*/
|
||||
length = vm->hactive * 24 / 32 / 16;
|
||||
length = (length + 15) / 16 * 16;
|
||||
serdes->i2c_write_reg(client, DES_RKLINK_REC01_PKT_LENGTH, E0_REPKT_LENGTH(length) |
|
||||
E1_REPKT_LENGTH(length));
|
||||
}
|
||||
|
||||
serdes->i2c_read_reg(client, RKLINK_DES_SOURCE_CFG, &val);
|
||||
|
||||
val &= ~(LANE0_ENGINE_ID(1) | LANE0_LANE_ID(1) | LANE1_ENGINE_ID(1) |
|
||||
|
||||
Reference in New Issue
Block a user