From 673444991a2dc7e2780b44f6715f1e71039aa896 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Wed, 18 Oct 2023 09:33:06 +0000 Subject: [PATCH] misc: rk628: display: compatible with rk628f Change-Id: I51e0ea03baa92e5e7083779b7a59fbe81d104ec5 Signed-off-by: Guochun Huang --- drivers/misc/rk628/panel.c | 2 +- drivers/misc/rk628/rk628.c | 178 +++++++++++++++++------- drivers/misc/rk628/rk628.h | 66 ++++++++- drivers/misc/rk628/rk628_csi.c | 11 +- drivers/misc/rk628/rk628_dsi.c | 11 +- drivers/misc/rk628/rk628_gvi.c | 13 +- drivers/misc/rk628/rk628_hdmirx.c | 4 +- drivers/misc/rk628/rk628_lvds.c | 15 +- drivers/misc/rk628/rk628_post_process.c | 2 +- drivers/misc/rk628/rk628_rgb.c | 9 +- 10 files changed, 231 insertions(+), 80 deletions(-) diff --git a/drivers/misc/rk628/panel.c b/drivers/misc/rk628/panel.c index 069b7e046f3c..64ed0fa4d136 100644 --- a/drivers/misc/rk628/panel.c +++ b/drivers/misc/rk628/panel.c @@ -183,7 +183,7 @@ int rk628_panel_info_get(struct rk628 *rk628, struct device_node *np) rk628->panel = panel; - if (rk628->output_mode == OUTPUT_MODE_DSI) { + if (rk628_output_is_dsi(rk628)) { ret = dsi_panel_get_cmds(rk628, np); if (ret) { dev_err(dev, "failed to get cmds\n"); diff --git a/drivers/misc/rk628/rk628.c b/drivers/misc/rk628/rk628.c index 8ceef76a3cf4..762109eca9f2 100644 --- a/drivers/misc/rk628/rk628.c +++ b/drivers/misc/rk628/rk628.c @@ -381,24 +381,24 @@ static void rk628_display_disable(struct rk628 *rk628) if (!rk628->display_enabled) return; - if (rk628->output_mode == OUTPUT_MODE_CSI) + if (rk628_output_is_csi(rk628)) rk628_csi_disable(rk628); - if (rk628->output_mode == OUTPUT_MODE_GVI) + if (rk628_output_is_gvi(rk628)) rk628_gvi_disable(rk628); - if (rk628->output_mode == OUTPUT_MODE_LVDS) + if (rk628_output_is_lvds(rk628)) rk628_lvds_disable(rk628); - if (rk628->output_mode == OUTPUT_MODE_DSI) + if (rk628_output_is_dsi(rk628)) rk628_dsi_disable(rk628); - if (rk628->output_mode == OUTPUT_MODE_RGB) + if (rk628_output_is_rgb(rk628)) rk628_rgb_tx_disable(rk628); rk628_post_process_disable(rk628); - if (rk628->input_mode == INPUT_MODE_HDMI) + if (rk628_input_is_hdmi(rk628)) rk628_hdmirx_disable(rk628); rk628->display_enabled = false; @@ -411,19 +411,19 @@ static void rk628_display_enable(struct rk628 *rk628) if (rk628->display_enabled) return; - if (rk628->input_mode == INPUT_MODE_RGB) + if (rk628_input_is_rgb(rk628)) rk628_rgb_rx_enable(rk628); - if (rk628->input_mode == INPUT_MODE_BT1120) + if (rk628_input_is_bt1120(rk628)) rk628_bt1120_rx_enable(rk628); - if (rk628->output_mode == OUTPUT_MODE_RGB) + if (rk628_output_is_rgb(rk628)) rk628_rgb_tx_enable(rk628); - if (rk628->output_mode == OUTPUT_MODE_DSI) + if (rk628_output_is_dsi(rk628)) queue_delayed_work(rk628->dsi_wq, &rk628->dsi_delay_work, msecs_to_jiffies(10)); - if (rk628->input_mode == INPUT_MODE_HDMI) { + if (rk628_input_is_hdmi(rk628)) { ret = rk628_hdmirx_enable(rk628); if ((ret == HDMIRX_PLUGOUT) || (ret & HDMIRX_NOSIGNAL)) { rk628_display_disable(rk628); @@ -431,25 +431,25 @@ static void rk628_display_enable(struct rk628 *rk628) } } - if (rk628->output_mode == OUTPUT_MODE_BT1120) + if (rk628_output_is_bt1120(rk628)) rk628_bt1120_tx_enable(rk628); - if (rk628->output_mode != OUTPUT_MODE_HDMI) { + if (!rk628_output_is_hdmi(rk628)) { rk628_post_process_init(rk628); rk628_post_process_enable(rk628); } - if (rk628->output_mode == OUTPUT_MODE_LVDS) + if (rk628_output_is_lvds(rk628)) rk628_lvds_enable(rk628); - if (rk628->output_mode == OUTPUT_MODE_GVI) + if (rk628_output_is_gvi(rk628)) rk628_gvi_enable(rk628); - if (rk628->output_mode == OUTPUT_MODE_CSI) + if (rk628_output_is_csi(rk628)) rk628_csi_enable(rk628); #ifdef CONFIG_RK628_MISC_HDMITX - if (rk628->output_mode == OUTPUT_MODE_HDMI) + if (rk628_output_is_hdmi(rk628)) rk628_hdmitx_enable(rk628); #endif @@ -476,7 +476,7 @@ static int rk628_fb_notifier_callback(struct notifier_block *nb, rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x30002000); rk628_cru_init(rk628); - if (rk628->input_mode == INPUT_MODE_HDMI) { + if (rk628_input_is_hdmi(rk628)) { rk628_i2c_write(rk628, GRF_INTR0_EN, 0x01000100); /* * make hdmi rx register domain polling @@ -497,7 +497,7 @@ static int rk628_fb_notifier_callback(struct notifier_block *nb, return NOTIFY_OK; case FB_BLANK_POWERDOWN: - if (rk628->input_mode == INPUT_MODE_HDMI) + if (rk628_input_is_hdmi(rk628)) cancel_delayed_work_sync(&rk628->delay_work); rk628_display_disable(rk628); @@ -517,7 +517,7 @@ static void rk628_display_work(struct work_struct *work) container_of(work, struct rk628, delay_work.work); int delay = msecs_to_jiffies(2000); - if (rk628->input_mode == INPUT_MODE_HDMI) { + if (rk628_input_is_hdmi(rk628)) { ret = rk628_hdmirx_detect(rk628); dev_info(rk628->dev, "%s: hdmirx detect status:0x%x\n", __func__, ret); if (!(ret & (HDMIRX_CHANGED | HDMIRX_NOLOCK))) { @@ -538,7 +538,7 @@ static void rk628_display_work(struct work_struct *work) rk628_display_disable(rk628); } - if (rk628->input_mode == INPUT_MODE_HDMI) { + if (rk628_input_is_hdmi(rk628)) { if (!rk628->plugin_det_gpio) { if (ret & HDMIRX_NOLOCK) delay = msecs_to_jiffies(200); @@ -574,12 +574,76 @@ static irqreturn_t rk628_hdmirx_plugin_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static bool rk628_input_is_rgb(struct rk628 *rk628) +static bool rk628_display_route_check(struct rk628 *rk628) { - if (rk628->input_mode == INPUT_MODE_RGB || rk628->input_mode == INPUT_MODE_BT1120) + if (!hweight32(rk628->input_mode) || !hweight32(rk628->output_mode)) + return false; + + /* + * the RGB/BT1120 RX and RGB/BT1120 TX are the same shared IP + * and cannot be used as both input and output simultaneously. + */ + if ((rk628_input_is_rgb(rk628) || rk628_input_is_bt1120(rk628)) && + (rk628_output_is_rgb(rk628) || rk628_output_is_bt1120(rk628))) + return false; + + if (rk628->version == RK628F_VERSION) return true; - return false; + /* rk628d only support rgb and hdmi output simultaneously */ + if (hweight32(rk628->output_mode) > 2) + return false; + + if (hweight32(rk628->output_mode) == 2 && + !(rk628_output_is_rgb(rk628) && rk628_output_is_hdmi(rk628))) + return false; + + return true; +} + +static void rk628_final_display_route(struct rk628 *rk628) +{ + char *input = NULL; + char *output = NULL; + char buf[20]; + + if (rk628_input_is_hdmi(rk628)) + input = "hdmi"; + else if (rk628_input_is_bt1120(rk628)) + input = "bt1120"; + else + input = "rgb"; + + if (rk628_output_is_gvi(rk628)) + output = "gvi"; + else if (rk628_output_is_lvds(rk628)) + output = "lvds"; + else if (rk628_output_is_dsi(rk628)) + output = "dsi"; + else if (rk628_output_is_csi(rk628)) + output = "csi"; + + if (rk628_output_is_bt1120(rk628)) { + if (output) + sprintf(buf, "%s & %s", output, "bt1120"); + else + output = "bt1120"; + } else if (rk628_output_is_rgb(rk628)) { + if (output) + sprintf(buf, "%s & %s", output, "rgb"); + else + output = "rgb"; + } + + if (rk628_output_is_hdmi(rk628)) { + if (output) + sprintf(buf, "%s & %s", output, "hdmi"); + else + output = "hdmi"; + } + + dev_info(rk628->dev, "input_mode:%s output_mode:%s\n", input, + hweight32(rk628->output_mode) > 1 ? buf : output); } static int rk628_display_route_info_parse(struct rk628 *rk628) @@ -589,44 +653,50 @@ static int rk628_display_route_info_parse(struct rk628 *rk628) u32 val; if (of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-in")) - rk628->input_mode = INPUT_MODE_HDMI; + rk628->input_mode = BIT(INPUT_MODE_HDMI); else if (of_property_read_bool(rk628->dev->of_node, "rk628,rgb-in")) - rk628->input_mode = INPUT_MODE_RGB; + rk628->input_mode = BIT(INPUT_MODE_RGB); else if (of_property_read_bool(rk628->dev->of_node, "rk628,bt1120-in")) - rk628->input_mode = INPUT_MODE_BT1120; + rk628->input_mode = BIT(INPUT_MODE_BT1120); else - rk628->input_mode = INPUT_MODE_RGB; + rk628->input_mode = BIT(INPUT_MODE_RGB); - if (of_find_node_by_name(rk628->dev->of_node, "rk628-dsi")) { - np = of_find_node_by_name(rk628->dev->of_node, "rk628-dsi"); - ret = rk628_dsi_parse(rk628, np); + if (of_find_node_by_name(rk628->dev->of_node, "rk628-gvi")) { + np = of_find_node_by_name(rk628->dev->of_node, "rk628-gvi"); + rk628->output_mode |= BIT(OUTPUT_MODE_GVI); + ret = rk628_gvi_parse(rk628, np); } else if (of_find_node_by_name(rk628->dev->of_node, "rk628-lvds")) { np = of_find_node_by_name(rk628->dev->of_node, "rk628-lvds"); + rk628->output_mode |= BIT(OUTPUT_MODE_LVDS); ret = rk628_lvds_parse(rk628, np); - } else if (of_find_node_by_name(rk628->dev->of_node, "rk628-gvi")) { - np = of_find_node_by_name(rk628->dev->of_node, "rk628-gvi"); - ret = rk628_gvi_parse(rk628, np); - } else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120")) { - rk628->output_mode = OUTPUT_MODE_BT1120; - } else if (of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-out")) { - rk628->output_mode = OUTPUT_MODE_HDMI; + } else if (of_find_node_by_name(rk628->dev->of_node, "rk628-dsi")) { + np = of_find_node_by_name(rk628->dev->of_node, "rk628-dsi"); + rk628->output_mode |= BIT(OUTPUT_MODE_DSI); + ret = rk628_dsi_parse(rk628, np); } else if (of_property_read_bool(rk628->dev->of_node, "rk628,csi-out")) { - rk628->output_mode = OUTPUT_MODE_CSI; - } else if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb")) { - ret = rk628_rgb_parse(rk628, NULL); - rk628->output_mode = OUTPUT_MODE_RGB; - } else { - rk628->output_mode = OUTPUT_MODE_RGB; + rk628->output_mode |= BIT(OUTPUT_MODE_CSI); } + if (of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-out")) + rk628->output_mode |= BIT(OUTPUT_MODE_HDMI); + + if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb")) { + ret = rk628_rgb_parse(rk628, NULL); + rk628->output_mode |= BIT(OUTPUT_MODE_RGB); + } else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120")) { + rk628->output_mode |= BIT(OUTPUT_MODE_BT1120); + } + + if (!rk628_display_route_check(rk628)) + return -EINVAL; + + rk628_final_display_route(rk628); + if (of_property_read_u32(rk628->dev->of_node, "mode-sync-pol", &val) < 0) rk628->sync_pol = MODE_FLAG_PSYNC; else rk628->sync_pol = (!val ? MODE_FLAG_NSYNC : MODE_FLAG_PSYNC); - if (rk628_input_is_rgb(rk628) && rk628->output_mode == OUTPUT_MODE_RGB) - return -EINVAL; - return ret; } @@ -1140,9 +1210,9 @@ rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) return ret; } - if (rk628->output_mode != OUTPUT_MODE_CSI) { + if (!rk628_output_is_csi(rk628)) { ret = rk628_display_timings_get(rk628); - if (ret && rk628->output_mode != OUTPUT_MODE_HDMI) { + if (ret && !rk628_output_is_hdmi(rk628)) { dev_info(dev, "display timings err\n"); return ret; } @@ -1216,7 +1286,7 @@ rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) WQ_MEM_RECLAIM | WQ_FREEZABLE, "rk628-monitor-wq"); INIT_DELAYED_WORK(&rk628->delay_work, rk628_display_work); - if (rk628->output_mode == OUTPUT_MODE_DSI) { + if (rk628_output_is_dsi(rk628)) { rk628->dsi_wq = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM | WQ_FREEZABLE, "rk628-dsi-wq"); INIT_DELAYED_WORK(&rk628->dsi_delay_work, rk628_dsi_work); @@ -1224,10 +1294,10 @@ rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) rk628_cru_init(rk628); - if (rk628->output_mode == OUTPUT_MODE_CSI) + if (rk628_output_is_csi(rk628)) rk628_csi_init(rk628); - if (rk628->input_mode == INPUT_MODE_HDMI) { + if (rk628_input_is_hdmi(rk628)) { if (rk628->plugin_det_gpio) { rk628->plugin_irq = gpiod_to_irq(rk628->plugin_det_gpio); if (rk628->plugin_irq < 0) { @@ -1287,7 +1357,7 @@ static int rk628_i2c_remove(struct i2c_client *client) struct rk628 *rk628 = i2c_get_clientdata(client); struct device *dev = &client->dev; - if (rk628->output_mode == OUTPUT_MODE_DSI) { + if (rk628_output_is_dsi(rk628)) { cancel_delayed_work_sync(&rk628->dsi_delay_work); destroy_workqueue(rk628->dsi_wq); } @@ -1323,7 +1393,7 @@ static int rk628_resume(struct device *dev) rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x30002000); rk628_cru_init(rk628); - if (rk628->input_mode == INPUT_MODE_HDMI) { + if (rk628_input_is_hdmi(rk628)) { rk628_i2c_write(rk628, GRF_INTR0_EN, 0x01000100); /* * make hdmi rx register domain polling diff --git a/drivers/misc/rk628/rk628.h b/drivers/misc/rk628/rk628.h index 6e22425375ae..c76a898b5e7b 100644 --- a/drivers/misc/rk628/rk628.h +++ b/drivers/misc/rk628/rk628.h @@ -39,8 +39,16 @@ #define SW_BT_DATA_OEN BIT(9) #define SW_EFUSE_HDCP_EN_MASK BIT(8) #define SW_EFUSE_HDCP_EN(x) UPDATE(x, 8, 8) -#define SW_OUTPUT_MODE_MASK GENMASK(7, 3) -#define SW_OUTPUT_MODE(x) UPDATE(x, 7, 3) +#define SW_OUTPUT_MODE_MASK GENMASK(5, 3) +#define SW_OUTPUT_MODE(x) UPDATE(x, 5, 3) +/* compatible with rk628f */ +#define SW_OUTPUT_RGB_MODE_MASK GENMASK(7, 6) +#define SW_OUTPUT_RGB_MODE(x) UPDATE(x, 7, 6) +#define SW_HDMITX_EN_MASK BIT(5) +#define SW_HDMITX_EN(x) UPDATE(x, 5, 5) +#define SW_OUTPUT_COMBTX_MODE_MASK GENMASK(4, 3) +#define SW_OUTPUT_COMBTX_MODE(x) UPDATE(x, 4, 3) + #define SW_INPUT_MODE_MASK GENMASK(2, 0) #define SW_INPUT_MODE(x) UPDATE(x, 2, 0) #define GRF_SYSTEM_CON1 0x0004 @@ -444,8 +452,8 @@ struct rk628 { struct rk628_panel_simple *panel; void *hdmirx; bool display_enabled; - enum rk628_input_mode input_mode; - enum rk628_output_mode output_mode; + u32 input_mode; + u32 output_mode; struct rk628_display_mode src_mode; struct rk628_display_mode dst_mode; enum bus_format input_fmt; @@ -461,6 +469,56 @@ struct rk628 { u32 version; }; +static inline bool rk628_input_is_hdmi(struct rk628 *rk628) +{ + return rk628->input_mode & BIT(INPUT_MODE_HDMI); +} + +static inline bool rk628_input_is_rgb(struct rk628 *rk628) +{ + return rk628->input_mode & BIT(INPUT_MODE_RGB); +} + +static inline bool rk628_input_is_bt1120(struct rk628 *rk628) +{ + return rk628->input_mode & BIT(INPUT_MODE_BT1120); +} + +static inline bool rk628_output_is_rgb(struct rk628 *rk628) +{ + return rk628->output_mode & BIT(OUTPUT_MODE_RGB); +} + +static inline bool rk628_output_is_bt1120(struct rk628 *rk628) +{ + return rk628->output_mode & BIT(OUTPUT_MODE_BT1120); +} + +static inline bool rk628_output_is_gvi(struct rk628 *rk628) +{ + return rk628->output_mode & BIT(OUTPUT_MODE_GVI); +} + +static inline bool rk628_output_is_lvds(struct rk628 *rk628) +{ + return rk628->output_mode & BIT(OUTPUT_MODE_LVDS); +} + +static inline bool rk628_output_is_dsi(struct rk628 *rk628) +{ + return rk628->output_mode & BIT(OUTPUT_MODE_DSI); +} + +static inline bool rk628_output_is_csi(struct rk628 *rk628) +{ + return rk628->output_mode & BIT(OUTPUT_MODE_CSI); +} + +static inline bool rk628_output_is_hdmi(struct rk628 *rk628) +{ + return rk628->output_mode & BIT(OUTPUT_MODE_HDMI); +} + static inline int rk628_i2c_write(struct rk628 *rk628, u32 reg, u32 val) { int region = (reg >> 16) & 0xff; diff --git a/drivers/misc/rk628/rk628_csi.c b/drivers/misc/rk628/rk628_csi.c index a121c8f08173..dd3d4dd98c6c 100644 --- a/drivers/misc/rk628/rk628_csi.c +++ b/drivers/misc/rk628/rk628_csi.c @@ -416,8 +416,15 @@ static void enable_stream(struct rk628 *rk628, bool en) void rk628_csi_init(struct rk628 *rk628) { - rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, - SW_OUTPUT_MODE_MASK, SW_OUTPUT_MODE(OUTPUT_MODE_CSI)); + u32 mask = SW_OUTPUT_MODE_MASK; + u32 val = SW_OUTPUT_MODE(OUTPUT_MODE_CSI); + + if (rk628->version == RK628F_VERSION) { + mask = SW_OUTPUT_COMBTX_MODE_MASK; + val = SW_OUTPUT_COMBTX_MODE(OUTPUT_MODE_CSI - 1); + } + + rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, mask, val); rk628_csi_get_detected_timings(rk628); mipi_dphy_reset(rk628); } diff --git a/drivers/misc/rk628/rk628_dsi.c b/drivers/misc/rk628/rk628_dsi.c index 368f704351e9..37c6b8237a06 100644 --- a/drivers/misc/rk628/rk628_dsi.c +++ b/drivers/misc/rk628/rk628_dsi.c @@ -237,7 +237,6 @@ int rk628_dsi_parse(struct rk628 *rk628, struct device_node *dsi_np) if (!of_device_is_available(dsi_np)) return -EINVAL; - rk628->output_mode = OUTPUT_MODE_DSI; rk628->dsi0.id = 0; rk628->dsi0.channel = 0; rk628->dsi0.rk628 = rk628; @@ -1210,9 +1209,15 @@ void rk628_mipi_dsi_pre_enable(struct rk628 *rk628) const struct rk628_dsi *dsi1 = &rk628->dsi1; u32 rate = rk628_dsi_get_lane_rate(dsi); int bus_width; + u32 mask = SW_OUTPUT_MODE_MASK; + u32 val = SW_OUTPUT_MODE(OUTPUT_MODE_DSI); - rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_OUTPUT_MODE_MASK, - SW_OUTPUT_MODE(OUTPUT_MODE_DSI)); + if (rk628->version == RK628F_VERSION) { + mask = SW_OUTPUT_COMBTX_MODE_MASK; + val = SW_OUTPUT_COMBTX_MODE(OUTPUT_MODE_DSI - 2); + } + + rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, mask, val); rk628_i2c_update_bits(rk628, GRF_POST_PROC_CON, SW_SPLIT_EN, dsi->slave ? SW_SPLIT_EN : 0); diff --git a/drivers/misc/rk628/rk628_gvi.c b/drivers/misc/rk628/rk628_gvi.c index 7539cb7d7054..019f83f52334 100644 --- a/drivers/misc/rk628/rk628_gvi.c +++ b/drivers/misc/rk628/rk628_gvi.c @@ -21,8 +21,6 @@ int rk628_gvi_parse(struct rk628 *rk628, struct device_node *gvi_np) if (!of_device_is_available(gvi_np)) return -EINVAL; - rk628->output_mode = OUTPUT_MODE_GVI; - if (!of_property_read_u32(gvi_np, "gvi,lanes", &val)) rk628->gvi.lanes = val; @@ -196,14 +194,21 @@ void rk628_gvi_enable(struct rk628 *rk628) { struct rk628_gvi *gvi = &rk628->gvi; unsigned int rate; + u32 mask = SW_OUTPUT_MODE_MASK; + u32 val = SW_OUTPUT_MODE(OUTPUT_MODE_GVI); rk628_gvi_get_info(gvi); rate = rk628_gvi_get_lane_rate(rk628); /* set gvi_hpd and gvi_lock mux */ rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x06000600); - rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_OUTPUT_MODE_MASK, - SW_OUTPUT_MODE(OUTPUT_MODE_GVI)); + + if (rk628->version == RK628F_VERSION) { + mask = SW_OUTPUT_COMBTX_MODE_MASK; + val = SW_OUTPUT_COMBTX_MODE(OUTPUT_MODE_GVI); + } + + rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, mask, val); rk628_combtxphy_set_bus_width(rk628, rate); rk628_combtxphy_set_gvi_division_mode(rk628, gvi->division_mode); rk628_combtxphy_set_mode(rk628, PHY_MODE_VIDEO_GVI); diff --git a/drivers/misc/rk628/rk628_hdmirx.c b/drivers/misc/rk628/rk628_hdmirx.c index bfb8866f77e3..ff0c55783f2e 100644 --- a/drivers/misc/rk628/rk628_hdmirx.c +++ b/drivers/misc/rk628/rk628_hdmirx.c @@ -655,7 +655,9 @@ static int rk628_hdmirx_init(struct rk628 *rk628) /* if GVI and HDMITX OUT, HDMIRX missing signal */ rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, - SW_OUTPUT_MODE_MASK, SW_OUTPUT_MODE(OUTPUT_MODE_RGB)); + SW_OUTPUT_RGB_MODE_MASK, + SW_OUTPUT_RGB_MODE(OUTPUT_MODE_RGB >> 3)); + rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_INPUT_MODE_MASK, SW_INPUT_MODE(INPUT_MODE_HDMI)); rk628_hdmirx_set_edid(rk628); diff --git a/drivers/misc/rk628/rk628_lvds.c b/drivers/misc/rk628/rk628_lvds.c index b0587b4daea8..4894b007878f 100644 --- a/drivers/misc/rk628/rk628_lvds.c +++ b/drivers/misc/rk628/rk628_lvds.c @@ -30,8 +30,6 @@ int rk628_lvds_parse(struct rk628 *rk628, struct device_node *lvds_np) if (!of_device_is_available(lvds_np)) return -EINVAL; - rk628->output_mode = OUTPUT_MODE_LVDS; - if (!of_property_read_string(lvds_np, "bus-format", &string)) { if (!strcmp(string, "jeida_24")) rk628->lvds.format = LVDS_FORMAT_JEIDA_24BIT; @@ -68,10 +66,17 @@ void rk628_lvds_enable(struct rk628 *rk628) enum lvds_link_type link_type = rk628->lvds.link_type; enum lvds_format format = rk628->lvds.format; const struct rk628_display_mode *mode = &rk628->dst_mode; - u32 val, bus_width; + u32 val, mask, bus_width; - lvds_update_bits(rk628, GRF_SYSTEM_CON0, SW_OUTPUT_MODE_MASK, - SW_OUTPUT_MODE(OUTPUT_MODE_LVDS)); + mask = SW_OUTPUT_MODE_MASK; + val = SW_OUTPUT_MODE(OUTPUT_MODE_LVDS); + + if (rk628->version == RK628F_VERSION) { + mask = SW_OUTPUT_COMBTX_MODE_MASK; + val = SW_OUTPUT_COMBTX_MODE(OUTPUT_MODE_LVDS); + } + + lvds_update_bits(rk628, GRF_SYSTEM_CON0, mask, val); switch (link_type) { case LVDS_DUAL_LINK_ODD_EVEN_PIXELS: diff --git a/drivers/misc/rk628/rk628_post_process.c b/drivers/misc/rk628/rk628_post_process.c index d5ffa3d69fbd..31327cdd2526 100644 --- a/drivers/misc/rk628/rk628_post_process.c +++ b/drivers/misc/rk628/rk628_post_process.c @@ -213,7 +213,7 @@ void rk628_post_process_init(struct rk628 *rk628) rk628_cru_clk_set_rate(rk628, CGU_CLK_RX_READ, src->clock * 1000); rk628_cru_clk_set_rate(rk628, CGU_SCLK_VOP, dst_rate * 1000); - if (rk628->output_mode == OUTPUT_MODE_HDMI) { + if (rk628_output_is_hdmi(rk628)) { rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_VSYNC_POL_MASK, SW_VSYNC_POL(rk628->sync_pol)); rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_HSYNC_POL_MASK, diff --git a/drivers/misc/rk628/rk628_rgb.c b/drivers/misc/rk628/rk628_rgb.c index 0631681a8294..2469008ae62b 100644 --- a/drivers/misc/rk628/rk628_rgb.c +++ b/drivers/misc/rk628/rk628_rgb.c @@ -40,8 +40,8 @@ void rk628_rgb_decoder_enable(struct rk628 *rk628) void rk628_rgb_encoder_enable(struct rk628 *rk628) { rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, - SW_BT_DATA_OEN_MASK | SW_OUTPUT_MODE_MASK, - SW_OUTPUT_MODE(OUTPUT_MODE_RGB)); + SW_BT_DATA_OEN_MASK | SW_OUTPUT_RGB_MODE_MASK, + SW_OUTPUT_RGB_MODE(OUTPUT_MODE_RGB >> 3)); rk628_i2c_update_bits(rk628, GRF_POST_PROC_CON, SW_DCLK_OUT_INV_EN, SW_DCLK_OUT_INV_EN); @@ -160,10 +160,9 @@ void rk628_bt1120_encoder_enable(struct rk628 *rk628) rk628_i2c_write(rk628, GRF_GPIO3A_D0_CON, 0xffff1011); rk628_i2c_write(rk628, GRF_GPIO3B_D_CON, 0xf0001); - /* config sw_input_mode bt1120 */ rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, - SW_BT_DATA_OEN_MASK | SW_OUTPUT_MODE_MASK, - SW_OUTPUT_MODE(OUTPUT_MODE_BT1120)); + SW_BT_DATA_OEN_MASK | SW_OUTPUT_RGB_MODE_MASK, + SW_OUTPUT_RGB_MODE(OUTPUT_MODE_BT1120 >> 3)); rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, SW_R2Y_EN(1)); rk628_i2c_update_bits(rk628, GRF_POST_PROC_CON, SW_DCLK_OUT_INV_EN, SW_DCLK_OUT_INV_EN);