Commit d076e2bd authored by Simona Vetter's avatar Simona Vetter
Browse files

Merge tag 'drm-misc-next-2024-07-04' of...

Merge tag 'drm-misc-next-2024-07-04' of https://gitlab.freedesktop.org/drm/misc/kernel

 into drm-next

drm-misc-next for $kernel-version:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:
  - dp/mst: Fix daisy-chaining at resume
  - dsc: Add helper to dump the DSC configuration
  - tests: Add tests for the new monochrome TV mode variant

Driver Changes:
  - ast: Refactor the mode setting code
  - panfrost: Fix devfreq job reporting
  - stm: Add LDVS support, DSI PHY updates
  - panels:
    - New panel: AUO G104STN01, K&d kd101ne3-40ti,

Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240704-curvy-outstanding-lizard-bcea78@houat
parents bfc10936 896868ed
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ properties:
    items:
      - enum:
          - chongzhou,cz101b4001
          - kingdisplay,kd101ne3-40ti
          - radxa,display-10hd-ad001
          - radxa,display-8hd-ad002
      - const: jadard,jd9365da-h3
+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ properties:
      - auo,g101evn010
        # AU Optronics Corporation 10.4" (800x600) color TFT LCD panel
      - auo,g104sn02
        # AU Optronics Corporation 10.4" (800x600) color TFT LCD panel
      - auo,g104stn01
        # AU Optronics Corporation 12.1" (1280x800) TFT LCD panel
      - auo,g121ean01
        # AU Optronics Corporation 15.6" (1366x768) TFT LCD panel
+119 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/st,stm32mp25-lvds.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: STMicroelectronics STM32 LVDS Display Interface Transmitter

maintainers:
  - Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com>
  - Yannick Fertre <yannick.fertre@foss.st.com>

description: |
  The STMicroelectronics STM32 LVDS Display Interface Transmitter handles the
  LVDS protocol: it maps the pixels received from the upstream Pixel-DMA (LTDC)
  onto the LVDS PHY.

  It is composed of three sub blocks:
    - LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps its input
      pixels onto the data lanes of the PHY
    - LVDS PHY: parallelize the data and drives the LVDS data lanes
    - LVDS wrapper: handles top-level settings

  The LVDS controller driver supports the following high-level features:
    - FDP-Link-I and OpenLDI (v0.95) protocols
    - Single-Link or Dual-Link operation
    - Single-Display or Double-Display (with the same content duplicated on both)
    - Flexible Bit-Mapping, including JEIDA and VESA
    - RGB888 or RGB666 output
    - Synchronous design, with one input pixel per clock cycle

properties:
  compatible:
    const: st,stm32mp25-lvds

  "#clock-cells":
    const: 0
    description:
      Provides the internal LVDS PHY clock to the framework.

  reg:
    maxItems: 1

  clocks:
    items:
      - description: APB peripheral clock
      - description: Reference clock for the internal PLL

  clock-names:
    items:
      - const: pclk
      - const: ref

  resets:
    maxItems: 1

  ports:
    $ref: /schemas/graph.yaml#/properties/ports

    properties:
      port@0:
        $ref: /schemas/graph.yaml#/properties/port
        description:
          LVDS input port node, connected to the LTDC RGB output port.

      port@1:
        $ref: /schemas/graph.yaml#/properties/port
        description:
          LVDS output port node, connected to a panel or bridge input port.

    required:
      - port@0
      - port@1

required:
  - compatible
  - "#clock-cells"
  - reg
  - clocks
  - clock-names
  - resets
  - ports

additionalProperties: false

examples:
  - |
    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
    #include <dt-bindings/reset/st,stm32mp25-rcc.h>

    lvds: lvds@48060000 {
        compatible = "st,stm32mp25-lvds";
        reg = <0x48060000 0x2000>;
        #clock-cells = <0>;
        clocks = <&rcc CK_BUS_LVDS>, <&rcc CK_KER_LVDSPHY>;
        clock-names = "pclk", "ref";
        resets = <&rcc LVDS_R>;

        ports {
            #address-cells = <1>;
            #size-cells = <0>;

            port@0 {
                reg = <0>;
                lvds_in: endpoint {
                   remote-endpoint = <&ltdc_ep1_out>;
                };
            };

            port@1 {
                reg = <1>;
                lvds_out0: endpoint {
                   remote-endpoint = <&lvds_panel_in>;
                };
            };
        };
    };

