Commit 6dac1612 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-next-2024-06-06' of...

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

 into drm-next

drm-misc-next for 6.10:

UAPI Changes:

Cross-subsystem Changes:
  - dma-buf: Warn when reserving 0 fence slots, internal API
    enhancements for heaps

Core Changes:

Driver Changes:
  - atmel-hlcdc: Support XLCDC in sam9x7
  - msm: Validate registers XML description against schema in CI
  - v3d: Fix build warning
  - bridges:
    - analogix_dp: Various improvements
  - panels:
    - New panel: WL-355608-A8

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

From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240606-vivid-amphibian-jackrabbit-40b1d1@houat
parents f680df51 310ec038
Loading
Loading
Loading
Loading
+60 −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/panel/wl-355608-a8.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: WL-355608-A8 3.5" (640x480 pixels) 24-bit IPS LCD panel

maintainers:
  - Ryan Walklin <ryan@testtoast.com>

allOf:
  - $ref: panel-common.yaml#
  - $ref: /schemas/spi/spi-peripheral-props.yaml#

properties:
  compatible:
    const: wl-355608-a8

  reg:
    maxItems: 1

  spi-3wire: true

required:
  - compatible
  - reg
  - port
  - power-supply
  - reset-gpios

unevaluatedProperties: false

examples:
  - |
    #include <dt-bindings/gpio/gpio.h>

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

        panel@0 {
            compatible = "wl-355608-a8";
            reg = <0>;

            spi-3wire;
            spi-max-frequency = <3125000>;

            reset-gpios = <&pio 8 14 GPIO_ACTIVE_LOW>; // PI14

            backlight = <&backlight>;
            power-supply = <&reg_lcd>;

            port {
                endpoint {
                    remote-endpoint = <&tcon_lcd0_out_lcd>;
                };
            };
        };
    };
+0 −1
Original line number Diff line number Diff line
@@ -7566,7 +7566,6 @@ F: include/drm/gpu_scheduler.h
DRM PANEL DRIVERS
M:	Neil Armstrong <neil.armstrong@linaro.org>
R:	Jessica Zhang <quic_jesszhan@quicinc.com>
R:	Sam Ravnborg <sam@ravnborg.org>
L:	dri-devel@lists.freedesktop.org
S:	Maintained
T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
+2 −2
Original line number Diff line number Diff line
@@ -50,8 +50,8 @@ static struct class *dma_heap_class;
static DEFINE_XARRAY_ALLOC(dma_heap_minors);

static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
				 unsigned int fd_flags,
				 unsigned int heap_flags)
				 u32 fd_flags,
				 u64 heap_flags)
{
	struct dma_buf *dmabuf;
	int fd;
+7 −0
Original line number Diff line number Diff line
@@ -186,6 +186,13 @@ int dma_resv_reserve_fences(struct dma_resv *obj, unsigned int num_fences)

	dma_resv_assert_held(obj);

	/* Driver and component code should never call this function with
	 * num_fences=0. If they do it usually points to bugs when calculating
	 * the number of needed fences dynamically.
	 */
	if (WARN_ON(!num_fences))
		return -EINVAL;

	old = dma_resv_fences_list(obj);
	if (old && old->max_fences) {
		if ((old->num_fences + num_fences) <= old->max_fences)
+141 −31
Original line number Diff line number Diff line
@@ -30,10 +30,12 @@
 *
 * @base: base CRTC state
 * @output_mode: RGBXXX output mode
 * @dpi: output DPI mode
 */
struct atmel_hlcdc_crtc_state {
	struct drm_crtc_state base;
	unsigned int output_mode;
	u8 dpi;
};

static inline struct atmel_hlcdc_crtc_state *
@@ -164,18 +166,24 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
	state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state);
	cfg = state->output_mode << 8;

	if (!crtc->dc->desc->is_xlcdc) {
		if (adj->flags & DRM_MODE_FLAG_NVSYNC)
			cfg |= ATMEL_HLCDC_VSPOL;

		if (adj->flags & DRM_MODE_FLAG_NHSYNC)
			cfg |= ATMEL_HLCDC_HSPOL;
	} else {
		cfg |= state->dpi << 11;
	}

	regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5),
			   ATMEL_HLCDC_HSPOL | ATMEL_HLCDC_VSPOL |
			   ATMEL_HLCDC_VSPDLYS | ATMEL_HLCDC_VSPDLYE |
			   ATMEL_HLCDC_DISPPOL | ATMEL_HLCDC_DISPDLY |
			   ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO |
			   ATMEL_HLCDC_GUARDTIME_MASK | ATMEL_HLCDC_MODE_MASK,
			   ATMEL_HLCDC_GUARDTIME_MASK |
			   (crtc->dc->desc->is_xlcdc ? ATMEL_XLCDC_MODE_MASK |
			   ATMEL_XLCDC_DPI : ATMEL_HLCDC_MODE_MASK),
			   cfg);

	clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
