mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
drm/bridge: synopsys: dw-hdmi-qp: Get uboot color format from avi regs in dsc mode
RK3588/RK3576 hdmi color format setting and dsc mode setting are the same mask in the same register. If dsc is enabled for hdmi in uboot, what color is hdmi output in uboot that cannot be obtained from this register in kernel. Since hdmi in dsc mode always sends avi infoframe, color format of hdmi output in uboot can be read from the avi register. Change-Id: I68157455342302338370feb9176b46e2051b4f01 Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
This commit is contained in:
@@ -73,6 +73,15 @@
|
||||
|
||||
#define HDMI_CTRL_CLK_EN 0x15
|
||||
|
||||
#define DW_HDMI_QP_RGB 0
|
||||
#define DW_HDMI_QP_YUV422 0x1
|
||||
#define DW_HDMI_QP_YUV444 0x2
|
||||
#define DW_HDMI_QP_YUV420 0x3
|
||||
#define DW_HDMI_QP_DSC 0xb
|
||||
|
||||
#define IPI_FORMAT_MASK 0xf
|
||||
#define IPI_COLOR_DEPTH_MASK 0xf0
|
||||
|
||||
static const unsigned int dw_hdmi_cable[] = {
|
||||
EXTCON_DISP_HDMI,
|
||||
EXTCON_NONE,
|
||||
@@ -2990,20 +2999,107 @@ dw_hdmi_connector_set_property(struct drm_connector *connector,
|
||||
property, val);
|
||||
}
|
||||
|
||||
static u64 dw_hdmi_qp_get_avi_color_fmt(struct dw_hdmi_qp *hdmi, u32 depth)
|
||||
{
|
||||
u32 fmt;
|
||||
u64 bus_format;
|
||||
|
||||
fmt = (hdmi_readl(hdmi, PKT_AVI_CONTENTS1) >> 13) & 0x3;
|
||||
|
||||
switch (fmt) {
|
||||
case DW_HDMI_QP_YUV444:
|
||||
if (!depth)
|
||||
bus_format = MEDIA_BUS_FMT_YUV8_1X24;
|
||||
else
|
||||
bus_format = MEDIA_BUS_FMT_YUV10_1X30;
|
||||
break;
|
||||
case DW_HDMI_QP_YUV422:
|
||||
bus_format = MEDIA_BUS_FMT_YUYV10_1X20;
|
||||
break;
|
||||
case DW_HDMI_QP_YUV420:
|
||||
if (!depth)
|
||||
bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
|
||||
else
|
||||
bus_format = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
|
||||
break;
|
||||
case DW_HDMI_QP_RGB:
|
||||
if (!depth)
|
||||
bus_format = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
else
|
||||
bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
|
||||
break;
|
||||
default:
|
||||
dev_err(hdmi->dev, "can't get correct color format\n");
|
||||
bus_format = MEDIA_BUS_FMT_YUV8_1X24;
|
||||
break;
|
||||
}
|
||||
|
||||
return bus_format;
|
||||
}
|
||||
|
||||
static u64 dw_hdmi_qp_get_color_fmt(struct dw_hdmi_qp *hdmi)
|
||||
{
|
||||
u32 fmt, depth;
|
||||
u64 bus_format;
|
||||
|
||||
fmt = hdmi_readl(hdmi, VIDEO_INTERFACE_STATUS0);
|
||||
depth = fmt & IPI_COLOR_DEPTH_MASK;
|
||||
fmt = fmt & IPI_FORMAT_MASK;
|
||||
|
||||
switch (fmt) {
|
||||
case DW_HDMI_QP_YUV444:
|
||||
if (!depth)
|
||||
bus_format = MEDIA_BUS_FMT_YUV8_1X24;
|
||||
else
|
||||
bus_format = MEDIA_BUS_FMT_YUV10_1X30;
|
||||
break;
|
||||
case DW_HDMI_QP_YUV422:
|
||||
bus_format = MEDIA_BUS_FMT_YUYV10_1X20;
|
||||
break;
|
||||
case DW_HDMI_QP_YUV420:
|
||||
if (!depth)
|
||||
bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
|
||||
else
|
||||
bus_format = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
|
||||
break;
|
||||
case DW_HDMI_QP_RGB:
|
||||
if (!depth)
|
||||
bus_format = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
else
|
||||
bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
|
||||
break;
|
||||
/*
|
||||
* RK3588/RK3576 hdmi color format setting and dsc mode setting are
|
||||
* the same mask in the same register. If dsc is enabled for hdmi in
|
||||
* uboot, what color is hdmi output in uboot that cannot be obtained
|
||||
* from this register in kernel.
|
||||
* Since hdmi in dsc mode always sends avi infoframe, color format
|
||||
* of hdmi output in uboot can be read from the avi register.
|
||||
*/
|
||||
case DW_HDMI_QP_DSC:
|
||||
bus_format = dw_hdmi_qp_get_avi_color_fmt(hdmi, depth);
|
||||
break;
|
||||
default:
|
||||
dev_err(hdmi->dev, "can't get correct color format\n");
|
||||
bus_format = MEDIA_BUS_FMT_YUV8_1X24;
|
||||
break;
|
||||
}
|
||||
|
||||
return bus_format;
|
||||
}
|
||||
|
||||
static void dw_hdmi_attach_properties(struct dw_hdmi_qp *hdmi)
|
||||
{
|
||||
u32 val;
|
||||
u64 color = MEDIA_BUS_FMT_YUV8_1X24;
|
||||
const struct dw_hdmi_property_ops *ops =
|
||||
hdmi->plat_data->property_ops;
|
||||
void *data = hdmi->plat_data->phy_data;
|
||||
enum drm_connector_status connect_status =
|
||||
hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
|
||||
|
||||
if ((connect_status == connector_status_connected) &&
|
||||
hdmi->initialized) {
|
||||
if (hdmi->plat_data->get_grf_color_fmt)
|
||||
color = hdmi->plat_data->get_grf_color_fmt(data);
|
||||
color = dw_hdmi_qp_get_color_fmt(hdmi);
|
||||
|
||||
val = (hdmi_readl(hdmi, PKT_VSI_CONTENTS1) >> 8) & 0xffffff;
|
||||
if (val == HDMI_FORUM_OUI)
|
||||
@@ -3613,6 +3709,7 @@ static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge,
|
||||
|
||||
cancel_work_sync(&hdmi->flt_work);
|
||||
flush_workqueue(hdmi->workqueue);
|
||||
dw_hdmi_qp_flt_ltsl(hdmi);
|
||||
|
||||
if (hdmi->panel)
|
||||
drm_panel_unprepare(hdmi->panel);
|
||||
|
||||
@@ -2399,45 +2399,6 @@ static void rk3588_get_grf_color_fmt(struct rockchip_hdmi *hdmi, u32 *fmt, u32 *
|
||||
*fmt = *fmt & RK3588_COLOR_FORMAT_MASK;
|
||||
}
|
||||
|
||||
static u64 rockchip_get_grf_color_fmt(void *data)
|
||||
{
|
||||
struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
|
||||
u32 fmt, depth;
|
||||
u64 bus_format;
|
||||
|
||||
hdmi->chip_data->ops->get_grf_color_fmt(hdmi, &fmt, &depth);
|
||||
|
||||
switch (fmt) {
|
||||
case RK3588_YUV444:
|
||||
if (!depth)
|
||||
bus_format = MEDIA_BUS_FMT_YUV8_1X24;
|
||||
else
|
||||
bus_format = MEDIA_BUS_FMT_YUV10_1X30;
|
||||
break;
|
||||
case RK3588_YUV422:
|
||||
bus_format = MEDIA_BUS_FMT_YUYV10_1X20;
|
||||
break;
|
||||
case RK3588_YUV420:
|
||||
if (!depth)
|
||||
bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
|
||||
else
|
||||
bus_format = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
|
||||
break;
|
||||
case RK3588_RGB:
|
||||
if (!depth)
|
||||
bus_format = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
else
|
||||
bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
|
||||
break;
|
||||
default:
|
||||
dev_err(hdmi->dev, "can't get correct color format\n");
|
||||
bus_format = MEDIA_BUS_FMT_YUV8_1X24;
|
||||
break;
|
||||
}
|
||||
|
||||
return bus_format;
|
||||
}
|
||||
|
||||
static void
|
||||
dw_hdmi_rockchip_select_output(struct drm_connector_state *conn_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
@@ -4603,7 +4564,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
||||
plat_data->set_hdcp2_enable = rockchip_set_hdcp2_enable;
|
||||
plat_data->set_hdcp_status = rockchip_set_hdcp_status;
|
||||
plat_data->set_grf_cfg = rockchip_set_grf_cfg;
|
||||
plat_data->get_grf_color_fmt = rockchip_get_grf_color_fmt;
|
||||
plat_data->convert_to_split_mode = drm_mode_convert_to_split_mode;
|
||||
plat_data->convert_to_origin_mode = drm_mode_convert_to_origin_mode;
|
||||
plat_data->dclk_set = dw_hdmi_dclk_set;
|
||||
|
||||
@@ -273,7 +273,6 @@ struct dw_hdmi_plat_data {
|
||||
void (*set_hdcp_status)(void *data, u8 status);
|
||||
void (*set_hdcp2_enable)(void *data, bool enable);
|
||||
void (*set_grf_cfg)(void *data);
|
||||
u64 (*get_grf_color_fmt)(void *data);
|
||||
void (*convert_to_split_mode)(struct drm_display_mode *mode);
|
||||
void (*convert_to_origin_mode)(struct drm_display_mode *mode);
|
||||
int (*dclk_set)(void *data, bool enable, int vp_id);
|
||||
|
||||
Reference in New Issue
Block a user