...
+1 −0
Original line number Diff line number Diff line
@@ -7484,6 +7484,7 @@ L: dri-devel@lists.freedesktop.org
S:	Maintained
T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
F:	Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml
F:	Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
F:	drivers/gpu/drm/stm
DRM DRIVERS FOR TI KEYSTONE
+109 −95
Original line number Diff line number Diff line
@@ -303,7 +303,7 @@ static void ast_set_std_reg(struct ast_device *ast,

	/* Set SEQ; except Screen Disable field */
	ast_set_index_reg(ast, AST_IO_VGASRI, 0x00, 0x03);
	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, stdtable->seq[0]);
	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0x20, stdtable->seq[0]);
	for (i = 1; i < 4; i++) {
		jreg = stdtable->seq[i];
		ast_set_index_reg(ast, AST_IO_VGASRI, (i + 1), jreg);
@@ -649,12 +649,12 @@ static void ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
	struct drm_framebuffer *old_fb = old_plane_state->fb;
	struct ast_plane *ast_plane = to_ast_plane(plane);
	struct drm_crtc *crtc = plane_state->crtc;
	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
	struct drm_rect damage;
	struct drm_atomic_helper_damage_iter iter;

	if (!old_fb || (fb->format != old_fb->format)) {
		struct drm_crtc *crtc = plane_state->crtc;
		struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
	if (!old_fb || (fb->format != old_fb->format) || crtc_state->mode_changed) {
		struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
		struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;

@@ -690,15 +690,15 @@ static void ast_primary_plane_helper_atomic_enable(struct drm_plane *plane,
	 * Therefore only reprogram the address after enabling the plane.
	 */
	ast_set_start_address_crt1(ast, (u32)ast_plane->offset);
	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x00);
}

static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
						    struct drm_atomic_state *state)
{
	struct ast_device *ast = to_ast_device(plane->dev);

	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x20);
	/*
	 * Keep this empty function to avoid calling
	 * atomic_update when disabling the plane.
	 */
}

static int ast_primary_plane_helper_get_scanout_buffer(struct drm_plane *plane,
@@ -1019,62 +1019,6 @@ static int ast_cursor_plane_init(struct ast_device *ast)
 * CRTC
 */

static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
{
	struct ast_device *ast = to_ast_device(crtc->dev);
	u8 ch = AST_DPMS_VSYNC_OFF | AST_DPMS_HSYNC_OFF;
	struct ast_crtc_state *ast_state;
	const struct drm_format_info *format;
	struct ast_vbios_mode_info *vbios_mode_info;

	/* TODO: Maybe control display signal generation with
	 *       Sync Enable (bit CR17.7).
	 */
	switch (mode) {
	case DRM_MODE_DPMS_ON:
		ast_set_index_reg_mask(ast, AST_IO_VGASRI,  0x01, 0xdf, 0);
		ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0);
		if (ast->tx_chip_types & AST_TX_DP501_BIT)
			ast_set_dp501_video_output(crtc->dev, 1);

		if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
			ast_dp_power_on_off(crtc->dev, AST_DP_POWER_ON);
			ast_wait_for_vretrace(ast);
			ast_dp_set_on_off(crtc->dev, 1);
		}

		ast_state = to_ast_crtc_state(crtc->state);
		format = ast_state->format;

		if (format) {
			vbios_mode_info = &ast_state->vbios_mode_info;

			ast_set_color_reg(ast, format);
			ast_set_vbios_color_reg(ast, format, vbios_mode_info);
			if (crtc->state->gamma_lut)
				ast_crtc_set_gamma(ast, format, crtc->state->gamma_lut->data);
			else
				ast_crtc_set_gamma_linear(ast, format);
		}
		break;
	case DRM_MODE_DPMS_STANDBY:
	case DRM_MODE_DPMS_SUSPEND:
	case DRM_MODE_DPMS_OFF:
		ch = mode;
		if (ast->tx_chip_types & AST_TX_DP501_BIT)
			ast_set_dp501_video_output(crtc->dev, 0);

		if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
			ast_dp_set_on_off(crtc->dev, 0);
			ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF);
		}

		ast_set_index_reg_mask(ast, AST_IO_VGASRI,  0x01, 0xdf, 0x20);
		ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, ch);
		break;
	}
}

static enum drm_mode_status
ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
{
@@ -1147,6 +1091,33 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode
	return status;
}

static void ast_crtc_helper_mode_set_nofb(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct ast_device *ast = to_ast_device(dev);
	struct drm_crtc_state *crtc_state = crtc->state;
	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
	struct ast_vbios_mode_info *vbios_mode_info =
		&ast_crtc_state->vbios_mode_info;
	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;

	/*
	 * Ensure that no scanout takes place before reprogramming mode
	 * and format registers.
	 *
	 * TODO: Get vblank interrupts working and remove this line.
	 */
	ast_wait_for_vretrace(ast);

	ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
	ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
	ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
	ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
	ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
	ast_set_crtthd_reg(ast);
	ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
}

static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
					struct drm_atomic_state *state)
{
@@ -1206,7 +1177,6 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
	struct drm_device *dev = crtc->dev;
	struct ast_device *ast = to_ast_device(dev);
	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
	struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;

