mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
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:
commit
e21cba7047
3
.mailmap
3
.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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 = <®ulator1>;
|
||||
iovcc-supply = <®ulator2>;
|
||||
vsp-supply = <®ulator3>;
|
||||
vsn-supply = <®ulator4>;
|
||||
reset-gpios = <&gpiobank 42 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
panel0_in: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -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
|
||||
===================
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
499
drivers/gpu/drm/panel/panel-raydium-rm67200.c
Normal file
499
drivers/gpu/drm/panel/panel-raydium-rm67200.c
Normal 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");
|
@ -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,
|
||||
|
@ -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);
|
||||
|
132
drivers/gpu/drm/panel/panel-summit.c
Normal file
132
drivers/gpu/drm/panel/panel-summit.c
Normal 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");
|
442
drivers/gpu/drm/panel/panel-visionox-rm692e5.c
Normal file
442
drivers/gpu/drm/panel/panel-visionox-rm692e5.c
Normal 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");
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
91
drivers/gpu/drm/scheduler/sched_internal.h
Normal file
91
drivers/gpu/drm/scheduler/sched_internal.h
Normal 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
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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]);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user