Commit f602a96e authored by Dave Airlie's avatar Dave Airlie

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: default avatarDave Airlie <airlied@redhat.com>

From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210923074522.zaja7mzxeimxf6g3@gilmour
parents 0dfc7081 9c2fce13
# 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>;
};
};
};
};
};
};
......@@ -6022,7 +6022,7 @@ DRM DRIVER FOR SAMSUNG S6D27A1 PANELS
M: Markuss Broks <markuss.broks@gmail.com>
S: Maintained
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
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: 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
M: Alexey Klimov <klimov.linux@gmail.com>
L: linux-media@vger.kernel.org
......
......@@ -144,6 +144,7 @@ CONFIG_VIDEO_MT9V032=m
CONFIG_DRM=y
CONFIG_DRM_ATMEL_HLCDC=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_FB_ATMEL=y
CONFIG_BACKLIGHT_ATMEL_LCDC=y
CONFIG_BACKLIGHT_PWM=y
......
......@@ -227,6 +227,7 @@ CONFIG_DRM_EXYNOS_DPI=y
CONFIG_DRM_EXYNOS_DSI=y
CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=y
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
......
......@@ -281,6 +281,7 @@ CONFIG_DRM=y
CONFIG_DRM_MSM=y
CONFIG_DRM_PANEL_LVDS=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
CONFIG_DRM_TI_TFP410=y
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
......
......@@ -108,6 +108,7 @@ CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_DRM=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_PL111=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
......
......@@ -194,6 +194,7 @@ CONFIG_VIDEO_ATMEL_ISI=m
CONFIG_DRM=y
CONFIG_DRM_ATMEL_HLCDC=m
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_ASPEED_GFX=m
CONFIG_FB_IMX=y
CONFIG_FB_ATMEL=y
......
......@@ -704,6 +704,7 @@ CONFIG_DRM_TEGRA=y
CONFIG_DRM_STM=m
CONFIG_DRM_STM_DSI=m
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
......
......@@ -511,6 +511,7 @@ CONFIG_OMAP2_DSS_DSI=y
CONFIG_DRM_TILCDC=m
CONFIG_DRM_PANEL_DSI_CM=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_PANEL_EDP=m
CONFIG_DRM_PANEL_LG_LB035Q02=m
CONFIG_DRM_PANEL_NEC_NL8048HL11=m
CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m
......
......@@ -158,6 +158,7 @@ CONFIG_MEDIA_SUPPORT=y
CONFIG_DRM=y
CONFIG_DRM_MSM=m
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_ANALOGIX_ANX78XX=m
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
......
......@@ -61,6 +61,7 @@ CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_DRM=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_DISPLAY_CONNECTOR=y
CONFIG_DRM_SIMPLE_BRIDGE=y
CONFIG_DRM_PL111=y
......
......@@ -160,6 +160,7 @@ CONFIG_VIDEO_MT9V032=m
CONFIG_DRM=y
CONFIG_DRM_ATMEL_HLCDC=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_PWM=y
......
......@@ -129,6 +129,7 @@ CONFIG_VIDEO_ML86V7667=y
CONFIG_DRM=y
CONFIG_DRM_RCAR_DU=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_DISPLAY_CONNECTOR=y
CONFIG_DRM_LVDS_CODEC=y
CONFIG_DRM_SII902X=y
......
......@@ -108,6 +108,7 @@ CONFIG_DRM_SUN4I_HDMI_CEC=y
CONFIG_DRM_SUN8I_DW_HDMI=y
CONFIG_DRM_PANEL_LVDS=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_SIMPLE_BRIDGE=y
CONFIG_DRM_LIMA=y
CONFIG_FB_SIMPLE=y
......
......@@ -199,6 +199,7 @@ CONFIG_DRM_TEGRA=y
CONFIG_DRM_TEGRA_STAGING=y
CONFIG_DRM_PANEL_LVDS=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_LVDS_CODEC=y
CONFIG_FB=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
......
......@@ -57,6 +57,7 @@ CONFIG_GPIO_PL061=y
CONFIG_DRM=y
CONFIG_DRM_PANEL_ARM_VERSATILE=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_DISPLAY_CONNECTOR=y
CONFIG_DRM_SIMPLE_BRIDGE=y
CONFIG_DRM_PL111=y
......
......@@ -77,6 +77,7 @@ CONFIG_SENSORS_VEXPRESS=y
CONFIG_REGULATOR_VEXPRESS=y
CONFIG_DRM=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_SII902X=y
CONFIG_DRM_PL111=y
CONFIG_FB=y
......
......@@ -697,6 +697,7 @@ CONFIG_DRM_MSM=m
CONFIG_DRM_TEGRA=m
CONFIG_DRM_PANEL_LVDS=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_PANEL_EDP=m
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
......
......@@ -918,11 +918,23 @@ static int it66121_probe(struct i2c_client *client,
return -EINVAL;
ep = of_graph_get_remote_node(dev->of_node, 1, -1);
if (!ep)
return -EPROBE_DEFER;
if (!ep) {
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);
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)
return -EPROBE_DEFER;
......
......@@ -9,6 +9,7 @@
#include <drm/drm_connector.h>
#include <drm/drm_encoder.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_print.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;
}
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;
}
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
MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
......
......@@ -1620,7 +1620,7 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties);
* connectors.
*
* 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.
*/
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_\*).
*
* 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.
*
* This is the atomic version of drm_mode_create_scaling_mode_property().
......
This diff is collapsed.
......@@ -77,14 +77,26 @@ config DRM_PANEL_LVDS
backlight handling if the panel is attached to a backlight controller.
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 BACKLIGHT_CLASS_DEVICE
depends on PM
select VIDEOMODE_HELPERS
select DRM_DP_AUX_BUS
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
that it can be automatically turned off when the panel goes into a
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_LVDS) += panel-lvds.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_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
......
This diff is collapsed.
This diff is collapsed.
......@@ -398,8 +398,7 @@ void panfrost_device_reset(struct panfrost_device *pfdev)
#ifdef CONFIG_PM
int panfrost_device_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct panfrost_device *pfdev = platform_get_drvdata(pdev);
struct panfrost_device *pfdev = dev_get_drvdata(dev);
panfrost_device_reset(pfdev);
panfrost_devfreq_resume(pfdev);
......@@ -409,8 +408,7 @@ int panfrost_device_resume(struct device *dev)
int panfrost_device_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct panfrost_device *pfdev = platform_get_drvdata(pdev);
struct panfrost_device *pfdev = dev_get_drvdata(dev);
if (!panfrost_job_is_idle(pfdev))
return -EBUSY;
......
......@@ -638,8 +638,8 @@ static const struct panfrost_compatible amlogic_data = {
.vendor_quirk = panfrost_gpu_amlogic_quirk,
};
const char * const mediatek_mt8183_supplies[] = { "mali", "sram" };
const char * const mediatek_mt8183_pm_domains[] = { "core0", "core1", "core2" };
static const char * const mediatek_mt8183_supplies[] = { "mali", "sram" };
static const char * const mediatek_mt8183_pm_domains[] = { "core0", "core1", "core2" };
static const struct panfrost_compatible mediatek_mt8183_data = {
.num_supplies = ARRAY_SIZE(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,
u64 iova, u64 size)
u64 region_start, u64 size)
{
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
* with fls. The size must be clamped to hardware bounds.
if (!size)
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 = fls64(size - 1) - 1;
region |= region_width;
region_width = max(fls64(region_start ^ (region_end - 1)),
const_ilog2(AS_LOCK_REGION_MIN_SIZE)) - 1;
/*
* 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 */
mmu_write(pfdev, AS_LOCKADDR_LO(as_nr), lower_32_bits(region));
......
......@@ -467,6 +467,6 @@ struct platform_driver rockchip_dp_driver = {
.driver = {
.name = "rockchip-dp",
.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_node *np = dev->of_node;
struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,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);
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dp->regs = devm_ioremap_resource(dev, res);
dp->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dp->regs)) {
DRM_DEV_ERROR(dev, "ioremap reg failed\n");
return PTR_ERR(dp->regs);
......
......@@ -14,7 +14,6 @@
#include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/pm_runtime.h>
#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <video/mipi_display.h>
......@@ -643,7 +642,7 @@ struct hstt {
}
/* Table A-3 High-Speed Transition Times */
struct hstt hstt_table[] = {
static struct hstt hstt_table[] = {
HSTT( 90, 32, 20, 26, 13),
HSTT( 100, 35, 23, 28, 14),
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 drm_device *drm = data;
struct inno_hdmi *hdmi;
struct resource *iores;
int irq;
int ret;
......@@ -821,8 +820,7 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
hdmi->dev = dev;
hdmi->drm_dev = drm;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hdmi->regs = devm_ioremap_resource(dev, iores);
hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_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;
INIT_LIST_HEAD(&private->psr_list);
mutex_init(&private->psr_list_lock);
ret = rockchip_drm_init_iommu(drm_dev);
if (ret)
goto err_free;
......@@ -275,10 +272,17 @@ int rockchip_drm_endpoint_is_subdriver(struct device_node *ep)
return -ENODEV;
/* 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);
of_node_put(node);
/* enabled non-platform-devices can immediately return here */
if (!pdev)
return -ENODEV;
return false;
/*
* 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);
if (!iommu || !of_device_is_available(iommu->parent)) {
if (!iommu || !of_device_is_available(iommu)) {
DRM_DEV_DEBUG(dev,
"no iommu attached for %pOF, using non-iommu buffers\n",
port->parent);
......
......@@ -48,8 +48,6 @@ struct rockchip_drm_private {
struct iommu_domain *domain;
struct mutex mm_lock;
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,
......
......@@ -19,6 +19,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_dp_helper.h>
#include <drm/drm_of.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,
struct rockchip_lvds *lvds)
{
struct resource *res;
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
lvds->regs = devm_ioremap_resource(lvds->dev, res);
lvds->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_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);
connector = &lvds->connector;
if (lvds->panel) {
connector = &lvds->connector;
connector->dpms = DRM_MODE_DPMS_OFF;
ret = drm_connector_init(drm_dev, connector,
&rockchip_lvds_connector_funcs,
......@@ -627,17 +626,27 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
drm_connector_helper_add(connector,
&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 {
ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 0);
ret = drm_bridge_attach(encoder, lvds->bridge, NULL,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret)
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);
......
......@@ -10,6 +10,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_dp_helper.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
......@@ -27,6 +28,7 @@ struct rockchip_rgb {
struct drm_device *drm_dev;
struct drm_bridge *bridge;
struct drm_encoder encoder;
struct drm_connector connector;
int output_mode;
};
......@@ -80,6 +82,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
int ret = 0, child_count = 0;
struct drm_panel *panel;
struct drm_bridge *bridge;
struct drm_connector *connector;
rgb = devm_kzalloc(dev, sizeof(*rgb), GFP_KERNEL);
if (!rgb)
......@@ -142,12 +145,32 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
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)
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;
err_free_connector:
drm_connector_cleanup(connector);
err_free_encoder:
drm_encoder_cleanup(encoder);
return ERR_PTR(ret);
......@@ -157,6 +180,7 @@ EXPORT_SYMBOL_GPL(rockchip_rgb_init);
void rockchip_rgb_fini(struct rockchip_rgb *rgb)
{
drm_panel_bridge_remove(rgb->bridge);
drm_connector_cleanup(&rgb->connector);
drm_encoder_cleanup(&rgb->encoder);
}
EXPORT_SYMBOL_GPL(rockchip_rgb_fini);
......@@ -1124,6 +1124,6 @@ struct platform_driver vop_platform_driver = {
.remove = vop_remove,
.driver = {
.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");
if (IS_ERR(dsi->regulator)) {
dev_err(dev, "Couldn't get VCC-DSI supply\n");
return PTR_ERR(dsi->regulator);
}
if (IS_ERR(dsi->regulator))
return dev_err_probe(dev, PTR_ERR(dsi->regulator),
"Couldn't get VCC-DSI supply\n");
dsi->reset = devm_reset_control_get_shared(dev, NULL);
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);
if (IS_ERR(dsi->bus_clk)) {
dev_err(dev, "Couldn't get the DSI bus clock\n");
return PTR_ERR(dsi->bus_clk);
}
if (IS_ERR(dsi->bus_clk))
return dev_err_probe(dev, PTR_ERR(dsi->bus_clk),
"Couldn't get the DSI bus clock\n");
ret = regmap_mmio_attach_clk(dsi->regs, dsi->bus_clk);
if (ret)
......
......@@ -153,22 +153,19 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
return -EPROBE_DEFER;
hdmi->rst_ctrl = devm_reset_control_get(dev, "ctrl");
if (IS_ERR(hdmi->rst_ctrl)) {
dev_err(dev, "Could not get ctrl reset control\n");
return PTR_ERR(hdmi->rst_ctrl);
}
if (IS_ERR(hdmi->rst_ctrl))
return dev_err_probe(dev, PTR_ERR(hdmi->rst_ctrl),
"Could not get ctrl reset control\n");
hdmi->clk_tmds = devm_clk_get(dev, "tmds");
if (IS_ERR(hdmi->clk_tmds)) {
dev_err(dev, "Couldn't get the tmds clock\n");
return PTR_ERR(hdmi->clk_tmds);
}
if (IS_ERR(hdmi->clk_tmds))
return dev_err_probe(dev, PTR_ERR(hdmi->clk_tmds),
"Couldn't get the tmds clock\n");
hdmi->regulator = devm_regulator_get(dev, "hvcc");
if (IS_ERR(hdmi->regulator)) {
dev_err(dev, "Couldn't get regulator\n");
return PTR_ERR(hdmi->regulator);
}
if (IS_ERR(hdmi->regulator))
return dev_err_probe(dev, PTR_ERR(hdmi->regulator),
"Couldn't get regulator\n");
ret = sun8i_dw_hdmi_find_connector_pdev(dev, &connector_pdev);
if (!ret) {
......
......@@ -206,10 +206,7 @@ MODULE_DEVICE_TABLE(of, v3d_of_match);
static int
map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name)
{
struct resource *res =
platform_get_resource_byname(v3d_to_pdev(v3d), IORESOURCE_MEM, name);
*regs = devm_ioremap_resource(v3d->drm.dev, res);
*regs = devm_platform_ioremap_resource_byname(v3d_to_pdev(v3d), name);
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) {
bin = kcalloc(1, sizeof(*bin), GFP_KERNEL);
if (!bin) {
v3d_job_put(&render->base);
v3d_job_cleanup(&render->base);
return -ENOMEM;
}
ret = v3d_job_init(v3d, file_priv, &bin->base,
v3d_job_free, args->in_sync_bcl, V3D_BIN);
if (ret) {
v3d_job_put(&render->base);
v3d_job_cleanup(&render->base);
kfree(bin);
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),
sizeof(*job->base.bo), GFP_KERNEL);
if (!job->base.bo) {
v3d_job_put(&job->base);
v3d_job_cleanup(&job->base);
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);
if (!clean_job) {
v3d_job_put(&job->base);
kfree(job);
v3d_job_cleanup(&job->base);
return -ENOMEM;
}
ret = v3d_job_init(v3d, file_priv, clean_job, v3d_job_free, 0, V3D_CACHE_CLEAN);
if (ret) {
v3d_job_put(&job->base);
v3d_job_cleanup(&job->base);
kfree(clean_job);
return ret;
}
......
......@@ -91,9 +91,7 @@ virtio_gpu_get_vbuf(struct virtio_gpu_device *vgdev,
{
struct virtio_gpu_vbuffer *vbuf;
vbuf = kmem_cache_zalloc(vgdev->vbufs, GFP_KERNEL);
if (!vbuf)
return ERR_PTR(-ENOMEM);
vbuf = kmem_cache_zalloc(vgdev->vbufs, GFP_KERNEL | __GFP_NOFAIL);
BUG_ON(size > MAX_INLINE_CMD_SIZE ||
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,
resp_size, resp_buf, cb);
if (IS_ERR(vbuf)) {
*vbuffer_p = NULL;
return ERR_CAST(vbuf);
}
*vbuffer_p = vbuf;
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;
}
/**
* 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);
struct edid *drm_do_get_edid(struct drm_connector *connector,
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);
struct edid *drm_get_edid(struct drm_connector *connector,
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 i2c_adapter *adapter);
struct edid *drm_edid_duplicate(const struct edid *edid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment