drm-misc-next for 5.15:
UAPI Changes: Cross-subsystem Changes: Core Changes: Driver Changes: - Conversions to dev_err_probe() helper - rockchip: Various build improvements, Use DRM_BRIDGE_ATTACH_NO_CONNECTOR for LVDS and RGB - panel: New panel-edp driver -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQRcEzekXsqa64kGDp7j7w1vZxhRxQUCYUwwfAAKCRDj7w1vZxhR xaiVAP0VRNLapEFzXiSKz4BC3lK1bxMW9EA41fw6QqOgc1W7dgD7BDc07sSR4i1h 1eAAYyuygCFH9JPaDmjTB4uH+X+QKgw= =wh6l -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-2021-09-23' of git://anongit.freedesktop.org/drm/drm-misc into drm-next drm-misc-next for 5.15: UAPI Changes: Cross-subsystem Changes: Core Changes: Driver Changes: - Conversions to dev_err_probe() helper - rockchip: Various build improvements, Use DRM_BRIDGE_ATTACH_NO_CONNECTOR for LVDS and RGB - panel: New panel-edp driver Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20210923074522.zaja7mzxeimxf6g3@gilmour
This commit is contained in:
commit
f602a96e02
|
@ -0,0 +1,188 @@
|
||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/display/panel/panel-edp.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Probeable (via DP AUX / EDID) eDP Panels with simple poweron sequences
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Douglas Anderson <dianders@chromium.org>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
This binding file can be used to indicate that an eDP panel is connected
|
||||||
|
to a Embedded DisplayPort AUX bus (see display/dp-aux-bus.yaml) without
|
||||||
|
actually specifying exactly what panel is connected. This is useful for
|
||||||
|
the case that more than one different panel could be connected to the
|
||||||
|
board, either for second-sourcing purposes or to support multiple SKUs
|
||||||
|
with different LCDs that hook up to a common board.
|
||||||
|
|
||||||
|
As per above, a requirement for using this binding is that the panel is
|
||||||
|
represented under the DP AUX bus. This means that we can use any
|
||||||
|
information provided by the DP AUX bus (including the EDID) to identify
|
||||||
|
the panel. We can use this to identify display size, resolution, and
|
||||||
|
timings among other things.
|
||||||
|
|
||||||
|
One piece of information about eDP panels that is typically _not_
|
||||||
|
provided anywhere on the DP AUX bus is the power sequencing timings.
|
||||||
|
This is the reason why, historically, we've always had to explicitly
|
||||||
|
list eDP panels. We solve that here with two tricks. The "worst case"
|
||||||
|
power on timings for any panels expected to be connected to a board are
|
||||||
|
specified in these bindings. Once we've powered on, it's expected that
|
||||||
|
the operating system will lookup the panel in a table (based on EDID
|
||||||
|
information) to figure out other power sequencing timings.
|
||||||
|
|
||||||
|
eDP panels in general can have somewhat arbitrary power sequencing
|
||||||
|
requirements. However, even though it's arbitrary in general, the
|
||||||
|
vast majority of panel datasheets have a power sequence diagram that
|
||||||
|
looks the exactly the same as every other panel. Each panel datasheet
|
||||||
|
cares about different timings in this diagram but the fact that the
|
||||||
|
diagram is so similar means we can come up with a single driver to
|
||||||
|
handle it.
|
||||||
|
|
||||||
|
These diagrams all look roughly like this, sometimes labeled with
|
||||||
|
slightly different numbers / lines but all pretty much the same
|
||||||
|
sequence. This is because much of this diagram comes straight from
|
||||||
|
the eDP Standard.
|
||||||
|
|
||||||
|
__________________________________________________
|
||||||
|
Vdd ___/: :\____ /
|
||||||
|
_/ : : \_____/
|
||||||
|
:<T1>:<T2>: :<--T10-->:<T11>:<T12>:
|
||||||
|
: +-----------------------+---------+---------+
|
||||||
|
eDP -----------+ Black video | Src vid | Blk vid +
|
||||||
|
Display : +-----------------------+---------+---------+
|
||||||
|
: _______________________:_________:_________:
|
||||||
|
HPD :<T3>| : : |
|
||||||
|
___________| : : |_____________
|
||||||
|
: : : :
|
||||||
|
Sink +-----------------------:---------:---------+
|
||||||
|
AUX CH -----------+ AUX Ch operational : : +-------------
|
||||||
|
+-----------------------:---------:---------+
|
||||||
|
: : : :
|
||||||
|
:<T4>: :<T7>: : :
|
||||||
|
Src main +------+------+--------------+---------+
|
||||||
|
lnk data----------------+LnkTrn| Idle |Valid vid data| Idle/off+-------------
|
||||||
|
+------+------+--------------+---------+
|
||||||
|
: <T5> :<-T6->:<-T8->: :
|
||||||
|
:__:<T9>:
|
||||||
|
LED_EN | |
|
||||||
|
_____________________________________| |____________________________
|
||||||
|
: :
|
||||||
|
__________:__:_
|
||||||
|
PWM | : : |
|
||||||
|
__________________________| : : |__________________________
|
||||||
|
: : : :
|
||||||
|
_____________:__________:__:_:______
|
||||||
|
Bklight ____/: : : : : :\____
|
||||||
|
power _______/ :<---T13---->: : : :<T16>: \______________
|
||||||
|
(Vbl) :<T17>:<---------T14--------->: :<-T15->:<T18>:
|
||||||
|
|
||||||
|
The above looks fairly complex but, as per above, each panel only cares
|
||||||
|
about a subset of those timings.
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: panel-common.yaml#
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: edp-panel
|
||||||
|
|
||||||
|
hpd-reliable-delay-ms:
|
||||||
|
description:
|
||||||
|
A fixed amount of time that must be waited after powering on the
|
||||||
|
panel's power-supply before the HPD signal is a reliable way to know
|
||||||
|
when the AUX channel is ready. This is useful for panels that glitch
|
||||||
|
the HPD at the start of power-on. This value is not needed if HPD is
|
||||||
|
always reliable for all panels that might be connected.
|
||||||
|
|
||||||
|
hpd-absent-delay-ms:
|
||||||
|
description:
|
||||||
|
The panel specifies that HPD will be asserted this many milliseconds
|
||||||
|
from power on (timing T3 in the diagram above). If we have no way to
|
||||||
|
measure HPD then a fixed delay of this many milliseconds can be used.
|
||||||
|
This can also be used as a timeout when waiting for HPD. Does not
|
||||||
|
include the hpd-reliable-delay, so if hpd-reliable-delay was 80 ms
|
||||||
|
and hpd-absent-delay was 200 ms then we'd do a fixed 80 ms delay and
|
||||||
|
then we know HPD would assert in the next 120 ms. This value is not
|
||||||
|
needed if HPD hooked up, either through a GPIO in the panel node or
|
||||||
|
hooked up directly to the eDP controller.
|
||||||
|
|
||||||
|
backlight: true
|
||||||
|
enable-gpios: true
|
||||||
|
port: true
|
||||||
|
power-supply: true
|
||||||
|
no-hpd: true
|
||||||
|
hpd-gpios: true
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- power-supply
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
|
||||||
|
i2c {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
bridge@2d {
|
||||||
|
compatible = "ti,sn65dsi86";
|
||||||
|
reg = <0x2d>;
|
||||||
|
|
||||||
|
interrupt-parent = <&tlmm>;
|
||||||
|
interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
|
||||||
|
enable-gpios = <&tlmm 102 GPIO_ACTIVE_HIGH>;
|
||||||
|
|
||||||
|
vpll-supply = <&src_pp1800_s4a>;
|
||||||
|
vccio-supply = <&src_pp1800_s4a>;
|
||||||
|
vcca-supply = <&src_pp1200_l2a>;
|
||||||
|
vcc-supply = <&src_pp1200_l2a>;
|
||||||
|
|
||||||
|
clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
|
||||||
|
clock-names = "refclk";
|
||||||
|
|
||||||
|
no-hpd;
|
||||||
|
|
||||||
|
ports {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
port@0 {
|
||||||
|
reg = <0>;
|
||||||
|
endpoint {
|
||||||
|
remote-endpoint = <&dsi0_out>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
port@1 {
|
||||||
|
reg = <1>;
|
||||||
|
sn65dsi86_out: endpoint {
|
||||||
|
remote-endpoint = <&panel_in_edp>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
aux-bus {
|
||||||
|
panel {
|
||||||
|
compatible = "edp-panel";
|
||||||
|
power-supply = <&pp3300_dx_edp>;
|
||||||
|
backlight = <&backlight>;
|
||||||
|
hpd-gpios = <&sn65dsi86_bridge 2 GPIO_ACTIVE_HIGH>;
|
||||||
|
hpd-reliable-delay-ms = <15>;
|
||||||
|
|
||||||
|
port {
|
||||||
|
panel_in_edp: endpoint {
|
||||||
|
remote-endpoint = <&sn65dsi86_out>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
10
MAINTAINERS
10
MAINTAINERS
|
@ -6022,7 +6022,7 @@ DRM DRIVER FOR SAMSUNG S6D27A1 PANELS
|
||||||
M: Markuss Broks <markuss.broks@gmail.com>
|
M: Markuss Broks <markuss.broks@gmail.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/display/panel/samsung,s6d27a1.yaml
|
F: Documentation/devicetree/bindings/display/panel/samsung,s6d27a1.yaml
|
||||||
F: driver/gpu/drm/panel/panel-samsung-s6d27a1.c
|
F: drivers/gpu/drm/panel/panel-samsung-s6d27a1.c
|
||||||
|
|
||||||
DRM DRIVER FOR SITRONIX ST7703 PANELS
|
DRM DRIVER FOR SITRONIX ST7703 PANELS
|
||||||
M: Guido Günther <agx@sigxcpu.org>
|
M: Guido Günther <agx@sigxcpu.org>
|
||||||
|
@ -6431,6 +6431,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||||
F: drivers/gpu/drm/ttm/
|
F: drivers/gpu/drm/ttm/
|
||||||
F: include/drm/ttm/
|
F: include/drm/ttm/
|
||||||
|
|
||||||
|
DRM GPU SCHEDULER
|
||||||
|
M: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
|
||||||
|
L: dri-devel@lists.freedesktop.org
|
||||||
|
S: Maintained
|
||||||
|
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||||
|
F: drivers/gpu/drm/scheduler/
|
||||||
|
F: include/drm/gpu_scheduler.h
|
||||||
|
|
||||||
DSBR100 USB FM RADIO DRIVER
|
DSBR100 USB FM RADIO DRIVER
|
||||||
M: Alexey Klimov <klimov.linux@gmail.com>
|
M: Alexey Klimov <klimov.linux@gmail.com>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
|
|
|
@ -144,6 +144,7 @@ CONFIG_VIDEO_MT9V032=m
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_ATMEL_HLCDC=y
|
CONFIG_DRM_ATMEL_HLCDC=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_FB_ATMEL=y
|
CONFIG_FB_ATMEL=y
|
||||||
CONFIG_BACKLIGHT_ATMEL_LCDC=y
|
CONFIG_BACKLIGHT_ATMEL_LCDC=y
|
||||||
CONFIG_BACKLIGHT_PWM=y
|
CONFIG_BACKLIGHT_PWM=y
|
||||||
|
|
|
@ -227,6 +227,7 @@ CONFIG_DRM_EXYNOS_DPI=y
|
||||||
CONFIG_DRM_EXYNOS_DSI=y
|
CONFIG_DRM_EXYNOS_DSI=y
|
||||||
CONFIG_DRM_EXYNOS_HDMI=y
|
CONFIG_DRM_EXYNOS_HDMI=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
|
CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
|
||||||
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=y
|
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=y
|
||||||
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
|
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
|
||||||
|
|
|
@ -281,6 +281,7 @@ CONFIG_DRM=y
|
||||||
CONFIG_DRM_MSM=y
|
CONFIG_DRM_MSM=y
|
||||||
CONFIG_DRM_PANEL_LVDS=y
|
CONFIG_DRM_PANEL_LVDS=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
|
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
|
||||||
CONFIG_DRM_TI_TFP410=y
|
CONFIG_DRM_TI_TFP410=y
|
||||||
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
|
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
|
||||||
|
|
|
@ -108,6 +108,7 @@ CONFIG_REGULATOR=y
|
||||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_PL111=y
|
CONFIG_DRM_PL111=y
|
||||||
CONFIG_FB_MODE_HELPERS=y
|
CONFIG_FB_MODE_HELPERS=y
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
|
|
|
@ -194,6 +194,7 @@ CONFIG_VIDEO_ATMEL_ISI=m
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_ATMEL_HLCDC=m
|
CONFIG_DRM_ATMEL_HLCDC=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_ASPEED_GFX=m
|
CONFIG_DRM_ASPEED_GFX=m
|
||||||
CONFIG_FB_IMX=y
|
CONFIG_FB_IMX=y
|
||||||
CONFIG_FB_ATMEL=y
|
CONFIG_FB_ATMEL=y
|
||||||
|
|
|
@ -704,6 +704,7 @@ CONFIG_DRM_TEGRA=y
|
||||||
CONFIG_DRM_STM=m
|
CONFIG_DRM_STM=m
|
||||||
CONFIG_DRM_STM_DSI=m
|
CONFIG_DRM_STM_DSI=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
|
CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
|
||||||
CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
|
CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
|
||||||
CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
|
CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
|
||||||
|
|
|
@ -511,6 +511,7 @@ CONFIG_OMAP2_DSS_DSI=y
|
||||||
CONFIG_DRM_TILCDC=m
|
CONFIG_DRM_TILCDC=m
|
||||||
CONFIG_DRM_PANEL_DSI_CM=m
|
CONFIG_DRM_PANEL_DSI_CM=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=m
|
CONFIG_DRM_PANEL_SIMPLE=m
|
||||||
|
CONFIG_DRM_PANEL_EDP=m
|
||||||
CONFIG_DRM_PANEL_LG_LB035Q02=m
|
CONFIG_DRM_PANEL_LG_LB035Q02=m
|
||||||
CONFIG_DRM_PANEL_NEC_NL8048HL11=m
|
CONFIG_DRM_PANEL_NEC_NL8048HL11=m
|
||||||
CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m
|
CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m
|
||||||
|
|
|
@ -158,6 +158,7 @@ CONFIG_MEDIA_SUPPORT=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_MSM=m
|
CONFIG_DRM_MSM=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_ANALOGIX_ANX78XX=m
|
CONFIG_DRM_ANALOGIX_ANX78XX=m
|
||||||
CONFIG_FB=y
|
CONFIG_FB=y
|
||||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||||
|
|
|
@ -61,6 +61,7 @@ CONFIG_REGULATOR=y
|
||||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
||||||
CONFIG_DRM_SIMPLE_BRIDGE=y
|
CONFIG_DRM_SIMPLE_BRIDGE=y
|
||||||
CONFIG_DRM_PL111=y
|
CONFIG_DRM_PL111=y
|
||||||
|
|
|
@ -160,6 +160,7 @@ CONFIG_VIDEO_MT9V032=m
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_ATMEL_HLCDC=y
|
CONFIG_DRM_ATMEL_HLCDC=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_LCD_CLASS_DEVICE=y
|
CONFIG_LCD_CLASS_DEVICE=y
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
CONFIG_BACKLIGHT_PWM=y
|
CONFIG_BACKLIGHT_PWM=y
|
||||||
|
|
|
@ -129,6 +129,7 @@ CONFIG_VIDEO_ML86V7667=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_RCAR_DU=y
|
CONFIG_DRM_RCAR_DU=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
||||||
CONFIG_DRM_LVDS_CODEC=y
|
CONFIG_DRM_LVDS_CODEC=y
|
||||||
CONFIG_DRM_SII902X=y
|
CONFIG_DRM_SII902X=y
|
||||||
|
|
|
@ -108,6 +108,7 @@ CONFIG_DRM_SUN4I_HDMI_CEC=y
|
||||||
CONFIG_DRM_SUN8I_DW_HDMI=y
|
CONFIG_DRM_SUN8I_DW_HDMI=y
|
||||||
CONFIG_DRM_PANEL_LVDS=y
|
CONFIG_DRM_PANEL_LVDS=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_SIMPLE_BRIDGE=y
|
CONFIG_DRM_SIMPLE_BRIDGE=y
|
||||||
CONFIG_DRM_LIMA=y
|
CONFIG_DRM_LIMA=y
|
||||||
CONFIG_FB_SIMPLE=y
|
CONFIG_FB_SIMPLE=y
|
||||||
|
|
|
@ -199,6 +199,7 @@ CONFIG_DRM_TEGRA=y
|
||||||
CONFIG_DRM_TEGRA_STAGING=y
|
CONFIG_DRM_TEGRA_STAGING=y
|
||||||
CONFIG_DRM_PANEL_LVDS=y
|
CONFIG_DRM_PANEL_LVDS=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_LVDS_CODEC=y
|
CONFIG_DRM_LVDS_CODEC=y
|
||||||
CONFIG_FB=y
|
CONFIG_FB=y
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
|
|
|
@ -57,6 +57,7 @@ CONFIG_GPIO_PL061=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_ARM_VERSATILE=y
|
CONFIG_DRM_PANEL_ARM_VERSATILE=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
||||||
CONFIG_DRM_SIMPLE_BRIDGE=y
|
CONFIG_DRM_SIMPLE_BRIDGE=y
|
||||||
CONFIG_DRM_PL111=y
|
CONFIG_DRM_PL111=y
|
||||||
|
|
|
@ -77,6 +77,7 @@ CONFIG_SENSORS_VEXPRESS=y
|
||||||
CONFIG_REGULATOR_VEXPRESS=y
|
CONFIG_REGULATOR_VEXPRESS=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_SII902X=y
|
CONFIG_DRM_SII902X=y
|
||||||
CONFIG_DRM_PL111=y
|
CONFIG_DRM_PL111=y
|
||||||
CONFIG_FB=y
|
CONFIG_FB=y
|
||||||
|
|
|
@ -697,6 +697,7 @@ CONFIG_DRM_MSM=m
|
||||||
CONFIG_DRM_TEGRA=m
|
CONFIG_DRM_TEGRA=m
|
||||||
CONFIG_DRM_PANEL_LVDS=m
|
CONFIG_DRM_PANEL_LVDS=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=m
|
CONFIG_DRM_PANEL_SIMPLE=m
|
||||||
|
CONFIG_DRM_PANEL_EDP=m
|
||||||
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
|
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
|
||||||
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
|
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
|
||||||
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
|
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
|
||||||
|
|
|
@ -918,11 +918,23 @@ static int it66121_probe(struct i2c_client *client,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ep = of_graph_get_remote_node(dev->of_node, 1, -1);
|
ep = of_graph_get_remote_node(dev->of_node, 1, -1);
|
||||||
if (!ep)
|
if (!ep) {
|
||||||
return -EPROBE_DEFER;
|
dev_err(ctx->dev, "The endpoint is unconnected\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!of_device_is_available(ep)) {
|
||||||
|
of_node_put(ep);
|
||||||
|
dev_err(ctx->dev, "The remote device is disabled\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->next_bridge = of_drm_find_bridge(ep);
|
ctx->next_bridge = of_drm_find_bridge(ep);
|
||||||
of_node_put(ep);
|
of_node_put(ep);
|
||||||
|
if (!ctx->next_bridge) {
|
||||||
|
dev_dbg(ctx->dev, "Next bridge not found, deferring probe\n");
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ctx->next_bridge)
|
if (!ctx->next_bridge)
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <drm/drm_connector.h>
|
#include <drm/drm_connector.h>
|
||||||
#include <drm/drm_encoder.h>
|
#include <drm/drm_encoder.h>
|
||||||
#include <drm/drm_modeset_helper_vtables.h>
|
#include <drm/drm_modeset_helper_vtables.h>
|
||||||
|
#include <drm/drm_of.h>
|
||||||
#include <drm/drm_panel.h>
|
#include <drm/drm_panel.h>
|
||||||
#include <drm/drm_print.h>
|
#include <drm/drm_print.h>
|
||||||
#include <drm/drm_probe_helper.h>
|
#include <drm/drm_probe_helper.h>
|
||||||
|
@ -332,3 +333,39 @@ struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge)
|
||||||
return &panel_bridge->connector;
|
return &panel_bridge->connector;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_panel_bridge_connector);
|
EXPORT_SYMBOL(drm_panel_bridge_connector);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
/**
|
||||||
|
* devm_drm_of_get_bridge - Return next bridge in the chain
|
||||||
|
* @dev: device to tie the bridge lifetime to
|
||||||
|
* @np: device tree node containing encoder output ports
|
||||||
|
* @port: port in the device tree node
|
||||||
|
* @endpoint: endpoint in the device tree node
|
||||||
|
*
|
||||||
|
* Given a DT node's port and endpoint number, finds the connected node
|
||||||
|
* and returns the associated bridge if any, or creates and returns a
|
||||||
|
* drm panel bridge instance if a panel is connected.
|
||||||
|
*
|
||||||
|
* Returns a pointer to the bridge if successful, or an error pointer
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
struct drm_bridge *devm_drm_of_get_bridge(struct device *dev,
|
||||||
|
struct device_node *np,
|
||||||
|
u32 port, u32 endpoint)
|
||||||
|
{
|
||||||
|
struct drm_bridge *bridge;
|
||||||
|
struct drm_panel *panel;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = drm_of_find_panel_or_bridge(np, port, endpoint,
|
||||||
|
&panel, &bridge);
|
||||||
|
if (ret)
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
|
if (panel)
|
||||||
|
bridge = devm_drm_panel_bridge_add(dev, panel);
|
||||||
|
|
||||||
|
return bridge;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(devm_drm_of_get_bridge);
|
||||||
|
#endif
|
||||||
|
|
|
@ -1232,40 +1232,6 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(of_drm_find_bridge);
|
EXPORT_SYMBOL(of_drm_find_bridge);
|
||||||
|
|
||||||
/**
|
|
||||||
* devm_drm_of_get_bridge - Return next bridge in the chain
|
|
||||||
* @dev: device to tie the bridge lifetime to
|
|
||||||
* @np: device tree node containing encoder output ports
|
|
||||||
* @port: port in the device tree node
|
|
||||||
* @endpoint: endpoint in the device tree node
|
|
||||||
*
|
|
||||||
* Given a DT node's port and endpoint number, finds the connected node
|
|
||||||
* and returns the associated bridge if any, or creates and returns a
|
|
||||||
* drm panel bridge instance if a panel is connected.
|
|
||||||
*
|
|
||||||
* Returns a pointer to the bridge if successful, or an error pointer
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
struct drm_bridge *devm_drm_of_get_bridge(struct device *dev,
|
|
||||||
struct device_node *np,
|
|
||||||
u32 port, u32 endpoint)
|
|
||||||
{
|
|
||||||
struct drm_bridge *bridge;
|
|
||||||
struct drm_panel *panel;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = drm_of_find_panel_or_bridge(np, port, endpoint,
|
|
||||||
&panel, &bridge);
|
|
||||||
if (ret)
|
|
||||||
return ERR_PTR(ret);
|
|
||||||
|
|
||||||
if (panel)
|
|
||||||
bridge = devm_drm_panel_bridge_add(dev, panel);
|
|
||||||
|
|
||||||
return bridge;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(devm_drm_of_get_bridge);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
|
MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
|
||||||
|
|
|
@ -1620,7 +1620,7 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties);
|
||||||
* connectors.
|
* connectors.
|
||||||
*
|
*
|
||||||
* Atomic drivers should use drm_connector_attach_scaling_mode_property()
|
* Atomic drivers should use drm_connector_attach_scaling_mode_property()
|
||||||
* instead to correctly assign &drm_connector_state.picture_aspect_ratio
|
* instead to correctly assign &drm_connector_state.scaling_mode
|
||||||
* in the atomic state.
|
* in the atomic state.
|
||||||
*/
|
*/
|
||||||
int drm_mode_create_scaling_mode_property(struct drm_device *dev)
|
int drm_mode_create_scaling_mode_property(struct drm_device *dev)
|
||||||
|
@ -1740,7 +1740,7 @@ EXPORT_SYMBOL(drm_connector_attach_vrr_capable_property);
|
||||||
* @scaling_mode_mask: or'ed mask of BIT(%DRM_MODE_SCALE_\*).
|
* @scaling_mode_mask: or'ed mask of BIT(%DRM_MODE_SCALE_\*).
|
||||||
*
|
*
|
||||||
* This is used to add support for scaling mode to atomic drivers.
|
* This is used to add support for scaling mode to atomic drivers.
|
||||||
* The scaling mode will be set to &drm_connector_state.picture_aspect_ratio
|
* The scaling mode will be set to &drm_connector_state.scaling_mode
|
||||||
* and can be used from &drm_connector_helper_funcs->atomic_check for validation.
|
* and can be used from &drm_connector_helper_funcs->atomic_check for validation.
|
||||||
*
|
*
|
||||||
* This is the atomic version of drm_mode_create_scaling_mode_property().
|
* This is the atomic version of drm_mode_create_scaling_mode_property().
|
||||||
|
|
|
@ -100,122 +100,127 @@ struct detailed_mode_closure {
|
||||||
#define LEVEL_GTF2 2
|
#define LEVEL_GTF2 2
|
||||||
#define LEVEL_CVT 3
|
#define LEVEL_CVT 3
|
||||||
|
|
||||||
|
#define EDID_QUIRK(vend, product_id, _quirks) \
|
||||||
|
{ \
|
||||||
|
.panel_id = drm_edid_encode_panel_id(vend, product_id), \
|
||||||
|
.quirks = _quirks \
|
||||||
|
}
|
||||||
|
|
||||||
static const struct edid_quirk {
|
static const struct edid_quirk {
|
||||||
char vendor[4];
|
u32 panel_id;
|
||||||
int product_id;
|
|
||||||
u32 quirks;
|
u32 quirks;
|
||||||
} edid_quirk_list[] = {
|
} edid_quirk_list[] = {
|
||||||
/* Acer AL1706 */
|
/* Acer AL1706 */
|
||||||
{ "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
|
EDID_QUIRK("ACR", 44358, EDID_QUIRK_PREFER_LARGE_60),
|
||||||
/* Acer F51 */
|
/* Acer F51 */
|
||||||
{ "API", 0x7602, EDID_QUIRK_PREFER_LARGE_60 },
|
EDID_QUIRK("API", 0x7602, EDID_QUIRK_PREFER_LARGE_60),
|
||||||
|
|
||||||
/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
|
/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
|
||||||
{ "AEO", 0, EDID_QUIRK_FORCE_6BPC },
|
EDID_QUIRK("AEO", 0, EDID_QUIRK_FORCE_6BPC),
|
||||||
|
|
||||||
/* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc panel */
|
/* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc panel */
|
||||||
{ "BOE", 0x78b, EDID_QUIRK_FORCE_6BPC },
|
EDID_QUIRK("BOE", 0x78b, EDID_QUIRK_FORCE_6BPC),
|
||||||
|
|
||||||
/* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
|
/* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
|
||||||
{ "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
|
EDID_QUIRK("CPT", 0x17df, EDID_QUIRK_FORCE_6BPC),
|
||||||
|
|
||||||
/* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */
|
/* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */
|
||||||
{ "SDC", 0x3652, EDID_QUIRK_FORCE_6BPC },
|
EDID_QUIRK("SDC", 0x3652, EDID_QUIRK_FORCE_6BPC),
|
||||||
|
|
||||||
/* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */
|
/* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */
|
||||||
{ "BOE", 0x0771, EDID_QUIRK_FORCE_6BPC },
|
EDID_QUIRK("BOE", 0x0771, EDID_QUIRK_FORCE_6BPC),
|
||||||
|
|
||||||
/* Belinea 10 15 55 */
|
/* Belinea 10 15 55 */
|
||||||
{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
|
EDID_QUIRK("MAX", 1516, EDID_QUIRK_PREFER_LARGE_60),
|
||||||
{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
|
EDID_QUIRK("MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60),
|
||||||
|
|
||||||
/* Envision Peripherals, Inc. EN-7100e */
|
/* Envision Peripherals, Inc. EN-7100e */
|
||||||
{ "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
|
EDID_QUIRK("EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH),
|
||||||
/* Envision EN2028 */
|
/* Envision EN2028 */
|
||||||
{ "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },
|
EDID_QUIRK("EPI", 8232, EDID_QUIRK_PREFER_LARGE_60),
|
||||||
|
|
||||||
/* Funai Electronics PM36B */
|
/* Funai Electronics PM36B */
|
||||||
{ "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
|
EDID_QUIRK("FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
|
||||||
EDID_QUIRK_DETAILED_IN_CM },
|
EDID_QUIRK_DETAILED_IN_CM),
|
||||||
|
|
||||||
/* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */
|
/* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */
|
||||||
{ "LGD", 764, EDID_QUIRK_FORCE_10BPC },
|
EDID_QUIRK("LGD", 764, EDID_QUIRK_FORCE_10BPC),
|
||||||
|
|
||||||
/* LG Philips LCD LP154W01-A5 */
|
/* LG Philips LCD LP154W01-A5 */
|
||||||
{ "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
|
EDID_QUIRK("LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE),
|
||||||
{ "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
|
EDID_QUIRK("LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE),
|
||||||
|
|
||||||
/* Samsung SyncMaster 205BW. Note: irony */
|
/* Samsung SyncMaster 205BW. Note: irony */
|
||||||
{ "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },
|
EDID_QUIRK("SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP),
|
||||||
/* Samsung SyncMaster 22[5-6]BW */
|
/* Samsung SyncMaster 22[5-6]BW */
|
||||||
{ "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
|
EDID_QUIRK("SAM", 596, EDID_QUIRK_PREFER_LARGE_60),
|
||||||
{ "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
|
EDID_QUIRK("SAM", 638, EDID_QUIRK_PREFER_LARGE_60),
|
||||||
|
|
||||||
/* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
|
/* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
|
||||||
{ "SNY", 0x2541, EDID_QUIRK_FORCE_12BPC },
|
EDID_QUIRK("SNY", 0x2541, EDID_QUIRK_FORCE_12BPC),
|
||||||
|
|
||||||
/* ViewSonic VA2026w */
|
/* ViewSonic VA2026w */
|
||||||
{ "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
|
EDID_QUIRK("VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING),
|
||||||
|
|
||||||
/* Medion MD 30217 PG */
|
/* Medion MD 30217 PG */
|
||||||
{ "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 },
|
EDID_QUIRK("MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75),
|
||||||
|
|
||||||
/* Lenovo G50 */
|
/* Lenovo G50 */
|
||||||
{ "SDC", 18514, EDID_QUIRK_FORCE_6BPC },
|
EDID_QUIRK("SDC", 18514, EDID_QUIRK_FORCE_6BPC),
|
||||||
|
|
||||||
/* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
|
/* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
|
||||||
{ "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC },
|
EDID_QUIRK("SEC", 0xd033, EDID_QUIRK_FORCE_8BPC),
|
||||||
|
|
||||||
/* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
|
/* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
|
||||||
{ "ETR", 13896, EDID_QUIRK_FORCE_8BPC },
|
EDID_QUIRK("ETR", 13896, EDID_QUIRK_FORCE_8BPC),
|
||||||
|
|
||||||
/* Valve Index Headset */
|
/* Valve Index Headset */
|
||||||
{ "VLV", 0x91a8, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91a8, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b0, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b0, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b1, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b1, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b2, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b2, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b3, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b3, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b4, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b4, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b5, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b5, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b6, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b6, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b7, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b7, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b8, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b8, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91b9, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91b9, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91ba, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91ba, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91bb, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91bb, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91bc, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91bc, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91bd, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91bd, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91be, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91be, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "VLV", 0x91bf, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("VLV", 0x91bf, EDID_QUIRK_NON_DESKTOP),
|
||||||
|
|
||||||
/* HTC Vive and Vive Pro VR Headsets */
|
/* HTC Vive and Vive Pro VR Headsets */
|
||||||
{ "HVR", 0xaa01, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("HVR", 0xaa01, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "HVR", 0xaa02, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("HVR", 0xaa02, EDID_QUIRK_NON_DESKTOP),
|
||||||
|
|
||||||
/* Oculus Rift DK1, DK2, CV1 and Rift S VR Headsets */
|
/* Oculus Rift DK1, DK2, CV1 and Rift S VR Headsets */
|
||||||
{ "OVR", 0x0001, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("OVR", 0x0001, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "OVR", 0x0003, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("OVR", 0x0003, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "OVR", 0x0004, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("OVR", 0x0004, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "OVR", 0x0012, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("OVR", 0x0012, EDID_QUIRK_NON_DESKTOP),
|
||||||
|
|
||||||
/* Windows Mixed Reality Headsets */
|
/* Windows Mixed Reality Headsets */
|
||||||
{ "ACR", 0x7fce, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("ACR", 0x7fce, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "HPN", 0x3515, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("HPN", 0x3515, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "LEN", 0x0408, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("LEN", 0x0408, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "LEN", 0xb800, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("LEN", 0xb800, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "FUJ", 0x1970, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("FUJ", 0x1970, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "DEL", 0x7fce, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("DEL", 0x7fce, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "SEC", 0x144a, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("SEC", 0x144a, EDID_QUIRK_NON_DESKTOP),
|
||||||
{ "AUS", 0xc102, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("AUS", 0xc102, EDID_QUIRK_NON_DESKTOP),
|
||||||
|
|
||||||
/* Sony PlayStation VR Headset */
|
/* Sony PlayStation VR Headset */
|
||||||
{ "SNY", 0x0704, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("SNY", 0x0704, EDID_QUIRK_NON_DESKTOP),
|
||||||
|
|
||||||
/* Sensics VR Headsets */
|
/* Sensics VR Headsets */
|
||||||
{ "SEN", 0x1019, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("SEN", 0x1019, EDID_QUIRK_NON_DESKTOP),
|
||||||
|
|
||||||
/* OSVR HDK and HDK2 VR Headsets */
|
/* OSVR HDK and HDK2 VR Headsets */
|
||||||
{ "SVR", 0x1019, EDID_QUIRK_NON_DESKTOP },
|
EDID_QUIRK("SVR", 0x1019, EDID_QUIRK_NON_DESKTOP),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1905,6 +1910,44 @@ int drm_add_override_edid_modes(struct drm_connector *connector)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_add_override_edid_modes);
|
EXPORT_SYMBOL(drm_add_override_edid_modes);
|
||||||
|
|
||||||
|
static struct edid *drm_do_get_edid_base_block(
|
||||||
|
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
|
||||||
|
size_t len),
|
||||||
|
void *data, bool *edid_corrupt, int *null_edid_counter)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
void *edid;
|
||||||
|
|
||||||
|
edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
|
||||||
|
if (edid == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* base block fetch */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
if (get_edid_block(data, edid, 0, EDID_LENGTH))
|
||||||
|
goto out;
|
||||||
|
if (drm_edid_block_valid(edid, 0, false, edid_corrupt))
|
||||||
|
break;
|
||||||
|
if (i == 0 && drm_edid_is_zero(edid, EDID_LENGTH)) {
|
||||||
|
if (null_edid_counter)
|
||||||
|
(*null_edid_counter)++;
|
||||||
|
goto carp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == 4)
|
||||||
|
goto carp;
|
||||||
|
|
||||||
|
return edid;
|
||||||
|
|
||||||
|
carp:
|
||||||
|
kfree(edid);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree(edid);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_do_get_edid - get EDID data using a custom EDID block read function
|
* drm_do_get_edid - get EDID data using a custom EDID block read function
|
||||||
* @connector: connector we're probing
|
* @connector: connector we're probing
|
||||||
|
@ -1938,25 +1981,16 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
|
||||||
if (override)
|
if (override)
|
||||||
return override;
|
return override;
|
||||||
|
|
||||||
if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
|
edid = (u8 *)drm_do_get_edid_base_block(get_edid_block, data,
|
||||||
|
&connector->edid_corrupt,
|
||||||
|
&connector->null_edid_counter);
|
||||||
|
if (IS_ERR_OR_NULL(edid)) {
|
||||||
|
if (IS_ERR(edid))
|
||||||
|
connector_bad_edid(connector, edid, 1);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* base block fetch */
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (get_edid_block(data, edid, 0, EDID_LENGTH))
|
|
||||||
goto out;
|
|
||||||
if (drm_edid_block_valid(edid, 0, false,
|
|
||||||
&connector->edid_corrupt))
|
|
||||||
break;
|
|
||||||
if (i == 0 && drm_edid_is_zero(edid, EDID_LENGTH)) {
|
|
||||||
connector->null_edid_counter++;
|
|
||||||
goto carp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (i == 4)
|
|
||||||
goto carp;
|
|
||||||
|
|
||||||
/* if there's no extensions, we're done */
|
/* if there's no extensions or no connector, we're done */
|
||||||
valid_extensions = edid[0x7e];
|
valid_extensions = edid[0x7e];
|
||||||
if (valid_extensions == 0)
|
if (valid_extensions == 0)
|
||||||
return (struct edid *)edid;
|
return (struct edid *)edid;
|
||||||
|
@ -2010,8 +2044,6 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
|
||||||
|
|
||||||
return (struct edid *)edid;
|
return (struct edid *)edid;
|
||||||
|
|
||||||
carp:
|
|
||||||
connector_bad_edid(connector, edid, 1);
|
|
||||||
out:
|
out:
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2060,6 +2092,72 @@ struct edid *drm_get_edid(struct drm_connector *connector,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_get_edid);
|
EXPORT_SYMBOL(drm_get_edid);
|
||||||
|
|
||||||
|
static u32 edid_extract_panel_id(const struct edid *edid)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We represent the ID as a 32-bit number so it can easily be compared
|
||||||
|
* with "==".
|
||||||
|
*
|
||||||
|
* NOTE that we deal with endianness differently for the top half
|
||||||
|
* of this ID than for the bottom half. The bottom half (the product
|
||||||
|
* id) gets decoded as little endian by the EDID_PRODUCT_ID because
|
||||||
|
* that's how everyone seems to interpret it. The top half (the mfg_id)
|
||||||
|
* gets stored as big endian because that makes
|
||||||
|
* drm_edid_encode_panel_id() and drm_edid_decode_panel_id() easier
|
||||||
|
* to write (it's easier to extract the ASCII). It doesn't really
|
||||||
|
* matter, though, as long as the number here is unique.
|
||||||
|
*/
|
||||||
|
return (u32)edid->mfg_id[0] << 24 |
|
||||||
|
(u32)edid->mfg_id[1] << 16 |
|
||||||
|
(u32)EDID_PRODUCT_ID(edid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_edid_get_panel_id - Get a panel's ID through DDC
|
||||||
|
* @adapter: I2C adapter to use for DDC
|
||||||
|
*
|
||||||
|
* This function reads the first block of the EDID of a panel and (assuming
|
||||||
|
* that the EDID is valid) extracts the ID out of it. The ID is a 32-bit value
|
||||||
|
* (16 bits of manufacturer ID and 16 bits of per-manufacturer ID) that's
|
||||||
|
* supposed to be different for each different modem of panel.
|
||||||
|
*
|
||||||
|
* This function is intended to be used during early probing on devices where
|
||||||
|
* more than one panel might be present. Because of its intended use it must
|
||||||
|
* assume that the EDID of the panel is correct, at least as far as the ID
|
||||||
|
* is concerned (in other words, we don't process any overrides here).
|
||||||
|
*
|
||||||
|
* NOTE: it's expected that this function and drm_do_get_edid() will both
|
||||||
|
* be read the EDID, but there is no caching between them. Since we're only
|
||||||
|
* reading the first block, hopefully this extra overhead won't be too big.
|
||||||
|
*
|
||||||
|
* Return: A 32-bit ID that should be different for each make/model of panel.
|
||||||
|
* See the functions drm_edid_encode_panel_id() and
|
||||||
|
* drm_edid_decode_panel_id() for some details on the structure of this
|
||||||
|
* ID.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 drm_edid_get_panel_id(struct i2c_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct edid *edid;
|
||||||
|
u32 panel_id;
|
||||||
|
|
||||||
|
edid = drm_do_get_edid_base_block(drm_do_probe_ddc_edid, adapter,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are no manufacturer IDs of 0, so if there is a problem reading
|
||||||
|
* the EDID then we'll just return 0.
|
||||||
|
*/
|
||||||
|
if (IS_ERR_OR_NULL(edid))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
panel_id = edid_extract_panel_id(edid);
|
||||||
|
kfree(edid);
|
||||||
|
|
||||||
|
return panel_id;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_edid_get_panel_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_get_edid_switcheroo - get EDID data for a vga_switcheroo output
|
* drm_get_edid_switcheroo - get EDID data for a vga_switcheroo output
|
||||||
* @connector: connector we're probing
|
* @connector: connector we're probing
|
||||||
|
@ -2103,25 +2201,6 @@ EXPORT_SYMBOL(drm_edid_duplicate);
|
||||||
|
|
||||||
/*** EDID parsing ***/
|
/*** EDID parsing ***/
|
||||||
|
|
||||||
/**
|
|
||||||
* edid_vendor - match a string against EDID's obfuscated vendor field
|
|
||||||
* @edid: EDID to match
|
|
||||||
* @vendor: vendor string
|
|
||||||
*
|
|
||||||
* Returns true if @vendor is in @edid, false otherwise
|
|
||||||
*/
|
|
||||||
static bool edid_vendor(const struct edid *edid, const char *vendor)
|
|
||||||
{
|
|
||||||
char edid_vendor[3];
|
|
||||||
|
|
||||||
edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
|
|
||||||
edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
|
|
||||||
((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
|
|
||||||
edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
|
|
||||||
|
|
||||||
return !strncmp(edid_vendor, vendor, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* edid_get_quirks - return quirk flags for a given EDID
|
* edid_get_quirks - return quirk flags for a given EDID
|
||||||
* @edid: EDID to process
|
* @edid: EDID to process
|
||||||
|
@ -2130,14 +2209,13 @@ static bool edid_vendor(const struct edid *edid, const char *vendor)
|
||||||
*/
|
*/
|
||||||
static u32 edid_get_quirks(const struct edid *edid)
|
static u32 edid_get_quirks(const struct edid *edid)
|
||||||
{
|
{
|
||||||
|
u32 panel_id = edid_extract_panel_id(edid);
|
||||||
const struct edid_quirk *quirk;
|
const struct edid_quirk *quirk;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
|
for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
|
||||||
quirk = &edid_quirk_list[i];
|
quirk = &edid_quirk_list[i];
|
||||||
|
if (quirk->panel_id == panel_id)
|
||||||
if (edid_vendor(edid, quirk->vendor) &&
|
|
||||||
(EDID_PRODUCT_ID(edid) == quirk->product_id))
|
|
||||||
return quirk->quirks;
|
return quirk->quirks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,14 +77,26 @@ config DRM_PANEL_LVDS
|
||||||
backlight handling if the panel is attached to a backlight controller.
|
backlight handling if the panel is attached to a backlight controller.
|
||||||
|
|
||||||
config DRM_PANEL_SIMPLE
|
config DRM_PANEL_SIMPLE
|
||||||
tristate "support for simple panels"
|
tristate "support for simple panels (other than eDP ones)"
|
||||||
|
depends on OF
|
||||||
|
depends on BACKLIGHT_CLASS_DEVICE
|
||||||
|
depends on PM
|
||||||
|
select VIDEOMODE_HELPERS
|
||||||
|
help
|
||||||
|
DRM panel driver for dumb non-eDP panels that need at most a regulator
|
||||||
|
and a GPIO to be powered up. Optionally a backlight can be attached so
|
||||||
|
that it can be automatically turned off when the panel goes into a
|
||||||
|
low power state.
|
||||||
|
|
||||||
|
config DRM_PANEL_EDP
|
||||||
|
tristate "support for simple Embedded DisplayPort panels"
|
||||||
depends on OF
|
depends on OF
|
||||||
depends on BACKLIGHT_CLASS_DEVICE
|
depends on BACKLIGHT_CLASS_DEVICE
|
||||||
depends on PM
|
depends on PM
|
||||||
select VIDEOMODE_HELPERS
|
select VIDEOMODE_HELPERS
|
||||||
select DRM_DP_AUX_BUS
|
select DRM_DP_AUX_BUS
|
||||||
help
|
help
|
||||||
DRM panel driver for dumb panels that need at most a regulator and
|
DRM panel driver for dumb eDP panels that need at most a regulator and
|
||||||
a GPIO to be powered up. Optionally a backlight can be attached so
|
a GPIO to be powered up. Optionally a backlight can be attached so
|
||||||
that it can be automatically turned off when the panel goes into a
|
that it can be automatically turned off when the panel goes into a
|
||||||
low power state.
|
low power state.
|
||||||
|
|
|
@ -7,6 +7,7 @@ obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o
|
||||||
obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o
|
obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o
|
||||||
obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o
|
obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o
|
||||||
obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
|
obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
|
||||||
|
obj-$(CONFIG_DRM_PANEL_EDP) += panel-edp.o
|
||||||
obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
|
obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
|
||||||
obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
|
obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
|
||||||
obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
|
obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -398,8 +398,7 @@ void panfrost_device_reset(struct panfrost_device *pfdev)
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
int panfrost_device_resume(struct device *dev)
|
int panfrost_device_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct panfrost_device *pfdev = dev_get_drvdata(dev);
|
||||||
struct panfrost_device *pfdev = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
panfrost_device_reset(pfdev);
|
panfrost_device_reset(pfdev);
|
||||||
panfrost_devfreq_resume(pfdev);
|
panfrost_devfreq_resume(pfdev);
|
||||||
|
@ -409,8 +408,7 @@ int panfrost_device_resume(struct device *dev)
|
||||||
|
|
||||||
int panfrost_device_suspend(struct device *dev)
|
int panfrost_device_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct panfrost_device *pfdev = dev_get_drvdata(dev);
|
||||||
struct panfrost_device *pfdev = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
if (!panfrost_job_is_idle(pfdev))
|
if (!panfrost_job_is_idle(pfdev))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
|
@ -638,8 +638,8 @@ static const struct panfrost_compatible amlogic_data = {
|
||||||
.vendor_quirk = panfrost_gpu_amlogic_quirk,
|
.vendor_quirk = panfrost_gpu_amlogic_quirk,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * const mediatek_mt8183_supplies[] = { "mali", "sram" };
|
static const char * const mediatek_mt8183_supplies[] = { "mali", "sram" };
|
||||||
const char * const mediatek_mt8183_pm_domains[] = { "core0", "core1", "core2" };
|
static const char * const mediatek_mt8183_pm_domains[] = { "core0", "core1", "core2" };
|
||||||
static const struct panfrost_compatible mediatek_mt8183_data = {
|
static const struct panfrost_compatible mediatek_mt8183_data = {
|
||||||
.num_supplies = ARRAY_SIZE(mediatek_mt8183_supplies),
|
.num_supplies = ARRAY_SIZE(mediatek_mt8183_supplies),
|
||||||
.supply_names = mediatek_mt8183_supplies,
|
.supply_names = mediatek_mt8183_supplies,
|
||||||
|
|
|
@ -58,17 +58,33 @@ static int write_cmd(struct panfrost_device *pfdev, u32 as_nr, u32 cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lock_region(struct panfrost_device *pfdev, u32 as_nr,
|
static void lock_region(struct panfrost_device *pfdev, u32 as_nr,
|
||||||
u64 iova, u64 size)
|
u64 region_start, u64 size)
|
||||||
{
|
{
|
||||||
u8 region_width;
|
u8 region_width;
|
||||||
u64 region = iova & PAGE_MASK;
|
u64 region;
|
||||||
|
u64 region_end = region_start + size;
|
||||||
|
|
||||||
/* The size is encoded as ceil(log2) minus(1), which may be calculated
|
if (!size)
|
||||||
* with fls. The size must be clamped to hardware bounds.
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The locked region is a naturally aligned power of 2 block encoded as
|
||||||
|
* log2 minus(1).
|
||||||
|
* Calculate the desired start/end and look for the highest bit which
|
||||||
|
* differs. The smallest naturally aligned block must include this bit
|
||||||
|
* change, the desired region starts with this bit (and subsequent bits)
|
||||||
|
* zeroed and ends with the bit (and subsequent bits) set to one.
|
||||||
*/
|
*/
|
||||||
size = max_t(u64, size, AS_LOCK_REGION_MIN_SIZE);
|
region_width = max(fls64(region_start ^ (region_end - 1)),
|
||||||
region_width = fls64(size - 1) - 1;
|
const_ilog2(AS_LOCK_REGION_MIN_SIZE)) - 1;
|
||||||
region |= region_width;
|
|
||||||
|
/*
|
||||||
|
* Mask off the low bits of region_start (which would be ignored by
|
||||||
|
* the hardware anyway)
|
||||||
|
*/
|
||||||
|
region_start &= GENMASK_ULL(63, region_width);
|
||||||
|
|
||||||
|
region = region_width | region_start;
|
||||||
|
|
||||||
/* Lock the region that needs to be updated */
|
/* Lock the region that needs to be updated */
|
||||||
mmu_write(pfdev, AS_LOCKADDR_LO(as_nr), lower_32_bits(region));
|
mmu_write(pfdev, AS_LOCKADDR_LO(as_nr), lower_32_bits(region));
|
||||||
|
|
|
@ -467,6 +467,6 @@ struct platform_driver rockchip_dp_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "rockchip-dp",
|
.name = "rockchip-dp",
|
||||||
.pm = &rockchip_dp_pm_ops,
|
.pm = &rockchip_dp_pm_ops,
|
||||||
.of_match_table = of_match_ptr(rockchip_dp_dt_ids),
|
.of_match_table = rockchip_dp_dt_ids,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -697,7 +697,6 @@ static int cdn_dp_parse_dt(struct cdn_dp_device *dp)
|
||||||
struct device *dev = dp->dev;
|
struct device *dev = dp->dev;
|
||||||
struct device_node *np = dev->of_node;
|
struct device_node *np = dev->of_node;
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
struct resource *res;
|
|
||||||
|
|
||||||
dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
|
dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
|
||||||
if (IS_ERR(dp->grf)) {
|
if (IS_ERR(dp->grf)) {
|
||||||
|
@ -705,8 +704,7 @@ static int cdn_dp_parse_dt(struct cdn_dp_device *dp)
|
||||||
return PTR_ERR(dp->grf);
|
return PTR_ERR(dp->grf);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
dp->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||||
dp->regs = devm_ioremap_resource(dev, res);
|
|
||||||
if (IS_ERR(dp->regs)) {
|
if (IS_ERR(dp->regs)) {
|
||||||
DRM_DEV_ERROR(dev, "ioremap reg failed\n");
|
DRM_DEV_ERROR(dev, "ioremap reg failed\n");
|
||||||
return PTR_ERR(dp->regs);
|
return PTR_ERR(dp->regs);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/phy/phy.h>
|
#include <linux/phy/phy.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/phy/phy.h>
|
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
|
|
||||||
#include <video/mipi_display.h>
|
#include <video/mipi_display.h>
|
||||||
|
@ -643,7 +642,7 @@ struct hstt {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Table A-3 High-Speed Transition Times */
|
/* Table A-3 High-Speed Transition Times */
|
||||||
struct hstt hstt_table[] = {
|
static struct hstt hstt_table[] = {
|
||||||
HSTT( 90, 32, 20, 26, 13),
|
HSTT( 90, 32, 20, 26, 13),
|
||||||
HSTT( 100, 35, 23, 28, 14),
|
HSTT( 100, 35, 23, 28, 14),
|
||||||
HSTT( 110, 32, 22, 26, 13),
|
HSTT( 110, 32, 22, 26, 13),
|
||||||
|
|
|
@ -810,7 +810,6 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
struct drm_device *drm = data;
|
struct drm_device *drm = data;
|
||||||
struct inno_hdmi *hdmi;
|
struct inno_hdmi *hdmi;
|
||||||
struct resource *iores;
|
|
||||||
int irq;
|
int irq;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -821,8 +820,7 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
|
||||||
hdmi->dev = dev;
|
hdmi->dev = dev;
|
||||||
hdmi->drm_dev = drm;
|
hdmi->drm_dev = drm;
|
||||||
|
|
||||||
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||||
hdmi->regs = devm_ioremap_resource(dev, iores);
|
|
||||||
if (IS_ERR(hdmi->regs))
|
if (IS_ERR(hdmi->regs))
|
||||||
return PTR_ERR(hdmi->regs);
|
return PTR_ERR(hdmi->regs);
|
||||||
|
|
||||||
|
|
|
@ -138,9 +138,6 @@ static int rockchip_drm_bind(struct device *dev)
|
||||||
|
|
||||||
drm_dev->dev_private = private;
|
drm_dev->dev_private = private;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&private->psr_list);
|
|
||||||
mutex_init(&private->psr_list_lock);
|
|
||||||
|
|
||||||
ret = rockchip_drm_init_iommu(drm_dev);
|
ret = rockchip_drm_init_iommu(drm_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
@ -275,10 +272,17 @@ int rockchip_drm_endpoint_is_subdriver(struct device_node *ep)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* status disabled will prevent creation of platform-devices */
|
/* status disabled will prevent creation of platform-devices */
|
||||||
|
if (!of_device_is_available(node)) {
|
||||||
|
of_node_put(node);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
pdev = of_find_device_by_node(node);
|
pdev = of_find_device_by_node(node);
|
||||||
of_node_put(node);
|
of_node_put(node);
|
||||||
|
|
||||||
|
/* enabled non-platform-devices can immediately return here */
|
||||||
if (!pdev)
|
if (!pdev)
|
||||||
return -ENODEV;
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All rockchip subdrivers have probed at this point, so
|
* All rockchip subdrivers have probed at this point, so
|
||||||
|
@ -370,7 +374,7 @@ static int rockchip_drm_platform_of_probe(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
iommu = of_parse_phandle(port->parent, "iommus", 0);
|
iommu = of_parse_phandle(port->parent, "iommus", 0);
|
||||||
if (!iommu || !of_device_is_available(iommu->parent)) {
|
if (!iommu || !of_device_is_available(iommu)) {
|
||||||
DRM_DEV_DEBUG(dev,
|
DRM_DEV_DEBUG(dev,
|
||||||
"no iommu attached for %pOF, using non-iommu buffers\n",
|
"no iommu attached for %pOF, using non-iommu buffers\n",
|
||||||
port->parent);
|
port->parent);
|
||||||
|
|
|
@ -48,8 +48,6 @@ struct rockchip_drm_private {
|
||||||
struct iommu_domain *domain;
|
struct iommu_domain *domain;
|
||||||
struct mutex mm_lock;
|
struct mutex mm_lock;
|
||||||
struct drm_mm mm;
|
struct drm_mm mm;
|
||||||
struct list_head psr_list;
|
|
||||||
struct mutex psr_list_lock;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
|
int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include <drm/drm_atomic_helper.h>
|
#include <drm/drm_atomic_helper.h>
|
||||||
#include <drm/drm_bridge.h>
|
#include <drm/drm_bridge.h>
|
||||||
|
#include <drm/drm_bridge_connector.h>
|
||||||
#include <drm/drm_dp_helper.h>
|
#include <drm/drm_dp_helper.h>
|
||||||
#include <drm/drm_of.h>
|
#include <drm/drm_of.h>
|
||||||
#include <drm/drm_panel.h>
|
#include <drm/drm_panel.h>
|
||||||
|
@ -439,11 +440,9 @@ struct drm_encoder_helper_funcs px30_lvds_encoder_helper_funcs = {
|
||||||
static int rk3288_lvds_probe(struct platform_device *pdev,
|
static int rk3288_lvds_probe(struct platform_device *pdev,
|
||||||
struct rockchip_lvds *lvds)
|
struct rockchip_lvds *lvds)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
lvds->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||||
lvds->regs = devm_ioremap_resource(lvds->dev, res);
|
|
||||||
if (IS_ERR(lvds->regs))
|
if (IS_ERR(lvds->regs))
|
||||||
return PTR_ERR(lvds->regs);
|
return PTR_ERR(lvds->regs);
|
||||||
|
|
||||||
|
@ -612,9 +611,9 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_encoder_helper_add(encoder, lvds->soc_data->helper_funcs);
|
drm_encoder_helper_add(encoder, lvds->soc_data->helper_funcs);
|
||||||
|
connector = &lvds->connector;
|
||||||
|
|
||||||
if (lvds->panel) {
|
if (lvds->panel) {
|
||||||
connector = &lvds->connector;
|
|
||||||
connector->dpms = DRM_MODE_DPMS_OFF;
|
connector->dpms = DRM_MODE_DPMS_OFF;
|
||||||
ret = drm_connector_init(drm_dev, connector,
|
ret = drm_connector_init(drm_dev, connector,
|
||||||
&rockchip_lvds_connector_funcs,
|
&rockchip_lvds_connector_funcs,
|
||||||
|
@ -627,17 +626,27 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
|
||||||
|
|
||||||
drm_connector_helper_add(connector,
|
drm_connector_helper_add(connector,
|
||||||
&rockchip_lvds_connector_helper_funcs);
|
&rockchip_lvds_connector_helper_funcs);
|
||||||
|
|
||||||
ret = drm_connector_attach_encoder(connector, encoder);
|
|
||||||
if (ret < 0) {
|
|
||||||
DRM_DEV_ERROR(drm_dev->dev,
|
|
||||||
"failed to attach encoder: %d\n", ret);
|
|
||||||
goto err_free_connector;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 0);
|
ret = drm_bridge_attach(encoder, lvds->bridge, NULL,
|
||||||
|
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_encoder;
|
goto err_free_encoder;
|
||||||
|
|
||||||
|
connector = drm_bridge_connector_init(lvds->drm_dev, encoder);
|
||||||
|
if (IS_ERR(connector)) {
|
||||||
|
DRM_DEV_ERROR(drm_dev->dev,
|
||||||
|
"failed to initialize bridge connector: %pe\n",
|
||||||
|
connector);
|
||||||
|
ret = PTR_ERR(connector);
|
||||||
|
goto err_free_encoder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drm_connector_attach_encoder(connector, encoder);
|
||||||
|
if (ret < 0) {
|
||||||
|
DRM_DEV_ERROR(drm_dev->dev,
|
||||||
|
"failed to attach encoder: %d\n", ret);
|
||||||
|
goto err_free_connector;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_runtime_enable(dev);
|
pm_runtime_enable(dev);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <drm/drm_atomic_helper.h>
|
#include <drm/drm_atomic_helper.h>
|
||||||
#include <drm/drm_bridge.h>
|
#include <drm/drm_bridge.h>
|
||||||
|
#include <drm/drm_bridge_connector.h>
|
||||||
#include <drm/drm_dp_helper.h>
|
#include <drm/drm_dp_helper.h>
|
||||||
#include <drm/drm_of.h>
|
#include <drm/drm_of.h>
|
||||||
#include <drm/drm_panel.h>
|
#include <drm/drm_panel.h>
|
||||||
|
@ -27,6 +28,7 @@ struct rockchip_rgb {
|
||||||
struct drm_device *drm_dev;
|
struct drm_device *drm_dev;
|
||||||
struct drm_bridge *bridge;
|
struct drm_bridge *bridge;
|
||||||
struct drm_encoder encoder;
|
struct drm_encoder encoder;
|
||||||
|
struct drm_connector connector;
|
||||||
int output_mode;
|
int output_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,6 +82,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
|
||||||
int ret = 0, child_count = 0;
|
int ret = 0, child_count = 0;
|
||||||
struct drm_panel *panel;
|
struct drm_panel *panel;
|
||||||
struct drm_bridge *bridge;
|
struct drm_bridge *bridge;
|
||||||
|
struct drm_connector *connector;
|
||||||
|
|
||||||
rgb = devm_kzalloc(dev, sizeof(*rgb), GFP_KERNEL);
|
rgb = devm_kzalloc(dev, sizeof(*rgb), GFP_KERNEL);
|
||||||
if (!rgb)
|
if (!rgb)
|
||||||
|
@ -142,12 +145,32 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
|
||||||
|
|
||||||
rgb->bridge = bridge;
|
rgb->bridge = bridge;
|
||||||
|
|
||||||
ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0);
|
ret = drm_bridge_attach(encoder, rgb->bridge, NULL,
|
||||||
|
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_encoder;
|
goto err_free_encoder;
|
||||||
|
|
||||||
|
connector = &rgb->connector;
|
||||||
|
connector = drm_bridge_connector_init(rgb->drm_dev, encoder);
|
||||||
|
if (IS_ERR(connector)) {
|
||||||
|
DRM_DEV_ERROR(drm_dev->dev,
|
||||||
|
"failed to initialize bridge connector: %pe\n",
|
||||||
|
connector);
|
||||||
|
ret = PTR_ERR(connector);
|
||||||
|
goto err_free_encoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drm_connector_attach_encoder(connector, encoder);
|
||||||
|
if (ret < 0) {
|
||||||
|
DRM_DEV_ERROR(drm_dev->dev,
|
||||||
|
"failed to attach encoder: %d\n", ret);
|
||||||
|
goto err_free_connector;
|
||||||
|
}
|
||||||
|
|
||||||
return rgb;
|
return rgb;
|
||||||
|
|
||||||
|
err_free_connector:
|
||||||
|
drm_connector_cleanup(connector);
|
||||||
err_free_encoder:
|
err_free_encoder:
|
||||||
drm_encoder_cleanup(encoder);
|
drm_encoder_cleanup(encoder);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
|
@ -157,6 +180,7 @@ EXPORT_SYMBOL_GPL(rockchip_rgb_init);
|
||||||
void rockchip_rgb_fini(struct rockchip_rgb *rgb)
|
void rockchip_rgb_fini(struct rockchip_rgb *rgb)
|
||||||
{
|
{
|
||||||
drm_panel_bridge_remove(rgb->bridge);
|
drm_panel_bridge_remove(rgb->bridge);
|
||||||
|
drm_connector_cleanup(&rgb->connector);
|
||||||
drm_encoder_cleanup(&rgb->encoder);
|
drm_encoder_cleanup(&rgb->encoder);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rockchip_rgb_fini);
|
EXPORT_SYMBOL_GPL(rockchip_rgb_fini);
|
||||||
|
|
|
@ -1124,6 +1124,6 @@ struct platform_driver vop_platform_driver = {
|
||||||
.remove = vop_remove,
|
.remove = vop_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "rockchip-vop",
|
.name = "rockchip-vop",
|
||||||
.of_match_table = of_match_ptr(vop_driver_dt_match),
|
.of_match_table = vop_driver_dt_match,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1126,10 +1126,9 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
dsi->regulator = devm_regulator_get(dev, "vcc-dsi");
|
dsi->regulator = devm_regulator_get(dev, "vcc-dsi");
|
||||||
if (IS_ERR(dsi->regulator)) {
|
if (IS_ERR(dsi->regulator))
|
||||||
dev_err(dev, "Couldn't get VCC-DSI supply\n");
|
return dev_err_probe(dev, PTR_ERR(dsi->regulator),
|
||||||
return PTR_ERR(dsi->regulator);
|
"Couldn't get VCC-DSI supply\n");
|
||||||
}
|
|
||||||
|
|
||||||
dsi->reset = devm_reset_control_get_shared(dev, NULL);
|
dsi->reset = devm_reset_control_get_shared(dev, NULL);
|
||||||
if (IS_ERR(dsi->reset)) {
|
if (IS_ERR(dsi->reset)) {
|
||||||
|
@ -1144,10 +1143,9 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
dsi->bus_clk = devm_clk_get(dev, bus_clk_name);
|
dsi->bus_clk = devm_clk_get(dev, bus_clk_name);
|
||||||
if (IS_ERR(dsi->bus_clk)) {
|
if (IS_ERR(dsi->bus_clk))
|
||||||
dev_err(dev, "Couldn't get the DSI bus clock\n");
|
return dev_err_probe(dev, PTR_ERR(dsi->bus_clk),
|
||||||
return PTR_ERR(dsi->bus_clk);
|
"Couldn't get the DSI bus clock\n");
|
||||||
}
|
|
||||||
|
|
||||||
ret = regmap_mmio_attach_clk(dsi->regs, dsi->bus_clk);
|
ret = regmap_mmio_attach_clk(dsi->regs, dsi->bus_clk);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -153,22 +153,19 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
|
||||||
hdmi->rst_ctrl = devm_reset_control_get(dev, "ctrl");
|
hdmi->rst_ctrl = devm_reset_control_get(dev, "ctrl");
|
||||||
if (IS_ERR(hdmi->rst_ctrl)) {
|
if (IS_ERR(hdmi->rst_ctrl))
|
||||||
dev_err(dev, "Could not get ctrl reset control\n");
|
return dev_err_probe(dev, PTR_ERR(hdmi->rst_ctrl),
|
||||||
return PTR_ERR(hdmi->rst_ctrl);
|
"Could not get ctrl reset control\n");
|
||||||
}
|
|
||||||
|
|
||||||
hdmi->clk_tmds = devm_clk_get(dev, "tmds");
|
hdmi->clk_tmds = devm_clk_get(dev, "tmds");
|
||||||
if (IS_ERR(hdmi->clk_tmds)) {
|
if (IS_ERR(hdmi->clk_tmds))
|
||||||
dev_err(dev, "Couldn't get the tmds clock\n");
|
return dev_err_probe(dev, PTR_ERR(hdmi->clk_tmds),
|
||||||
return PTR_ERR(hdmi->clk_tmds);
|
"Couldn't get the tmds clock\n");
|
||||||
}
|
|
||||||
|
|
||||||
hdmi->regulator = devm_regulator_get(dev, "hvcc");
|
hdmi->regulator = devm_regulator_get(dev, "hvcc");
|
||||||
if (IS_ERR(hdmi->regulator)) {
|
if (IS_ERR(hdmi->regulator))
|
||||||
dev_err(dev, "Couldn't get regulator\n");
|
return dev_err_probe(dev, PTR_ERR(hdmi->regulator),
|
||||||
return PTR_ERR(hdmi->regulator);
|
"Couldn't get regulator\n");
|
||||||
}
|
|
||||||
|
|
||||||
ret = sun8i_dw_hdmi_find_connector_pdev(dev, &connector_pdev);
|
ret = sun8i_dw_hdmi_find_connector_pdev(dev, &connector_pdev);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
|
|
@ -206,10 +206,7 @@ MODULE_DEVICE_TABLE(of, v3d_of_match);
|
||||||
static int
|
static int
|
||||||
map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name)
|
map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name)
|
||||||
{
|
{
|
||||||
struct resource *res =
|
*regs = devm_platform_ioremap_resource_byname(v3d_to_pdev(v3d), name);
|
||||||
platform_get_resource_byname(v3d_to_pdev(v3d), IORESOURCE_MEM, name);
|
|
||||||
|
|
||||||
*regs = devm_ioremap_resource(v3d->drm.dev, res);
|
|
||||||
return PTR_ERR_OR_ZERO(*regs);
|
return PTR_ERR_OR_ZERO(*regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -567,14 +567,14 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
||||||
if (args->bcl_start != args->bcl_end) {
|
if (args->bcl_start != args->bcl_end) {
|
||||||
bin = kcalloc(1, sizeof(*bin), GFP_KERNEL);
|
bin = kcalloc(1, sizeof(*bin), GFP_KERNEL);
|
||||||
if (!bin) {
|
if (!bin) {
|
||||||
v3d_job_put(&render->base);
|
v3d_job_cleanup(&render->base);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = v3d_job_init(v3d, file_priv, &bin->base,
|
ret = v3d_job_init(v3d, file_priv, &bin->base,
|
||||||
v3d_job_free, args->in_sync_bcl, V3D_BIN);
|
v3d_job_free, args->in_sync_bcl, V3D_BIN);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
v3d_job_put(&render->base);
|
v3d_job_cleanup(&render->base);
|
||||||
kfree(bin);
|
kfree(bin);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -716,7 +716,7 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
|
||||||
job->base.bo = kcalloc(ARRAY_SIZE(args->bo_handles),
|
job->base.bo = kcalloc(ARRAY_SIZE(args->bo_handles),
|
||||||
sizeof(*job->base.bo), GFP_KERNEL);
|
sizeof(*job->base.bo), GFP_KERNEL);
|
||||||
if (!job->base.bo) {
|
if (!job->base.bo) {
|
||||||
v3d_job_put(&job->base);
|
v3d_job_cleanup(&job->base);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,14 +810,13 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data,
|
||||||
|
|
||||||
clean_job = kcalloc(1, sizeof(*clean_job), GFP_KERNEL);
|
clean_job = kcalloc(1, sizeof(*clean_job), GFP_KERNEL);
|
||||||
if (!clean_job) {
|
if (!clean_job) {
|
||||||
v3d_job_put(&job->base);
|
v3d_job_cleanup(&job->base);
|
||||||
kfree(job);
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = v3d_job_init(v3d, file_priv, clean_job, v3d_job_free, 0, V3D_CACHE_CLEAN);
|
ret = v3d_job_init(v3d, file_priv, clean_job, v3d_job_free, 0, V3D_CACHE_CLEAN);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
v3d_job_put(&job->base);
|
v3d_job_cleanup(&job->base);
|
||||||
kfree(clean_job);
|
kfree(clean_job);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,9 +91,7 @@ virtio_gpu_get_vbuf(struct virtio_gpu_device *vgdev,
|
||||||
{
|
{
|
||||||
struct virtio_gpu_vbuffer *vbuf;
|
struct virtio_gpu_vbuffer *vbuf;
|
||||||
|
|
||||||
vbuf = kmem_cache_zalloc(vgdev->vbufs, GFP_KERNEL);
|
vbuf = kmem_cache_zalloc(vgdev->vbufs, GFP_KERNEL | __GFP_NOFAIL);
|
||||||
if (!vbuf)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
BUG_ON(size > MAX_INLINE_CMD_SIZE ||
|
BUG_ON(size > MAX_INLINE_CMD_SIZE ||
|
||||||
size < sizeof(struct virtio_gpu_ctrl_hdr));
|
size < sizeof(struct virtio_gpu_ctrl_hdr));
|
||||||
|
@ -147,10 +145,6 @@ static void *virtio_gpu_alloc_cmd_resp(struct virtio_gpu_device *vgdev,
|
||||||
|
|
||||||
vbuf = virtio_gpu_get_vbuf(vgdev, cmd_size,
|
vbuf = virtio_gpu_get_vbuf(vgdev, cmd_size,
|
||||||
resp_size, resp_buf, cb);
|
resp_size, resp_buf, cb);
|
||||||
if (IS_ERR(vbuf)) {
|
|
||||||
*vbuffer_p = NULL;
|
|
||||||
return ERR_CAST(vbuf);
|
|
||||||
}
|
|
||||||
*vbuffer_p = vbuf;
|
*vbuffer_p = vbuf;
|
||||||
return (struct virtio_gpu_command *)vbuf->buf;
|
return (struct virtio_gpu_command *)vbuf->buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -508,6 +508,50 @@ static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
|
||||||
return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
|
return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_edid_encode_panel_id - Encode an ID for matching against drm_edid_get_panel_id()
|
||||||
|
* @vend: 3-character vendor string
|
||||||
|
* @product_id: The 16-bit product ID.
|
||||||
|
*
|
||||||
|
* This is a macro so that it can be calculated at compile time and used
|
||||||
|
* as an initializer.
|
||||||
|
*
|
||||||
|
* For instance:
|
||||||
|
* drm_edid_encode_panel_id("BOE", 0x2d08) => 0x09e52d08
|
||||||
|
*
|
||||||
|
* Return: a 32-bit ID per panel.
|
||||||
|
*/
|
||||||
|
#define drm_edid_encode_panel_id(vend, product_id) \
|
||||||
|
((((u32)((vend)[0]) - '@') & 0x1f) << 26 | \
|
||||||
|
(((u32)((vend)[1]) - '@') & 0x1f) << 21 | \
|
||||||
|
(((u32)((vend)[2]) - '@') & 0x1f) << 16 | \
|
||||||
|
((product_id) & 0xffff))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_edid_decode_panel_id - Decode a panel ID from drm_edid_encode_panel_id()
|
||||||
|
* @panel_id: The panel ID to decode.
|
||||||
|
* @vend: A 4-byte buffer to store the 3-letter vendor string plus a '\0'
|
||||||
|
* termination
|
||||||
|
* @product_id: The product ID will be returned here.
|
||||||
|
*
|
||||||
|
* For instance, after:
|
||||||
|
* drm_edid_decode_panel_id(0x09e52d08, vend, &product_id)
|
||||||
|
* These will be true:
|
||||||
|
* vend[0] = 'B'
|
||||||
|
* vend[1] = 'O'
|
||||||
|
* vend[2] = 'E'
|
||||||
|
* vend[3] = '\0'
|
||||||
|
* product_id = 0x2d08
|
||||||
|
*/
|
||||||
|
static inline void drm_edid_decode_panel_id(u32 panel_id, char vend[4], u16 *product_id)
|
||||||
|
{
|
||||||
|
*product_id = (u16)(panel_id & 0xffff);
|
||||||
|
vend[0] = '@' + ((panel_id >> 26) & 0x1f);
|
||||||
|
vend[1] = '@' + ((panel_id >> 21) & 0x1f);
|
||||||
|
vend[2] = '@' + ((panel_id >> 16) & 0x1f);
|
||||||
|
vend[3] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
bool drm_probe_ddc(struct i2c_adapter *adapter);
|
bool drm_probe_ddc(struct i2c_adapter *adapter);
|
||||||
struct edid *drm_do_get_edid(struct drm_connector *connector,
|
struct edid *drm_do_get_edid(struct drm_connector *connector,
|
||||||
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
|
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
|
||||||
|
@ -515,6 +559,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
|
||||||
void *data);
|
void *data);
|
||||||
struct edid *drm_get_edid(struct drm_connector *connector,
|
struct edid *drm_get_edid(struct drm_connector *connector,
|
||||||
struct i2c_adapter *adapter);
|
struct i2c_adapter *adapter);
|
||||||
|
u32 drm_edid_get_panel_id(struct i2c_adapter *adapter);
|
||||||
struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
|
struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
|
||||||
struct i2c_adapter *adapter);
|
struct i2c_adapter *adapter);
|
||||||
struct edid *drm_edid_duplicate(const struct edid *edid);
|
struct edid *drm_edid_duplicate(const struct edid *edid);
|
||||||
|
|
Loading…
Reference in New Issue