@@ -202,20 +210,37 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,

	pm_runtime_get_sync(dev->dev);

	if (crtc->dc->desc->is_xlcdc) {
		regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_CM);
		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
					     !(status & ATMEL_XLCDC_CM),
					     10, 1000))
			dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");

		regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_SD);
		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
					     status & ATMEL_XLCDC_SD,
					     10, 1000))
			dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
	}

	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP);
	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
	       (status & ATMEL_HLCDC_DISP))
		cpu_relax();
	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
				     !(status & ATMEL_HLCDC_DISP),
				    10, 1000))
		dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n");

	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_SYNC);
	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
	       (status & ATMEL_HLCDC_SYNC))
		cpu_relax();
	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
				     !(status & ATMEL_HLCDC_SYNC),
				    10, 1000))
		dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n");

	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_PIXEL_CLK);
	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
	       (status & ATMEL_HLCDC_PIXEL_CLK))
		cpu_relax();
	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
				     !(status & ATMEL_HLCDC_PIXEL_CLK),
				    10, 1000))
		dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n");

	clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
	pinctrl_pm_select_sleep_state(dev->dev);
@@ -241,20 +266,36 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
	clk_prepare_enable(crtc->dc->hlcdc->sys_clk);

	regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PIXEL_CLK);
	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
	       !(status & ATMEL_HLCDC_PIXEL_CLK))
		cpu_relax();

	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
				     status & ATMEL_HLCDC_PIXEL_CLK,
				     10, 1000))
		dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n");

	regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_SYNC);
	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
	       !(status & ATMEL_HLCDC_SYNC))
		cpu_relax();
	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
				     status & ATMEL_HLCDC_SYNC,
				     10, 1000))
		dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n");

	regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_DISP);
	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
	       !(status & ATMEL_HLCDC_DISP))
		cpu_relax();
	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
				     status & ATMEL_HLCDC_DISP,
				     10, 1000))
		dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n");

	if (crtc->dc->desc->is_xlcdc) {
		regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_CM);
		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
					     status & ATMEL_XLCDC_CM,
					     10, 1000))
			dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");

		regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_SD);
		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
					     !(status & ATMEL_XLCDC_SD),
					     10, 1000))
			dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
	}

	pm_runtime_put_sync(dev->dev);

@@ -264,7 +305,56 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
#define ATMEL_HLCDC_RGB565_OUTPUT		BIT(1)
#define ATMEL_HLCDC_RGB666_OUTPUT		BIT(2)
#define ATMEL_HLCDC_RGB888_OUTPUT		BIT(3)
#define ATMEL_HLCDC_DPI_RGB565C1_OUTPUT		BIT(4)
#define ATMEL_HLCDC_DPI_RGB565C2_OUTPUT		BIT(5)
#define ATMEL_HLCDC_DPI_RGB565C3_OUTPUT		BIT(6)
#define ATMEL_HLCDC_DPI_RGB666C1_OUTPUT		BIT(7)
#define ATMEL_HLCDC_DPI_RGB666C2_OUTPUT		BIT(8)
#define ATMEL_HLCDC_DPI_RGB888_OUTPUT		BIT(9)
#define ATMEL_HLCDC_OUTPUT_MODE_MASK		GENMASK(3, 0)
#define ATMEL_XLCDC_OUTPUT_MODE_MASK		GENMASK(9, 0)