	/*
	 * The gamma LUT has to be reloaded after changing the primary
@@ -1220,40 +1190,27 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
		else
			ast_crtc_set_gamma_linear(ast, ast_crtc_state->format);
	}

	//Set Aspeed Display-Port
	if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
		ast_dp_set_mode(crtc, vbios_mode_info);
}

static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
{
	struct drm_device *dev = crtc->dev;
	struct ast_device *ast = to_ast_device(dev);
	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
	struct ast_vbios_mode_info *vbios_mode_info =
		&ast_crtc_state->vbios_mode_info;
	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;

	ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
	ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
	ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
	ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
	ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
	ast_set_crtthd_reg(ast);
	ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
	struct ast_device *ast = to_ast_device(crtc->dev);

	ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0x00);
	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x00);
}

static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
{
	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
	struct drm_device *dev = crtc->dev;
	struct ast_device *ast = to_ast_device(dev);
	struct ast_device *ast = to_ast_device(crtc->dev);
	u8 vgacrb6;

	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, AST_IO_VGASR1_SD);

	ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
	vgacrb6 = AST_IO_VGACRB6_VSYNC_OFF |
		  AST_IO_VGACRB6_HSYNC_OFF;
	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, vgacrb6);

	/*
	 * HW cursors require the underlying primary plane and CRTC to
@@ -1266,16 +1223,11 @@ static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_ato
	 * simple pageflips on the planes.
	 */
	drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);

	/*
	 * Ensure that no scanout takes place before reprogramming mode
	 * and format registers.
	 */
	ast_wait_for_vretrace(ast);
}

static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
	.mode_valid = ast_crtc_helper_mode_valid,
	.mode_set_nofb = ast_crtc_helper_mode_set_nofb,
	.atomic_check = ast_crtc_helper_atomic_check,
	.atomic_flush = ast_crtc_helper_atomic_flush,
	.atomic_enable = ast_crtc_helper_atomic_enable,
@@ -1521,6 +1473,27 @@ static const struct drm_encoder_funcs ast_dp501_encoder_funcs = {
	.destroy = drm_encoder_cleanup,
};

static void ast_dp501_encoder_helper_atomic_enable(struct drm_encoder *encoder,
						   struct drm_atomic_state *state)
{
	struct drm_device *dev = encoder->dev;

	ast_set_dp501_video_output(dev, 1);
}

static void ast_dp501_encoder_helper_atomic_disable(struct drm_encoder *encoder,
						    struct drm_atomic_state *state)
{
	struct drm_device *dev = encoder->dev;

	ast_set_dp501_video_output(dev, 0);
}

static const struct drm_encoder_helper_funcs ast_dp501_encoder_helper_funcs = {
	.atomic_enable = ast_dp501_encoder_helper_atomic_enable,
	.atomic_disable = ast_dp501_encoder_helper_atomic_disable,
};

/*
 * DP501 Connector
 */
@@ -1607,6 +1580,8 @@ static int ast_dp501_output_init(struct ast_device *ast)
			       DRM_MODE_ENCODER_TMDS, NULL);
	if (ret)
		return ret;
	drm_encoder_helper_add(encoder, &ast_dp501_encoder_helper_funcs);

	encoder->possible_crtcs = drm_crtc_mask(crtc);

	ret = ast_dp501_connector_init(dev, connector);
@@ -1628,6 +1603,43 @@ static const struct drm_encoder_funcs ast_astdp_encoder_funcs = {
	.destroy = drm_encoder_cleanup,
};

static void ast_astdp_encoder_helper_atomic_mode_set(struct drm_encoder *encoder,
						     struct drm_crtc_state *crtc_state,
						     struct drm_connector_state *conn_state)
{
	struct drm_crtc *crtc = crtc_state->crtc;
	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
	struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;

	ast_dp_set_mode(crtc, vbios_mode_info);
}

static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder,
						   struct drm_atomic_state *state)
{
	struct drm_device *dev = encoder->dev;
	struct ast_device *ast = to_ast_device(dev);

	ast_dp_power_on_off(dev, AST_DP_POWER_ON);
	ast_wait_for_vretrace(ast);
	ast_dp_set_on_off(dev, 1);
}

static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder,
						    struct drm_atomic_state *state)
{
	struct drm_device *dev = encoder->dev;

	ast_dp_set_on_off(dev, 0);
	ast_dp_power_on_off(dev, AST_DP_POWER_OFF);
}

static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = {
	.atomic_mode_set = ast_astdp_encoder_helper_atomic_mode_set,
	.atomic_enable = ast_astdp_encoder_helper_atomic_enable,
	.atomic_disable = ast_astdp_encoder_helper_atomic_disable,
};

/*
 * ASPEED Display-Port Connector
 */
@@ -1726,6 +1738,8 @@ static int ast_astdp_output_init(struct ast_device *ast)
			       DRM_MODE_ENCODER_TMDS, NULL);
	if (ret)
		return ret;
	drm_encoder_helper_add(encoder, &ast_astdp_encoder_helper_funcs);

	encoder->possible_crtcs = drm_crtc_mask(crtc);

	ret = ast_astdp_connector_init(dev, connector);
@@ -1851,7 +1865,7 @@ static void ast_mode_config_helper_atomic_commit_tail(struct drm_atomic_state *s
	 * the I/O-register lock. Released in atomic_flush().
	 */
	mutex_lock(&ast->modeset_lock);
	drm_atomic_helper_commit_tail_rpm(state);
	drm_atomic_helper_commit_tail(state);
	mutex_unlock(&ast->modeset_lock);
}

Loading