mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 03:24:19 +02:00
Mediatek DRM Fixes - 20250104
1. Revert "drm/mediatek: dsi: Correct calculation formula of PHY Timing" 2. Set private->all_drm_private[i]->drm to NULL if mtk_drm_bind returns err 3. Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb() 4. Only touch DISP_REG_OVL_PITCH_MSB if AFBC is supported 5. Add support for 180-degree rotation in the display driver 6. Stop selecting foreign drivers 7. Revert "drm/mediatek: Switch to for_each_child_of_node_scoped()" 8. Fix YCbCr422 color format issue for DP 9. Fix mode valid issue for dp 10. dp: Reference common DAI properties 11. dsi: Add registers to pdata to fix MT8186/MT8188 12. Remove unneeded semicolon 13. Add return value check when reading DPCD 14. Initialize pointer in mtk_drm_of_ddp_path_build_one() -----BEGIN PGP SIGNATURE----- iQJMBAABCgA2FiEEACwLKSDmq+9RDv5P4cpzo8lZTiQFAmd5KnMYHGNodW5rdWFu Zy5odUBrZXJuZWwub3JnAAoJEOHKc6PJWU4knsAP/3/WLT3sNSvlrT2t4AwMwrgt jSFV1jtiDpEaPF8+tlg0BdE1CTqkCQOCOZMBKYvsUEifAT7MDBdfIAWBMZbpRRh/ ptvHw1vBEBQpAkmo2hPJfK+J1BDncpqh65A+C1TFiBG5XKv9Zp5QXShBfZsdmqYO zfWKJ4pfUnvUgwM0RQhdRws5S45mbDqGtENiL/8MZXyouOyawqzt6hDSqSglJ+h9 NaWD+607dmAzkMYaGe35gvTsFpxV/8euNWxskbciH/vm33mBm95hsymQOKP7spuq XmKq+mbRa+mZgBGznT+MdyGwHBN0h/yrv1mHUDoi5O5MFQJ4kDuRB/c5bVG1FAoN 4AQLEv6TXhAMZWlf3LOGGVgwEO8mG+7mNF7dXMckMgNCQAZVKfaPIyoFgHn29+6g Dnom/LIOQzP65x0ta5ihCaH//6e7QCsVOWvQnqfn3JUlwtYv2NTjYu6l8+RO+kFS 2/WP4hOpJlqjESiEMoRSpbriYN3dCI64OY4mNB7pr0ea8YtPehE09uzvHSmfDbGe GT+9lWsYblTFTkZXJdthUC39v0grJh4QTKBWNldAaqGsS3hItsuDHOrGlLFJwtSx 9tXlQR27XOJVt0hfRKJMiONW2xXW2sNUnlt3kA7qPmH+zjdeo3vKxlCBYzISKepI kg4CeI6clR9ocZkTPa/0 =bc7g -----END PGP SIGNATURE----- Merge tag 'mediatek-drm-fixes-20250104' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-fixes Mediatek DRM Fixes - 20250104 1. Revert "drm/mediatek: dsi: Correct calculation formula of PHY Timing" 2. Set private->all_drm_private[i]->drm to NULL if mtk_drm_bind returns err 3. Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb() 4. Only touch DISP_REG_OVL_PITCH_MSB if AFBC is supported 5. Add support for 180-degree rotation in the display driver 6. Stop selecting foreign drivers 7. Revert "drm/mediatek: Switch to for_each_child_of_node_scoped()" 8. Fix YCbCr422 color format issue for DP 9. Fix mode valid issue for dp 10. dp: Reference common DAI properties 11. dsi: Add registers to pdata to fix MT8186/MT8188 12. Remove unneeded semicolon 13. Add return value check when reading DPCD 14. Initialize pointer in mtk_drm_of_ddp_path_build_one() Signed-off-by: Dave Airlie <airlied@redhat.com> From: Chun-Kuang Hu <chunkuang.hu@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20250104124227.45505-1-chunkuang.hu@kernel.org
This commit is contained in:
commit
fddb4fd91a
|
|
@ -42,6 +42,9 @@ properties:
|
|||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
|
|
@ -85,7 +88,21 @@ required:
|
|||
- ports
|
||||
- max-linkrate-mhz
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/sound/dai-common.yaml#
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- mediatek,mt8188-dp-tx
|
||||
- mediatek,mt8195-dp-tx
|
||||
then:
|
||||
properties:
|
||||
'#sound-dai-cells': false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ config DRM_MEDIATEK
|
|||
select DRM_BRIDGE_CONNECTOR
|
||||
select DRM_MIPI_DSI
|
||||
select DRM_PANEL
|
||||
select MEMORY
|
||||
select MTK_SMI
|
||||
select PHY_MTK_MIPI_DSI
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
Choose this option if you have a Mediatek SoCs.
|
||||
|
|
@ -27,7 +24,6 @@ config DRM_MEDIATEK
|
|||
config DRM_MEDIATEK_DP
|
||||
tristate "DRM DPTX Support for MediaTek SoCs"
|
||||
depends on DRM_MEDIATEK
|
||||
select PHY_MTK_DP
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
select DRM_DISPLAY_DP_AUX_BUS
|
||||
|
|
@ -38,6 +34,5 @@ config DRM_MEDIATEK_HDMI
|
|||
tristate "DRM HDMI Support for Mediatek SoCs"
|
||||
depends on DRM_MEDIATEK
|
||||
select SND_SOC_HDMI_CODEC if SND_SOC
|
||||
select PHY_MTK_HDMI
|
||||
help
|
||||
DRM/KMS HDMI driver for Mediatek SoCs
|
||||
|
|
|
|||
|
|
@ -112,6 +112,11 @@ static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
|
|||
|
||||
drm_crtc_handle_vblank(&mtk_crtc->base);
|
||||
|
||||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
if (mtk_crtc->cmdq_client.chan)
|
||||
return;
|
||||
#endif
|
||||
|
||||
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
|
||||
if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
|
||||
mtk_crtc_finish_page_flip(mtk_crtc);
|
||||
|
|
@ -284,10 +289,8 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
|
|||
state = to_mtk_crtc_state(mtk_crtc->base.state);
|
||||
|
||||
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
|
||||
if (mtk_crtc->config_updating) {
|
||||
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
|
||||
if (mtk_crtc->config_updating)
|
||||
goto ddp_cmdq_cb_out;
|
||||
}
|
||||
|
||||
state->pending_config = false;
|
||||
|
||||
|
|
@ -315,10 +318,15 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
|
|||
mtk_crtc->pending_async_planes = false;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
|
||||
|
||||
ddp_cmdq_cb_out:
|
||||
|
||||
if (mtk_crtc->pending_needs_vblank) {
|
||||
mtk_crtc_finish_page_flip(mtk_crtc);
|
||||
mtk_crtc->pending_needs_vblank = false;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
|
||||
|
||||
mtk_crtc->cmdq_vblank_cnt = 0;
|
||||
wake_up(&mtk_crtc->cb_blocking_queue);
|
||||
}
|
||||
|
|
@ -606,13 +614,18 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
|
|||
*/
|
||||
mtk_crtc->cmdq_vblank_cnt = 3;
|
||||
|
||||
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
|
||||
mtk_crtc->config_updating = false;
|
||||
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
|
||||
|
||||
mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
|
||||
mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
|
||||
mtk_crtc->config_updating = false;
|
||||
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
|
||||
#endif
|
||||
|
||||
mutex_unlock(&mtk_crtc->hw_lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -460,6 +460,29 @@ static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl,
|
|||
}
|
||||
}
|
||||
|
||||
static void mtk_ovl_afbc_layer_config(struct mtk_disp_ovl *ovl,
|
||||
unsigned int idx,
|
||||
struct mtk_plane_pending_state *pending,
|
||||
struct cmdq_pkt *cmdq_pkt)
|
||||
{
|
||||
unsigned int pitch_msb = pending->pitch >> 16;
|
||||
unsigned int hdr_pitch = pending->hdr_pitch;
|
||||
unsigned int hdr_addr = pending->hdr_addr;
|
||||
|
||||
if (pending->modifier != DRM_FORMAT_MOD_LINEAR) {
|
||||
mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
|
||||
DISP_REG_OVL_HDR_ADDR(ovl, idx));
|
||||
mtk_ddp_write_relaxed(cmdq_pkt,
|
||||
OVL_PITCH_MSB_2ND_SUBBUF | pitch_msb,
|
||||
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
|
||||
mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
|
||||
DISP_REG_OVL_HDR_PITCH(ovl, idx));
|
||||
} else {
|
||||
mtk_ddp_write_relaxed(cmdq_pkt, pitch_msb,
|
||||
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
|
||||
}
|
||||
}
|
||||
|
||||
void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
|
||||
struct mtk_plane_state *state,
|
||||
struct cmdq_pkt *cmdq_pkt)
|
||||
|
|
@ -467,25 +490,14 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
|
|||
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
|
||||
struct mtk_plane_pending_state *pending = &state->pending;
|
||||
unsigned int addr = pending->addr;
|
||||
unsigned int hdr_addr = pending->hdr_addr;
|
||||
unsigned int pitch = pending->pitch;
|
||||
unsigned int hdr_pitch = pending->hdr_pitch;
|
||||
unsigned int pitch_lsb = pending->pitch & GENMASK(15, 0);
|
||||
unsigned int fmt = pending->format;
|
||||
unsigned int rotation = pending->rotation;
|
||||
unsigned int offset = (pending->y << 16) | pending->x;
|
||||
unsigned int src_size = (pending->height << 16) | pending->width;
|
||||
unsigned int blend_mode = state->base.pixel_blend_mode;
|
||||
unsigned int ignore_pixel_alpha = 0;
|
||||
unsigned int con;
|
||||
bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
|
||||
union overlay_pitch {
|
||||
struct split_pitch {
|
||||
u16 lsb;
|
||||
u16 msb;
|
||||
} split_pitch;
|
||||
u32 pitch;
|
||||
} overlay_pitch;
|
||||
|
||||
overlay_pitch.pitch = pitch;
|
||||
|
||||
if (!pending->enable) {
|
||||
mtk_ovl_layer_off(dev, idx, cmdq_pkt);
|
||||
|
|
@ -513,22 +525,30 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
|
|||
ignore_pixel_alpha = OVL_CONST_BLEND;
|
||||
}
|
||||
|
||||
if (pending->rotation & DRM_MODE_REFLECT_Y) {
|
||||
/*
|
||||
* Treat rotate 180 as flip x + flip y, and XOR the original rotation value
|
||||
* to flip x + flip y to support both in the same time.
|
||||
*/
|
||||
if (rotation & DRM_MODE_ROTATE_180)
|
||||
rotation ^= DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
|
||||
|
||||
if (rotation & DRM_MODE_REFLECT_Y) {
|
||||
con |= OVL_CON_VIRT_FLIP;
|
||||
addr += (pending->height - 1) * pending->pitch;
|
||||
}
|
||||
|
||||
if (pending->rotation & DRM_MODE_REFLECT_X) {
|
||||
if (rotation & DRM_MODE_REFLECT_X) {
|
||||
con |= OVL_CON_HORZ_FLIP;
|
||||
addr += pending->pitch - 1;
|
||||
}
|
||||
|
||||
if (ovl->data->supports_afbc)
|
||||
mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc);
|
||||
mtk_ovl_set_afbc(ovl, cmdq_pkt, idx,
|
||||
pending->modifier != DRM_FORMAT_MOD_LINEAR);
|
||||
|
||||
mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
|
||||
DISP_REG_OVL_CON(idx));
|
||||
mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha,
|
||||
mtk_ddp_write_relaxed(cmdq_pkt, pitch_lsb | ignore_pixel_alpha,
|
||||
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));
|
||||
mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
|
||||
DISP_REG_OVL_SRC_SIZE(idx));
|
||||
|
|
@ -537,19 +557,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
|
|||
mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
|
||||
DISP_REG_OVL_ADDR(ovl, idx));
|
||||
|
||||
if (is_afbc) {
|
||||
mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
|
||||
DISP_REG_OVL_HDR_ADDR(ovl, idx));
|
||||
mtk_ddp_write_relaxed(cmdq_pkt,
|
||||
OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb,
|
||||
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
|
||||
mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
|
||||
DISP_REG_OVL_HDR_PITCH(ovl, idx));
|
||||
} else {
|
||||
mtk_ddp_write_relaxed(cmdq_pkt,
|
||||
overlay_pitch.split_pitch.msb,
|
||||
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
|
||||
}
|
||||
if (ovl->data->supports_afbc)
|
||||
mtk_ovl_afbc_layer_config(ovl, idx, pending, cmdq_pkt);
|
||||
|
||||
mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
|
||||
mtk_ovl_layer_on(dev, idx, cmdq_pkt);
|
||||
|
|
|
|||
|
|
@ -543,18 +543,16 @@ static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
|
|||
enum dp_pixelformat color_format)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* update MISC0 */
|
||||
mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
|
||||
color_format << DP_TEST_COLOR_FORMAT_SHIFT,
|
||||
DP_TEST_COLOR_FORMAT_MASK);
|
||||
u32 misc0_color;
|
||||
|
||||
switch (color_format) {
|
||||
case DP_PIXELFORMAT_YUV422:
|
||||
val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422;
|
||||
misc0_color = DP_COLOR_FORMAT_YCbCr422;
|
||||
break;
|
||||
case DP_PIXELFORMAT_RGB:
|
||||
val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
|
||||
misc0_color = DP_COLOR_FORMAT_RGB;
|
||||
break;
|
||||
default:
|
||||
drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
|
||||
|
|
@ -562,6 +560,11 @@ static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* update MISC0 */
|
||||
mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
|
||||
misc0_color,
|
||||
DP_TEST_COLOR_FORMAT_MASK);
|
||||
|
||||
mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
|
||||
val, PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK);
|
||||
return 0;
|
||||
|
|
@ -2100,7 +2103,6 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
|
|||
struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
|
||||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
bool enabled = mtk_dp->enabled;
|
||||
u8 sink_count = 0;
|
||||
|
||||
if (!mtk_dp->train_info.cable_plugged_in)
|
||||
return ret;
|
||||
|
|
@ -2115,8 +2117,8 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
|
|||
* function, we just need to check the HPD connection to check
|
||||
* whether we connect to a sink device.
|
||||
*/
|
||||
drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
|
||||
if (DP_GET_SINK_COUNT(sink_count))
|
||||
|
||||
if (drm_dp_read_sink_count(&mtk_dp->aux) > 0)
|
||||
ret = connector_status_connected;
|
||||
|
||||
if (!enabled)
|
||||
|
|
@ -2408,12 +2410,19 @@ mtk_dp_bridge_mode_valid(struct drm_bridge *bridge,
|
|||
{
|
||||
struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
|
||||
u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24;
|
||||
u32 rate = min_t(u32, drm_dp_max_link_rate(mtk_dp->rx_cap) *
|
||||
drm_dp_max_lane_count(mtk_dp->rx_cap),
|
||||
drm_dp_bw_code_to_link_rate(mtk_dp->max_linkrate) *
|
||||
mtk_dp->max_lanes);
|
||||
u32 lane_count_min = mtk_dp->train_info.lane_count;
|
||||
u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) *
|
||||
lane_count_min;
|
||||
|
||||
if (rate < mode->clock * bpp / 8)
|
||||
/*
|
||||
*FEC overhead is approximately 2.4% from DP 1.4a spec 2.2.1.4.2.
|
||||
*The down-spread amplitude shall either be disabled (0.0%) or up
|
||||
*to 0.5% from 1.4a 3.5.2.6. Add up to approximately 3% total overhead.
|
||||
*
|
||||
*Because rate is already divided by 10,
|
||||
*mode->clock does not need to be multiplied by 10
|
||||
*/
|
||||
if ((rate * 97 / 100) < (mode->clock * bpp / 8))
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
return MODE_OK;
|
||||
|
|
@ -2454,10 +2463,9 @@ static u32 *mtk_dp_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
|
|||
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
|
||||
struct drm_display_info *display_info =
|
||||
&conn_state->connector->display_info;
|
||||
u32 rate = min_t(u32, drm_dp_max_link_rate(mtk_dp->rx_cap) *
|
||||
drm_dp_max_lane_count(mtk_dp->rx_cap),
|
||||
drm_dp_bw_code_to_link_rate(mtk_dp->max_linkrate) *
|
||||
mtk_dp->max_lanes);
|
||||
u32 lane_count_min = mtk_dp->train_info.lane_count;
|
||||
u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) *
|
||||
lane_count_min;
|
||||
|
||||
*num_input_fmts = 0;
|
||||
|
||||
|
|
@ -2466,8 +2474,8 @@ static u32 *mtk_dp_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
|
|||
* datarate of YUV422 and sink device supports YUV422, we output YUV422
|
||||
* format. Use this condition, we can support more resolution.
|
||||
*/
|
||||
if ((rate < (mode->clock * 24 / 8)) &&
|
||||
(rate > (mode->clock * 16 / 8)) &&
|
||||
if (((rate * 97 / 100) < (mode->clock * 24 / 8)) &&
|
||||
((rate * 97 / 100) > (mode->clock * 16 / 8)) &&
|
||||
(display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
|
||||
input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
|
||||
if (!input_fmts)
|
||||
|
|
|
|||
|
|
@ -373,11 +373,12 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
|
|||
struct mtk_drm_private *temp_drm_priv;
|
||||
struct device_node *phandle = dev->parent->of_node;
|
||||
const struct of_device_id *of_id;
|
||||
struct device_node *node;
|
||||
struct device *drm_dev;
|
||||
unsigned int cnt = 0;
|
||||
int i, j;
|
||||
|
||||
for_each_child_of_node_scoped(phandle->parent, node) {
|
||||
for_each_child_of_node(phandle->parent, node) {
|
||||
struct platform_device *pdev;
|
||||
|
||||
of_id = of_match_node(mtk_drm_of_ids, node);
|
||||
|
|
@ -406,8 +407,10 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
|
|||
if (temp_drm_priv->mtk_drm_bound)
|
||||
cnt++;
|
||||
|
||||
if (cnt == MAX_CRTC)
|
||||
if (cnt == MAX_CRTC) {
|
||||
of_node_put(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (drm_priv->data->mmsys_dev_num == cnt) {
|
||||
|
|
@ -673,6 +676,8 @@ static int mtk_drm_bind(struct device *dev)
|
|||
err_free:
|
||||
private->drm = NULL;
|
||||
drm_dev_put(drm);
|
||||
for (i = 0; i < private->data->mmsys_dev_num; i++)
|
||||
private->all_drm_private[i]->drm = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -900,7 +905,7 @@ static int mtk_drm_of_ddp_path_build_one(struct device *dev, enum mtk_crtc_path
|
|||
const unsigned int **out_path,
|
||||
unsigned int *out_path_len)
|
||||
{
|
||||
struct device_node *next, *prev, *vdo = dev->parent->of_node;
|
||||
struct device_node *next = NULL, *prev, *vdo = dev->parent->of_node;
|
||||
unsigned int temp_path[DDP_COMPONENT_DRM_ID_MAX] = { 0 };
|
||||
unsigned int *final_ddp_path;
|
||||
unsigned short int idx = 0;
|
||||
|
|
@ -1089,7 +1094,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
|||
/* No devicetree graphs support: go with hardcoded paths if present */
|
||||
dev_dbg(dev, "Using hardcoded paths for MMSYS %u\n", mtk_drm_data->mmsys_id);
|
||||
private->data = mtk_drm_data;
|
||||
};
|
||||
}
|
||||
|
||||
private->all_drm_private = devm_kmalloc_array(dev, private->data->mmsys_dev_num,
|
||||
sizeof(*private->all_drm_private),
|
||||
|
|
|
|||
|
|
@ -139,11 +139,11 @@
|
|||
#define CLK_HS_POST GENMASK(15, 8)
|
||||
#define CLK_HS_EXIT GENMASK(23, 16)
|
||||
|
||||
#define DSI_VM_CMD_CON 0x130
|
||||
/* DSI_VM_CMD_CON */
|
||||
#define VM_CMD_EN BIT(0)
|
||||
#define TS_VFP_EN BIT(5)
|
||||
|
||||
#define DSI_SHADOW_DEBUG 0x190U
|
||||
/* DSI_SHADOW_DEBUG */
|
||||
#define FORCE_COMMIT BIT(0)
|
||||
#define BYPASS_SHADOW BIT(1)
|
||||
|
||||
|
|
@ -187,6 +187,8 @@ struct phy;
|
|||
|
||||
struct mtk_dsi_driver_data {
|
||||
const u32 reg_cmdq_off;
|
||||
const u32 reg_vm_cmd_off;
|
||||
const u32 reg_shadow_dbg_off;
|
||||
bool has_shadow_ctl;
|
||||
bool has_size_ctl;
|
||||
bool cmdq_long_packet_ctl;
|
||||
|
|
@ -246,23 +248,22 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
|
|||
u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, HZ_PER_MHZ);
|
||||
struct mtk_phy_timing *timing = &dsi->phy_timing;
|
||||
|
||||
timing->lpx = (80 * data_rate_mhz / (8 * 1000)) + 1;
|
||||
timing->da_hs_prepare = (59 * data_rate_mhz + 4 * 1000) / 8000 + 1;
|
||||
timing->da_hs_zero = (163 * data_rate_mhz + 11 * 1000) / 8000 + 1 -
|
||||
timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1;
|
||||
timing->da_hs_prepare = (80 * data_rate_mhz + 4 * 1000) / 8000;
|
||||
timing->da_hs_zero = (170 * data_rate_mhz + 10 * 1000) / 8000 + 1 -
|
||||
timing->da_hs_prepare;
|
||||
timing->da_hs_trail = (78 * data_rate_mhz + 7 * 1000) / 8000 + 1;
|
||||
timing->da_hs_trail = timing->da_hs_prepare + 1;
|
||||
|
||||
timing->ta_go = 4 * timing->lpx;
|
||||
timing->ta_sure = 3 * timing->lpx / 2;
|
||||
timing->ta_get = 5 * timing->lpx;
|
||||
timing->da_hs_exit = (118 * data_rate_mhz / (8 * 1000)) + 1;
|
||||
timing->ta_go = 4 * timing->lpx - 2;
|
||||
timing->ta_sure = timing->lpx + 2;
|
||||
timing->ta_get = 4 * timing->lpx;
|
||||
timing->da_hs_exit = 2 * timing->lpx + 1;
|
||||
|
||||
timing->clk_hs_prepare = (57 * data_rate_mhz / (8 * 1000)) + 1;
|
||||
timing->clk_hs_post = (65 * data_rate_mhz + 53 * 1000) / 8000 + 1;
|
||||
timing->clk_hs_trail = (78 * data_rate_mhz + 7 * 1000) / 8000 + 1;
|
||||
timing->clk_hs_zero = (330 * data_rate_mhz / (8 * 1000)) + 1 -
|
||||
timing->clk_hs_prepare;
|
||||
timing->clk_hs_exit = (118 * data_rate_mhz / (8 * 1000)) + 1;
|
||||
timing->clk_hs_prepare = 70 * data_rate_mhz / (8 * 1000);
|
||||
timing->clk_hs_post = timing->clk_hs_prepare + 8;
|
||||
timing->clk_hs_trail = timing->clk_hs_prepare;
|
||||
timing->clk_hs_zero = timing->clk_hs_trail * 4;
|
||||
timing->clk_hs_exit = 2 * timing->clk_hs_trail;
|
||||
|
||||
timcon0 = FIELD_PREP(LPX, timing->lpx) |
|
||||
FIELD_PREP(HS_PREP, timing->da_hs_prepare) |
|
||||
|
|
@ -367,8 +368,8 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
|
|||
|
||||
static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
|
||||
{
|
||||
mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
|
||||
mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
|
||||
mtk_dsi_mask(dsi, dsi->driver_data->reg_vm_cmd_off, VM_CMD_EN, VM_CMD_EN);
|
||||
mtk_dsi_mask(dsi, dsi->driver_data->reg_vm_cmd_off, TS_VFP_EN, TS_VFP_EN);
|
||||
}
|
||||
|
||||
static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
|
||||
|
|
@ -714,7 +715,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
|
|||
|
||||
if (dsi->driver_data->has_shadow_ctl)
|
||||
writel(FORCE_COMMIT | BYPASS_SHADOW,
|
||||
dsi->regs + DSI_SHADOW_DEBUG);
|
||||
dsi->regs + dsi->driver_data->reg_shadow_dbg_off);
|
||||
|
||||
mtk_dsi_reset_engine(dsi);
|
||||
mtk_dsi_phy_timconfig(dsi);
|
||||
|
|
@ -1263,26 +1264,36 @@ static void mtk_dsi_remove(struct platform_device *pdev)
|
|||
|
||||
static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = {
|
||||
.reg_cmdq_off = 0x200,
|
||||
.reg_vm_cmd_off = 0x130,
|
||||
.reg_shadow_dbg_off = 0x190
|
||||
};
|
||||
|
||||
static const struct mtk_dsi_driver_data mt2701_dsi_driver_data = {
|
||||
.reg_cmdq_off = 0x180,
|
||||
.reg_vm_cmd_off = 0x130,
|
||||
.reg_shadow_dbg_off = 0x190
|
||||
};
|
||||
|
||||
static const struct mtk_dsi_driver_data mt8183_dsi_driver_data = {
|
||||
.reg_cmdq_off = 0x200,
|
||||
.reg_vm_cmd_off = 0x130,
|
||||
.reg_shadow_dbg_off = 0x190,
|
||||
.has_shadow_ctl = true,
|
||||
.has_size_ctl = true,
|
||||
};
|
||||
|
||||
static const struct mtk_dsi_driver_data mt8186_dsi_driver_data = {
|
||||
.reg_cmdq_off = 0xd00,
|
||||
.reg_vm_cmd_off = 0x200,
|
||||
.reg_shadow_dbg_off = 0xc00,
|
||||
.has_shadow_ctl = true,
|
||||
.has_size_ctl = true,
|
||||
};
|
||||
|
||||
static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
|
||||
.reg_cmdq_off = 0xd00,
|
||||
.reg_vm_cmd_off = 0x200,
|
||||
.reg_shadow_dbg_off = 0xc00,
|
||||
.has_shadow_ctl = true,
|
||||
.has_size_ctl = true,
|
||||
.cmdq_long_packet_ctl = true,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user