static int atmel_xlcdc_connector_output_dsi(struct drm_encoder *encoder,
					    struct drm_display_info *info)
{
	int j;
	unsigned int supported_fmts = 0;

	switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
	case 0:
		break;
	case MEDIA_BUS_FMT_RGB565_1X16:
		return ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
	case MEDIA_BUS_FMT_RGB666_1X18:
		return ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
		return ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
	case MEDIA_BUS_FMT_RGB888_1X24:
		return ATMEL_HLCDC_DPI_RGB888_OUTPUT;
	default:
		return -EINVAL;
	}

	for (j = 0; j < info->num_bus_formats; j++) {
		switch (info->bus_formats[j]) {
		case MEDIA_BUS_FMT_RGB565_1X16:
			supported_fmts |= ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
			break;
		case MEDIA_BUS_FMT_RGB666_1X18:
			supported_fmts |= ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
			break;
		case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
			supported_fmts |= ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
			break;
		case MEDIA_BUS_FMT_RGB888_1X24:
			supported_fmts |= ATMEL_HLCDC_DPI_RGB888_OUTPUT;
			break;
		default:
			break;
		}
	}
	return supported_fmts;
}

static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
{
@@ -277,6 +367,13 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
	encoder = state->best_encoder;
	if (!encoder)
		encoder = connector->encoder;
	/*
	 * atmel-hlcdc to support DSI formats with DSI video pipeline
	 * when DRM_MODE_ENCODER_DSI type is set by
	 * connector driver component.
	 */
	if (encoder->encoder_type == DRM_MODE_ENCODER_DSI)
		return atmel_xlcdc_connector_output_dsi(encoder, info);

	switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
	case 0:
@@ -317,7 +414,7 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)

static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
{
	unsigned int output_fmts = ATMEL_HLCDC_OUTPUT_MODE_MASK;
	unsigned int output_fmts;
	struct atmel_hlcdc_crtc_state *hstate;
	struct drm_connector_state *cstate;
	struct drm_connector *connector;
@@ -325,6 +422,8 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
	int i;

	crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);
	output_fmts = crtc->dc->desc->is_xlcdc ? ATMEL_XLCDC_OUTPUT_MODE_MASK :
		      ATMEL_HLCDC_OUTPUT_MODE_MASK;

	for_each_new_connector_in_state(state->state, connector, cstate, i) {
		unsigned int supported_fmts = 0;
@@ -345,7 +444,15 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)

	hstate = drm_crtc_state_to_atmel_hlcdc_crtc_state(state);
	hstate->output_mode = fls(output_fmts) - 1;

	if (crtc->dc->desc->is_xlcdc) {
		/* check if MIPI DPI bit needs to be set */
		if (fls(output_fmts) > 3) {
			hstate->output_mode -= 4;
			hstate->dpi = 1;
		} else {
			hstate->dpi = 0;
		}
	}
	return 0;
}

@@ -449,6 +556,7 @@ static struct drm_crtc_state *
atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
{
	struct atmel_hlcdc_crtc_state *state, *cur;
	struct atmel_hlcdc_crtc *c = drm_crtc_to_atmel_hlcdc_crtc(crtc);

	if (WARN_ON(!crtc->state))
		return NULL;
@@ -460,6 +568,8 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)

	cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
	state->output_mode = cur->output_mode;
	if (c->dc->desc->is_xlcdc)
		state->dpi = cur->dpi;

	return &state->base;
}
Loading