Commit d62dec8c authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'mediatek-drm-next-20260117' of...

Merge tag 'mediatek-drm-next-20260117' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux

 into drm-next

Mediatek DRM Next - 20260117

1. mtk_hdmi_v2: Remove unneeded semicolon
2. Move DP training to hotplug thread
3. Convert legacy DRM logging to drm_* helpers in mtk_crtc.c
4. mtk_dsi: Add support for High Speed (HS) mode
5. Add HDMI support for Mediatek Genio 510/700/1200-EVK and Radxa NIO-12L boards

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Link: https://patch.msgid.link/20260117005152.3770-1-chunkuang.hu@kernel.org
parents 95adee9a 79643afd
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -26,6 +26,10 @@ properties:
          - enum:
              - mediatek,mt7623-hdmi-phy
          - const: mediatek,mt2701-hdmi-phy
      - items:
          - enum:
              - mediatek,mt8188-hdmi-phy
          - const: mediatek,mt8195-hdmi-phy
      - const: mediatek,mt2701-hdmi-phy
      - const: mediatek,mt8173-hdmi-phy
      - const: mediatek,mt8195-hdmi-phy
@@ -34,16 +38,23 @@ properties:
    maxItems: 1

  clocks:
    minItems: 1
    items:
      - description: PLL reference clock
      - description: HDMI 26MHz clock
      - description: HDMI PLL1 clock
      - description: HDMI PLL2 clock

  clock-names:
    minItems: 1
    items:
      - const: pll_ref
      - const: 26m
      - const: pll1
      - const: pll2

  clock-output-names:
    items:
      - const: hdmitx_dig_cts
    maxItems: 1

  "#phy-cells":
    const: 0
@@ -76,6 +87,20 @@ required:
  - "#phy-cells"
  - "#clock-cells"

allOf:
  - if:
      not:
        properties:
          compatible:
            contains:
              const: mediatek,mt8195-hdmi-phy
    then:
      properties:
        clocks:
          maxItems: 1
        clock-names:
          maxItems: 1

additionalProperties: false

examples:
+15 −9
Original line number Diff line number Diff line
@@ -225,13 +225,14 @@ static void mtk_crtc_mode_set_nofb(struct drm_crtc *crtc)

static int mtk_crtc_ddp_clk_enable(struct mtk_crtc *mtk_crtc)
{
	struct drm_device *dev = mtk_crtc->base.dev;
	int ret;
	int i;

	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
		ret = mtk_ddp_comp_clk_enable(mtk_crtc->ddp_comp[i]);
		if (ret) {
			DRM_ERROR("Failed to enable clock %d: %d\n", i, ret);
			drm_err(dev, "Failed to enable clock %d: %d\n", i, ret);
			goto err;
		}
	}
@@ -343,6 +344,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)
	struct drm_connector *connector;
	struct drm_encoder *encoder;
	struct drm_connector_list_iter conn_iter;
	struct drm_device *dev = mtk_crtc->base.dev;
	unsigned int width, height, vrefresh, bpc = MTK_MAX_BPC;
	int ret;
	int i;
@@ -371,19 +373,19 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)

	ret = pm_runtime_resume_and_get(crtc->dev->dev);
	if (ret < 0) {
		DRM_ERROR("Failed to enable power domain: %d\n", ret);
		drm_err(dev, "Failed to enable power domain: %d\n", ret);
		return ret;
	}

	ret = mtk_mutex_prepare(mtk_crtc->mutex);
	if (ret < 0) {
		DRM_ERROR("Failed to enable mutex clock: %d\n", ret);
		drm_err(dev, "Failed to enable mutex clock: %d\n", ret);
		goto err_pm_runtime_put;
	}

	ret = mtk_crtc_ddp_clk_enable(mtk_crtc);
	if (ret < 0) {
		DRM_ERROR("Failed to enable component clocks: %d\n", ret);
		drm_err(dev, "Failed to enable component clocks: %d\n", ret);
		goto err_mutex_unprepare;
	}

@@ -648,10 +650,11 @@ static void mtk_crtc_ddp_irq(void *data)
	struct mtk_drm_private *priv = crtc->dev->dev_private;

