summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.mailmap3
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml2
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-simple.yaml2
-rw-r--r--Documentation/devicetree/bindings/display/panel/raydium,rm67200.yaml72
-rw-r--r--Documentation/devicetree/bindings/display/panel/visionox,rm692e5.yaml77
-rw-r--r--Documentation/gpu/drm-internals.rst7
-rw-r--r--MAINTAINERS8
-rw-r--r--drivers/bus/mhi/host/boot.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_job.c22
-rw-r--r--drivers/gpu/drm/aspeed/aspeed_gfx_drv.c4
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi86.c6
-rw-r--r--drivers/gpu/drm/display/drm_dp_helper.c61
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c4
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c42
-rw-r--r--drivers/gpu/drm/drm_writeback.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c24
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_color.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_gamma.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_merge.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_ovl.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_rdma.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_hdmi.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_mdp_rdma.c4
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.c15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c17
-rw-r--r--drivers/gpu/drm/panel/Kconfig29
-rw-r--r--drivers/gpu/drm/panel/Makefile3
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9882t.c2
-rw-r--r--drivers/gpu/drm/panel/panel-raydium-rm67200.c499
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c64
-rw-r--r--drivers/gpu/drm/panel/panel-sony-td4353-jdi.c107
-rw-r--r--drivers/gpu/drm/panel/panel-summit.c132
-rw-r--r--drivers/gpu/drm/panel/panel-visionox-rm692e5.c442
-rw-r--r--drivers/gpu/drm/scheduler/sched_entity.c23
-rw-r--r--drivers/gpu/drm/scheduler/sched_fence.c2
-rw-r--r--drivers/gpu/drm/scheduler/sched_internal.h91
-rw-r--r--drivers/gpu/drm/scheduler/sched_main.c7
-rw-r--r--drivers/gpu/drm/stm/ltdc.c4
-rw-r--r--drivers/gpu/drm/tiny/arcpgu.c4
-rw-r--r--drivers/gpu/drm/tiny/repaper.c4
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c53
-rw-r--r--include/drm/display/drm_dp_helper.h2
-rw-r--r--include/drm/drm_mipi_dsi.h2
-rw-r--r--include/drm/gpu_scheduler.h122
45 files changed, 1680 insertions, 314 deletions
diff --git a/.mailmap b/.mailmap
index a897c16d3bae..ffb3a7e5e088 100644
--- a/.mailmap
+++ b/.mailmap
@@ -323,7 +323,8 @@ Jeff Johnson <jeff.johnson@oss.qualcomm.com> <quic_jjohnson@quicinc.com>
Jeff Layton <jlayton@kernel.org> <jlayton@poochiereds.net>
Jeff Layton <jlayton@kernel.org> <jlayton@primarydata.com>
Jeff Layton <jlayton@kernel.org> <jlayton@redhat.com>
-Jeffrey Hugo <quic_jhugo@quicinc.com> <jhugo@codeaurora.org>
+Jeff Hugo <jeff.hugo@oss.qualcomm.com> <jhugo@codeaurora.org>
+Jeff Hugo <jeff.hugo@oss.qualcomm.com> <quic_jhugo@quicinc.com>
Jens Axboe <axboe@kernel.dk> <axboe@suse.de>
Jens Axboe <axboe@kernel.dk> <jens.axboe@oracle.com>
Jens Axboe <axboe@kernel.dk> <axboe@fb.com>
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml
index e80fc7006984..548f5ac14500 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml
@@ -40,6 +40,8 @@ properties:
- auo,g185han01
# AU Optronics Corporation 19.0" (1280x1024) TFT LCD panel
- auo,g190ean01
+ # BOE AV123Z7M-N17 12.3" (1920x720) LVDS TFT LCD panel
+ - boe,av123z7m-n17
# Kaohsiung Opto-Electronics Inc. 10.1" WUXGA (1920 x 1200) LVDS TFT LCD panel
- koe,tx26d202vm0bwa
# Lincoln Technology Solutions, LCD185-101CT 10.1" TFT 1920x1200
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index e3ee3a332bb7..b0de4fd6f3d4 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -63,6 +63,8 @@ properties:
- auo,t215hvn01
# Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
- avic,tm070ddh03
+ # BOE AV101HDT-a10 10.1" 1280x720 LVDS panel
+ - boe,av101hdt-a10
# BOE BP082WX1-100 8.2" WXGA (1280x800) LVDS panel
- boe,bp082wx1-100
# BOE BP101WX1-100 10.1" WXGA (1280x800) LVDS panel
diff --git a/Documentation/devicetree/bindings/display/panel/raydium,rm67200.yaml b/Documentation/devicetree/bindings/display/panel/raydium,rm67200.yaml
new file mode 100644
index 000000000000..54c9c0ef45ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/raydium,rm67200.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/raydium,rm67200.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Raydium RM67200 based MIPI-DSI panels
+
+maintainers:
+ - Sebastian Reichel <sebastian.reichel@collabora.com>
+
+allOf:
+ - $ref: panel-common.yaml#
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - wanchanglong,w552793baa
+ - const: raydium,rm67200
+
+ reg:
+ maxItems: 1
+
+ vdd-supply:
+ description: 2.8V Logic voltage
+
+ iovcc-supply:
+ description: 1.8V IO voltage
+
+ vsp-supply:
+ description: positive 5.5V voltage
+
+ vsn-supply:
+ description: negative 5.5V voltage
+
+ backlight: true
+ port: true
+ reset-gpios: true
+
+required:
+ - compatible
+ - port
+ - reg
+ - reset-gpios
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ panel@0 {
+ compatible = "wanchanglong,w552793baa", "raydium,rm67200";
+ reg = <0>;
+
+ vdd-supply = <&regulator1>;
+ iovcc-supply = <&regulator2>;
+ vsp-supply = <&regulator3>;
+ vsn-supply = <&regulator4>;
+ reset-gpios = <&gpiobank 42 GPIO_ACTIVE_LOW>;
+
+ port {
+ panel0_in: endpoint {
+ remote-endpoint = <&dsi0_out>;
+ };
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/display/panel/visionox,rm692e5.yaml b/Documentation/devicetree/bindings/display/panel/visionox,rm692e5.yaml
new file mode 100644
index 000000000000..d4b4672815fe
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/visionox,rm692e5.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/visionox,rm692e5.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Visionox RM692E5 6.55" 2400x1080 120Hz MIPI-DSI Panel
+
+maintainers:
+ - Danila Tikhonov <danila@jiaxyga.com>
+
+description:
+ The Visionox RM692E5 is a generic DSI Panel IC used to control
+ AMOLED panels.
+
+allOf:
+ - $ref: panel-common.yaml#
+
+properties:
+ compatible:
+ oneOf:
+ - enum:
+ - visionox,rm692e5
+ - items:
+ - enum:
+ - nothing,rm692e5-spacewar
+ - const: visionox,rm692e5
+
+ reg:
+ maxItems: 1
+
+ vdd-supply:
+ description: 3.3V source voltage rail
+
+ vddio-supply:
+ description: 1.8V I/O source voltage rail
+
+ reset-gpios: true
+ port: true
+
+required:
+ - compatible
+ - reg
+ - reset-gpios
+ - vdd-supply
+ - vddio-supply
+ - port
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel@0 {
+ compatible = "nothing,rm692e5-spacewar",
+ "visionox,rm692e5";
+ reg = <0>;
+
+ reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
+
+ vdd-supply = <&vdd_oled>;
+ vddio-supply = <&vdd_io_oled>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+ };
+
+...
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index cb9ae282771c..94f93fd3b8a0 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -208,6 +208,13 @@ follows:
``CONFIG_VIRTIO_UML`` and ``CONFIG_UML_PCI_OVER_VIRTIO`` are not
included in it because they are only required for User Mode Linux.
+KUnit Coverage Rules
+~~~~~~~~~~~~~~~~~~~~
+
+KUnit support is gradually added to the DRM framework and helpers. There's no
+general requirement for the framework and helpers to have KUnit tests at the
+moment. However, patches that are affecting a function or helper already
+covered by KUnit tests must provide tests if the change calls for one.
Legacy Support Code
===================
diff --git a/MAINTAINERS b/MAINTAINERS
index cddcb097f7f3..04ceba1a506c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7347,7 +7347,8 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/mgag200/
DRM DRIVER FOR MI0283QT
-S: Orphan
+M: Alex Lanzano <lanzano.alex@gmail.com>
+S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
F: drivers/gpu/drm/tiny/mi0283qt.c
@@ -7449,7 +7450,8 @@ F: Documentation/devicetree/bindings/display/bridge/ps8640.yaml
F: drivers/gpu/drm/bridge/parade-ps8640.c
DRM DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS
-S: Orphan
+M: Alex Lanzano <lanzano.alex@gmail.com>
+S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/repaper.txt
F: drivers/gpu/drm/tiny/repaper.c
@@ -19425,7 +19427,7 @@ F: drivers/clk/qcom/
F: include/dt-bindings/clock/qcom,*
QUALCOMM CLOUD AI (QAIC) DRIVER
-M: Jeffrey Hugo <quic_jhugo@quicinc.com>
+M: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
R: Carl Vanderlip <quic_carlv@quicinc.com>
L: linux-arm-msm@vger.kernel.org
L: dri-devel@lists.freedesktop.org
diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c
index c8e48f621a8c..efa3b6dddf4d 100644
--- a/drivers/bus/mhi/host/boot.c
+++ b/drivers/bus/mhi/host/boot.c
@@ -608,7 +608,7 @@ fw_load_ready_state:
return;
error_ready_state:
- if (fw_load_type == MHI_FW_LOAD_FBC) {
+ if (mhi_cntrl->fbc_image) {
mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
mhi_cntrl->fbc_image = NULL;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 100f04475943..1899c601c95c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -411,8 +411,24 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
return fence;
}
-#define to_drm_sched_job(sched_job) \
- container_of((sched_job), struct drm_sched_job, queue_node)
+/*
+ * This is a duplicate function from DRM scheduler sched_internal.h.
+ * Plan is to remove it when amdgpu_job_stop_all_jobs_on_sched is removed, due
+ * latter being incorrect and racy.
+ *
+ * See https://lore.kernel.org/amd-gfx/44edde63-7181-44fb-a4f7-94e50514f539@amd.com/
+ */
+static struct drm_sched_job *
+drm_sched_entity_queue_pop(struct drm_sched_entity *entity)
+{
+ struct spsc_node *node;
+
+ node = spsc_queue_pop(&entity->job_queue);
+ if (!node)
+ return NULL;
+
+ return container_of(node, struct drm_sched_job, queue_node);
+}
void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)
{
@@ -425,7 +441,7 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)
struct drm_sched_rq *rq = sched->sched_rq[i];
spin_lock(&rq->lock);
list_for_each_entry(s_entity, &rq->entities, list) {
- while ((s_job = to_drm_sched_job(spsc_queue_pop(&s_entity->job_queue)))) {
+ while ((s_job = drm_sched_entity_queue_pop(s_entity))) {
struct drm_sched_fence *s_fence = s_job->s_fence;
dma_fence_signal(&s_fence->scheduled);
diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
index 397e677a691c..46094cca2974 100644
--- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
+++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
@@ -144,11 +144,9 @@ static int aspeed_gfx_load(struct drm_device *drm)
struct aspeed_gfx *priv = to_aspeed_gfx(drm);
struct device_node *np = pdev->dev.of_node;
const struct aspeed_gfx_config *config;
- struct resource *res;
int ret;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->base = devm_ioremap_resource(drm->dev, res);
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index ae34585e05b3..01d456b955ab 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -195,7 +195,7 @@ struct ti_sn65dsi86 {
struct gpio_chip gchip;
DECLARE_BITMAP(gchip_output, SN_NUM_GPIOS);
#endif
-#if defined(CONFIG_PWM)
+#if IS_REACHABLE(CONFIG_PWM)
struct pwm_chip *pchip;
bool pwm_enabled;
atomic_t pwm_pin_busy;
@@ -1362,7 +1362,7 @@ static struct auxiliary_driver ti_sn_bridge_driver = {
/* -----------------------------------------------------------------------------
* PWM Controller
*/
-#if defined(CONFIG_PWM)
+#if IS_REACHABLE(CONFIG_PWM)
static int ti_sn_pwm_pin_request(struct ti_sn65dsi86 *pdata)
{
return atomic_xchg(&pdata->pwm_pin_busy, 1) ? -EBUSY : 0;
@@ -1956,7 +1956,7 @@ static int ti_sn65dsi86_probe(struct i2c_client *client)
return ret;
}
- if (IS_ENABLED(CONFIG_PWM)) {
+ if (IS_REACHABLE(CONFIG_PWM)) {
ret = ti_sn65dsi86_add_aux_device(pdata, &pdata->pwm_aux, "pwm");
if (ret)
return ret;
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index f5c596234729..dbce1c3f4969 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2876,6 +2876,67 @@ int drm_dp_lttpr_max_link_rate(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
EXPORT_SYMBOL(drm_dp_lttpr_max_link_rate);
/**
+ * drm_dp_lttpr_set_transparent_mode() - set the LTTPR in transparent mode
+ * @aux: DisplayPort AUX channel
+ * @enable: Enable or disable transparent mode
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int drm_dp_lttpr_set_transparent_mode(struct drm_dp_aux *aux, bool enable)
+{
+ u8 val = enable ? DP_PHY_REPEATER_MODE_TRANSPARENT :
+ DP_PHY_REPEATER_MODE_NON_TRANSPARENT;
+ int ret = drm_dp_dpcd_writeb(aux, DP_PHY_REPEATER_MODE, val);
+
+ if (ret < 0)
+ return ret;
+
+ return (ret == 1) ? 0 : -EIO;
+}
+EXPORT_SYMBOL(drm_dp_lttpr_set_transparent_mode);
+
+/**
+ * drm_dp_lttpr_init() - init LTTPR transparency mode according to DP standard
+ * @aux: DisplayPort AUX channel
+ * @lttpr_count: Number of LTTPRs. Between 0 and 8, according to DP standard.
+ * Negative error code for any non-valid number.
+ * See drm_dp_lttpr_count().
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int drm_dp_lttpr_init(struct drm_dp_aux *aux, int lttpr_count)
+{
+ int ret;
+
+ if (!lttpr_count)
+ return 0;
+
+ /*
+ * See DP Standard v2.0 3.6.6.1 about the explicit disabling of
+ * non-transparent mode and the disable->enable non-transparent mode
+ * sequence.
+ */
+ ret = drm_dp_lttpr_set_transparent_mode(aux, true);
+ if (ret)
+ return ret;
+
+ if (lttpr_count < 0)
+ return -ENODEV;
+
+ if (drm_dp_lttpr_set_transparent_mode(aux, false)) {
+ /*
+ * Roll-back to transparent mode if setting non-transparent
+ * mode has failed
+ */
+ drm_dp_lttpr_set_transparent_mode(aux, true);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_dp_lttpr_init);
+
+/**
* drm_dp_lttpr_max_lane_count - get the maximum lane count supported by all LTTPRs
* @caps: LTTPR common capabilities
*
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 7a25e70694ba..5302ab324898 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3409,6 +3409,10 @@ EXPORT_SYMBOL(drm_atomic_helper_disable_all);
* This implies a reset of all active components available between the CRTC and
* connectors.
*
+ * NOTE: This relies on resetting &drm_crtc_state.connectors_changed.
+ * For drivers which optimize out unnecessary modesets this will result in
+ * a no-op commit, achieving nothing.
+ *
* Returns:
* 0 on success or a negative error code on failure.
*/
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 5e5c5f84daac..2e148753ea97 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -1266,25 +1266,6 @@ int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address);
/**
- * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
- * output signal on the TE signal line
- * @dsi: DSI peripheral device
- *
- * Return: 0 on success or a negative error code on failure
- */
-int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
-{
- ssize_t err;
-
- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
- if (err < 0)
- return err;
-
- return 0;
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off);
-
-/**
* mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
* output signal on the TE signal line.
* @dsi: DSI peripheral device
@@ -1714,6 +1695,29 @@ void mipi_dsi_turn_on_peripheral_multi(struct mipi_dsi_multi_context *ctx)
EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral_multi);
/**
+ * mipi_dsi_dcs_set_tear_off_multi() - turn off the display module's Tearing Effect
+ * output signal on the TE signal line
+ * @ctx: Context for multiple DSI transactions
+ */
+void mipi_dsi_dcs_set_tear_off_multi(struct mipi_dsi_multi_context *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t err;
+
+ if (ctx->accum_err)
+ return;
+
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
+ if (err < 0) {
+ ctx->accum_err = err;
+ dev_err(dev, "Failed to set tear off: %d\n",
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off_multi);
+
+/**
* mipi_dsi_dcs_soft_reset_multi() - perform a software reset of the display module
* @ctx: Context for multiple DSI transactions
*
diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c
index f139b49af4c9..edbeab88ff2b 100644
--- a/drivers/gpu/drm/drm_writeback.c
+++ b/drivers/gpu/drm/drm_writeback.c
@@ -213,7 +213,7 @@ static void delete_writeback_properties(struct drm_device *dev)
}
/**
- * drm_writeback_connector_init_with_encoder - Initialize a writeback connector with
+ * __drm_writeback_connector_init - Initialize a writeback connector with
* a custom encoder
*
* @dev: DRM device
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 11953b03bb6a..66fcd90f0028 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -119,9 +119,6 @@ intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable)
u8 val = enable ? DP_PHY_REPEATER_MODE_TRANSPARENT :
DP_PHY_REPEATER_MODE_NON_TRANSPARENT;
- if (drm_dp_dpcd_write(&intel_dp->aux, DP_PHY_REPEATER_MODE, &val, 1) != 1)
- return false;
-
intel_dp->lttpr_common_caps[DP_PHY_REPEATER_MODE -
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV] = val;
@@ -146,6 +143,7 @@ bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp)
static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
{
int lttpr_count;
+ int ret;
if (!intel_dp_read_lttpr_common_caps(intel_dp, dpcd))
return 0;
@@ -172,22 +170,8 @@ static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_
return lttpr_count;
}
- /*
- * See DP Standard v2.0 3.6.6.1. about the explicit disabling of
- * non-transparent mode and the disable->enable non-transparent mode
- * sequence.
- */
- intel_dp_set_lttpr_transparent_mode(intel_dp, true);
-
- /*
- * In case of unsupported number of LTTPRs or failing to switch to
- * non-transparent mode fall-back to transparent link training mode,
- * still taking into account any LTTPR common lane- rate/count limits.
- */
- if (lttpr_count < 0)
- goto out_reset_lttpr_count;
-
- if (!intel_dp_set_lttpr_transparent_mode(intel_dp, false)) {
+ ret = drm_dp_lttpr_init(&intel_dp->aux, lttpr_count);
+ if (ret) {
lt_dbg(intel_dp, DP_PHY_DPRX,
"Switching to LTTPR non-transparent LT mode failed, fall-back to transparent mode\n");
@@ -196,6 +180,8 @@ static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_
goto out_reset_lttpr_count;
}
+ intel_dp_set_lttpr_transparent_mode(intel_dp, false);
+
return lttpr_count;
out_reset_lttpr_count:
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index dd8433a38282..39c7de4cdcc1 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -96,7 +96,6 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mtk_disp_color *priv;
- struct resource *res;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -108,8 +107,7 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(priv->clk),
"failed to get color clk\n");
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->regs = devm_ioremap_resource(dev, res);
+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->regs))
return dev_err_probe(dev, PTR_ERR(priv->regs),
"failed to ioremap color\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
index b17b11d93846..8afd15006df2 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
@@ -256,7 +256,6 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mtk_disp_gamma *priv;
- struct resource *res;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -268,8 +267,7 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(priv->clk),
"failed to get gamma clk\n");
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->regs = devm_ioremap_resource(dev, res);
+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->regs))
return dev_err_probe(dev, PTR_ERR(priv->regs),
"failed to ioremap gamma\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 563b1b248fbb..b174dda091d3 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -306,7 +306,6 @@ static const struct component_ops mtk_disp_merge_component_ops = {
static int mtk_disp_merge_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct resource *res;
struct mtk_disp_merge *priv;
int ret;
@@ -314,8 +313,7 @@ static int mtk_disp_merge_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->regs = devm_ioremap_resource(dev, res);
+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->regs))
return dev_err_probe(dev, PTR_ERR(priv->regs),
"failed to ioremap merge\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index df82cea4bb79..d0581c4e3c99 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -604,7 +604,6 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mtk_disp_ovl *priv;
- struct resource *res;
int irq;
int ret;
@@ -621,8 +620,7 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(priv->clk),
"failed to get ovl clk\n");
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->regs = devm_ioremap_resource(dev, res);
+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->regs))
return dev_err_probe(dev, PTR_ERR(priv->regs),
"failed to ioremap ovl\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index bf47790e4d6b..c9d41d75e7f2 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -313,7 +313,6 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mtk_disp_rdma *priv;
- struct resource *res;
int irq;
int ret;
@@ -330,8 +329,7 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(priv->clk),
"failed to get rdma clk\n");
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->regs = devm_ioremap_resource(dev, res);
+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->regs))
return dev_err_probe(dev, PTR_ERR(priv->regs),
"failed to ioremap rdma\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b50dc9a013ac..0683c2b3ca5b 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1192,7 +1192,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
{
struct mtk_dsi *dsi;
struct device *dev = &pdev->dev;
- struct resource *regs;
int irq_num;
int ret;
@@ -1217,8 +1216,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
if (IS_ERR(dsi->hs_clk))
return dev_err_probe(dev, PTR_ERR(dsi->hs_clk), "Failed to get hs clock\n");
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dsi->regs = devm_ioremap_resource(dev, regs);
+ dsi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dsi->regs))
return dev_err_probe(dev, PTR_ERR(dsi->regs), "Failed to ioremap memory\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index ac5e40c27617..d4ab098e1174 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1424,7 +1424,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
struct device_node *cec_np, *remote, *i2c_np;
struct platform_device *cec_pdev;
struct regmap *regmap;
- struct resource *mem;
int ret;
ret = mtk_hdmi_get_all_clk(hdmi, np);
@@ -1470,8 +1469,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
}
hdmi->sys_regmap = regmap;
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- hdmi->regs = devm_ioremap_resource(dev, mem);
+ hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(hdmi->regs)) {
ret = PTR_ERR(hdmi->regs);
goto put_device;
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
index fc69ee38ce7d..7982788ae9df 100644
--- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
@@ -291,7 +291,6 @@ static const struct component_ops mtk_mdp_rdma_component_ops = {
static int mtk_mdp_rdma_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct resource *res;
struct mtk_mdp_rdma *priv;
int ret = 0;
@@ -299,8 +298,7 @@ static int mtk_mdp_rdma_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->regs = devm_ioremap_resource(dev, res);
+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->regs))
return dev_err_probe(dev, PTR_ERR(priv->regs),
"failed to ioremap rdma\n");
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index a542d2781a09..9aa8bbd73d86 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -367,6 +367,19 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d
return 0;
}
+static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp)
+{
+ u8 lttpr_caps[DP_LTTPR_COMMON_CAP_SIZE];
+ int rc;
+
+ if (drm_dp_read_lttpr_common_caps(dp->aux, dp->panel->dpcd, lttpr_caps))
+ return;
+
+ rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(lttpr_caps));
+ if (rc)
+ DRM_ERROR("failed to set LTTPRs transparency mode, rc=%d\n", rc);
+}
+
static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
{
struct drm_connector *connector = dp->msm_dp_display.connector;
@@ -377,6 +390,8 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
if (rc)
goto end;
+ msm_dp_display_lttpr_init(dp);
+
msm_dp_link_process_request(dp->link);
if (!dp->msm_dp_display.is_edp)
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index bcda0105160f..55691ec44aba 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -79,21 +79,8 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
!drm_dp_read_lttpr_common_caps(aux, dpcd, outp->dp.lttpr.caps)) {
int nr = drm_dp_lttpr_count(outp->dp.lttpr.caps);
- if (nr) {
- drm_dp_dpcd_writeb(aux, DP_PHY_REPEATER_MODE,
- DP_PHY_REPEATER_MODE_TRANSPARENT);
-
- if (nr > 0) {
- ret = drm_dp_dpcd_writeb(aux, DP_PHY_REPEATER_MODE,
- DP_PHY_REPEATER_MODE_NON_TRANSPARENT);
- if (ret != 1) {
- drm_dp_dpcd_writeb(aux, DP_PHY_REPEATER_MODE,
- DP_PHY_REPEATER_MODE_TRANSPARENT);
- } else {
- outp->dp.lttpr.nr = nr;
- }
- }
- }
+ if (!drm_dp_lttpr_init(aux, nr))
+ outp->dp.lttpr.nr = nr;
}
ret = drm_dp_read_dpcd_caps(aux, dpcd);
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index d7469c565d1d..5927806cb4a9 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -573,6 +573,16 @@ config DRM_PANEL_RAYDIUM_RM67191
Say Y here if you want to enable support for Raydium RM67191 FHD
(1080x1920) DSI panel.
+config DRM_PANEL_RAYDIUM_RM67200
+ tristate "Raydium RM67200-based DSI panel"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ help
+ Say Y here if you want to enable support for Raydium RM67200-based
+ DSI video mode panels. This panel controller can be found in the
+ Wanchanglong W552793BAA panel found on the Rockchip RK3588 EVB1
+ evaluation boards.
+
config DRM_PANEL_RAYDIUM_RM68200
tristate "Raydium RM68200 720x1280 DSI video mode panel"
depends on OF
@@ -925,6 +935,15 @@ config DRM_PANEL_SIMPLE
that it can be automatically turned off when the panel goes into a
low power state.
+config DRM_PANEL_SUMMIT
+ tristate "Apple Summit display panel"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
+ help
+ Say Y if you want to enable support for the "Summit" display panel
+ used as a touchbar on certain Apple laptops.
+
config DRM_PANEL_SYNAPTICS_R63353
tristate "Synaptics R63353-based panels"
depends on OF
@@ -996,6 +1015,16 @@ config DRM_PANEL_VISIONOX_RM69299
Say Y here if you want to enable support for Visionox
RM69299 DSI Video Mode panel.
+config DRM_PANEL_VISIONOX_RM692E5
+ tristate "Visionox RM692E5"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
+ help
+ Say Y here if you want to enable support for Visionox RM692E5 amoled
+ display panels, such as the one found in the Nothing Phone (1)
+ smartphone.
+
config DRM_PANEL_VISIONOX_VTDR6130
tristate "Visionox VTDR6130"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 7dcf72646cac..1bb8ae46b59b 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS) += panel-osd-osd101t2587-53ts.o
obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o
obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o
+obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67200) += panel-raydium-rm67200.o
obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o
obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM692E5) += panel-raydium-rm692e5.o
obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM69380) += panel-raydium-rm69380.o
@@ -89,6 +90,7 @@ obj-$(CONFIG_DRM_PANEL_SHARP_LS060T1SX01) += panel-sharp-ls060t1sx01.o
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7703) += panel-sitronix-st7703.o
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
+obj-$(CONFIG_DRM_PANEL_SUMMIT) += panel-summit.o
obj-$(CONFIG_DRM_PANEL_SYNAPTICS_R63353) += panel-synaptics-r63353.o
obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
obj-$(CONFIG_DRM_PANEL_SONY_TD4353_JDI) += panel-sony-td4353-jdi.o
@@ -100,6 +102,7 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o
+obj-$(CONFIG_DRM_PANEL_VISIONOX_RM692E5) += panel-visionox-rm692e5.o
obj-$(CONFIG_DRM_PANEL_VISIONOX_VTDR6130) += panel-visionox-vtdr6130.o
obj-$(CONFIG_DRM_PANEL_VISIONOX_R66451) += panel-visionox-r66451.o
obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
index 266a087fe14c..3c24a63b6be8 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -607,7 +607,7 @@ static int ili9882t_add(struct ili9882t *ili)
ili->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(ili->enable_gpio)) {
- dev_err(dev, "cannot get reset-gpios %ld\n",
+ dev_err(dev, "cannot get enable-gpios %ld\n",
PTR_ERR(ili->enable_gpio));
return PTR_ERR(ili->enable_gpio);
}
diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67200.c b/drivers/gpu/drm/panel/panel-raydium-rm67200.c
new file mode 100644
index 000000000000..64b685dc11f6
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-raydium-rm67200.c
@@ -0,0 +1,499 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2024 Collabora
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+struct raydium_rm67200_panel_info {
+ struct drm_display_mode mode;
+ const struct regulator_bulk_data *regulators;
+ int num_regulators;
+ void (*panel_setup)(struct mipi_dsi_multi_context *ctx);
+};
+
+struct raydium_rm67200 {
+ struct drm_panel panel;
+ const struct raydium_rm67200_panel_info *panel_info;
+ struct mipi_dsi_device *dsi;
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data *supplies;
+ int num_supplies;
+};
+
+static inline struct raydium_rm67200 *to_raydium_rm67200(struct drm_panel *panel)
+{
+ return container_of(panel, struct raydium_rm67200, panel);
+}
+
+static void raydium_rm67200_reset(struct raydium_rm67200 *ctx)
+{
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+ msleep(60);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ msleep(60);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+ msleep(60);
+}
+
+static void raydium_rm67200_write(struct mipi_dsi_multi_context *ctx,
+ u8 arg1, u8 arg2)
+{
+ u8 d[] = { arg1, arg2 };
+
+ mipi_dsi_generic_write_multi(ctx, d, ARRAY_SIZE(d));
+}
+
+static void w552793baa_setup(struct mipi_dsi_multi_context *ctx)
+{
+ raydium_rm67200_write(ctx, 0xfe, 0x21);
+ raydium_rm67200_write(ctx, 0x04, 0x00);
+ raydium_rm67200_write(ctx, 0x00, 0x64);
+ raydium_rm67200_write(ctx, 0x2a, 0x00);
+ raydium_rm67200_write(ctx, 0x26, 0x64);
+ raydium_rm67200_write(ctx, 0x54, 0x00);
+ raydium_rm67200_write(ctx, 0x50, 0x64);
+ raydium_rm67200_write(ctx, 0x7b, 0x00);
+ raydium_rm67200_write(ctx, 0x77, 0x64);
+ raydium_rm67200_write(ctx, 0xa2, 0x00);
+ raydium_rm67200_write(ctx, 0x9d, 0x64);
+ raydium_rm67200_write(ctx, 0xc9, 0x00);
+ raydium_rm67200_write(ctx, 0xc5, 0x64);
+ raydium_rm67200_write(ctx, 0x01, 0x71);
+ raydium_rm67200_write(ctx, 0x27, 0x71);
+ raydium_rm67200_write(ctx, 0x51, 0x71);
+ raydium_rm67200_write(ctx, 0x78, 0x71);
+ raydium_rm67200_write(ctx, 0x9e, 0x71);
+ raydium_rm67200_write(ctx, 0xc6, 0x71);
+ raydium_rm67200_write(ctx, 0x02, 0x89);
+ raydium_rm67200_write(ctx, 0x28, 0x89);
+ raydium_rm67200_write(ctx, 0x52, 0x89);
+ raydium_rm67200_write(ctx, 0x79, 0x89);
+ raydium_rm67200_write(ctx, 0x9f, 0x89);
+ raydium_rm67200_write(ctx, 0xc7, 0x89);
+ raydium_rm67200_write(ctx, 0x03, 0x9e);
+ raydium_rm67200_write(ctx, 0x29, 0x9e);
+ raydium_rm67200_write(ctx, 0x53, 0x9e);
+ raydium_rm67200_write(ctx, 0x7a, 0x9e);
+ raydium_rm67200_write(ctx, 0xa0, 0x9e);
+ raydium_rm67200_write(ctx, 0xc8, 0x9e);
+ raydium_rm67200_write(ctx, 0x09, 0x00);
+ raydium_rm67200_write(ctx, 0x05, 0xb0);
+ raydium_rm67200_write(ctx, 0x31, 0x00);
+ raydium_rm67200_write(ctx, 0x2b, 0xb0);
+ raydium_rm67200_write(ctx, 0x5a, 0x00);
+ raydium_rm67200_write(ctx, 0x55, 0xb0);
+ raydium_rm67200_write(ctx, 0x80, 0x00);
+ raydium_rm67200_write(ctx, 0x7c, 0xb0);
+ raydium_rm67200_write(ctx, 0xa7, 0x00);
+ raydium_rm67200_write(ctx, 0xa3, 0xb0);
+ raydium_rm67200_write(ctx, 0xce, 0x00);
+ raydium_rm67200_write(ctx, 0xca, 0xb0);
+ raydium_rm67200_write(ctx, 0x06, 0xc0);
+ raydium_rm67200_write(ctx, 0x2d, 0xc0);
+ raydium_rm67200_write(ctx, 0x56, 0xc0);
+ raydium_rm67200_write(ctx, 0x7d, 0xc0);
+ raydium_rm67200_write(ctx, 0xa4, 0xc0);
+ raydium_rm67200_write(ctx, 0xcb, 0xc0);
+ raydium_rm67200_write(ctx, 0x07, 0xcf);
+ raydium_rm67200_write(ctx, 0x2f, 0xcf);
+ raydium_rm67200_write(ctx, 0x58, 0xcf);
+ raydium_rm67200_write(ctx, 0x7e, 0xcf);
+ raydium_rm67200_write(ctx, 0xa5, 0xcf);
+ raydium_rm67200_write(ctx, 0xcc, 0xcf);
+ raydium_rm67200_write(ctx, 0x08, 0xdd);
+ raydium_rm67200_write(ctx, 0x30, 0xdd);
+ raydium_rm67200_write(ctx, 0x59, 0xdd);
+ raydium_rm67200_write(ctx, 0x7f, 0xdd);
+ raydium_rm67200_write(ctx, 0xa6, 0xdd);
+ raydium_rm67200_write(ctx, 0xcd, 0xdd);
+ raydium_rm67200_write(ctx, 0x0e, 0x15);
+ raydium_rm67200_write(ctx, 0x0a, 0xe9);
+ raydium_rm67200_write(ctx, 0x36, 0x15);
+ raydium_rm67200_write(ctx, 0x32, 0xe9);
+ raydium_rm67200_write(ctx, 0x5f, 0x15);
+ raydium_rm67200_write(ctx, 0x5b, 0xe9);
+ raydium_rm67200_write(ctx, 0x85, 0x15);
+ raydium_rm67200_write(ctx, 0x81, 0xe9);
+ raydium_rm67200_write(ctx, 0xad, 0x15);
+ raydium_rm67200_write(ctx, 0xa9, 0xe9);
+ raydium_rm67200_write(ctx, 0xd3, 0x15);
+ raydium_rm67200_write(ctx, 0xcf, 0xe9);
+ raydium_rm67200_write(ctx, 0x0b, 0x14);
+ raydium_rm67200_write(ctx, 0x33, 0x14);
+ raydium_rm67200_write(ctx, 0x5c, 0x14);
+ raydium_rm67200_write(ctx, 0x82, 0x14);
+ raydium_rm67200_write(ctx, 0xaa, 0x14);
+ raydium_rm67200_write(ctx, 0xd0, 0x14);
+ raydium_rm67200_write(ctx, 0x0c, 0x36);
+ raydium_rm67200_write(ctx, 0x34, 0x36);
+ raydium_rm67200_write(ctx, 0x5d, 0x36);
+ raydium_rm67200_write(ctx, 0x83, 0x36);
+ raydium_rm67200_write(ctx, 0xab, 0x36);
+ raydium_rm67200_write(ctx, 0xd1, 0x36);
+ raydium_rm67200_write(ctx, 0x0d, 0x6b);
+ raydium_rm67200_write(ctx, 0x35, 0x6b);
+ raydium_rm67200_write(ctx, 0x5e, 0x6b);
+ raydium_rm67200_write(ctx, 0x84, 0x6b);
+ raydium_rm67200_write(ctx, 0xac, 0x6b);
+ raydium_rm67200_write(ctx, 0xd2, 0x6b);
+ raydium_rm67200_write(ctx, 0x13, 0x5a);
+ raydium_rm67200_write(ctx, 0x0f, 0x94);
+ raydium_rm67200_write(ctx, 0x3b, 0x5a);
+ raydium_rm67200_write(ctx, 0x37, 0x94);
+ raydium_rm67200_write(ctx, 0x64, 0x5a);
+ raydium_rm67200_write(ctx, 0x60, 0x94);
+ raydium_rm67200_write(ctx, 0x8a, 0x5a);
+ raydium_rm67200_write(ctx, 0x86, 0x94);
+ raydium_rm67200_write(ctx, 0xb2, 0x5a);
+ raydium_rm67200_write(ctx, 0xae, 0x94);
+ raydium_rm67200_write(ctx, 0xd8, 0x5a);
+ raydium_rm67200_write(ctx, 0xd4, 0x94);
+ raydium_rm67200_write(ctx, 0x10, 0xd1);
+ raydium_rm67200_write(ctx, 0x38, 0xd1);
+ raydium_rm67200_write(ctx, 0x61, 0xd1);
+ raydium_rm67200_write(ctx, 0x87, 0xd1);
+ raydium_rm67200_write(ctx, 0xaf, 0xd1);
+ raydium_rm67200_write(ctx, 0xd5, 0xd1);
+ raydium_rm67200_write(ctx, 0x11, 0x04);
+ raydium_rm67200_write(ctx, 0x39, 0x04);
+ raydium_rm67200_write(ctx, 0x62, 0x04);
+ raydium_rm67200_write(ctx, 0x88, 0x04);
+ raydium_rm67200_write(ctx, 0xb0, 0x04);
+ raydium_rm67200_write(ctx, 0xd6, 0x04);
+ raydium_rm67200_write(ctx, 0x12, 0x05);
+ raydium_rm67200_write(ctx, 0x3a, 0x05);
+ raydium_rm67200_write(ctx, 0x63, 0x05);
+ raydium_rm67200_write(ctx, 0x89, 0x05);
+ raydium_rm67200_write(ctx, 0xb1, 0x05);
+ raydium_rm67200_write(ctx, 0xd7, 0x05);
+ raydium_rm67200_write(ctx, 0x18, 0xaa);
+ raydium_rm67200_write(ctx, 0x14, 0x36);
+ raydium_rm67200_write(ctx, 0x42, 0xaa);
+ raydium_rm67200_write(ctx, 0x3d, 0x36);
+ raydium_rm67200_write(ctx, 0x69, 0xaa);
+ raydium_rm67200_write(ctx, 0x65, 0x36);
+ raydium_rm67200_write(ctx, 0x8f, 0xaa);
+ raydium_rm67200_write(ctx, 0x8b, 0x36);
+ raydium_rm67200_write(ctx, 0xb7, 0xaa);
+ raydium_rm67200_write(ctx, 0xb3, 0x36);
+ raydium_rm67200_write(ctx, 0xdd, 0xaa);
+ raydium_rm67200_write(ctx, 0xd9, 0x36);
+ raydium_rm67200_write(ctx, 0x15, 0x74);
+ raydium_rm67200_write(ctx, 0x3f, 0x74);
+ raydium_rm67200_write(ctx, 0x66, 0x74);
+ raydium_rm67200_write(ctx, 0x8c, 0x74);
+ raydium_rm67200_write(ctx, 0xb4, 0x74);
+ raydium_rm67200_write(ctx, 0xda, 0x74);
+ raydium_rm67200_write(ctx, 0x16, 0x9f);
+ raydium_rm67200_write(ctx, 0x40, 0x9f);
+ raydium_rm67200_write(ctx, 0x67, 0x9f);
+ raydium_rm67200_write(ctx, 0x8d, 0x9f);
+ raydium_rm67200_write(ctx, 0xb5, 0x9f);
+ raydium_rm67200_write(ctx, 0xdb, 0x9f);
+ raydium_rm67200_write(ctx, 0x17, 0xdc);
+ raydium_rm67200_write(ctx, 0x41, 0xdc);
+ raydium_rm67200_write(ctx, 0x68, 0xdc);
+ raydium_rm67200_write(ctx, 0x8e, 0xdc);
+ raydium_rm67200_write(ctx, 0xb6, 0xdc);
+ raydium_rm67200_write(ctx, 0xdc, 0xdc);
+ raydium_rm67200_write(ctx, 0x1d, 0xff);
+ raydium_rm67200_write(ctx, 0x19, 0x03);
+ raydium_rm67200_write(ctx, 0x47, 0xff);
+ raydium_rm67200_write(ctx, 0x43, 0x03);
+ raydium_rm67200_write(ctx, 0x6e, 0xff);
+ raydium_rm67200_write(ctx, 0x6a, 0x03);
+ raydium_rm67200_write(ctx, 0x94, 0xff);
+ raydium_rm67200_write(ctx, 0x90, 0x03);
+ raydium_rm67200_write(ctx, 0xbc, 0xff);
+ raydium_rm67200_write(ctx, 0xb8, 0x03);
+ raydium_rm67200_write(ctx, 0xe2, 0xff);
+ raydium_rm67200_write(ctx, 0xde, 0x03);
+ raydium_rm67200_write(ctx, 0x1a, 0x35);
+ raydium_rm67200_write(ctx, 0x44, 0x35);
+ raydium_rm67200_write(ctx, 0x6b, 0x35);
+ raydium_rm67200_write(ctx, 0x91, 0x35);
+ raydium_rm67200_write(ctx, 0xb9, 0x35);
+ raydium_rm67200_write(ctx, 0xdf, 0x35);
+ raydium_rm67200_write(ctx, 0x1b, 0x45);
+ raydium_rm67200_write(ctx, 0x45, 0x45);
+ raydium_rm67200_write(ctx, 0x6c, 0x45);
+ raydium_rm67200_write(ctx, 0x92, 0x45);
+ raydium_rm67200_write(ctx, 0xba, 0x45);
+ raydium_rm67200_write(ctx, 0xe0, 0x45);
+ raydium_rm67200_write(ctx, 0x1c, 0x55);
+ raydium_rm67200_write(ctx, 0x46, 0x55);
+ raydium_rm67200_write(ctx, 0x6d, 0x55);
+ raydium_rm67200_write(ctx, 0x93, 0x55);
+ raydium_rm67200_write(ctx, 0xbb, 0x55);
+ raydium_rm67200_write(ctx, 0xe1, 0x55);
+ raydium_rm67200_write(ctx, 0x22, 0xff);
+ raydium_rm67200_write(ctx, 0x1e, 0x68);
+ raydium_rm67200_write(ctx, 0x4c, 0xff);
+ raydium_rm67200_write(ctx, 0x48, 0x68);
+ raydium_rm67200_write(ctx, 0x73, 0xff);
+ raydium_rm67200_write(ctx, 0x6f, 0x68);
+ raydium_rm67200_write(ctx, 0x99, 0xff);
+ raydium_rm67200_write(ctx, 0x95, 0x68);
+ raydium_rm67200_write(ctx, 0xc1, 0xff);
+ raydium_rm67200_write(ctx, 0xbd, 0x68);
+ raydium_rm67200_write(ctx, 0xe7, 0xff);
+ raydium_rm67200_write(ctx, 0xe3, 0x68);
+ raydium_rm67200_write(ctx, 0x1f, 0x7e);
+ raydium_rm67200_write(ctx, 0x49, 0x7e);
+ raydium_rm67200_write(ctx, 0x70, 0x7e);
+ raydium_rm67200_write(ctx, 0x96, 0x7e);
+ raydium_rm67200_write(ctx, 0xbe, 0x7e);
+ raydium_rm67200_write(ctx, 0xe4, 0x7e);
+ raydium_rm67200_write(ctx, 0x20, 0x97);
+ raydium_rm67200_write(ctx, 0x4a, 0x97);
+ raydium_rm67200_write(ctx, 0x71, 0x97);
+ raydium_rm67200_write(ctx, 0x97, 0x97);
+ raydium_rm67200_write(ctx, 0xbf, 0x97);
+ raydium_rm67200_write(ctx, 0xe5, 0x97);
+ raydium_rm67200_write(ctx, 0x21, 0xb5);
+ raydium_rm67200_write(ctx, 0x4b, 0xb5);
+ raydium_rm67200_write(ctx, 0x72, 0xb5);
+ raydium_rm67200_write(ctx, 0x98, 0xb5);
+ raydium_rm67200_write(ctx, 0xc0, 0xb5);
+ raydium_rm67200_write(ctx, 0xe6, 0xb5);
+ raydium_rm67200_write(ctx, 0x25, 0xf0);
+ raydium_rm67200_write(ctx, 0x23, 0xe8);
+ raydium_rm67200_write(ctx, 0x4f, 0xf0);
+ raydium_rm67200_write(ctx, 0x4d, 0xe8);
+ raydium_rm67200_write(ctx, 0x76, 0xf0);
+ raydium_rm67200_write(ctx, 0x74, 0xe8);
+ raydium_rm67200_write(ctx, 0x9c, 0xf0);
+ raydium_rm67200_write(ctx, 0x9a, 0xe8);
+ raydium_rm67200_write(ctx, 0xc4, 0xf0);
+ raydium_rm67200_write(ctx, 0xc2, 0xe8);
+ raydium_rm67200_write(ctx, 0xea, 0xf0);
+ raydium_rm67200_write(ctx, 0xe8, 0xe8);
+ raydium_rm67200_write(ctx, 0x24, 0xff);
+ raydium_rm67200_write(ctx, 0x4e, 0xff);
+ raydium_rm67200_write(ctx, 0x75, 0xff);
+ raydium_rm67200_write(ctx, 0x9b, 0xff);
+ raydium_rm67200_write(ctx, 0xc3, 0xff);
+ raydium_rm67200_write(ctx, 0xe9, 0xff);
+ raydium_rm67200_write(ctx, 0xfe, 0x3d);
+ raydium_rm67200_write(ctx, 0x00, 0x04);
+ raydium_rm67200_write(ctx, 0xfe, 0x23);
+ raydium_rm67200_write(ctx, 0x08, 0x82);
+ raydium_rm67200_write(ctx, 0x0a, 0x00);
+ raydium_rm67200_write(ctx, 0x0b, 0x00);
+ raydium_rm67200_write(ctx, 0x0c, 0x01);
+ raydium_rm67200_write(ctx, 0x16, 0x00);
+ raydium_rm67200_write(ctx, 0x18, 0x02);
+ raydium_rm67200_write(ctx, 0x1b, 0x04);
+ raydium_rm67200_write(ctx, 0x19, 0x04);
+ raydium_rm67200_write(ctx, 0x1c, 0x81);
+ raydium_rm67200_write(ctx, 0x1f, 0x00);
+ raydium_rm67200_write(ctx, 0x20, 0x03);
+ raydium_rm67200_write(ctx, 0x23, 0x04);
+ raydium_rm67200_write(ctx, 0x21, 0x01);
+ raydium_rm67200_write(ctx, 0x54, 0x63);
+ raydium_rm67200_write(ctx, 0x55, 0x54);
+ raydium_rm67200_write(ctx, 0x6e, 0x45);
+ raydium_rm67200_write(ctx, 0x6d, 0x36);
+ raydium_rm67200_write(ctx, 0xfe, 0x3d);
+ raydium_rm67200_write(ctx, 0x55, 0x78);
+ raydium_rm67200_write(ctx, 0xfe, 0x20);
+ raydium_rm67200_write(ctx, 0x26, 0x30);
+ raydium_rm67200_write(ctx, 0xfe, 0x3d);
+ raydium_rm67200_write(ctx, 0x20, 0x71);
+ raydium_rm67200_write(ctx, 0x50, 0x8f);
+ raydium_rm67200_write(ctx, 0x51, 0x8f);
+ raydium_rm67200_write(ctx, 0xfe, 0x00);
+ raydium_rm67200_write(ctx, 0x35, 0x00);
+}
+
+static int raydium_rm67200_prepare(struct drm_panel *panel)
+{
+ struct raydium_rm67200 *ctx = to_raydium_rm67200(panel);
+ int ret;
+
+ ret = regulator_bulk_enable(ctx->num_supplies, ctx->supplies);
+ if (ret < 0)
+ return ret;
+
+ raydium_rm67200_reset(ctx);
+
+ msleep(60);
+
+ return 0;
+}
+
+static int raydium_rm67200_unprepare(struct drm_panel *panel)
+{
+ struct raydium_rm67200 *ctx = to_raydium_rm67200(panel);
+
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ regulator_bulk_disable(ctx->num_supplies, ctx->supplies);
+
+ msleep(60);
+
+ return 0;
+}
+
+static int raydium_rm67200_enable(struct drm_panel *panel)
+{
+ struct raydium_rm67200 *rm67200 = to_raydium_rm67200(panel);
+ struct mipi_dsi_multi_context ctx = { .dsi = rm67200->dsi };
+
+ rm67200->panel_info->panel_setup(&ctx);
+ mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
+ mipi_dsi_msleep(&ctx, 120);
+ mipi_dsi_dcs_set_display_on_multi(&ctx);
+ mipi_dsi_msleep(&ctx, 30);
+
+ return ctx.accum_err;
+}
+
+static int raydium_rm67200_disable(struct drm_panel *panel)
+{
+ struct raydium_rm67200 *rm67200 = to_raydium_rm67200(panel);
+ struct mipi_dsi_multi_context ctx = { .dsi = rm67200->dsi };
+
+ mipi_dsi_dcs_set_display_off_multi(&ctx);
+ mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
+ mipi_dsi_msleep(&ctx, 60);
+
+ return ctx.accum_err;
+}
+
+static int raydium_rm67200_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct raydium_rm67200 *ctx = to_raydium_rm67200(panel);
+
+ return drm_connector_helper_get_modes_fixed(connector, &ctx->panel_info->mode);
+}
+
+static const struct drm_panel_funcs raydium_rm67200_funcs = {
+ .prepare = raydium_rm67200_prepare,
+ .unprepare = raydium_rm67200_unprepare,
+ .get_modes = raydium_rm67200_get_modes,
+ .enable = raydium_rm67200_enable,
+ .disable = raydium_rm67200_disable,
+};
+
+static int raydium_rm67200_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct raydium_rm67200 *ctx;
+ int ret = 0;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->panel_info = device_get_match_data(dev);
+ if (!ctx->panel_info)
+ return -EINVAL;
+
+ ctx->num_supplies = ctx->panel_info->num_regulators;
+ ret = devm_regulator_bulk_get_const(&dsi->dev,
+ ctx->panel_info->num_regulators,
+ ctx->panel_info->regulators,
+ &ctx->supplies);
+ if (ret < 0)
+ return ret;
+
+ ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(ctx->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
+ "Failed to get reset-gpios\n");
+
+ ctx->dsi = dsi;
+ mipi_dsi_set_drvdata(dsi, ctx);
+
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM;
+ ctx->panel.prepare_prev_first = true;
+
+ drm_panel_init(&ctx->panel, dev, &raydium_rm67200_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+
+ ret = drm_panel_of_backlight(&ctx->panel);
+ if (ret)
+ return ret;
+
+ drm_panel_add(&ctx->panel);
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
+ drm_panel_remove(&ctx->panel);
+ }
+
+ return ret;
+}
+
+static void raydium_rm67200_remove(struct mipi_dsi_device *dsi)
+{
+ struct raydium_rm67200 *ctx = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ ret = mipi_dsi_detach(dsi);
+ if (ret < 0)
+ dev_err(&dsi->dev, "Failed to detach DSI host: %d\n", ret);
+
+ drm_panel_remove(&ctx->panel);
+}
+
+static const struct regulator_bulk_data w552793baa_regulators[] = {
+ { .supply = "vdd", }, /* 2.8V */
+ { .supply = "iovcc", }, /* 1.8V */
+ { .supply = "vsp", }, /* +5.5V */
+ { .supply = "vsn", }, /* -5.5V */
+};
+
+static const struct raydium_rm67200_panel_info w552793baa_info = {
+ .mode = {
+ .clock = 132000,
+ .hdisplay = 1080,
+ .hsync_start = 1095,
+ .hsync_end = 1125,
+ .htotal = 1129,
+ .vdisplay = 1920,
+ .vsync_start = 1935,
+ .vsync_end = 1950,
+ .vtotal = 1952,
+ .width_mm = 68, /* 68.04mm */
+ .height_mm = 121, /* 120.96mm */
+ .type = DRM_MODE_TYPE_DRIVER,
+ },
+ .regulators = w552793baa_regulators,
+ .num_regulators = ARRAY_SIZE(w552793baa_regulators),
+ .panel_setup = w552793baa_setup,
+};
+
+static const struct of_device_id raydium_rm67200_of_match[] = {
+ { .compatible = "wanchanglong,w552793baa", .data = &w552793baa_info },
+ { /*sentinel*/ }
+};
+MODULE_DEVICE_TABLE(of, raydium_rm67200_of_match);
+
+static struct mipi_dsi_driver raydium_rm67200_driver = {
+ .probe = raydium_rm67200_probe,
+ .remove = raydium_rm67200_remove,
+ .driver = {
+ .name = "panel-raydium-rm67200",
+ .of_match_table = raydium_rm67200_of_match,
+ },
+};
+module_mipi_dsi_driver(raydium_rm67200_driver);
+
+MODULE_AUTHOR("Sebastian Reichel <sebastian.reichel@collabora.com>");
+MODULE_DESCRIPTION("DRM driver for RM67200-equipped DSI panels");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 9b2f128fd309..232b03c1a259 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1374,6 +1374,64 @@ static const struct panel_desc bananapi_s070wv20_ct16 = {
},
};
+static const struct display_timing boe_av101hdt_a10_timing = {
+ .pixelclock = { 74210000, 75330000, 76780000, },
+ .hactive = { 1280, 1280, 1280, },
+ .hfront_porch = { 10, 42, 33, },
+ .hback_porch = { 10, 18, 33, },
+ .hsync_len = { 30, 10, 30, },
+ .vactive = { 720, 720, 720, },
+ .vfront_porch = { 200, 183, 200, },
+ .vback_porch = { 8, 8, 8, },
+ .vsync_len = { 2, 19, 2, },
+ .flags = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
+};
+
+static const struct panel_desc boe_av101hdt_a10 = {
+ .timings = &boe_av101hdt_a10_timing,
+ .num_timings = 1,
+ .bpc = 8,
+ .size = {
+ .width = 224,
+ .height = 126,
+ },
+ .delay = {
+ .enable = 50,
+ .disable = 50,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+ .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
+static const struct display_timing boe_av123z7m_n17_timing = {
+ .pixelclock = { 86600000, 88000000, 90800000, },
+ .hactive = { 1920, 1920, 1920, },
+ .hfront_porch = { 10, 10, 10, },
+ .hback_porch = { 10, 10, 10, },
+ .hsync_len = { 9, 12, 25, },
+ .vactive = { 720, 720, 720, },
+ .vfront_porch = { 7, 10, 13, },
+ .vback_porch = { 7, 10, 13, },
+ .vsync_len = { 7, 11, 14, },
+ .flags = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
+};
+
+static const struct panel_desc boe_av123z7m_n17 = {
+ .timings = &boe_av123z7m_n17_timing,
+ .bpc = 8,
+ .num_timings = 1,
+ .size = {
+ .width = 292,
+ .height = 110,
+ },
+ .delay = {
+ .prepare = 50,
+ .disable = 50,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+ .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
static const struct drm_display_mode boe_bp101wx1_100_mode = {
.clock = 78945,
.hdisplay = 1280,
@@ -4814,6 +4872,12 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "bananapi,s070wv20-ct16",
.data = &bananapi_s070wv20_ct16,
}, {
+ .compatible = "boe,av101hdt-a10",
+ .data = &boe_av101hdt_a10,
+ }, {
+ .compatible = "boe,av123z7m-n17",
+ .data = &boe_av123z7m_n17,
+ }, {
.compatible = "boe,bp082wx1-100",
.data = &boe_bp082wx1_100,
}, {
diff --git a/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c b/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c
index 472195d4bbbe..97f4bb4e1029 100644
--- a/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c
+++ b/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c
@@ -47,93 +47,40 @@ static inline struct sony_td4353_jdi *to_sony_td4353_jdi(struct drm_panel *panel
static int sony_td4353_jdi_on(struct sony_td4353_jdi *ctx)
{
struct mipi_dsi_device *dsi = ctx->dsi;
- struct device *dev = &dsi->dev;
- int ret;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
- ret = mipi_dsi_dcs_set_column_address(dsi, 0x0000, 1080 - 1);
- if (ret < 0) {
- dev_err(dev, "Failed to set column address: %d\n", ret);
- return ret;
- }
-
- ret = mipi_dsi_dcs_set_page_address(dsi, 0x0000, 2160 - 1);
- if (ret < 0) {
- dev_err(dev, "Failed to set page address: %d\n", ret);
- return ret;
- }
-
- ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0);
- if (ret < 0) {
- dev_err(dev, "Failed to set tear scanline: %d\n", ret);
- return ret;
- }
-
- ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
- if (ret < 0) {
- dev_err(dev, "Failed to set tear on: %d\n", ret);
- return ret;
- }
+ mipi_dsi_dcs_set_column_address_multi(&dsi_ctx, 0x0000, 1080 - 1);
+ mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0x0000, 2160 - 1);
+ mipi_dsi_dcs_set_tear_scanline_multi(&dsi_ctx, 0);
+ mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
- mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
-
- ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x77);
- if (ret < 0) {
- dev_err(dev, "Failed to set pixel format: %d\n", ret);
- return ret;
- }
-
- mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_ROWS,
- 0x00, 0x00, 0x08, 0x6f);
-
- ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
- if (ret < 0) {
- dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
- return ret;
- }
- msleep(70);
+ mipi_dsi_dcs_set_pixel_format_multi(&dsi_ctx, 0x77);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_PARTIAL_ROWS,
+ 0x00, 0x00, 0x08, 0x6f);
- mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_MEMORY_START);
+ mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 70);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_MEMORY_START);
+ mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
- ret = mipi_dsi_dcs_set_display_on(dsi);
- if (ret < 0) {
- dev_err(dev, "Failed to turn display on: %d\n", ret);
- return ret;
- }
-
- return 0;
+ return dsi_ctx.accum_err;
}
-static int sony_td4353_jdi_off(struct sony_td4353_jdi *ctx)
+static void sony_td4353_jdi_off(struct sony_td4353_jdi *ctx)
{
struct mipi_dsi_device *dsi = ctx->dsi;
- struct device *dev = &dsi->dev;
- int ret;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
- ret = mipi_dsi_dcs_set_display_off(dsi);
- if (ret < 0) {
- dev_err(dev, "Failed to set display off: %d\n", ret);
- return ret;
- }
- msleep(22);
-
- ret = mipi_dsi_dcs_set_tear_off(dsi);
- if (ret < 0) {
- dev_err(dev, "Failed to set tear off: %d\n", ret);
- return ret;
- }
-
- ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
- if (ret < 0) {
- dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
- return ret;
- }
- msleep(80);
-
- return 0;
+ mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 22);
+ mipi_dsi_dcs_set_tear_off_multi(&dsi_ctx);
+ mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 80);
}
static void sony_td4353_assert_reset_gpios(struct sony_td4353_jdi *ctx, int mode)
@@ -146,14 +93,11 @@ static void sony_td4353_assert_reset_gpios(struct sony_td4353_jdi *ctx, int mode
static int sony_td4353_jdi_prepare(struct drm_panel *panel)
{
struct sony_td4353_jdi *ctx = to_sony_td4353_jdi(panel);
- struct device *dev = &ctx->dsi->dev;
int ret;
ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
- if (ret < 0) {
- dev_err(dev, "Failed to enable regulators: %d\n", ret);
+ if (ret < 0)
return ret;
- }
msleep(100);
@@ -161,7 +105,6 @@ static int sony_td4353_jdi_prepare(struct drm_panel *panel)
ret = sony_td4353_jdi_on(ctx);
if (ret < 0) {
- dev_err(dev, "Failed to power on panel: %d\n", ret);
sony_td4353_assert_reset_gpios(ctx, 0);
regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
return ret;
@@ -173,12 +116,8 @@ static int sony_td4353_jdi_prepare(struct drm_panel *panel)
static int sony_td4353_jdi_unprepare(struct drm_panel *panel)
{
struct sony_td4353_jdi *ctx = to_sony_td4353_jdi(panel);
- struct device *dev = &ctx->dsi->dev;
- int ret;
- ret = sony_td4353_jdi_off(ctx);
- if (ret < 0)
- dev_err(dev, "Failed to power off panel: %d\n", ret);
+ sony_td4353_jdi_off(ctx);
sony_td4353_assert_reset_gpios(ctx, 0);
regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
diff --git a/drivers/gpu/drm/panel/panel-summit.c b/drivers/gpu/drm/panel/panel-summit.c
new file mode 100644
index 000000000000..e780faee1857
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-summit.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/backlight.h>
+#include <drm/drm_device.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_mode.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_probe_helper.h>
+#include <video/mipi_display.h>
+
+struct summit_data {
+ struct mipi_dsi_device *dsi;
+ struct backlight_device *bl;
+ struct drm_panel panel;
+};
+
+static int summit_set_brightness(struct device *dev)
+{
+ struct summit_data *s_data = dev_get_drvdata(dev);
+ int level = backlight_get_brightness(s_data->bl);
+
+ return mipi_dsi_dcs_set_display_brightness(s_data->dsi, level);
+}
+
+static int summit_bl_update_status(struct backlight_device *dev)
+{
+ return summit_set_brightness(&dev->dev);
+}
+
+static const struct backlight_ops summit_bl_ops = {
+ .update_status = summit_bl_update_status,
+};
+
+static struct drm_display_mode summit_mode = {
+ .vdisplay = 2008,
+ .hdisplay = 60,
+ .hsync_start = 60 + 8,
+ .hsync_end = 60 + 8 + 80,
+ .htotal = 60 + 8 + 80 + 40,
+ .vsync_start = 2008 + 1,
+ .vsync_end = 2008 + 1 + 15,
+ .vtotal = 2008 + 1 + 15 + 6,
+ .clock = ((60 + 8 + 80 + 40) * (2008 + 1 + 15 + 6) * 60) / 1000,
+ .type = DRM_MODE_TYPE_DRIVER,
+ .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC,
+};
+
+static int summit_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ connector->display_info.non_desktop = true;
+ drm_object_property_set_value(&connector->base,
+ connector->dev->mode_config.non_desktop_property,
+ connector->display_info.non_desktop);
+
+ return drm_connector_helper_get_modes_fixed(connector, &summit_mode);
+}
+
+static const struct drm_panel_funcs summit_panel_funcs = {
+ .get_modes = summit_get_modes,
+};
+
+static int summit_probe(struct mipi_dsi_device *dsi)
+{
+ struct backlight_properties props = { 0 };
+ struct device *dev = &dsi->dev;
+ struct summit_data *s_data;
+ int ret;
+
+ s_data = devm_kzalloc(dev, sizeof(*s_data), GFP_KERNEL);
+ if (!s_data)
+ return -ENOMEM;
+
+ mipi_dsi_set_drvdata(dsi, s_data);
+ s_data->dsi = dsi;
+
+ ret = device_property_read_u32(dev, "max-brightness", &props.max_brightness);
+ if (ret)
+ return ret;
+ props.type = BACKLIGHT_RAW;
+
+ s_data->bl = devm_backlight_device_register(dev, dev_name(dev),
+ dev, s_data, &summit_bl_ops, &props);
+ if (IS_ERR(s_data->bl))
+ return PTR_ERR(s_data->bl);
+
+ drm_panel_init(&s_data->panel, dev, &summit_panel_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ drm_panel_add(&s_data->panel);
+
+ return mipi_dsi_attach(dsi);
+}
+
+static void summit_remove(struct mipi_dsi_device *dsi)
+{
+ struct summit_data *s_data = mipi_dsi_get_drvdata(dsi);
+
+ mipi_dsi_detach(dsi);
+ drm_panel_remove(&s_data->panel);
+}
+
+static int summit_suspend(struct device *dev)
+{
+ struct summit_data *s_data = dev_get_drvdata(dev);
+
+ return mipi_dsi_dcs_set_display_brightness(s_data->dsi, 0);
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(summit_pm_ops, summit_suspend,
+ summit_set_brightness);
+
+static const struct of_device_id summit_of_match[] = {
+ { .compatible = "apple,summit" },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, summit_of_match);
+
+static struct mipi_dsi_driver summit_driver = {
+ .probe = summit_probe,
+ .remove = summit_remove,
+ .driver = {
+ .name = "panel-summit",
+ .of_match_table = summit_of_match,
+ .pm = pm_sleep_ptr(&summit_pm_ops),
+ },
+};
+module_mipi_dsi_driver(summit_driver);
+
+MODULE_DESCRIPTION("Summit Display Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/panel/panel-visionox-rm692e5.c b/drivers/gpu/drm/panel/panel-visionox-rm692e5.c
new file mode 100644
index 000000000000..4db7fa8d74c4
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-visionox-rm692e5.c
@@ -0,0 +1,442 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree:
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2025, Eugene Lepshy <fekz115@gmail.com>
+ * Copyright (c) 2025, Danila Tikhonov <danila@jiaxyga.com>
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/display/drm_dsc.h>
+#include <drm/display/drm_dsc_helper.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_probe_helper.h>
+
+struct visionox_rm692e5 {
+ struct drm_panel panel;
+ struct mipi_dsi_device *dsi;
+ struct drm_dsc_config dsc;
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data *supplies;
+};
+
+static const struct regulator_bulk_data visionox_rm692e5_supplies[] = {
+ { .supply = "vddio" }, /* 1p8 */
+ { .supply = "vdd" }, /* 3p3 */
+};
+
+static inline
+struct visionox_rm692e5 *to_visionox_rm692e5(struct drm_panel *panel)
+{
+ return container_of(panel, struct visionox_rm692e5, panel);
+}
+
+static void visionox_rm692e5_reset(struct visionox_rm692e5 *ctx)
+{
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+ usleep_range(10000, 11000);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ usleep_range(1000, 2000);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+ msleep(32);
+}
+
+static int visionox_rm692e5_on(struct visionox_rm692e5 *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xbd, 0x07);
+ mipi_dsi_usleep_range(&dsi_ctx, 17000, 18000);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xd2);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x11);
+ mipi_dsi_dcs_set_display_brightness_multi(&dsi_ctx, 0x00ab);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x30);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x38);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x14);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_CABC_MIN_BRIGHTNESS, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0xe8);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x33);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x38);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x54);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x62);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x69);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x70);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x77);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x79);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x7b);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x7d);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x7e);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x83, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x84, 0x22);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x85, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x86, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x87, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x88, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x89, 0xbe);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8a, 0x3a);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8b, 0xfc);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8c, 0x3a);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8d, 0xfa);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8e, 0x3a);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8f, 0xf8);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x90, 0x3b);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x91, 0x38);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x92, 0x3b);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x93, 0x78);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x94, 0x3b);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x95, 0xb6);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x96, 0x4b);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x97, 0xf6);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x98, 0x4c);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x99, 0x34);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9a, 0x4c);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9b, 0x74);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9c, 0x5c);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9d, 0x74);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9e, 0x8c);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9f, 0xf4);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_READ_PPS_START, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa3, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa4, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa5, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa6, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa7, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_READ_PPS_CONTINUE, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xaa, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa0, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xa1);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xcd, 0x6b);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xce, 0xbb);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb4, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x38);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfa, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xc2, 0x08);
+ mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+ mipi_dsi_dcs_set_display_brightness_multi(&dsi_ctx, 0x000d);
+ mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 50);
+ mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+ mipi_dsi_usleep_range(&dsi_ctx, 1000, 2000);
+
+ return dsi_ctx.accum_err;
+}
+
+static int visionox_rm692e5_disable(struct drm_panel *panel)
+{
+ struct visionox_rm692e5 *ctx = to_visionox_rm692e5(panel);
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
+ mipi_dsi_usleep_range(&dsi_ctx, 1000, 2000);
+ mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
+ mipi_dsi_usleep_range(&dsi_ctx, 1000, 2000);
+
+ return dsi_ctx.accum_err;
+}
+
+static int visionox_rm692e5_prepare(struct drm_panel *panel)
+{
+ struct visionox_rm692e5 *ctx = to_visionox_rm692e5(panel);
+ struct drm_dsc_picture_parameter_set pps;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(visionox_rm692e5_supplies),
+ ctx->supplies);
+ if (ret < 0)
+ return ret;
+
+ visionox_rm692e5_reset(ctx);
+
+ ret = visionox_rm692e5_on(ctx);
+ if (ret < 0) {
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ goto err;
+ }
+
+ drm_dsc_pps_payload_pack(&pps, &ctx->dsc);
+ mipi_dsi_picture_parameter_set_multi(&dsi_ctx, &pps);
+ mipi_dsi_compression_mode_ext_multi(&dsi_ctx, true, MIPI_DSI_COMPRESSION_DSC, 0);
+
+ mipi_dsi_msleep(&dsi_ctx, 28);
+
+ if (dsi_ctx.accum_err < 0) {
+ ret = dsi_ctx.accum_err;
+ goto err;
+ }
+
+ return dsi_ctx.accum_err;
+err:
+ regulator_bulk_disable(ARRAY_SIZE(visionox_rm692e5_supplies),
+ ctx->supplies);
+ return ret;
+}
+
+static int visionox_rm692e5_unprepare(struct drm_panel *panel)
+{
+ struct visionox_rm692e5 *ctx = to_visionox_rm692e5(panel);
+
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(visionox_rm692e5_supplies),
+ ctx->supplies);
+
+ return 0;
+}
+
+static const struct drm_display_mode visionox_rm692e5_modes[] = {
+ /* Let's initialize the highest frequency first */
+ { /* 120Hz mode */
+ .clock = (1080 + 26 + 39 + 36) * (2400 + 16 + 21 + 16) * 120 / 1000,
+ .hdisplay = 1080,
+ .hsync_start = 1080 + 26,
+ .hsync_end = 1080 + 26 + 39,
+ .htotal = 1080 + 26 + 39 + 36,
+ .vdisplay = 2400,
+ .vsync_start = 2400 + 16,
+ .vsync_end = 2400 + 16 + 21,
+ .vtotal = 2400 + 16 + 21 + 16,
+ .width_mm = 68,
+ .height_mm = 152,
+ .type = DRM_MODE_TYPE_DRIVER,
+ },
+ { /* 90Hz mode */
+ .clock = (1080 + 26 + 39 + 36) * (2400 + 16 + 21 + 16) * 90 / 1000,
+ .hdisplay = 1080,
+ .hsync_start = 1080 + 26,
+ .hsync_end = 1080 + 26 + 39,
+ .htotal = 1080 + 26 + 39 + 36,
+ .vdisplay = 2400,
+ .vsync_start = 2400 + 16,
+ .vsync_end = 2400 + 16 + 21,
+ .vtotal = 2400 + 16 + 21 + 16,
+ .width_mm = 68,
+ .height_mm = 152,
+ .type = DRM_MODE_TYPE_DRIVER,
+ },
+ { /* 60Hz mode */
+ .clock = (1080 + 26 + 39 + 36) * (2400 + 16 + 21 + 16) * 60 / 1000,
+ .hdisplay = 1080,
+ .hsync_start = 1080 + 26,
+ .hsync_end = 1080 + 26 + 39,
+ .htotal = 1080 + 26 + 39 + 36,
+ .vdisplay = 2400,
+ .vsync_start = 2400 + 16,
+ .vsync_end = 2400 + 16 + 21,
+ .vtotal = 2400 + 16 + 21 + 16,
+ .width_mm = 68,
+ .height_mm = 152,
+ .type = DRM_MODE_TYPE_DRIVER,
+ },
+};
+
+static int visionox_rm692e5_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ int count = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(visionox_rm692e5_modes); i++)
+ count += drm_connector_helper_get_modes_fixed(connector,
+ &visionox_rm692e5_modes[i]);
+
+ return count;
+}
+
+static const struct drm_panel_funcs visionox_rm692e5_panel_funcs = {
+ .prepare = visionox_rm692e5_prepare,
+ .unprepare = visionox_rm692e5_unprepare,
+ .disable = visionox_rm692e5_disable,
+ .get_modes = visionox_rm692e5_get_modes,
+};
+
+static int visionox_rm692e5_bl_update_status(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ u16 brightness = backlight_get_brightness(bl);
+ int ret;
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
+ if (ret < 0)
+ return ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ return 0;
+}
+
+static int visionox_rm692e5_bl_get_brightness(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ u16 brightness;
+ int ret;
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness);
+ if (ret < 0)
+ return ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ return brightness;
+}
+
+static const struct backlight_ops visionox_rm692e5_bl_ops = {
+ .update_status = visionox_rm692e5_bl_update_status,
+ .get_brightness = visionox_rm692e5_bl_get_brightness,
+};
+
+static struct backlight_device *
+visionox_rm692e5_create_backlight(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ const struct backlight_properties props = {
+ .type = BACKLIGHT_RAW,
+ .brightness = 2047,
+ .max_brightness = 4095,
+ };
+
+ return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
+ &visionox_rm692e5_bl_ops, &props);
+}
+
+static int visionox_rm692e5_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct visionox_rm692e5 *ctx;
+ int ret;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ret = devm_regulator_bulk_get_const(&dsi->dev,
+ ARRAY_SIZE(visionox_rm692e5_supplies),
+ visionox_rm692e5_supplies,
+ &ctx->supplies);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to get regulators\n");
+
+ ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(ctx->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
+ "Failed to get reset-gpios\n");
+
+ ctx->dsi = dsi;
+ mipi_dsi_set_drvdata(dsi, ctx);
+
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS;
+
+ drm_panel_init(&ctx->panel, dev, &visionox_rm692e5_panel_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ ctx->panel.prepare_prev_first = true;
+
+ ctx->panel.backlight = visionox_rm692e5_create_backlight(dsi);
+ if (IS_ERR(ctx->panel.backlight))
+ return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
+ "Failed to create backlight\n");
+
+ drm_panel_add(&ctx->panel);
+
+ dsi->dsc = &ctx->dsc;
+ ctx->dsc.dsc_version_major = 1;
+ ctx->dsc.dsc_version_minor = 1;
+ ctx->dsc.slice_height = 20;
+ ctx->dsc.slice_width = 540;
+ ctx->dsc.slice_count = 1080 / ctx->dsc.slice_width;
+ ctx->dsc.bits_per_component = 10;
+ ctx->dsc.bits_per_pixel = 8 << 4;
+ ctx->dsc.block_pred_enable = true;
+
+ ret = devm_mipi_dsi_attach(dev, dsi);
+ if (ret < 0) {
+ drm_panel_remove(&ctx->panel);
+ return dev_err_probe(dev, ret, "Failed to attach to DSI host\n");
+ }
+
+ return 0;
+}
+
+static void visionox_rm692e5_remove(struct mipi_dsi_device *dsi)
+{
+ struct visionox_rm692e5 *ctx = mipi_dsi_get_drvdata(dsi);
+
+ drm_panel_remove(&ctx->panel);
+}
+
+static const struct of_device_id visionox_rm692e5_of_match[] = {
+ { .compatible = "visionox,rm692e5" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, visionox_rm692e5_of_match);
+
+static struct mipi_dsi_driver visionox_rm692e5_driver = {
+ .probe = visionox_rm692e5_probe,
+ .remove = visionox_rm692e5_remove,
+ .driver = {
+ .name = "panel-visionox-rm692e5",
+ .of_match_table = visionox_rm692e5_of_match,
+ },
+};
+module_mipi_dsi_driver(visionox_rm692e5_driver);
+
+MODULE_AUTHOR("Eugene Lepshy <fekz115@gmail.com>");
+MODULE_AUTHOR("Danila Tikhonov <danila@jiaxyga.com>");
+MODULE_DESCRIPTION("DRM driver for Visionox RM692E5 cmd mode dsi panel");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index 69bcf0e99d57..87f88259ddf6 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -28,10 +28,9 @@
#include <drm/drm_print.h>
#include <drm/gpu_scheduler.h>
-#include "gpu_scheduler_trace.h"
+#include "sched_internal.h"
-#define to_drm_sched_job(sched_job) \
- container_of((sched_job), struct drm_sched_job, queue_node)
+#include "gpu_scheduler_trace.h"
/**
* drm_sched_entity_init - Init a context entity used by scheduler when
@@ -152,18 +151,6 @@ static bool drm_sched_entity_is_idle(struct drm_sched_entity *entity)
return false;
}
-/* Return true if entity could provide a job. */
-bool drm_sched_entity_is_ready(struct drm_sched_entity *entity)
-{
- if (spsc_queue_peek(&entity->job_queue) == NULL)
- return false;
-
- if (READ_ONCE(entity->dependency))
- return false;
-
- return true;
-}
-
/**
* drm_sched_entity_error - return error of last scheduled job
* @entity: scheduler entity to check
@@ -255,7 +242,7 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
/* The entity is guaranteed to not be used by the scheduler */
prev = rcu_dereference_check(entity->last_scheduled, true);
dma_fence_get(prev);
- while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
+ while ((job = drm_sched_entity_queue_pop(entity))) {
struct drm_sched_fence *s_fence = job->s_fence;
dma_fence_get(&s_fence->finished);
@@ -477,7 +464,7 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
{
struct drm_sched_job *sched_job;
- sched_job = to_drm_sched_job(spsc_queue_peek(&entity->job_queue));
+ sched_job = drm_sched_entity_queue_peek(entity);
if (!sched_job)
return NULL;
@@ -513,7 +500,7 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) {
struct drm_sched_job *next;
- next = to_drm_sched_job(spsc_queue_peek(&entity->job_queue));
+ next = drm_sched_entity_queue_peek(entity);
if (next) {
struct drm_sched_rq *rq;
diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
index 0f35f009b9d3..e971528504a5 100644
--- a/drivers/gpu/drm/scheduler/sched_fence.c
+++ b/drivers/gpu/drm/scheduler/sched_fence.c
@@ -29,6 +29,8 @@
#include <drm/gpu_scheduler.h>
+#include "sched_internal.h"
+
static struct kmem_cache *sched_fence_slab;
static int __init drm_sched_fence_slab_init(void)
diff --git a/drivers/gpu/drm/scheduler/sched_internal.h b/drivers/gpu/drm/scheduler/sched_internal.h
new file mode 100644
index 000000000000..599cf6e1bb74
--- /dev/null
+++ b/drivers/gpu/drm/scheduler/sched_internal.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: MIT */
+
+#ifndef _DRM_GPU_SCHEDULER_INTERNAL_H_
+#define _DRM_GPU_SCHEDULER_INTERNAL_H_
+
+
+/* Used to choose between FIFO and RR job-scheduling */
+extern int drm_sched_policy;
+
+#define DRM_SCHED_POLICY_RR 0
+#define DRM_SCHED_POLICY_FIFO 1
+
+void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
+
+void drm_sched_rq_add_entity(struct drm_sched_rq *rq,
+ struct drm_sched_entity *entity);
+void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
+ struct drm_sched_entity *entity);
+
+void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity,
+ struct drm_sched_rq *rq, ktime_t ts);
+
+void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
+struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity);
+
+struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity *s_entity,
+ void *owner);
+void drm_sched_fence_init(struct drm_sched_fence *fence,
+ struct drm_sched_entity *entity);
+void drm_sched_fence_free(struct drm_sched_fence *fence);
+
+void drm_sched_fence_scheduled(struct drm_sched_fence *fence,
+ struct dma_fence *parent);
+void drm_sched_fence_finished(struct drm_sched_fence *fence, int result);
+
+/**
+ * drm_sched_entity_queue_pop - Low level helper for popping queued jobs
+ *
+ * @entity: scheduler entity
+ *
+ * Low level helper for popping queued jobs.
+ *
+ * Returns: The job dequeued or NULL.
+ */
+static inline struct drm_sched_job *
+drm_sched_entity_queue_pop(struct drm_sched_entity *entity)
+{
+ struct spsc_node *node;
+
+ node = spsc_queue_pop(&entity->job_queue);
+ if (!node)
+ return NULL;
+
+ return container_of(node, struct drm_sched_job, queue_node);
+}
+
+/**
+ * drm_sched_entity_queue_peek - Low level helper for peeking at the job queue
+ *
+ * @entity: scheduler entity
+ *
+ * Low level helper for peeking at the job queue
+ *
+ * Returns: The job at the head of the queue or NULL.
+ */
+static inline struct drm_sched_job *
+drm_sched_entity_queue_peek(struct drm_sched_entity *entity)
+{
+ struct spsc_node *node;
+
+ node = spsc_queue_peek(&entity->job_queue);
+ if (!node)
+ return NULL;
+
+ return container_of(node, struct drm_sched_job, queue_node);
+}
+
+/* Return true if entity could provide a job. */
+static inline bool
+drm_sched_entity_is_ready(struct drm_sched_entity *entity)
+{
+ if (!spsc_queue_count(&entity->job_queue))
+ return false;
+
+ if (READ_ONCE(entity->dependency))
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index 8c36a59afb72..c634993f1346 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -78,6 +78,8 @@
#include <drm/gpu_scheduler.h>
#include <drm/spsc_queue.h>
+#include "sched_internal.h"
+
#define CREATE_TRACE_POINTS
#include "gpu_scheduler_trace.h"
@@ -87,9 +89,6 @@ static struct lockdep_map drm_sched_lockdep_map = {
};
#endif
-#define to_drm_sched_job(sched_job) \
- container_of((sched_job), struct drm_sched_job, queue_node)
-
int drm_sched_policy = DRM_SCHED_POLICY_FIFO;
/**
@@ -123,7 +122,7 @@ static bool drm_sched_can_queue(struct drm_gpu_scheduler *sched,
{
struct drm_sched_job *s_job;
- s_job = to_drm_sched_job(spsc_queue_peek(&entity->job_queue));
+ s_job = drm_sched_entity_queue_peek(entity);
if (!s_job)
return false;
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 54a73753eff9..ba315c66a04d 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -1900,7 +1900,6 @@ int ltdc_load(struct drm_device *ddev)
struct drm_panel *panel;
struct drm_crtc *crtc;
struct reset_control *rstc;
- struct resource *res;
int irq, i, nb_endpoints;
int ret = -ENODEV;
@@ -1966,8 +1965,7 @@ int ltdc_load(struct drm_device *ddev)
reset_control_deassert(rstc);
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- ldev->regs = devm_ioremap_resource(dev, res);
+ ldev->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ldev->regs)) {
DRM_ERROR("Unable to get ltdc registers\n");
ret = PTR_ERR(ldev->regs);
diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c
index 2748d1f21d86..7cf0f0ea1bfe 100644
--- a/drivers/gpu/drm/tiny/arcpgu.c
+++ b/drivers/gpu/drm/tiny/arcpgu.c
@@ -253,7 +253,6 @@ static int arcpgu_load(struct arcpgu_drm_private *arcpgu)
struct device_node *encoder_node = NULL, *endpoint_node = NULL;
struct drm_connector *connector = NULL;
struct drm_device *drm = &arcpgu->drm;
- struct resource *res;
int ret;
arcpgu->clk = devm_clk_get(drm->dev, "pxlclk");
@@ -270,8 +269,7 @@ static int arcpgu_load(struct arcpgu_drm_private *arcpgu)
drm->mode_config.max_height = 1080;
drm->mode_config.funcs = &arcpgu_drm_modecfg_funcs;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- arcpgu->regs = devm_ioremap_resource(&pdev->dev, res);
+ arcpgu->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(arcpgu->regs))
return PTR_ERR(arcpgu->regs);
diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index 52ba6c699bc8..5c3b51eb0a97 100644
--- a/drivers/gpu/drm/tiny/repaper.c
+++ b/drivers/gpu/drm/tiny/repaper.c
@@ -456,7 +456,7 @@ static void repaper_frame_fixed_repeat(struct repaper_epd *epd, u8 fixed_value,
enum repaper_stage stage)
{
u64 start = local_clock();
- u64 end = start + (epd->factored_stage_time * 1000 * 1000);
+ u64 end = start + ((u64)epd->factored_stage_time * 1000 * 1000);
do {
repaper_frame_fixed(epd, fixed_value, stage);
@@ -467,7 +467,7 @@ static void repaper_frame_data_repeat(struct repaper_epd *epd, const u8 *image,
const u8 *mask, enum repaper_stage stage)
{
u64 start = local_clock();
- u64 end = start + (epd->factored_stage_time * 1000 * 1000);
+ u64 end = start + ((u64)epd->factored_stage_time * 1000 * 1000);
do {
repaper_frame_data(epd, image, mask, stage);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index e878eddc9c3f..d20e5c53ba75 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -2926,15 +2926,16 @@ static int vc5_hdmi_init_resources(struct drm_device *drm,
struct resource *res;
int ret;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi");
- if (!res)
- return -ENODEV;
-
- vc4_hdmi->hdmicore_regs = devm_ioremap(dev, res->start,
- resource_size(res));
+ vc4_hdmi->hdmicore_regs = devm_platform_ioremap_resource_byname(pdev,
+ "hdmi");
if (!vc4_hdmi->hdmicore_regs)
return -ENOMEM;
+ /* This is shared between both HDMI controllers. Cannot
+ * claim for both instances. Lets not convert to using
+ * devm_platform_ioremap_resource_byname() like
+ * the rest
+ */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hd");
if (!res)
return -ENODEV;
@@ -2943,51 +2944,33 @@ static int vc5_hdmi_init_resources(struct drm_device *drm,
if (!vc4_hdmi->hd_regs)
return -ENOMEM;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cec");
- if (!res)
- return -ENODEV;
-
- vc4_hdmi->cec_regs = devm_ioremap(dev, res->start, resource_size(res));
+ vc4_hdmi->cec_regs = devm_platform_ioremap_resource_byname(pdev,
+ "cec");
if (!vc4_hdmi->cec_regs)
return -ENOMEM;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csc");
- if (!res)
- return -ENODEV;
-
- vc4_hdmi->csc_regs = devm_ioremap(dev, res->start, resource_size(res));
+ vc4_hdmi->csc_regs = devm_platform_ioremap_resource_byname(pdev,
+ "csc");
if (!vc4_hdmi->csc_regs)
return -ENOMEM;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dvp");
- if (!res)
- return -ENODEV;
-
- vc4_hdmi->dvp_regs = devm_ioremap(dev, res->start, resource_size(res));
+ vc4_hdmi->dvp_regs = devm_platform_ioremap_resource_byname(pdev,
+ "dvp");
if (!vc4_hdmi->dvp_regs)
return -ENOMEM;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
- if (!res)
- return -ENODEV;
+ vc4_hdmi->phy_regs = devm_platform_ioremap_resource_byname(pdev,
+ "phy");
- vc4_hdmi->phy_regs = devm_ioremap(dev, res->start, resource_size(res));
if (!vc4_hdmi->phy_regs)
return -ENOMEM;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "packet");
- if (!res)
- return -ENODEV;
-
- vc4_hdmi->ram_regs = devm_ioremap(dev, res->start, resource_size(res));
+ vc4_hdmi->ram_regs = devm_platform_ioremap_resource_byname(pdev,
+ "packet");
if (!vc4_hdmi->ram_regs)
return -ENOMEM;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rm");
- if (!res)
- return -ENODEV;
-
- vc4_hdmi->rm_regs = devm_ioremap(dev, res->start, resource_size(res));
+ vc4_hdmi->rm_regs = devm_platform_ioremap_resource_byname(pdev, "rm");
if (!vc4_hdmi->rm_regs)
return -ENOMEM;
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index 89a34dff85a4..5ae4241959f2 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -630,6 +630,8 @@ int drm_dp_read_lttpr_phy_caps(struct drm_dp_aux *aux,
u8 caps[DP_LTTPR_PHY_CAP_SIZE]);
int drm_dp_lttpr_count(const u8 cap[DP_LTTPR_COMMON_CAP_SIZE]);
int drm_dp_lttpr_max_link_rate(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
+int drm_dp_lttpr_set_transparent_mode(struct drm_dp_aux *aux, bool enable);
+int drm_dp_lttpr_init(struct drm_dp_aux *aux, int lttpr_count);
int drm_dp_lttpr_max_lane_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
bool drm_dp_lttpr_voltage_swing_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]);
bool drm_dp_lttpr_pre_emphasis_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]);
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 94400a78031f..bd40a443385c 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -346,7 +346,6 @@ int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
u16 end);
int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
u16 end);
-int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
enum mipi_dsi_dcs_tear_mode mode);
int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format);
@@ -379,6 +378,7 @@ void mipi_dsi_dcs_set_page_address_multi(struct mipi_dsi_multi_context *ctx,
u16 start, u16 end);
void mipi_dsi_dcs_set_tear_scanline_multi(struct mipi_dsi_multi_context *ctx,
u16 scanline);
+void mipi_dsi_dcs_set_tear_off_multi(struct mipi_dsi_multi_context *ctx);
/**
* mipi_dsi_generic_write_seq - transmit data using a generic write packet
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 6bf458dbce84..50928a7ae98e 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -71,12 +71,6 @@ enum drm_sched_priority {
DRM_SCHED_PRIORITY_COUNT
};
-/* Used to choose between FIFO and RR job-scheduling */
-extern int drm_sched_policy;
-
-#define DRM_SCHED_POLICY_RR 0
-#define DRM_SCHED_POLICY_FIFO 1
-
/**
* struct drm_sched_entity - A wrapper around a job queue (typically
* attached to the DRM file_priv).
@@ -338,8 +332,14 @@ struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f);
* to schedule the job.
*/
struct drm_sched_job {
- struct spsc_node queue_node;
- struct list_head list;
+ u64 id;
+
+ /**
+ * @submit_ts:
+ *
+ * When the job was pushed into the entity queue.
+ */
+ ktime_t submit_ts;
/**
* @sched:
@@ -349,24 +349,30 @@ struct drm_sched_job {
* has finished.
*/
struct drm_gpu_scheduler *sched;
+
struct drm_sched_fence *s_fence;
+ struct drm_sched_entity *entity;
+ enum drm_sched_priority s_priority;
u32 credits;
+ /** @last_dependency: tracks @dependencies as they signal */
+ unsigned int last_dependency;
+ atomic_t karma;
+
+ struct spsc_node queue_node;
+ struct list_head list;
/*
* work is used only after finish_cb has been used and will not be
* accessed anymore.
*/
union {
- struct dma_fence_cb finish_cb;
- struct work_struct work;
+ struct dma_fence_cb finish_cb;
+ struct work_struct work;
};
- uint64_t id;
- atomic_t karma;
- enum drm_sched_priority s_priority;
- struct drm_sched_entity *entity;
struct dma_fence_cb cb;
+
/**
* @dependencies:
*
@@ -375,24 +381,8 @@ struct drm_sched_job {
* drm_sched_job_add_implicit_dependencies().
*/
struct xarray dependencies;
-
- /** @last_dependency: tracks @dependencies as they signal */
- unsigned long last_dependency;
-
- /**
- * @submit_ts:
- *
- * When the job was pushed into the entity queue.
- */
- ktime_t submit_ts;
};
-static inline bool drm_sched_invalidate_job(struct drm_sched_job *s_job,
- int threshold)
-{
- return s_job && atomic_inc_return(&s_job->karma) > threshold;
-}
-
enum drm_gpu_sched_stat {
DRM_GPU_SCHED_STAT_NONE, /* Reserve 0 */
DRM_GPU_SCHED_STAT_NOMINAL,
@@ -570,14 +560,36 @@ struct drm_sched_init_args {
struct device *dev;
};
+/* Scheduler operations */
+
int drm_sched_init(struct drm_gpu_scheduler *sched,
const struct drm_sched_init_args *args);
void drm_sched_fini(struct drm_gpu_scheduler *sched);
+
+unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched);
+void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
+ unsigned long remaining);
+void drm_sched_tdr_queue_imm(struct drm_gpu_scheduler *sched);
+bool drm_sched_wqueue_ready(struct drm_gpu_scheduler *sched);
+void drm_sched_wqueue_stop(struct drm_gpu_scheduler *sched);
+void drm_sched_wqueue_start(struct drm_gpu_scheduler *sched);
+void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad);
+void drm_sched_start(struct drm_gpu_scheduler *sched, int errno);
+void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched);
+void drm_sched_fault(struct drm_gpu_scheduler *sched);
+
+struct drm_gpu_scheduler *
+drm_sched_pick_best(struct drm_gpu_scheduler **sched_list,
+ unsigned int num_sched_list);
+
+/* Jobs */
+
int drm_sched_job_init(struct drm_sched_job *job,
struct drm_sched_entity *entity,
u32 credits, void *owner);
void drm_sched_job_arm(struct drm_sched_job *job);
+void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
int drm_sched_job_add_dependency(struct drm_sched_job *job,
struct dma_fence *fence);
int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
@@ -592,30 +604,16 @@ int drm_sched_job_add_implicit_dependencies(struct drm_sched_job *job,
bool write);
bool drm_sched_job_has_dependency(struct drm_sched_job *job,
struct dma_fence *fence);
-
-void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
- struct drm_gpu_scheduler **sched_list,
- unsigned int num_sched_list);
-
-void drm_sched_tdr_queue_imm(struct drm_gpu_scheduler *sched);
void drm_sched_job_cleanup(struct drm_sched_job *job);
-void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
-bool drm_sched_wqueue_ready(struct drm_gpu_scheduler *sched);
-void drm_sched_wqueue_stop(struct drm_gpu_scheduler *sched);
-void drm_sched_wqueue_start(struct drm_gpu_scheduler *sched);
-void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad);
-void drm_sched_start(struct drm_gpu_scheduler *sched, int errno);
-void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched);
void drm_sched_increase_karma(struct drm_sched_job *bad);
-void drm_sched_fault(struct drm_gpu_scheduler *sched);
-void drm_sched_rq_add_entity(struct drm_sched_rq *rq,
- struct drm_sched_entity *entity);
-void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
- struct drm_sched_entity *entity);
+static inline bool drm_sched_invalidate_job(struct drm_sched_job *s_job,
+ int threshold)
+{
+ return s_job && atomic_inc_return(&s_job->karma) > threshold;
+}
-void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity,
- struct drm_sched_rq *rq, ktime_t ts);
+/* Entities */
int drm_sched_entity_init(struct drm_sched_entity *entity,
enum drm_sched_priority priority,
@@ -625,29 +623,11 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
void drm_sched_entity_fini(struct drm_sched_entity *entity);
void drm_sched_entity_destroy(struct drm_sched_entity *entity);
-void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
-struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity);
-void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
enum drm_sched_priority priority);
-bool drm_sched_entity_is_ready(struct drm_sched_entity *entity);
int drm_sched_entity_error(struct drm_sched_entity *entity);
-
-struct drm_sched_fence *drm_sched_fence_alloc(
- struct drm_sched_entity *s_entity, void *owner);
-void drm_sched_fence_init(struct drm_sched_fence *fence,
- struct drm_sched_entity *entity);
-void drm_sched_fence_free(struct drm_sched_fence *fence);
-
-void drm_sched_fence_scheduled(struct drm_sched_fence *fence,
- struct dma_fence *parent);
-void drm_sched_fence_finished(struct drm_sched_fence *fence, int result);
-
-unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched);
-void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
- unsigned long remaining);
-struct drm_gpu_scheduler *
-drm_sched_pick_best(struct drm_gpu_scheduler **sched_list,
- unsigned int num_sched_list);
+void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
+ struct drm_gpu_scheduler **sched_list,
+ unsigned int num_sched_list);
#endif