drm-misc-next for v6.15:

Cross-subsystem Changes:
 
 bus:
 - mhi: Avoid access to uninitialized field
 
 Core Changes:
 
 - Fix docmentation
 
 dp:
 - Add helpers for LTTPR transparent mode
 
 sched:
 - Improve job peek/pop operations
 - Optimize layout of struct drm_sched_job
 
 Driver Changes:
 
 arc:
 - Convert to devm_platform_ioremap_resource()
 
 aspeed:
 - Convert to devm_platform_ioremap_resource()
 
 bridge:
 - ti-sn65dsi86: Support CONFIG_PWM tristate
 
 i915:
 - dp: Use helpers for LTTPR transparent mode
 
 mediatek:
 - Convert to devm_platform_ioremap_resource()
 
 msm:
 - dp: Use helpers for LTTPR transparent mode
 
 nouveau:
 - dp: Use helpers for LTTPR transparent mode
 
 panel:
 - raydium-rm67200: Add driver for Raydium RM67200
 - simple: Add support for BOE AV123Z7M-N17, BOE AV123Z7M-N17
 - sony-td4353-jdi: Use MIPI-DSI multi-func interface
 - summit: Add driver for Apple Summit display panel
 - visionox-rm692e5: Add driver for Visionox RM692E5
 
 repaper:
 - Fix integer overflows
 
 stm:
 - Convert to devm_platform_ioremap_resource()
 
 vc4:
 - Convert to devm_platform_ioremap_resource()
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmfAMnwACgkQaA3BHVML
 eiOszgf+NCaYdCCKXurnKy2DVHZ61ar+Fg/FHYs1oThFVqknRT9CBGY93g3I7VGs
 gYUATrH2fYt4daIF94ap4YLYuMrZSKXSd0duzr8lQzCVAb/UgvUap9yjGwJsCOZA
 bE2jxlKvo6cUJbq19+ATgrAQ7y31/w30PCPyBjMGR0t4C3bBbbCHpxFyKzDWCtFT
 JS6pNbCPblZCCvtFPmQRqQqLSE0K5x4SE49ZpHM6hhA4MavlwoN4ZkWincliSzF2
 XVCo7QHpVy3SItshhOB7ch7pIdkbm6nUvW2poR3UdXe+B+OSKRIz0C+2E98bYAra
 vwkyWoUP2A9nKZBsNy2d5026DeUDwg==
 =KURF
 -----END PGP SIGNATURE-----

Merge tag 'drm-misc-next-2025-02-27' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for v6.15:

Cross-subsystem Changes:

bus:
- mhi: Avoid access to uninitialized field

Core Changes:

- Fix docmentation

dp:
- Add helpers for LTTPR transparent mode

sched:
- Improve job peek/pop operations
- Optimize layout of struct drm_sched_job

Driver Changes:

arc:
- Convert to devm_platform_ioremap_resource()

aspeed:
- Convert to devm_platform_ioremap_resource()

bridge:
- ti-sn65dsi86: Support CONFIG_PWM tristate

i915:
- dp: Use helpers for LTTPR transparent mode

mediatek:
- Convert to devm_platform_ioremap_resource()

msm:
- dp: Use helpers for LTTPR transparent mode

nouveau:
- dp: Use helpers for LTTPR transparent mode

panel:
- raydium-rm67200: Add driver for Raydium RM67200
- simple: Add support for BOE AV123Z7M-N17, BOE AV123Z7M-N17
- sony-td4353-jdi: Use MIPI-DSI multi-func interface
- summit: Add driver for Apple Summit display panel
- visionox-rm692e5: Add driver for Visionox RM692E5

repaper:
- Fix integer overflows

stm:
- Convert to devm_platform_ioremap_resource()

vc4:
- Convert to devm_platform_ioremap_resource()

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

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20250227094041.GA114623@linux.fritz.box
This commit is contained in:
Dave Airlie 2025-02-28 12:35:52 +10:00
commit e21cba7047
45 changed files with 1681 additions and 315 deletions

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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>;
};
};
};
};
...

View File

@ -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>;
};
};
};
};
...

View File

@ -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
===================

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -2875,6 +2875,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

View File

@ -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.
*/

View File

@ -1265,25 +1265,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.
@ -1713,6 +1694,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

View File

@ -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

View File

@ -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:

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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;

View File

@ -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");

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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");

View File

@ -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,
@ -4813,6 +4871,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,

View File

@ -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;
}
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);
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;
}
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);
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;
}
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_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_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_write_seq(dsi, MIPI_DCS_WRITE_MEMORY_START);
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);

View File

@ -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");

View File

@ -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");

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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]);

View File

@ -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

View File

@ -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_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