#if IS_REACHABLE(CONFIG_MTK_CMDQ)
	struct drm_device *dev = mtk_crtc->base.dev;
	if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
		mtk_crtc_ddp_config(crtc, NULL);
	else if (mtk_crtc->cmdq_vblank_cnt > 0 && --mtk_crtc->cmdq_vblank_cnt == 0)
		DRM_ERROR("mtk_crtc %d CMDQ execute command timeout!\n",
		drm_err(dev, "mtk_crtc %d CMDQ execute command timeout!\n",
			drm_crtc_index(&mtk_crtc->base));
#else
	if (!priv->data->shadow_register)
@@ -776,9 +779,10 @@ static void mtk_crtc_atomic_enable(struct drm_crtc *crtc,
{
	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
	struct drm_device *dev = mtk_crtc->base.dev;
	int ret;

	DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
	drm_dbg_driver(dev, "%s %d\n", __func__, crtc->base.id);

	ret = mtk_ddp_comp_power_on(comp);
	if (ret < 0) {
@@ -803,9 +807,10 @@ static void mtk_crtc_atomic_disable(struct drm_crtc *crtc,
{
	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
	struct drm_device *dev = mtk_crtc->base.dev;
	int i;

	DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
	drm_dbg_driver(dev, "%s %d\n", __func__, crtc->base.id);
	if (!mtk_crtc->enabled)
		return;

@@ -845,10 +850,11 @@ static void mtk_crtc_atomic_begin(struct drm_crtc *crtc,
									  crtc);
	struct mtk_crtc_state *mtk_crtc_state = to_mtk_crtc_state(crtc_state);
	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
	struct drm_device *dev = mtk_crtc->base.dev;
	unsigned long flags;

	if (mtk_crtc->event && mtk_crtc_state->base.event)
		DRM_ERROR("new event while there is still a pending event\n");
		drm_err(dev, "new event while there is still a pending event\n");

	if (mtk_crtc_state->base.event) {
		mtk_crtc_state->base.event->pipe = drm_crtc_index(crtc);
+38 −19
Original line number Diff line number Diff line
@@ -1976,6 +1976,7 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
	struct mtk_dp *mtk_dp = dev;
	unsigned long flags;
	u32 status;
	int ret;

	if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in)
		msleep(100);
@@ -1994,9 +1995,28 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
			memset(&mtk_dp->info.audio_cur_cfg, 0,
			       sizeof(mtk_dp->info.audio_cur_cfg));

			mtk_dp->enabled = false;
			/* power off aux */
			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
					   DP_PWR_STATE_BANDGAP_TPLL,
					   DP_PWR_STATE_MASK);

			mtk_dp->need_debounce = false;
			mod_timer(&mtk_dp->debounce_timer,
				  jiffies + msecs_to_jiffies(100) - 1);
		} else {
			mtk_dp_aux_panel_poweron(mtk_dp, true);

			ret = mtk_dp_parse_capabilities(mtk_dp);
			if (ret)
				drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n");

			/* Training */
			ret = mtk_dp_training(mtk_dp);
			if (ret)
				drm_err(mtk_dp->drm_dev, "Training failed, %d\n", ret);

			mtk_dp->enabled = true;
		}
	}

@@ -2168,7 +2188,8 @@ static const struct drm_edid *mtk_dp_edid_read(struct drm_bridge *bridge,
	 * Parse capability here to let atomic_get_input_bus_fmts and
	 * mode_valid use the capability to calculate sink bitrates.
	 */
	if (mtk_dp_parse_capabilities(mtk_dp)) {
	if (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP &&
	    mtk_dp_parse_capabilities(mtk_dp)) {
		drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n");
		drm_edid_free(drm_edid);
		drm_edid = NULL;
@@ -2366,6 +2387,7 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
		return;
	}

	if (mtk_dp->data->bridge_type == DRM_MODE_CONNECTOR_eDP) {
		mtk_dp_aux_panel_poweron(mtk_dp, true);

		/* Training */
@@ -2374,6 +2396,7 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
			drm_err(mtk_dp->drm_dev, "Training failed, %d\n", ret);
			goto power_off_aux;
		}
	}

	ret = mtk_dp_video_config(mtk_dp);
	if (ret)
@@ -2392,7 +2415,9 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
		       sizeof(mtk_dp->info.audio_cur_cfg));
	}

	if (mtk_dp->data->bridge_type == DRM_MODE_CONNECTOR_eDP)
		mtk_dp->enabled = true;

	mtk_dp_update_plugged_status(mtk_dp);

	return;
@@ -2407,21 +2432,15 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
{
	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);

	if (mtk_dp->data->bridge_type == DRM_MODE_CONNECTOR_eDP) {
		mtk_dp->enabled = false;
		mtk_dp_aux_panel_poweron(mtk_dp, false);
	}

	mtk_dp_update_plugged_status(mtk_dp);
	mtk_dp_video_enable(mtk_dp, false);
	mtk_dp_audio_mute(mtk_dp, true);

	if (mtk_dp->train_info.cable_plugged_in) {
		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
		usleep_range(2000, 3000);
	}

	/* power off aux */
	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
			   DP_PWR_STATE_BANDGAP_TPLL,
			   DP_PWR_STATE_MASK);

	/* SDP path reset sw*/
	mtk_dp_sdp_path_reset(mtk_dp);

+4 −0
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@
#define SHORT_PACKET			0
#define LONG_PACKET			2
#define BTA				BIT(2)
#define HSTX				BIT(3)
#define DATA_ID				GENMASK(15, 8)
#define DATA_0				GENMASK(23, 16)
#define DATA_1				GENMASK(31, 24)
@@ -1080,6 +1081,9 @@ static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg *msg)
	else
		config = (msg->tx_len > 2) ? LONG_PACKET : SHORT_PACKET;

	if (!(msg->flags & MIPI_DSI_MSG_USE_LPM))
		config |= HSTX;

	if (msg->tx_len > 2) {
		cmdq_size = 1 + (msg->tx_len + 3) / 4;
		cmdq_off = 4;
+3 −3
Original line number Diff line number Diff line
@@ -746,7 +746,7 @@ static void mtk_hdmi_v2_change_video_resolution(struct mtk_hdmi *hdmi,
	case HDMI_COLORSPACE_YUV420:
		mtk_hdmi_yuv420_downsampling(hdmi, true);
		break;
	};
	}
}

static void mtk_hdmi_v2_output_set_display_mode(struct mtk_hdmi *hdmi,
@@ -1157,7 +1157,7 @@ static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge,
	case HDMI_INFOFRAME_TYPE_DRM:
	default:
		break;
	};
	}

	return 0;
}
@@ -1185,7 +1185,7 @@ static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge,
	default:
		dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type);
		break;
	};
	}

	return 0;
}