Merge tag 'drm-misc-next-2024-02-15' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.9: UAPI Changes: Cross-subsystem Changes: arch: - powerpc/ps3: select CONFIG_VIDEO Core Changes: ci: - msm: fix apq8016 runner display: - use newer DRM print helpers documentation: - fix typos print: - add device-specific error and debug printers sysfb: - set Linux parent device for firmware framebuffer tests: - mm: use newer DRM print helpers Driver Changes: bridge: - switch to ->read_edid callback throughout the bridge drivers - remove old ->get_edid callback i915: - use newer DRM print helpers lima: - improve stability by fixes to error handling and recovery mediathek: - switch to ->read_edid callback msm: - switch to ->read_edid callback omap: - switch to ->read_edid callback panel: - add Powkiddy RGB10MAX3 plus DT bindings - st7703: support panel rotation plus DT bindings rockchip: - DT bindings: remove port, add power-domains xe: - use newer DRM print helpers xlnx: - switch to ->read_edid callback Signed-off-by: Dave Airlie <airlied@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmXOD/oACgkQaA3BHVML # eiMWMAgArTVXF4UQ+FUxYZB5QTm2veYIpilvwmzaQLNxsM9SsWpzwMIVAi+xf93g # uqUqkl6QvZ9pJg6bxuXRNcJw/GObIO4x6tn+LkbccczgHiHwvn6ydNdUoMx8ulne # EsGC0z8bb5Gpwh9b/pnBul2AoIE7PHAJltgH271/O2xnhFMUbchQ0ckHvWnn8/GA # Nef145ySX4gkYtY8u2TRr4r6Bkp7Tpiyv6ipU7Cpu7KqyveTDMx3c9r5FaiHnJT/ # Hx/5s87q0Bx2m+iNjlBLJzYjF2UWth+pbfiu3xwyWOE7hdkPLwCQ5mqHWcFFqxfb # Vuj9jP+Vb68L7EvGpq2LArLdhZjHIQ== # =SsjX # -----END PGP SIGNATURE----- # gpg: Signature made Thu 15 Feb 2024 23:22:02 AEST # gpg: using RSA key 7217FBAC8CE9CF6344A168E5680DC11D530B7A23 # gpg: Can't check signature: No public key From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240215132610.GA1464@localhost.localdomain
This commit is contained in:
@@ -22,6 +22,8 @@ properties:
|
||||
enum:
|
||||
# Anberic RG353V-V2 5.0" 640x480 TFT LCD panel
|
||||
- anbernic,rg353v-panel-v2
|
||||
# Powkiddy RGB10MAX3 5.0" 720x1280 TFT LCD panel
|
||||
- powkiddy,rgb10max3-panel
|
||||
# Powkiddy RGB30 3.0" 720x720 TFT LCD panel
|
||||
- powkiddy,rgb30-panel
|
||||
# Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel
|
||||
@@ -43,6 +45,7 @@ properties:
|
||||
reset-gpios: true
|
||||
|
||||
backlight: true
|
||||
rotation: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
@@ -94,11 +94,14 @@ properties:
|
||||
- const: default
|
||||
- const: unwedge
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
patternProperties:
|
||||
"^port(@0)?$":
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Input of the DWC HDMI TX
|
||||
properties:
|
||||
@@ -108,11 +111,14 @@ properties:
|
||||
description: Connection to the VOPB
|
||||
endpoint@1:
|
||||
description: Connection to the VOPL
|
||||
properties:
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Output of the DWC HDMI TX
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
rockchip,grf:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
@@ -135,19 +141,25 @@ examples:
|
||||
#include <dt-bindings/clock/rk3288-cru.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/power/rk3288-power.h>
|
||||
|
||||
hdmi: hdmi@ff980000 {
|
||||
compatible = "rockchip,rk3288-dw-hdmi";
|
||||
reg = <0xff980000 0x20000>;
|
||||
reg-io-width = <4>;
|
||||
ddc-i2c-bus = <&i2c5>;
|
||||
rockchip,grf = <&grf>;
|
||||
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>;
|
||||
clock-names = "iahb", "isfr";
|
||||
ddc-i2c-bus = <&i2c5>;
|
||||
power-domains = <&power RK3288_PD_VIO>;
|
||||
rockchip,grf = <&grf>;
|
||||
|
||||
ports {
|
||||
port {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
@@ -155,11 +167,20 @@ examples:
|
||||
reg = <0>;
|
||||
remote-endpoint = <&vopb_out_hdmi>;
|
||||
};
|
||||
|
||||
hdmi_in_vopl: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&vopl_out_hdmi>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
hdmi_out_con: endpoint {
|
||||
remote-endpoint = <&hdmi_con_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ config PS3_VUART
|
||||
config PS3_PS3AV
|
||||
depends on PPC_PS3
|
||||
tristate "PS3 AV settings driver" if PS3_ADVANCED
|
||||
select VIDEO
|
||||
select PS3_VUART
|
||||
default y
|
||||
help
|
||||
|
||||
@@ -182,6 +182,7 @@ config MTK_ADSP_IPC
|
||||
config SYSFB
|
||||
bool
|
||||
select BOOT_VESA_SUPPORT
|
||||
select SCREEN_INFO
|
||||
|
||||
config SYSFB_SIMPLEFB
|
||||
bool "Mark VGA/VBE/EFI FB as generic system framebuffer"
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_data/simplefb.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/screen_info.h>
|
||||
@@ -69,24 +70,70 @@ void sysfb_disable(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sysfb_disable);
|
||||
|
||||
#if defined(CONFIG_PCI)
|
||||
static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
|
||||
{
|
||||
/*
|
||||
* TODO: Try to integrate this code into the PCI subsystem
|
||||
*/
|
||||
int ret;
|
||||
u16 command;
|
||||
|
||||
ret = pci_read_config_word(pdev, PCI_COMMAND, &command);
|
||||
if (ret != PCIBIOS_SUCCESSFUL)
|
||||
return false;
|
||||
if (!(command & PCI_COMMAND_MEMORY))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static __init struct device *sysfb_parent_dev(const struct screen_info *si)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
|
||||
pdev = screen_info_pci_dev(si);
|
||||
if (IS_ERR(pdev)) {
|
||||
return ERR_CAST(pdev);
|
||||
} else if (pdev) {
|
||||
if (!sysfb_pci_dev_is_enabled(pdev))
|
||||
return ERR_PTR(-ENODEV);
|
||||
return &pdev->dev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static __init int sysfb_init(void)
|
||||
{
|
||||
struct screen_info *si = &screen_info;
|
||||
struct device *parent;
|
||||
struct simplefb_platform_data mode;
|
||||
const char *name;
|
||||
bool compatible;
|
||||
int ret = 0;
|
||||
|
||||
screen_info_apply_fixups();
|
||||
|
||||
mutex_lock(&disable_lock);
|
||||
if (disabled)
|
||||
goto unlock_mutex;
|
||||
|
||||
sysfb_apply_efi_quirks();
|
||||
|
||||
parent = sysfb_parent_dev(si);
|
||||
if (IS_ERR(parent))
|
||||
goto unlock_mutex;
|
||||
|
||||
/* try to create a simple-framebuffer device */
|
||||
compatible = sysfb_parse_mode(si, &mode);
|
||||
if (compatible) {
|
||||
pd = sysfb_create_simplefb(si, &mode);
|
||||
pd = sysfb_create_simplefb(si, &mode, parent);
|
||||
if (!IS_ERR(pd))
|
||||
goto unlock_mutex;
|
||||
}
|
||||
@@ -109,6 +156,8 @@ static __init int sysfb_init(void)
|
||||
goto unlock_mutex;
|
||||
}
|
||||
|
||||
pd->dev.parent = parent;
|
||||
|
||||
sysfb_set_efifb_fwnode(pd);
|
||||
|
||||
ret = platform_device_add_data(pd, si, sizeof(*si));
|
||||
|
||||
@@ -91,7 +91,8 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
|
||||
}
|
||||
|
||||
__init struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
|
||||
const struct simplefb_platform_data *mode)
|
||||
const struct simplefb_platform_data *mode,
|
||||
struct device *parent)
|
||||
{
|
||||
struct platform_device *pd;
|
||||
struct resource res;
|
||||
@@ -143,6 +144,8 @@ __init struct platform_device *sysfb_create_simplefb(const struct screen_info *s
|
||||
if (!pd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pd->dev.parent = parent;
|
||||
|
||||
sysfb_set_efifb_fwnode(pd);
|
||||
|
||||
ret = platform_device_add_resources(pd, &res, 1);
|
||||
|
||||
@@ -604,10 +604,10 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
|
||||
* ADV75xx helpers
|
||||
*/
|
||||
|
||||
static struct edid *adv7511_get_edid(struct adv7511 *adv7511,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *adv7511_edid_read(struct adv7511 *adv7511,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
|
||||
/* Reading the EDID only works if the device is powered */
|
||||
if (!adv7511->powered) {
|
||||
@@ -621,31 +621,44 @@ static struct edid *adv7511_get_edid(struct adv7511 *adv7511,
|
||||
edid_i2c_addr);
|
||||
}
|
||||
|
||||
edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511);
|
||||
drm_edid = drm_edid_read_custom(connector, adv7511_get_edid_block, adv7511);
|
||||
|
||||
if (!adv7511->powered)
|
||||
__adv7511_power_off(adv7511);
|
||||
|
||||
adv7511_set_config_csc(adv7511, connector, adv7511->rgb,
|
||||
drm_detect_hdmi_monitor(edid));
|
||||
if (drm_edid) {
|
||||
/*
|
||||
* FIXME: The CEC physical address should be set using
|
||||
* cec_s_phys_addr(adap,
|
||||
* connector->display_info.source_physical_address, false) from
|
||||
* a path that has read the EDID and called
|
||||
* drm_edid_connector_update().
|
||||
*/
|
||||
const struct edid *edid = drm_edid_raw(drm_edid);
|
||||
|
||||
cec_s_phys_addr_from_edid(adv7511->cec_adap, edid);
|
||||
adv7511_set_config_csc(adv7511, connector, adv7511->rgb,
|
||||
drm_detect_hdmi_monitor(edid));
|
||||
|
||||
return edid;
|
||||
cec_s_phys_addr_from_edid(adv7511->cec_adap, edid);
|
||||
} else {
|
||||
cec_s_phys_addr_from_edid(adv7511->cec_adap, NULL);
|
||||
}
|
||||
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
static int adv7511_get_modes(struct adv7511 *adv7511,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
unsigned int count;
|
||||
|
||||
edid = adv7511_get_edid(adv7511, connector);
|
||||
drm_edid = adv7511_edid_read(adv7511, connector);
|
||||
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
count = drm_add_edid_modes(connector, edid);
|
||||
drm_edid_connector_update(connector, drm_edid);
|
||||
count = drm_edid_connector_add_modes(connector);
|
||||
|
||||
kfree(edid);
|
||||
drm_edid_free(drm_edid);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -953,12 +966,12 @@ static enum drm_connector_status adv7511_bridge_detect(struct drm_bridge *bridge
|
||||
return adv7511_detect(adv, NULL);
|
||||
}
|
||||
|
||||
static struct edid *adv7511_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *adv7511_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct adv7511 *adv = bridge_to_adv7511(bridge);
|
||||
|
||||
return adv7511_get_edid(adv, connector);
|
||||
return adv7511_edid_read(adv, connector);
|
||||
}
|
||||
|
||||
static void adv7511_bridge_hpd_notify(struct drm_bridge *bridge,
|
||||
@@ -977,7 +990,7 @@ static const struct drm_bridge_funcs adv7511_bridge_funcs = {
|
||||
.mode_valid = adv7511_bridge_mode_valid,
|
||||
.attach = adv7511_bridge_attach,
|
||||
.detect = adv7511_bridge_detect,
|
||||
.get_edid = adv7511_bridge_get_edid,
|
||||
.edid_read = adv7511_bridge_edid_read,
|
||||
.hpd_notify = adv7511_bridge_hpd_notify,
|
||||
};
|
||||
|
||||
|
||||
@@ -1784,24 +1784,14 @@ static ssize_t anx7625_aux_transfer(struct drm_dp_aux *aux,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct edid *anx7625_get_edid(struct anx7625_data *ctx)
|
||||
static const struct drm_edid *anx7625_edid_read(struct anx7625_data *ctx)
|
||||
{
|
||||
struct device *dev = ctx->dev;
|
||||
struct s_edid_data *p_edid = &ctx->slimport_edid_p;
|
||||
int edid_num;
|
||||
u8 *edid;
|
||||
|
||||
edid = kmalloc(FOUR_BLOCK_SIZE, GFP_KERNEL);
|
||||
if (!edid) {
|
||||
DRM_DEV_ERROR(dev, "Fail to allocate buffer\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->slimport_edid_p.edid_block_num > 0) {
|
||||
memcpy(edid, ctx->slimport_edid_p.edid_raw_data,
|
||||
FOUR_BLOCK_SIZE);
|
||||
return (struct edid *)edid;
|
||||
}
|
||||
if (ctx->slimport_edid_p.edid_block_num > 0)
|
||||
goto out;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
_anx7625_hpd_polling(ctx, 5000 * 100);
|
||||
@@ -1810,14 +1800,14 @@ static struct edid *anx7625_get_edid(struct anx7625_data *ctx)
|
||||
|
||||
if (edid_num < 1) {
|
||||
DRM_DEV_ERROR(dev, "Fail to read EDID: %d\n", edid_num);
|
||||
kfree(edid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p_edid->edid_block_num = edid_num;
|
||||
|
||||
memcpy(edid, ctx->slimport_edid_p.edid_raw_data, FOUR_BLOCK_SIZE);
|
||||
return (struct edid *)edid;
|
||||
out:
|
||||
return drm_edid_alloc(ctx->slimport_edid_p.edid_raw_data,
|
||||
FOUR_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static enum drm_connector_status anx7625_sink_detect(struct anx7625_data *ctx)
|
||||
@@ -2492,15 +2482,15 @@ anx7625_bridge_detect(struct drm_bridge *bridge)
|
||||
return anx7625_sink_detect(ctx);
|
||||
}
|
||||
|
||||
static struct edid *anx7625_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *anx7625_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct anx7625_data *ctx = bridge_to_anx7625(bridge);
|
||||
struct device *dev = ctx->dev;
|
||||
|
||||
DRM_DEV_DEBUG_DRIVER(dev, "drm bridge get edid\n");
|
||||
|
||||
return anx7625_get_edid(ctx);
|
||||
return anx7625_edid_read(ctx);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs anx7625_bridge_funcs = {
|
||||
@@ -2515,7 +2505,7 @@ static const struct drm_bridge_funcs anx7625_bridge_funcs = {
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
.detect = anx7625_bridge_detect,
|
||||
.get_edid = anx7625_bridge_get_edid,
|
||||
.edid_read = anx7625_bridge_edid_read,
|
||||
};
|
||||
|
||||
static int anx7625_register_i2c_dummy_clients(struct anx7625_data *ctx,
|
||||
|
||||
@@ -1505,33 +1505,35 @@ static void cdns_mhdp_link_down(struct cdns_mhdp_device *mhdp)
|
||||
mhdp->link_up = false;
|
||||
}
|
||||
|
||||
static struct edid *cdns_mhdp_get_edid(struct cdns_mhdp_device *mhdp,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *cdns_mhdp_edid_read(struct cdns_mhdp_device *mhdp,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
if (!mhdp->plugged)
|
||||
return NULL;
|
||||
|
||||
return drm_do_get_edid(connector, cdns_mhdp_get_edid_block, mhdp);
|
||||
return drm_edid_read_custom(connector, cdns_mhdp_get_edid_block, mhdp);
|
||||
}
|
||||
|
||||
static int cdns_mhdp_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct cdns_mhdp_device *mhdp = connector_to_mhdp(connector);
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
int num_modes;
|
||||
|
||||
if (!mhdp->plugged)
|
||||
return 0;
|
||||
|
||||
edid = cdns_mhdp_get_edid(mhdp, connector);
|
||||
if (!edid) {
|
||||
drm_edid = cdns_mhdp_edid_read(mhdp, connector);
|
||||
|
||||
drm_edid_connector_update(connector, drm_edid);
|
||||
|
||||
if (!drm_edid) {
|
||||
dev_err(mhdp->dev, "Failed to read EDID\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
num_modes = drm_add_edid_modes(connector, edid);
|
||||
kfree(edid);
|
||||
num_modes = drm_edid_connector_add_modes(connector);
|
||||
drm_edid_free(drm_edid);
|
||||
|
||||
/*
|
||||
* HACK: Warn about unsupported display formats until we deal
|
||||
@@ -2220,12 +2222,12 @@ static enum drm_connector_status cdns_mhdp_bridge_detect(struct drm_bridge *brid
|
||||
return cdns_mhdp_detect(mhdp);
|
||||
}
|
||||
|
||||
static struct edid *cdns_mhdp_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *cdns_mhdp_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
|
||||
|
||||
return cdns_mhdp_get_edid(mhdp, connector);
|
||||
return cdns_mhdp_edid_read(mhdp, connector);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = {
|
||||
@@ -2239,7 +2241,7 @@ static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = {
|
||||
.atomic_reset = cdns_mhdp_bridge_atomic_reset,
|
||||
.atomic_get_input_bus_fmts = cdns_mhdp_get_input_bus_fmts,
|
||||
.detect = cdns_mhdp_bridge_detect,
|
||||
.get_edid = cdns_mhdp_bridge_get_edid,
|
||||
.edid_read = cdns_mhdp_bridge_edid_read,
|
||||
.hpd_enable = cdns_mhdp_bridge_hpd_enable,
|
||||
.hpd_disable = cdns_mhdp_bridge_hpd_disable,
|
||||
};
|
||||
|
||||
@@ -81,12 +81,12 @@ display_connector_detect(struct drm_bridge *bridge)
|
||||
}
|
||||
}
|
||||
|
||||
static struct edid *display_connector_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *display_connector_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct display_connector *conn = to_display_connector(bridge);
|
||||
|
||||
return drm_get_edid(connector, conn->bridge.ddc);
|
||||
return drm_edid_read_ddc(connector, conn->bridge.ddc);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -172,7 +172,7 @@ static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge,
|
||||
static const struct drm_bridge_funcs display_connector_bridge_funcs = {
|
||||
.attach = display_connector_attach,
|
||||
.detect = display_connector_detect,
|
||||
.get_edid = display_connector_get_edid,
|
||||
.edid_read = display_connector_edid_read,
|
||||
.atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts,
|
||||
.atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts,
|
||||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
|
||||
@@ -458,7 +458,7 @@ struct it6505 {
|
||||
/* it6505 driver hold option */
|
||||
bool enable_drv_hold;
|
||||
|
||||
struct edid *cached_edid;
|
||||
const struct drm_edid *cached_edid;
|
||||
};
|
||||
|
||||
struct it6505_step_train_para {
|
||||
@@ -2263,7 +2263,7 @@ static void it6505_plugged_status_to_codec(struct it6505 *it6505)
|
||||
|
||||
static void it6505_remove_edid(struct it6505 *it6505)
|
||||
{
|
||||
kfree(it6505->cached_edid);
|
||||
drm_edid_free(it6505->cached_edid);
|
||||
it6505->cached_edid = NULL;
|
||||
}
|
||||
|
||||
@@ -3034,15 +3034,16 @@ it6505_bridge_detect(struct drm_bridge *bridge)
|
||||
return it6505_detect(it6505);
|
||||
}
|
||||
|
||||
static struct edid *it6505_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *it6505_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct it6505 *it6505 = bridge_to_it6505(bridge);
|
||||
struct device *dev = it6505->dev;
|
||||
|
||||
if (!it6505->cached_edid) {
|
||||
it6505->cached_edid = drm_do_get_edid(connector, it6505_get_edid_block,
|
||||
it6505);
|
||||
it6505->cached_edid = drm_edid_read_custom(connector,
|
||||
it6505_get_edid_block,
|
||||
it6505);
|
||||
|
||||
if (!it6505->cached_edid) {
|
||||
DRM_DEV_DEBUG_DRIVER(dev, "failed to get edid!");
|
||||
@@ -3050,7 +3051,7 @@ static struct edid *it6505_bridge_get_edid(struct drm_bridge *bridge,
|
||||
}
|
||||
}
|
||||
|
||||
return drm_edid_duplicate(it6505->cached_edid);
|
||||
return drm_edid_dup(it6505->cached_edid);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs it6505_bridge_funcs = {
|
||||
@@ -3065,7 +3066,7 @@ static const struct drm_bridge_funcs it6505_bridge_funcs = {
|
||||
.atomic_pre_enable = it6505_bridge_atomic_pre_enable,
|
||||
.atomic_post_disable = it6505_bridge_atomic_post_disable,
|
||||
.detect = it6505_bridge_detect,
|
||||
.get_edid = it6505_bridge_get_edid,
|
||||
.edid_read = it6505_bridge_edid_read,
|
||||
};
|
||||
|
||||
static __maybe_unused int it6505_bridge_resume(struct device *dev)
|
||||
|
||||
@@ -874,33 +874,33 @@ static void it66121_bridge_hpd_disable(struct drm_bridge *bridge)
|
||||
dev_err(ctx->dev, "failed to disable HPD IRQ\n");
|
||||
}
|
||||
|
||||
static struct edid *it66121_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *it66121_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge);
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
ret = it66121_preamble_ddc(ctx);
|
||||
if (ret) {
|
||||
edid = NULL;
|
||||
drm_edid = NULL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = regmap_write(ctx->regmap, IT66121_DDC_HEADER_REG,
|
||||
IT66121_DDC_HEADER_EDID);
|
||||
if (ret) {
|
||||
edid = NULL;
|
||||
drm_edid = NULL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
edid = drm_do_get_edid(connector, it66121_get_edid_block, ctx);
|
||||
drm_edid = drm_edid_read_custom(connector, it66121_get_edid_block, ctx);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&ctx->lock);
|
||||
|
||||
return edid;
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs it66121_bridge_funcs = {
|
||||
@@ -916,7 +916,7 @@ static const struct drm_bridge_funcs it66121_bridge_funcs = {
|
||||
.mode_set = it66121_bridge_mode_set,
|
||||
.mode_valid = it66121_bridge_mode_valid,
|
||||
.detect = it66121_bridge_detect,
|
||||
.get_edid = it66121_bridge_get_edid,
|
||||
.edid_read = it66121_bridge_edid_read,
|
||||
.hpd_enable = it66121_bridge_hpd_enable,
|
||||
.hpd_disable = it66121_bridge_hpd_disable,
|
||||
};
|
||||
|
||||
@@ -847,13 +847,13 @@ lt9611_bridge_atomic_post_disable(struct drm_bridge *bridge,
|
||||
lt9611_sleep_setup(lt9611);
|
||||
}
|
||||
|
||||
static struct edid *lt9611_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *lt9611_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
|
||||
|
||||
lt9611_power_on(lt9611);
|
||||
return drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
|
||||
return drm_edid_read_custom(connector, lt9611_get_edid_block, lt9611);
|
||||
}
|
||||
|
||||
static void lt9611_bridge_hpd_enable(struct drm_bridge *bridge)
|
||||
@@ -893,7 +893,7 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = {
|
||||
.attach = lt9611_bridge_attach,
|
||||
.mode_valid = lt9611_bridge_mode_valid,
|
||||
.detect = lt9611_bridge_detect,
|
||||
.get_edid = lt9611_bridge_get_edid,
|
||||
.edid_read = lt9611_bridge_edid_read,
|
||||
.hpd_enable = lt9611_bridge_hpd_enable,
|
||||
|
||||
.atomic_pre_enable = lt9611_bridge_atomic_pre_enable,
|
||||
|
||||
@@ -495,8 +495,8 @@ static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, siz
|
||||
return 0;
|
||||
};
|
||||
|
||||
static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *lt9611uxc_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge);
|
||||
int ret;
|
||||
@@ -510,7 +510,7 @@ static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return drm_do_get_edid(connector, lt9611uxc_get_edid_block, lt9611uxc);
|
||||
return drm_edid_read_custom(connector, lt9611uxc_get_edid_block, lt9611uxc);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs lt9611uxc_bridge_funcs = {
|
||||
@@ -518,7 +518,7 @@ static const struct drm_bridge_funcs lt9611uxc_bridge_funcs = {
|
||||
.mode_valid = lt9611uxc_bridge_mode_valid,
|
||||
.mode_set = lt9611uxc_bridge_mode_set,
|
||||
.detect = lt9611uxc_bridge_detect,
|
||||
.get_edid = lt9611uxc_bridge_get_edid,
|
||||
.edid_read = lt9611uxc_bridge_edid_read,
|
||||
};
|
||||
|
||||
static int lt9611uxc_parse_dt(struct device *dev,
|
||||
|
||||
@@ -91,26 +91,26 @@ static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *ge_b850v3_lvds_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct i2c_client *client;
|
||||
|
||||
client = ge_b850v3_lvds_ptr->stdp2690_i2c;
|
||||
|
||||
return drm_do_get_edid(connector, stdp2690_read_block, client);
|
||||
return drm_edid_read_custom(connector, stdp2690_read_block, client);
|
||||
}
|
||||
|
||||
static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
int num_modes;
|
||||
|
||||
edid = ge_b850v3_lvds_get_edid(&ge_b850v3_lvds_ptr->bridge, connector);
|
||||
drm_edid = ge_b850v3_lvds_edid_read(&ge_b850v3_lvds_ptr->bridge, connector);
|
||||
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
num_modes = drm_add_edid_modes(connector, edid);
|
||||
kfree(edid);
|
||||
drm_edid_connector_update(connector, drm_edid);
|
||||
num_modes = drm_edid_connector_add_modes(connector);
|
||||
drm_edid_free(drm_edid);
|
||||
|
||||
return num_modes;
|
||||
}
|
||||
@@ -226,7 +226,7 @@ static int ge_b850v3_lvds_attach(struct drm_bridge *bridge,
|
||||
static const struct drm_bridge_funcs ge_b850v3_lvds_funcs = {
|
||||
.attach = ge_b850v3_lvds_attach,
|
||||
.detect = ge_b850v3_lvds_bridge_detect,
|
||||
.get_edid = ge_b850v3_lvds_get_edid,
|
||||
.edid_read = ge_b850v3_lvds_edid_read,
|
||||
};
|
||||
|
||||
static int ge_b850v3_lvds_init(struct device *dev)
|
||||
|
||||
@@ -154,10 +154,11 @@ static void ptn3460_disable(struct drm_bridge *bridge)
|
||||
}
|
||||
|
||||
|
||||
static struct edid *ptn3460_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *ptn3460_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
|
||||
const struct drm_edid *drm_edid = NULL;
|
||||
bool power_off;
|
||||
u8 *edid;
|
||||
int ret;
|
||||
@@ -175,27 +176,28 @@ static struct edid *ptn3460_get_edid(struct drm_bridge *bridge,
|
||||
EDID_LENGTH);
|
||||
if (ret) {
|
||||
kfree(edid);
|
||||
edid = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
drm_edid = drm_edid_alloc(edid, EDID_LENGTH);
|
||||
|
||||
out:
|
||||
if (power_off)
|
||||
ptn3460_disable(&ptn_bridge->bridge);
|
||||
|
||||
return (struct edid *)edid;
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
static int ptn3460_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct ptn3460_bridge *ptn_bridge = connector_to_ptn3460(connector);
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
int num_modes;
|
||||
|
||||
edid = ptn3460_get_edid(&ptn_bridge->bridge, connector);
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
num_modes = drm_add_edid_modes(connector, edid);
|
||||
kfree(edid);
|
||||
drm_edid = ptn3460_edid_read(&ptn_bridge->bridge, connector);
|
||||
drm_edid_connector_update(connector, drm_edid);
|
||||
num_modes = drm_edid_connector_add_modes(connector);
|
||||
drm_edid_free(drm_edid);
|
||||
|
||||
return num_modes;
|
||||
}
|
||||
@@ -254,7 +256,7 @@ static const struct drm_bridge_funcs ptn3460_bridge_funcs = {
|
||||
.pre_enable = ptn3460_pre_enable,
|
||||
.disable = ptn3460_disable,
|
||||
.attach = ptn3460_bridge_attach,
|
||||
.get_edid = ptn3460_get_edid,
|
||||
.edid_read = ptn3460_edid_read,
|
||||
};
|
||||
|
||||
static int ptn3460_probe(struct i2c_client *client)
|
||||
|
||||
@@ -278,39 +278,35 @@ static const struct drm_connector_funcs sii902x_connector_funcs = {
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
};
|
||||
|
||||
static struct edid *sii902x_get_edid(struct sii902x *sii902x,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *sii902x_edid_read(struct sii902x *sii902x,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
|
||||
mutex_lock(&sii902x->mutex);
|
||||
|
||||
edid = drm_get_edid(connector, sii902x->i2cmux->adapter[0]);
|
||||
if (edid) {
|
||||
if (drm_detect_hdmi_monitor(edid))
|
||||
sii902x->sink_is_hdmi = true;
|
||||
else
|
||||
sii902x->sink_is_hdmi = false;
|
||||
}
|
||||
drm_edid = drm_edid_read_ddc(connector, sii902x->i2cmux->adapter[0]);
|
||||
|
||||
mutex_unlock(&sii902x->mutex);
|
||||
|
||||
return edid;
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
static int sii902x_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct sii902x *sii902x = connector_to_sii902x(connector);
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
int num = 0;
|
||||
|
||||
edid = sii902x_get_edid(sii902x, connector);
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
if (edid) {
|
||||
num = drm_add_edid_modes(connector, edid);
|
||||
kfree(edid);
|
||||
drm_edid = sii902x_edid_read(sii902x, connector);
|
||||
drm_edid_connector_update(connector, drm_edid);
|
||||
if (drm_edid) {
|
||||
num = drm_edid_connector_add_modes(connector);
|
||||
drm_edid_free(drm_edid);
|
||||
}
|
||||
|
||||
sii902x->sink_is_hdmi = connector->display_info.is_hdmi;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -465,12 +461,12 @@ static enum drm_connector_status sii902x_bridge_detect(struct drm_bridge *bridge
|
||||
return sii902x_detect(sii902x);
|
||||
}
|
||||
|
||||
static struct edid *sii902x_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *sii902x_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct sii902x *sii902x = bridge_to_sii902x(bridge);
|
||||
|
||||
return sii902x_get_edid(sii902x, connector);
|
||||
return sii902x_edid_read(sii902x, connector);
|
||||
}
|
||||
|
||||
static u32 *sii902x_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
|
||||
@@ -514,7 +510,7 @@ static const struct drm_bridge_funcs sii902x_bridge_funcs = {
|
||||
.disable = sii902x_bridge_disable,
|
||||
.enable = sii902x_bridge_enable,
|
||||
.detect = sii902x_bridge_detect,
|
||||
.get_edid = sii902x_bridge_get_edid,
|
||||
.edid_read = sii902x_bridge_edid_read,
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
|
||||
@@ -2454,27 +2454,35 @@ static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi)
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct edid *dw_hdmi_get_edid(struct dw_hdmi *hdmi,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *dw_hdmi_edid_read(struct dw_hdmi *hdmi,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
const struct edid *edid;
|
||||
|
||||
if (!hdmi->ddc)
|
||||
return NULL;
|
||||
|
||||
edid = drm_get_edid(connector, hdmi->ddc);
|
||||
if (!edid) {
|
||||
drm_edid = drm_edid_read_ddc(connector, hdmi->ddc);
|
||||
if (!drm_edid) {
|
||||
dev_dbg(hdmi->dev, "failed to get edid\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: This should use connector->display_info.is_hdmi and
|
||||
* connector->display_info.has_audio from a path that has read the EDID
|
||||
* and called drm_edid_connector_update().
|
||||
*/
|
||||
edid = drm_edid_raw(drm_edid);
|
||||
|
||||
dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
|
||||
edid->width_cm, edid->height_cm);
|
||||
|
||||
hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
|
||||
hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
|
||||
|
||||
return edid;
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
@@ -2493,17 +2501,16 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
|
||||
connector);
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
int ret;
|
||||
|
||||
edid = dw_hdmi_get_edid(hdmi, connector);
|
||||
if (!edid)
|
||||
return 0;
|
||||
drm_edid = dw_hdmi_edid_read(hdmi, connector);
|
||||
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
|
||||
ret = drm_add_edid_modes(connector, edid);
|
||||
kfree(edid);
|
||||
drm_edid_connector_update(connector, drm_edid);
|
||||
cec_notifier_set_phys_addr(hdmi->cec_notifier,
|
||||
connector->display_info.source_physical_address);
|
||||
ret = drm_edid_connector_add_modes(connector);
|
||||
drm_edid_free(drm_edid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2980,12 +2987,12 @@ static enum drm_connector_status dw_hdmi_bridge_detect(struct drm_bridge *bridge
|
||||
return dw_hdmi_detect(hdmi);
|
||||
}
|
||||
|
||||
static struct edid *dw_hdmi_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *dw_hdmi_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct dw_hdmi *hdmi = bridge->driver_private;
|
||||
|
||||
return dw_hdmi_get_edid(hdmi, connector);
|
||||
return dw_hdmi_edid_read(hdmi, connector);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
|
||||
@@ -3002,7 +3009,7 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
|
||||
.mode_set = dw_hdmi_bridge_mode_set,
|
||||
.mode_valid = dw_hdmi_bridge_mode_valid,
|
||||
.detect = dw_hdmi_bridge_detect,
|
||||
.get_edid = dw_hdmi_bridge_get_edid,
|
||||
.edid_read = dw_hdmi_bridge_edid_read,
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
||||
@@ -1651,19 +1651,19 @@ static void tc_bridge_mode_set(struct drm_bridge *bridge,
|
||||
drm_mode_copy(&tc->mode, mode);
|
||||
}
|
||||
|
||||
static struct edid *tc_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *tc_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct tc_data *tc = bridge_to_tc(bridge);
|
||||
|
||||
return drm_get_edid(connector, &tc->aux.ddc);
|
||||
return drm_edid_read_ddc(connector, &tc->aux.ddc);
|
||||
}
|
||||
|
||||
static int tc_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct tc_data *tc = connector_to_tc(connector);
|
||||
int num_modes;
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
int ret;
|
||||
|
||||
ret = tc_get_display_props(tc);
|
||||
@@ -1678,9 +1678,10 @@ static int tc_connector_get_modes(struct drm_connector *connector)
|
||||
return num_modes;
|
||||
}
|
||||
|
||||
edid = tc_get_edid(&tc->bridge, connector);
|
||||
num_modes = drm_add_edid_modes(connector, edid);
|
||||
kfree(edid);
|
||||
drm_edid = tc_edid_read(&tc->bridge, connector);
|
||||
drm_edid_connector_update(connector, drm_edid);
|
||||
num_modes = drm_edid_connector_add_modes(connector);
|
||||
drm_edid_free(drm_edid);
|
||||
|
||||
return num_modes;
|
||||
}
|
||||
@@ -1849,7 +1850,7 @@ static const struct drm_bridge_funcs tc_edp_bridge_funcs = {
|
||||
.atomic_enable = tc_edp_bridge_atomic_enable,
|
||||
.atomic_disable = tc_edp_bridge_atomic_disable,
|
||||
.detect = tc_bridge_detect,
|
||||
.get_edid = tc_get_edid,
|
||||
.edid_read = tc_edid_read,
|
||||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
|
||||
@@ -1207,19 +1207,19 @@ static enum drm_connector_status ti_sn_bridge_detect(struct drm_bridge *bridge)
|
||||
: connector_status_disconnected;
|
||||
}
|
||||
|
||||
static struct edid *ti_sn_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *ti_sn_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
|
||||
|
||||
return drm_get_edid(connector, &pdata->aux.ddc);
|
||||
return drm_edid_read_ddc(connector, &pdata->aux.ddc);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs ti_sn_bridge_funcs = {
|
||||
.attach = ti_sn_bridge_attach,
|
||||
.detach = ti_sn_bridge_detach,
|
||||
.mode_valid = ti_sn_bridge_mode_valid,
|
||||
.get_edid = ti_sn_bridge_get_edid,
|
||||
.edid_read = ti_sn_bridge_edid_read,
|
||||
.detect = ti_sn_bridge_detect,
|
||||
.atomic_pre_enable = ti_sn_bridge_atomic_pre_enable,
|
||||
.atomic_enable = ti_sn_bridge_atomic_enable,
|
||||
|
||||
@@ -119,7 +119,10 @@ msm:apq8016:
|
||||
DRIVER_NAME: msm
|
||||
BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/apq8016-sbc-usb-host.dtb
|
||||
GPU_VERSION: apq8016
|
||||
BM_CMDLINE: "ip=dhcp console=ttyMSM0,115200n8 $BM_KERNEL_EXTRA_ARGS root=/dev/nfs rw nfsrootdebug nfsroot=,tcp,nfsvers=4.2 init=/init $BM_KERNELARGS"
|
||||
# disabling unused clocks congests with the MDSS runtime PM trying to
|
||||
# disable those clocks and causes boot to fail.
|
||||
# Reproducer: DRM_MSM=y, DRM_I2C_ADV7511=m
|
||||
BM_KERNEL_EXTRA_ARGS: clk_ignore_unused
|
||||
RUNNER_TAG: google-freedreno-db410c
|
||||
script:
|
||||
- ./install/bare-metal/fastboot.sh
|
||||
|
||||
@@ -2897,22 +2897,19 @@ static const char *dp_content_type_get_name(enum dp_content_type content_type)
|
||||
}
|
||||
}
|
||||
|
||||
void drm_dp_vsc_sdp_log(const char *level, struct device *dev,
|
||||
const struct drm_dp_vsc_sdp *vsc)
|
||||
void drm_dp_vsc_sdp_log(struct drm_printer *p, const struct drm_dp_vsc_sdp *vsc)
|
||||
{
|
||||
#define DP_SDP_LOG(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__)
|
||||
DP_SDP_LOG("DP SDP: %s, revision %u, length %u\n", "VSC",
|
||||
drm_printf(p, "DP SDP: VSC, revision %u, length %u\n",
|
||||
vsc->revision, vsc->length);
|
||||
DP_SDP_LOG(" pixelformat: %s\n",
|
||||
drm_printf(p, " pixelformat: %s\n",
|
||||
dp_pixelformat_get_name(vsc->pixelformat));
|
||||
DP_SDP_LOG(" colorimetry: %s\n",
|
||||
drm_printf(p, " colorimetry: %s\n",
|
||||
dp_colorimetry_get_name(vsc->pixelformat, vsc->colorimetry));
|
||||
DP_SDP_LOG(" bpc: %u\n", vsc->bpc);
|
||||
DP_SDP_LOG(" dynamic range: %s\n",
|
||||
drm_printf(p, " bpc: %u\n", vsc->bpc);
|
||||
drm_printf(p, " dynamic range: %s\n",
|
||||
dp_dynamic_range_get_name(vsc->dynamic_range));
|
||||
DP_SDP_LOG(" content type: %s\n",
|
||||
drm_printf(p, " content type: %s\n",
|
||||
dp_content_type_get_name(vsc->content_type));
|
||||
#undef DP_SDP_LOG
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
|
||||
|
||||
|
||||
@@ -1306,7 +1306,8 @@ static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb,
|
||||
}
|
||||
out:
|
||||
if (unlikely(ret == -EIO) && drm_debug_enabled(DRM_UT_DP)) {
|
||||
struct drm_printer p = drm_debug_printer(DBG_PREFIX);
|
||||
struct drm_printer p = drm_dbg_printer(mgr->dev, DRM_UT_DP,
|
||||
DBG_PREFIX);
|
||||
|
||||
drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);
|
||||
}
|
||||
@@ -1593,10 +1594,11 @@ topology_ref_type_to_str(enum drm_dp_mst_topology_ref_type type)
|
||||
}
|
||||
|
||||
static void
|
||||
__dump_topology_ref_history(struct drm_dp_mst_topology_ref_history *history,
|
||||
__dump_topology_ref_history(struct drm_device *drm,
|
||||
struct drm_dp_mst_topology_ref_history *history,
|
||||
void *ptr, const char *type_str)
|
||||
{
|
||||
struct drm_printer p = drm_debug_printer(DBG_PREFIX);
|
||||
struct drm_printer p = drm_dbg_printer(drm, DRM_UT_DP, DBG_PREFIX);
|
||||
char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
int i;
|
||||
|
||||
@@ -1638,15 +1640,15 @@ out:
|
||||
static __always_inline void
|
||||
drm_dp_mst_dump_mstb_topology_history(struct drm_dp_mst_branch *mstb)
|
||||
{
|
||||
__dump_topology_ref_history(&mstb->topology_ref_history, mstb,
|
||||
"MSTB");
|
||||
__dump_topology_ref_history(mstb->mgr->dev, &mstb->topology_ref_history,
|
||||
mstb, "MSTB");
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port)
|
||||
{
|
||||
__dump_topology_ref_history(&port->topology_ref_history, port,
|
||||
"Port");
|
||||
__dump_topology_ref_history(port->mgr->dev, &port->topology_ref_history,
|
||||
port, "Port");
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
@@ -2824,7 +2826,9 @@ static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
|
||||
ret = drm_dp_send_sideband_msg(mgr, up, chunk, idx);
|
||||
if (ret) {
|
||||
if (drm_debug_enabled(DRM_UT_DP)) {
|
||||
struct drm_printer p = drm_debug_printer(DBG_PREFIX);
|
||||
struct drm_printer p = drm_dbg_printer(mgr->dev,
|
||||
DRM_UT_DP,
|
||||
DBG_PREFIX);
|
||||
|
||||
drm_printf(&p, "sideband msg failed to send\n");
|
||||
drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);
|
||||
@@ -2869,7 +2873,8 @@ static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
|
||||
list_add_tail(&txmsg->next, &mgr->tx_msg_downq);
|
||||
|
||||
if (drm_debug_enabled(DRM_UT_DP)) {
|
||||
struct drm_printer p = drm_debug_printer(DBG_PREFIX);
|
||||
struct drm_printer p = drm_dbg_printer(mgr->dev, DRM_UT_DP,
|
||||
DBG_PREFIX);
|
||||
|
||||
drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);
|
||||
}
|
||||
|
||||
@@ -1216,9 +1216,6 @@ EXPORT_SYMBOL_GPL(drm_bridge_get_modes);
|
||||
* DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.edid_read to get
|
||||
* the EDID and return it. Otherwise return NULL.
|
||||
*
|
||||
* If &drm_bridge_funcs.edid_read is not set, fall back to using
|
||||
* &drm_bridge_funcs.get_edid and wrapping it in struct drm_edid.
|
||||
*
|
||||
* RETURNS:
|
||||
* The retrieved EDID on success, or NULL otherwise.
|
||||
*/
|
||||
@@ -1228,22 +1225,6 @@ const struct drm_edid *drm_bridge_edid_read(struct drm_bridge *bridge,
|
||||
if (!(bridge->ops & DRM_BRIDGE_OP_EDID))
|
||||
return NULL;
|
||||
|
||||
/* Transitional: Fall back to ->get_edid. */
|
||||
if (!bridge->funcs->edid_read) {
|
||||
const struct drm_edid *drm_edid;
|
||||
struct edid *edid;
|
||||
|
||||
edid = bridge->funcs->get_edid(bridge, connector);
|
||||
if (!edid)
|
||||
return NULL;
|
||||
|
||||
drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
|
||||
|
||||
kfree(edid);
|
||||
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
return bridge->funcs->edid_read(bridge, connector);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_bridge_edid_read);
|
||||
|
||||
@@ -61,13 +61,13 @@
|
||||
* to one or more &drm_encoder, which are then each connected to one
|
||||
* &drm_connector.
|
||||
*
|
||||
* To create a CRTC, a KMS drivers allocates and zeroes an instances of
|
||||
* To create a CRTC, a KMS driver allocates and zeroes an instance of
|
||||
* &struct drm_crtc (possibly as part of a larger structure) and registers it
|
||||
* with a call to drm_crtc_init_with_planes().
|
||||
*
|
||||
* The CRTC is also the entry point for legacy modeset operations, see
|
||||
* &drm_crtc_funcs.set_config, legacy plane operations, see
|
||||
* &drm_crtc_funcs.page_flip and &drm_crtc_funcs.cursor_set2, and other legacy
|
||||
* The CRTC is also the entry point for legacy modeset operations (see
|
||||
* &drm_crtc_funcs.set_config), legacy plane operations (see
|
||||
* &drm_crtc_funcs.page_flip and &drm_crtc_funcs.cursor_set2), and other legacy
|
||||
* operations like &drm_crtc_funcs.gamma_set. For atomic drivers all these
|
||||
* features are controlled through &drm_property and
|
||||
* &drm_mode_config_funcs.atomic_check.
|
||||
|
||||
@@ -544,7 +544,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
|
||||
*/
|
||||
WARN_ON(!list_empty(&dev->mode_config.fb_list));
|
||||
list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
|
||||
struct drm_printer p = drm_debug_printer("[leaked fb]");
|
||||
struct drm_printer p = drm_dbg_printer(dev, DRM_UT_KMS, "[leaked fb]");
|
||||
|
||||
drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
|
||||
drm_framebuffer_print_info(&p, 1, fb);
|
||||
|
||||
@@ -91,7 +91,7 @@ static noinline depot_stack_handle_t __drm_stack_depot_save(void)
|
||||
|
||||
static void __drm_stack_depot_print(depot_stack_handle_t stack_depot)
|
||||
{
|
||||
struct drm_printer p = drm_debug_printer("drm_modeset_lock");
|
||||
struct drm_printer p = drm_dbg_printer(NULL, DRM_UT_KMS, "drm_modeset_lock");
|
||||
unsigned long *entries;
|
||||
unsigned int nr_entries;
|
||||
char *buf;
|
||||
|
||||
@@ -182,16 +182,35 @@ void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf)
|
||||
}
|
||||
EXPORT_SYMBOL(__drm_printfn_info);
|
||||
|
||||
void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf)
|
||||
void __drm_printfn_dbg(struct drm_printer *p, struct va_format *vaf)
|
||||
{
|
||||
/* pr_debug callsite decorations are unhelpful here */
|
||||
printk(KERN_DEBUG "%s %pV", p->prefix, vaf);
|
||||
const struct drm_device *drm = p->arg;
|
||||
const struct device *dev = drm ? drm->dev : NULL;
|
||||
enum drm_debug_category category = p->category;
|
||||
const char *prefix = p->prefix ?: "";
|
||||
const char *prefix_pad = p->prefix ? " " : "";
|
||||
|
||||
if (!__drm_debug_enabled(category))
|
||||
return;
|
||||
|
||||
/* Note: __builtin_return_address(0) is useless here. */
|
||||
if (dev)
|
||||
dev_printk(KERN_DEBUG, dev, "[" DRM_NAME "]%s%s %pV",
|
||||
prefix_pad, prefix, vaf);
|
||||
else
|
||||
printk(KERN_DEBUG "[" DRM_NAME "]%s%s %pV",
|
||||
prefix_pad, prefix, vaf);
|
||||
}
|
||||
EXPORT_SYMBOL(__drm_printfn_debug);
|
||||
EXPORT_SYMBOL(__drm_printfn_dbg);
|
||||
|
||||
void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf)
|
||||
{
|
||||
pr_err("*ERROR* %s %pV", p->prefix, vaf);
|
||||
struct drm_device *drm = p->arg;
|
||||
|
||||
if (p->prefix)
|
||||
drm_err(drm, "%s %pV", p->prefix, vaf);
|
||||
else
|
||||
drm_err(drm, "%pV", vaf);
|
||||
}
|
||||
EXPORT_SYMBOL(__drm_printfn_err);
|
||||
|
||||
|
||||
@@ -55,10 +55,9 @@ static void
|
||||
intel_dump_dp_vsc_sdp(struct drm_i915_private *i915,
|
||||
const struct drm_dp_vsc_sdp *vsc)
|
||||
{
|
||||
if (!drm_debug_enabled(DRM_UT_KMS))
|
||||
return;
|
||||
struct drm_printer p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, NULL);
|
||||
|
||||
drm_dp_vsc_sdp_log(KERN_DEBUG, i915->drm.dev, vsc);
|
||||
drm_dp_vsc_sdp_log(&p, vsc);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -4813,28 +4813,27 @@ pipe_config_infoframe_mismatch(struct drm_i915_private *dev_priv,
|
||||
}
|
||||
|
||||
static void
|
||||
pipe_config_dp_vsc_sdp_mismatch(struct drm_i915_private *dev_priv,
|
||||
pipe_config_dp_vsc_sdp_mismatch(struct drm_i915_private *i915,
|
||||
bool fastset, const char *name,
|
||||
const struct drm_dp_vsc_sdp *a,
|
||||
const struct drm_dp_vsc_sdp *b)
|
||||
{
|
||||
if (fastset) {
|
||||
if (!drm_debug_enabled(DRM_UT_KMS))
|
||||
return;
|
||||
struct drm_printer p;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"fastset requirement not met in %s dp sdp\n", name);
|
||||
drm_dbg_kms(&dev_priv->drm, "expected:\n");
|
||||
drm_dp_vsc_sdp_log(KERN_DEBUG, dev_priv->drm.dev, a);
|
||||
drm_dbg_kms(&dev_priv->drm, "found:\n");
|
||||
drm_dp_vsc_sdp_log(KERN_DEBUG, dev_priv->drm.dev, b);
|
||||
if (fastset) {
|
||||
p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, NULL);
|
||||
|
||||
drm_printf(&p, "fastset requirement not met in %s dp sdp\n", name);
|
||||
} else {
|
||||
drm_err(&dev_priv->drm, "mismatch in %s dp sdp\n", name);
|
||||
drm_err(&dev_priv->drm, "expected:\n");
|
||||
drm_dp_vsc_sdp_log(KERN_ERR, dev_priv->drm.dev, a);
|
||||
drm_err(&dev_priv->drm, "found:\n");
|
||||
drm_dp_vsc_sdp_log(KERN_ERR, dev_priv->drm.dev, b);
|
||||
p = drm_err_printer(&i915->drm, NULL);
|
||||
|
||||
drm_printf(&p, "mismatch in %s dp sdp\n", name);
|
||||
}
|
||||
|
||||
drm_printf(&p, "expected:\n");
|
||||
drm_dp_vsc_sdp_log(&p, a);
|
||||
drm_printf(&p, "found:\n");
|
||||
drm_dp_vsc_sdp_log(&p, b);
|
||||
}
|
||||
|
||||
/* Returns the length up to and including the last differing byte */
|
||||
|
||||
@@ -518,7 +518,8 @@ int intel_display_driver_probe(struct drm_i915_private *i915)
|
||||
|
||||
void intel_display_driver_register(struct drm_i915_private *i915)
|
||||
{
|
||||
struct drm_printer p = drm_debug_printer("i915 display info:");
|
||||
struct drm_printer p = drm_dbg_printer(&i915->drm, DRM_UT_KMS,
|
||||
"i915 display info:");
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
return;
|
||||
|
||||
@@ -96,7 +96,8 @@ static void heartbeat_commit(struct i915_request *rq,
|
||||
static void show_heartbeat(const struct i915_request *rq,
|
||||
struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_printer p = drm_debug_printer("heartbeat");
|
||||
struct drm_printer p = drm_dbg_printer(&rq->i915->drm, DRM_UT_DRIVER,
|
||||
"heartbeat");
|
||||
|
||||
if (!rq) {
|
||||
intel_engine_dump(engine, &p,
|
||||
|
||||
@@ -1015,7 +1015,8 @@ void intel_gt_set_wedged(struct intel_gt *gt)
|
||||
mutex_lock(>->reset.mutex);
|
||||
|
||||
if (GEM_SHOW_DEBUG()) {
|
||||
struct drm_printer p = drm_debug_printer(__func__);
|
||||
struct drm_printer p = drm_dbg_printer(>->i915->drm,
|
||||
DRM_UT_DRIVER, __func__);
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
|
||||
|
||||
@@ -1241,7 +1241,8 @@ static void __set_mcr_steering(struct i915_wa_list *wal,
|
||||
|
||||
static void debug_dump_steering(struct intel_gt *gt)
|
||||
{
|
||||
struct drm_printer p = drm_debug_printer("MCR Steering:");
|
||||
struct drm_printer p = drm_dbg_printer(>->i915->drm, DRM_UT_DRIVER,
|
||||
"MCR Steering:");
|
||||
|
||||
if (drm_debug_enabled(DRM_UT_DRIVER))
|
||||
intel_gt_mcr_report_steering(&p, gt, false);
|
||||
|
||||
@@ -285,7 +285,8 @@ out_engine:
|
||||
intel_engine_pm_flush(engine);
|
||||
|
||||
if (intel_engine_pm_is_awake(engine)) {
|
||||
struct drm_printer p = drm_debug_printer(__func__);
|
||||
struct drm_printer p = drm_dbg_printer(&engine->i915->drm,
|
||||
DRM_UT_DRIVER, __func__);
|
||||
|
||||
intel_engine_dump(engine, &p,
|
||||
"%s is still awake:%d after idle-barriers\n",
|
||||
|
||||
@@ -122,9 +122,9 @@ static int __live_idle_pulse(struct intel_engine_cs *engine,
|
||||
GEM_BUG_ON(!llist_empty(&engine->barrier_tasks));
|
||||
|
||||
if (engine_sync_barrier(engine)) {
|
||||
struct drm_printer m = drm_err_printer("pulse");
|
||||
struct drm_printer m = drm_err_printer(&engine->i915->drm, "pulse");
|
||||
|
||||
pr_err("%s: no heartbeat pulse?\n", engine->name);
|
||||
drm_printf(&m, "%s: no heartbeat pulse?\n", engine->name);
|
||||
intel_engine_dump(engine, &m, "%s", engine->name);
|
||||
|
||||
err = -ETIME;
|
||||
@@ -136,10 +136,10 @@ static int __live_idle_pulse(struct intel_engine_cs *engine,
|
||||
pulse_unlock_wait(p); /* synchronize with the retirement callback */
|
||||
|
||||
if (!i915_active_is_idle(&p->active)) {
|
||||
struct drm_printer m = drm_err_printer("pulse");
|
||||
struct drm_printer m = drm_err_printer(&engine->i915->drm, "pulse");
|
||||
|
||||
pr_err("%s: heartbeat pulse did not flush idle tasks\n",
|
||||
engine->name);
|
||||
drm_printf(&m, "%s: heartbeat pulse did not flush idle tasks\n",
|
||||
engine->name);
|
||||
i915_active_print(&p->active, &m);
|
||||
|
||||
err = -EINVAL;
|
||||
|
||||
@@ -681,7 +681,8 @@ i915_print_iommu_status(struct drm_i915_private *i915, struct drm_printer *p)
|
||||
static void i915_welcome_messages(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (drm_debug_enabled(DRM_UT_DRIVER)) {
|
||||
struct drm_printer p = drm_debug_printer("i915 device info:");
|
||||
struct drm_printer p = drm_dbg_printer(&dev_priv->drm, DRM_UT_DRIVER,
|
||||
"device info:");
|
||||
struct intel_gt *gt;
|
||||
unsigned int i;
|
||||
|
||||
|
||||
@@ -156,9 +156,9 @@ static int live_active_wait(void *arg)
|
||||
|
||||
__i915_active_wait(&active->base, TASK_UNINTERRUPTIBLE);
|
||||
if (!READ_ONCE(active->retired)) {
|
||||
struct drm_printer p = drm_err_printer(__func__);
|
||||
struct drm_printer p = drm_err_printer(&i915->drm, __func__);
|
||||
|
||||
pr_err("i915_active not retired after waiting!\n");
|
||||
drm_printf(&p, "i915_active not retired after waiting!\n");
|
||||
i915_active_print(&active->base, &p);
|
||||
|
||||
err = -EINVAL;
|
||||
@@ -189,9 +189,9 @@ static int live_active_retire(void *arg)
|
||||
err = -EIO;
|
||||
|
||||
if (!READ_ONCE(active->retired)) {
|
||||
struct drm_printer p = drm_err_printer(__func__);
|
||||
struct drm_printer p = drm_err_printer(&i915->drm, __func__);
|
||||
|
||||
pr_err("i915_active not retired after flushing!\n");
|
||||
drm_printf(&p, "i915_active not retired after flushing!\n");
|
||||
i915_active_print(&active->base, &p);
|
||||
|
||||
err = -EINVAL;
|
||||
|
||||
@@ -19,7 +19,7 @@ int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id)
|
||||
kref_init(&ctx->refcnt);
|
||||
|
||||
for (i = 0; i < lima_pipe_num; i++) {
|
||||
err = lima_sched_context_init(dev->pipe + i, ctx->context + i, &ctx->guilty);
|
||||
err = lima_sched_context_init(dev->pipe + i, ctx->context + i);
|
||||
if (err)
|
||||
goto err_out0;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ struct lima_ctx {
|
||||
struct kref refcnt;
|
||||
struct lima_device *dev;
|
||||
struct lima_sched_context context[lima_pipe_num];
|
||||
atomic_t guilty;
|
||||
|
||||
/* debug info */
|
||||
char pname[TASK_COMM_LEN];
|
||||
|
||||
@@ -34,11 +34,11 @@ static irqreturn_t lima_gp_irq_handler(int irq, void *data)
|
||||
if (state & LIMA_GP_IRQ_MASK_ERROR) {
|
||||
if ((state & LIMA_GP_IRQ_MASK_ERROR) ==
|
||||
LIMA_GP_IRQ_PLBU_OUT_OF_MEM) {
|
||||
dev_dbg(dev->dev, "gp out of heap irq status=%x\n",
|
||||
status);
|
||||
dev_dbg(dev->dev, "%s out of heap irq status=%x\n",
|
||||
lima_ip_name(ip), status);
|
||||
} else {
|
||||
dev_err(dev->dev, "gp error irq state=%x status=%x\n",
|
||||
state, status);
|
||||
dev_err(dev->dev, "%s error irq state=%x status=%x\n",
|
||||
lima_ip_name(ip), state, status);
|
||||
if (task)
|
||||
task->recoverable = false;
|
||||
}
|
||||
@@ -89,7 +89,8 @@ static int lima_gp_soft_reset_async_wait(struct lima_ip *ip)
|
||||
v & LIMA_GP_IRQ_RESET_COMPLETED,
|
||||
0, 100);
|
||||
if (err) {
|
||||
dev_err(dev->dev, "gp soft reset time out\n");
|
||||
dev_err(dev->dev, "%s soft reset time out\n",
|
||||
lima_ip_name(ip));
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -166,6 +167,11 @@ static void lima_gp_task_run(struct lima_sched_pipe *pipe,
|
||||
gp_write(LIMA_GP_CMD, cmd);
|
||||
}
|
||||
|
||||
static int lima_gp_bus_stop_poll(struct lima_ip *ip)
|
||||
{
|
||||
return !!(gp_read(LIMA_GP_STATUS) & LIMA_GP_STATUS_BUS_STOPPED);
|
||||
}
|
||||
|
||||
static int lima_gp_hard_reset_poll(struct lima_ip *ip)
|
||||
{
|
||||
gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC01A0000);
|
||||
@@ -179,16 +185,30 @@ static int lima_gp_hard_reset(struct lima_ip *ip)
|
||||
|
||||
gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC0FFE000);
|
||||
gp_write(LIMA_GP_INT_MASK, 0);
|
||||
|
||||
gp_write(LIMA_GP_CMD, LIMA_GP_CMD_STOP_BUS);
|
||||
ret = lima_poll_timeout(ip, lima_gp_bus_stop_poll, 10, 100);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "%s bus stop timeout\n", lima_ip_name(ip));
|
||||
return ret;
|
||||
}
|
||||
gp_write(LIMA_GP_CMD, LIMA_GP_CMD_RESET);
|
||||
ret = lima_poll_timeout(ip, lima_gp_hard_reset_poll, 10, 100);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "gp hard reset timeout\n");
|
||||
dev_err(dev->dev, "%s hard reset timeout\n", lima_ip_name(ip));
|
||||
return ret;
|
||||
}
|
||||
|
||||
gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0);
|
||||
gp_write(LIMA_GP_INT_CLEAR, LIMA_GP_IRQ_MASK_ALL);
|
||||
gp_write(LIMA_GP_INT_MASK, LIMA_GP_IRQ_MASK_USED);
|
||||
|
||||
/*
|
||||
* if there was an async soft reset queued,
|
||||
* don't wait for it in the next job
|
||||
*/
|
||||
ip->data.async_reset = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -201,8 +221,9 @@ static void lima_gp_task_error(struct lima_sched_pipe *pipe)
|
||||
{
|
||||
struct lima_ip *ip = pipe->processor[0];
|
||||
|
||||
dev_err(ip->dev->dev, "gp task error int_state=%x status=%x\n",
|
||||
gp_read(LIMA_GP_INT_STAT), gp_read(LIMA_GP_STATUS));
|
||||
dev_err(ip->dev->dev, "%s task error int_state=%x status=%x\n",
|
||||
lima_ip_name(ip), gp_read(LIMA_GP_INT_STAT),
|
||||
gp_read(LIMA_GP_STATUS));
|
||||
|
||||
lima_gp_hard_reset(ip);
|
||||
}
|
||||
@@ -305,7 +326,7 @@ int lima_gp_init(struct lima_ip *ip)
|
||||
err = devm_request_irq(dev->dev, ip->irq, lima_gp_irq_handler,
|
||||
IRQF_SHARED, lima_ip_name(ip), ip);
|
||||
if (err) {
|
||||
dev_err(dev->dev, "gp %s fail to request irq\n",
|
||||
dev_err(dev->dev, "%s fail to request irq\n",
|
||||
lima_ip_name(ip));
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ static int lima_l2_cache_wait_idle(struct lima_ip *ip)
|
||||
!(v & LIMA_L2_CACHE_STATUS_COMMAND_BUSY),
|
||||
0, 1000);
|
||||
if (err) {
|
||||
dev_err(dev->dev, "l2 cache wait command timeout\n");
|
||||
dev_err(dev->dev, "%s wait command timeout\n",
|
||||
lima_ip_name(ip));
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
@@ -83,7 +84,8 @@ int lima_l2_cache_init(struct lima_ip *ip)
|
||||
spin_lock_init(&ip->data.lock);
|
||||
|
||||
size = l2_cache_read(LIMA_L2_CACHE_SIZE);
|
||||
dev_info(dev->dev, "l2 cache %uK, %u-way, %ubyte cache line, %ubit external bus\n",
|
||||
dev_info(dev->dev, "%s %uK, %u-way, %ubyte cache line, %ubit external bus\n",
|
||||
lima_ip_name(ip),
|
||||
1 << (((size >> 16) & 0xff) - 10),
|
||||
1 << ((size >> 8) & 0xff),
|
||||
1 << (size & 0xff),
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
cond, 0, 100); \
|
||||
if (__ret) \
|
||||
dev_err(dev->dev, \
|
||||
"mmu command %x timeout\n", cmd); \
|
||||
"%s command %x timeout\n", \
|
||||
lima_ip_name(ip), cmd); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
@@ -40,14 +41,13 @@ static irqreturn_t lima_mmu_irq_handler(int irq, void *data)
|
||||
if (status & LIMA_MMU_INT_PAGE_FAULT) {
|
||||
u32 fault = mmu_read(LIMA_MMU_PAGE_FAULT_ADDR);
|
||||
|
||||
dev_err(dev->dev, "mmu page fault at 0x%x from bus id %d of type %s on %s\n",
|
||||
fault, LIMA_MMU_STATUS_BUS_ID(status),
|
||||
status & LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE ? "write" : "read",
|
||||
lima_ip_name(ip));
|
||||
dev_err(dev->dev, "%s page fault at 0x%x from bus id %d of type %s\n",
|
||||
lima_ip_name(ip), fault, LIMA_MMU_STATUS_BUS_ID(status),
|
||||
status & LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE ? "write" : "read");
|
||||
}
|
||||
|
||||
if (status & LIMA_MMU_INT_READ_BUS_ERROR)
|
||||
dev_err(dev->dev, "mmu %s irq bus error\n", lima_ip_name(ip));
|
||||
dev_err(dev->dev, "%s irq bus error\n", lima_ip_name(ip));
|
||||
|
||||
/* mask all interrupts before resume */
|
||||
mmu_write(LIMA_MMU_INT_MASK, 0);
|
||||
@@ -102,14 +102,14 @@ int lima_mmu_init(struct lima_ip *ip)
|
||||
|
||||
mmu_write(LIMA_MMU_DTE_ADDR, 0xCAFEBABE);
|
||||
if (mmu_read(LIMA_MMU_DTE_ADDR) != 0xCAFEB000) {
|
||||
dev_err(dev->dev, "mmu %s dte write test fail\n", lima_ip_name(ip));
|
||||
dev_err(dev->dev, "%s dte write test fail\n", lima_ip_name(ip));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
err = devm_request_irq(dev->dev, ip->irq, lima_mmu_irq_handler,
|
||||
IRQF_SHARED, lima_ip_name(ip), ip);
|
||||
if (err) {
|
||||
dev_err(dev->dev, "mmu %s fail to request irq\n", lima_ip_name(ip));
|
||||
dev_err(dev->dev, "%s fail to request irq\n", lima_ip_name(ip));
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ void lima_mmu_page_fault_resume(struct lima_ip *ip)
|
||||
u32 v;
|
||||
|
||||
if (status & LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE) {
|
||||
dev_info(dev->dev, "mmu resume\n");
|
||||
dev_info(dev->dev, "%s resume\n", lima_ip_name(ip));
|
||||
|
||||
mmu_write(LIMA_MMU_INT_MASK, 0);
|
||||
mmu_write(LIMA_MMU_DTE_ADDR, 0xCAFEBABE);
|
||||
|
||||
@@ -21,7 +21,8 @@ static int lima_pmu_wait_cmd(struct lima_ip *ip)
|
||||
v, v & LIMA_PMU_INT_CMD_MASK,
|
||||
100, 100000);
|
||||
if (err) {
|
||||
dev_err(dev->dev, "timeout wait pmu cmd\n");
|
||||
dev_err(dev->dev, "%s timeout wait pmu cmd\n",
|
||||
lima_ip_name(ip));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ static void lima_pp_handle_irq(struct lima_ip *ip, u32 state)
|
||||
if (state & LIMA_PP_IRQ_MASK_ERROR) {
|
||||
u32 status = pp_read(LIMA_PP_STATUS);
|
||||
|
||||
dev_err(dev->dev, "pp error irq state=%x status=%x\n",
|
||||
state, status);
|
||||
dev_err(dev->dev, "%s error irq state=%x status=%x\n",
|
||||
lima_ip_name(ip), state, status);
|
||||
|
||||
pipe->error = true;
|
||||
|
||||
@@ -125,7 +125,7 @@ static int lima_pp_soft_reset_async_wait_one(struct lima_ip *ip)
|
||||
|
||||
ret = lima_poll_timeout(ip, lima_pp_soft_reset_poll, 0, 100);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "pp %s reset time out\n", lima_ip_name(ip));
|
||||
dev_err(dev->dev, "%s reset time out\n", lima_ip_name(ip));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -168,6 +168,11 @@ static void lima_pp_write_frame(struct lima_ip *ip, u32 *frame, u32 *wb)
|
||||
}
|
||||
}
|
||||
|
||||
static int lima_pp_bus_stop_poll(struct lima_ip *ip)
|
||||
{
|
||||
return !!(pp_read(LIMA_PP_STATUS) & LIMA_PP_STATUS_BUS_STOPPED);
|
||||
}
|
||||
|
||||
static int lima_pp_hard_reset_poll(struct lima_ip *ip)
|
||||
{
|
||||
pp_write(LIMA_PP_PERF_CNT_0_LIMIT, 0xC01A0000);
|
||||
@@ -181,16 +186,31 @@ static int lima_pp_hard_reset(struct lima_ip *ip)
|
||||
|
||||
pp_write(LIMA_PP_PERF_CNT_0_LIMIT, 0xC0FFE000);
|
||||
pp_write(LIMA_PP_INT_MASK, 0);
|
||||
|
||||
pp_write(LIMA_PP_CTRL, LIMA_PP_CTRL_STOP_BUS);
|
||||
ret = lima_poll_timeout(ip, lima_pp_bus_stop_poll, 10, 100);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "%s bus stop timeout\n", lima_ip_name(ip));
|
||||
return ret;
|
||||
}
|
||||
|
||||
pp_write(LIMA_PP_CTRL, LIMA_PP_CTRL_FORCE_RESET);
|
||||
ret = lima_poll_timeout(ip, lima_pp_hard_reset_poll, 10, 100);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "pp hard reset timeout\n");
|
||||
dev_err(dev->dev, "%s hard reset timeout\n", lima_ip_name(ip));
|
||||
return ret;
|
||||
}
|
||||
|
||||
pp_write(LIMA_PP_PERF_CNT_0_LIMIT, 0);
|
||||
pp_write(LIMA_PP_INT_CLEAR, LIMA_PP_IRQ_MASK_ALL);
|
||||
pp_write(LIMA_PP_INT_MASK, LIMA_PP_IRQ_MASK_USED);
|
||||
|
||||
/*
|
||||
* if there was an async soft reset queued,
|
||||
* don't wait for it in the next job
|
||||
*/
|
||||
ip->data.async_reset = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -254,7 +274,7 @@ int lima_pp_init(struct lima_ip *ip)
|
||||
err = devm_request_irq(dev->dev, ip->irq, lima_pp_irq_handler,
|
||||
IRQF_SHARED, lima_ip_name(ip), ip);
|
||||
if (err) {
|
||||
dev_err(dev->dev, "pp %s fail to request irq\n",
|
||||
dev_err(dev->dev, "%s fail to request irq\n",
|
||||
lima_ip_name(ip));
|
||||
return err;
|
||||
}
|
||||
@@ -289,7 +309,7 @@ int lima_pp_bcast_init(struct lima_ip *ip)
|
||||
err = devm_request_irq(dev->dev, ip->irq, lima_pp_bcast_irq_handler,
|
||||
IRQF_SHARED, lima_ip_name(ip), ip);
|
||||
if (err) {
|
||||
dev_err(dev->dev, "pp %s fail to request irq\n",
|
||||
dev_err(dev->dev, "%s fail to request irq\n",
|
||||
lima_ip_name(ip));
|
||||
return err;
|
||||
}
|
||||
@@ -403,8 +423,9 @@ static void lima_pp_task_error(struct lima_sched_pipe *pipe)
|
||||
for (i = 0; i < pipe->num_processor; i++) {
|
||||
struct lima_ip *ip = pipe->processor[i];
|
||||
|
||||
dev_err(ip->dev->dev, "pp task error %d int_state=%x status=%x\n",
|
||||
i, pp_read(LIMA_PP_INT_STATUS), pp_read(LIMA_PP_STATUS));
|
||||
dev_err(ip->dev->dev, "%s task error %d int_state=%x status=%x\n",
|
||||
lima_ip_name(ip), i, pp_read(LIMA_PP_INT_STATUS),
|
||||
pp_read(LIMA_PP_STATUS));
|
||||
|
||||
lima_pp_hard_reset(ip);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
/* Copyright 2017-2019 Qiang Yu <yuq825@gmail.com> */
|
||||
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/iosys-map.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -153,13 +154,12 @@ void lima_sched_task_fini(struct lima_sched_task *task)
|
||||
}
|
||||
|
||||
int lima_sched_context_init(struct lima_sched_pipe *pipe,
|
||||
struct lima_sched_context *context,
|
||||
atomic_t *guilty)
|
||||
struct lima_sched_context *context)
|
||||
{
|
||||
struct drm_gpu_scheduler *sched = &pipe->base;
|
||||
|
||||
return drm_sched_entity_init(&context->base, DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, guilty);
|
||||
&sched, 1, NULL);
|
||||
}
|
||||
|
||||
void lima_sched_context_fini(struct lima_sched_pipe *pipe,
|
||||
@@ -401,9 +401,35 @@ static enum drm_gpu_sched_stat lima_sched_timedout_job(struct drm_sched_job *job
|
||||
struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
|
||||
struct lima_sched_task *task = to_lima_task(job);
|
||||
struct lima_device *ldev = pipe->ldev;
|
||||
struct lima_ip *ip = pipe->processor[0];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* If the GPU managed to complete this jobs fence, the timeout is
|
||||
* spurious. Bail out.
|
||||
*/
|
||||
if (dma_fence_is_signaled(task->fence)) {
|
||||
DRM_WARN("%s spurious timeout\n", lima_ip_name(ip));
|
||||
return DRM_GPU_SCHED_STAT_NOMINAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lima IRQ handler may take a long time to process an interrupt
|
||||
* if there is another IRQ handler hogging the processing.
|
||||
* In order to catch such cases and not report spurious Lima job
|
||||
* timeouts, synchronize the IRQ handler and re-check the fence
|
||||
* status.
|
||||
*/
|
||||
for (i = 0; i < pipe->num_processor; i++)
|
||||
synchronize_irq(pipe->processor[i]->irq);
|
||||
|
||||
if (dma_fence_is_signaled(task->fence)) {
|
||||
DRM_WARN("%s unexpectedly high interrupt latency\n", lima_ip_name(ip));
|
||||
return DRM_GPU_SCHED_STAT_NOMINAL;
|
||||
}
|
||||
|
||||
if (!pipe->error)
|
||||
DRM_ERROR("lima job timeout\n");
|
||||
DRM_ERROR("%s job timeout\n", lima_ip_name(ip));
|
||||
|
||||
drm_sched_stop(&pipe->base, &task->base);
|
||||
|
||||
@@ -417,8 +443,6 @@ static enum drm_gpu_sched_stat lima_sched_timedout_job(struct drm_sched_job *job
|
||||
if (pipe->bcast_mmu)
|
||||
lima_mmu_page_fault_resume(pipe->bcast_mmu);
|
||||
else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pipe->num_mmu; i++)
|
||||
lima_mmu_page_fault_resume(pipe->mmu[i]);
|
||||
}
|
||||
@@ -481,7 +505,7 @@ static void lima_sched_recover_work(struct work_struct *work)
|
||||
int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
|
||||
{
|
||||
unsigned int timeout = lima_sched_timeout_ms > 0 ?
|
||||
lima_sched_timeout_ms : 500;
|
||||
lima_sched_timeout_ms : 10000;
|
||||
|
||||
pipe->fence_context = dma_fence_context_alloc(1);
|
||||
spin_lock_init(&pipe->fence_lock);
|
||||
|
||||
@@ -91,8 +91,7 @@ int lima_sched_task_init(struct lima_sched_task *task,
|
||||
void lima_sched_task_fini(struct lima_sched_task *task);
|
||||
|
||||
int lima_sched_context_init(struct lima_sched_pipe *pipe,
|
||||
struct lima_sched_context *context,
|
||||
atomic_t *guilty);
|
||||
struct lima_sched_context *context);
|
||||
void lima_sched_context_fini(struct lima_sched_pipe *pipe,
|
||||
struct lima_sched_context *context);
|
||||
struct dma_fence *lima_sched_context_queue_task(struct lima_sched_task *task);
|
||||
|
||||
@@ -2042,12 +2042,12 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *mtk_dp_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
|
||||
bool enabled = mtk_dp->enabled;
|
||||
struct edid *new_edid = NULL;
|
||||
const struct drm_edid *drm_edid;
|
||||
struct mtk_dp_audio_cfg *audio_caps = &mtk_dp->info.audio_cur_cfg;
|
||||
|
||||
if (!enabled) {
|
||||
@@ -2055,7 +2055,7 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
|
||||
mtk_dp_aux_panel_poweron(mtk_dp, true);
|
||||
}
|
||||
|
||||
new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc);
|
||||
drm_edid = drm_edid_read_ddc(connector, &mtk_dp->aux.ddc);
|
||||
|
||||
/*
|
||||
* Parse capability here to let atomic_get_input_bus_fmts and
|
||||
@@ -2063,17 +2063,26 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
|
||||
*/
|
||||
if (mtk_dp_parse_capabilities(mtk_dp)) {
|
||||
drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n");
|
||||
kfree(new_edid);
|
||||
new_edid = NULL;
|
||||
drm_edid_free(drm_edid);
|
||||
drm_edid = NULL;
|
||||
}
|
||||
|
||||
if (new_edid) {
|
||||
if (drm_edid) {
|
||||
/*
|
||||
* FIXME: get rid of drm_edid_raw()
|
||||
*/
|
||||
const struct edid *edid = drm_edid_raw(drm_edid);
|
||||
struct cea_sad *sads;
|
||||
|
||||
audio_caps->sad_count = drm_edid_to_sad(new_edid, &sads);
|
||||
audio_caps->sad_count = drm_edid_to_sad(edid, &sads);
|
||||
kfree(sads);
|
||||
|
||||
audio_caps->detect_monitor = drm_detect_monitor_audio(new_edid);
|
||||
/*
|
||||
* FIXME: This should use connector->display_info.has_audio from
|
||||
* a path that has read the EDID and called
|
||||
* drm_edid_connector_update().
|
||||
*/
|
||||
audio_caps->detect_monitor = drm_detect_monitor_audio(edid);
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
@@ -2081,7 +2090,7 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
|
||||
drm_atomic_bridge_chain_post_disable(bridge, connector->state->state);
|
||||
}
|
||||
|
||||
return new_edid;
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
|
||||
@@ -2433,7 +2442,7 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
|
||||
.atomic_enable = mtk_dp_bridge_atomic_enable,
|
||||
.atomic_disable = mtk_dp_bridge_atomic_disable,
|
||||
.mode_valid = mtk_dp_bridge_mode_valid,
|
||||
.get_edid = mtk_dp_get_edid,
|
||||
.edid_read = mtk_dp_edid_read,
|
||||
.detect = mtk_dp_bdg_detect,
|
||||
};
|
||||
|
||||
|
||||
@@ -1265,19 +1265,27 @@ static enum drm_connector_status mtk_hdmi_bridge_detect(struct drm_bridge *bridg
|
||||
return mtk_hdmi_detect(hdmi);
|
||||
}
|
||||
|
||||
static struct edid *mtk_hdmi_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *mtk_hdmi_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
|
||||
if (!hdmi->ddc_adpt)
|
||||
return NULL;
|
||||
edid = drm_get_edid(connector, hdmi->ddc_adpt);
|
||||
if (!edid)
|
||||
return NULL;
|
||||
hdmi->dvi_mode = !drm_detect_monitor_audio(edid);
|
||||
return edid;
|
||||
drm_edid = drm_edid_read_ddc(connector, hdmi->ddc_adpt);
|
||||
if (drm_edid) {
|
||||
/*
|
||||
* FIXME: This should use !connector->display_info.has_audio (or
|
||||
* !connector->display_info.is_hdmi) from a path that has read
|
||||
* the EDID and called drm_edid_connector_update().
|
||||
*/
|
||||
const struct edid *edid = drm_edid_raw(drm_edid);
|
||||
|
||||
hdmi->dvi_mode = !drm_detect_monitor_audio(edid);
|
||||
}
|
||||
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge,
|
||||
@@ -1417,7 +1425,7 @@ static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = {
|
||||
.atomic_pre_enable = mtk_hdmi_bridge_atomic_pre_enable,
|
||||
.atomic_enable = mtk_hdmi_bridge_atomic_enable,
|
||||
.detect = mtk_hdmi_bridge_detect,
|
||||
.get_edid = mtk_hdmi_bridge_get_edid,
|
||||
.edid_read = mtk_hdmi_bridge_edid_read,
|
||||
};
|
||||
|
||||
static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
|
||||
|
||||
@@ -236,24 +236,33 @@ static void msm_hdmi_bridge_mode_set(struct drm_bridge *bridge,
|
||||
msm_hdmi_audio_update(hdmi);
|
||||
}
|
||||
|
||||
static struct edid *msm_hdmi_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *msm_hdmi_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
|
||||
struct hdmi *hdmi = hdmi_bridge->hdmi;
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
uint32_t hdmi_ctrl;
|
||||
|
||||
hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
|
||||
hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE);
|
||||
|
||||
edid = drm_get_edid(connector, hdmi->i2c);
|
||||
drm_edid = drm_edid_read_ddc(connector, hdmi->i2c);
|
||||
|
||||
hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);
|
||||
|
||||
hdmi->hdmi_mode = drm_detect_hdmi_monitor(edid);
|
||||
if (drm_edid) {
|
||||
/*
|
||||
* FIXME: This should use connector->display_info.is_hdmi from a
|
||||
* path that has read the EDID and called
|
||||
* drm_edid_connector_update().
|
||||
*/
|
||||
const struct edid *edid = drm_edid_raw(drm_edid);
|
||||
|
||||
return edid;
|
||||
hdmi->hdmi_mode = drm_detect_hdmi_monitor(edid);
|
||||
}
|
||||
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
static enum drm_mode_status msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
@@ -290,12 +299,12 @@ static enum drm_mode_status msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {
|
||||
.pre_enable = msm_hdmi_bridge_pre_enable,
|
||||
.post_disable = msm_hdmi_bridge_post_disable,
|
||||
.mode_set = msm_hdmi_bridge_mode_set,
|
||||
.mode_valid = msm_hdmi_bridge_mode_valid,
|
||||
.get_edid = msm_hdmi_bridge_get_edid,
|
||||
.detect = msm_hdmi_bridge_detect,
|
||||
.pre_enable = msm_hdmi_bridge_pre_enable,
|
||||
.post_disable = msm_hdmi_bridge_post_disable,
|
||||
.mode_set = msm_hdmi_bridge_mode_set,
|
||||
.mode_valid = msm_hdmi_bridge_mode_valid,
|
||||
.edid_read = msm_hdmi_bridge_edid_read,
|
||||
.detect = msm_hdmi_bridge_detect,
|
||||
};
|
||||
|
||||
static void
|
||||
|
||||
@@ -436,11 +436,11 @@ static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge,
|
||||
hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
|
||||
}
|
||||
|
||||
static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *hdmi4_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
|
||||
struct edid *edid = NULL;
|
||||
const struct drm_edid *drm_edid = NULL;
|
||||
unsigned int cec_addr;
|
||||
bool need_enable;
|
||||
int r;
|
||||
@@ -461,13 +461,21 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge,
|
||||
if (r)
|
||||
goto done;
|
||||
|
||||
edid = drm_do_get_edid(connector, hdmi4_core_ddc_read, &hdmi->core);
|
||||
drm_edid = drm_edid_read_custom(connector, hdmi4_core_ddc_read, &hdmi->core);
|
||||
|
||||
done:
|
||||
hdmi_runtime_put(hdmi);
|
||||
mutex_unlock(&hdmi->lock);
|
||||
|
||||
if (edid && edid->extensions) {
|
||||
if (drm_edid) {
|
||||
/*
|
||||
* FIXME: The CEC physical address should be set using
|
||||
* hdmi4_cec_set_phys_addr(&hdmi->core,
|
||||
* connector->display_info.source_physical_address) from a path
|
||||
* that has read the EDID and called
|
||||
* drm_edid_connector_update().
|
||||
*/
|
||||
const struct edid *edid = drm_edid_raw(drm_edid);
|
||||
unsigned int len = (edid->extensions + 1) * EDID_LENGTH;
|
||||
|
||||
cec_addr = cec_get_edid_phys_addr((u8 *)edid, len, NULL);
|
||||
@@ -480,7 +488,7 @@ done:
|
||||
if (need_enable)
|
||||
hdmi4_core_disable(&hdmi->core);
|
||||
|
||||
return edid;
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs hdmi4_bridge_funcs = {
|
||||
@@ -492,7 +500,7 @@ static const struct drm_bridge_funcs hdmi4_bridge_funcs = {
|
||||
.atomic_enable = hdmi4_bridge_enable,
|
||||
.atomic_disable = hdmi4_bridge_disable,
|
||||
.hpd_notify = hdmi4_bridge_hpd_notify,
|
||||
.get_edid = hdmi4_bridge_get_edid,
|
||||
.edid_read = hdmi4_bridge_edid_read,
|
||||
};
|
||||
|
||||
static void hdmi4_bridge_init(struct omap_hdmi *hdmi)
|
||||
|
||||
@@ -425,11 +425,11 @@ static void hdmi5_bridge_disable(struct drm_bridge *bridge,
|
||||
mutex_unlock(&hdmi->lock);
|
||||
}
|
||||
|
||||
static struct edid *hdmi5_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *hdmi5_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
|
||||
struct edid *edid;
|
||||
const struct drm_edid *drm_edid;
|
||||
bool need_enable;
|
||||
int idlemode;
|
||||
int r;
|
||||
@@ -452,7 +452,7 @@ static struct edid *hdmi5_bridge_get_edid(struct drm_bridge *bridge,
|
||||
|
||||
hdmi5_core_ddc_init(&hdmi->core);
|
||||
|
||||
edid = drm_do_get_edid(connector, hdmi5_core_ddc_read, &hdmi->core);
|
||||
drm_edid = drm_edid_read_custom(connector, hdmi5_core_ddc_read, &hdmi->core);
|
||||
|
||||
hdmi5_core_ddc_uninit(&hdmi->core);
|
||||
|
||||
@@ -464,7 +464,7 @@ static struct edid *hdmi5_bridge_get_edid(struct drm_bridge *bridge,
|
||||
if (need_enable)
|
||||
hdmi_core_disable(hdmi);
|
||||
|
||||
return (struct edid *)edid;
|
||||
return drm_edid;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs hdmi5_bridge_funcs = {
|
||||
@@ -475,7 +475,7 @@ static const struct drm_bridge_funcs hdmi5_bridge_funcs = {
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
.atomic_enable = hdmi5_bridge_enable,
|
||||
.atomic_disable = hdmi5_bridge_disable,
|
||||
.get_edid = hdmi5_bridge_get_edid,
|
||||
.edid_read = hdmi5_bridge_edid_read,
|
||||
};
|
||||
|
||||
static void hdmi5_bridge_init(struct omap_hdmi *hdmi)
|
||||
|
||||
@@ -62,6 +62,7 @@ struct st7703 {
|
||||
|
||||
struct dentry *debugfs;
|
||||
const struct st7703_panel_desc *desc;
|
||||
enum drm_panel_orientation orientation;
|
||||
};
|
||||
|
||||
struct st7703_panel_desc {
|
||||
@@ -521,6 +522,96 @@ static const struct st7703_panel_desc rgb30panel_desc = {
|
||||
.init_sequence = rgb30panel_init_sequence,
|
||||
};
|
||||
|
||||
static int rgb10max3_panel_init_sequence(struct st7703 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
|
||||
|
||||
/* Init sequence extracted from Powkiddy RGB10MAX3 BSP kernel. */
|
||||
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETAPID, 0x00, 0x00, 0x00, 0xda,
|
||||
0x80);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0xc8, 0x02, 0x30);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28,
|
||||
0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x04, 0x04);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x78, 0x78);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x25, 0x22, 0xf0,
|
||||
0x63);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05, 0xf9,
|
||||
0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a, 0x00,
|
||||
0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x47);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50,
|
||||
0x00, 0x00, 0x12, 0x70, 0x00);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x25, 0x00, 0x32,
|
||||
0x32, 0x77, 0xe1, 0xff, 0xff, 0xcc, 0xcc, 0x77,
|
||||
0x77);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETECO, 0x82, 0x00, 0xbf, 0xff,
|
||||
0x00, 0xff);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETIO, 0xb8, 0x00, 0x0a, 0x00,
|
||||
0x00, 0x00);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCABC, 0x10, 0x40, 0x1e,
|
||||
0x02);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x04, 0x07,
|
||||
0x2a, 0x39, 0x3f, 0x36, 0x31, 0x06, 0x0b, 0x0e,
|
||||
0x12, 0x14, 0x12, 0x13, 0x0f, 0x17, 0x00, 0x04,
|
||||
0x07, 0x2a, 0x39, 0x3f, 0x36, 0x31, 0x06, 0x0b,
|
||||
0x0e, 0x12, 0x14, 0x12, 0x13, 0x0f, 0x17);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x03, 0x03, 0x03, 0x03,
|
||||
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80,
|
||||
0xc0, 0x10);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x08, 0x00,
|
||||
0x00, 0x41, 0xf8, 0x12, 0x31, 0x23, 0x37, 0x86,
|
||||
0x11, 0xc8, 0x37, 0x2a, 0x00, 0x00, 0x0c, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x88, 0x20, 0x46, 0x02, 0x88, 0x88, 0x88, 0x88,
|
||||
0x88, 0x88, 0xff, 0x88, 0x31, 0x57, 0x13, 0x88,
|
||||
0x88, 0x88, 0x88, 0x88, 0x88, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x00, 0x1a, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x8f, 0x13, 0x31, 0x75, 0x88, 0x88, 0x88, 0x88,
|
||||
0x88, 0x88, 0xf8, 0x8f, 0x02, 0x20, 0x64, 0x88,
|
||||
0x88, 0x88, 0x88, 0x88, 0x88, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00);
|
||||
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_EF, 0xff, 0xff, 0x01);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode rgb10max3_panel_mode = {
|
||||
.hdisplay = 720,
|
||||
.hsync_start = 720 + 40,
|
||||
.hsync_end = 720 + 40 + 10,
|
||||
.htotal = 720 + 40 + 10 + 40,
|
||||
.vdisplay = 1280,
|
||||
.vsync_start = 1280 + 16,
|
||||
.vsync_end = 1280 + 16 + 4,
|
||||
.vtotal = 1280 + 16 + 4 + 14,
|
||||
.clock = 63800,
|
||||
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
|
||||
.width_mm = 62,
|
||||
.height_mm = 109,
|
||||
};
|
||||
|
||||
static const struct st7703_panel_desc rgb10max3_panel_desc = {
|
||||
.mode = &rgb10max3_panel_mode,
|
||||
.lanes = 4,
|
||||
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
|
||||
MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM,
|
||||
.format = MIPI_DSI_FMT_RGB888,
|
||||
.init_sequence = rgb10max3_panel_init_sequence,
|
||||
};
|
||||
|
||||
static int st7703_enable(struct drm_panel *panel)
|
||||
{
|
||||
struct st7703 *ctx = panel_to_st7703(panel);
|
||||
@@ -653,12 +744,20 @@ static int st7703_get_modes(struct drm_panel *panel,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static enum drm_panel_orientation st7703_get_orientation(struct drm_panel *panel)
|
||||
{
|
||||
struct st7703 *st7703 = panel_to_st7703(panel);
|
||||
|
||||
return st7703->orientation;
|
||||
}
|
||||
|
||||
static const struct drm_panel_funcs st7703_drm_funcs = {
|
||||
.disable = st7703_disable,
|
||||
.unprepare = st7703_unprepare,
|
||||
.prepare = st7703_prepare,
|
||||
.enable = st7703_enable,
|
||||
.get_modes = st7703_get_modes,
|
||||
.get_orientation = st7703_get_orientation,
|
||||
};
|
||||
|
||||
static int allpixelson_set(void *data, u64 val)
|
||||
@@ -727,6 +826,10 @@ static int st7703_probe(struct mipi_dsi_device *dsi)
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->iovcc),
|
||||
"Failed to request iovcc regulator\n");
|
||||
|
||||
ret = of_drm_get_panel_orientation(dsi->dev.of_node, &ctx->orientation);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&dsi->dev, ret, "Failed to get orientation\n");
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &st7703_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
@@ -784,6 +887,7 @@ static void st7703_remove(struct mipi_dsi_device *dsi)
|
||||
|
||||
static const struct of_device_id st7703_of_match[] = {
|
||||
{ .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc },
|
||||
{ .compatible = "powkiddy,rgb10max3-panel", .data = &rgb10max3_panel_desc },
|
||||
{ .compatible = "powkiddy,rgb30-panel", .data = &rgb30panel_desc },
|
||||
{ .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc },
|
||||
{ .compatible = "xingbangda,xbd599", .data = &xbd599_desc },
|
||||
|
||||
@@ -188,7 +188,7 @@ out:
|
||||
|
||||
static void drm_test_mm_debug(struct kunit *test)
|
||||
{
|
||||
struct drm_printer p = drm_debug_printer(test->name);
|
||||
struct drm_printer p = drm_dbg_printer(NULL, DRM_UT_CORE, test->name);
|
||||
struct drm_mm mm;
|
||||
struct drm_mm_node nodes[2];
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,
|
||||
struct ttm_placement *placement)
|
||||
{
|
||||
struct drm_printer p = drm_debug_printer(TTM_PFX);
|
||||
struct drm_printer p = drm_dbg_printer(NULL, DRM_UT_CORE, TTM_PFX);
|
||||
struct ttm_resource_manager *man;
|
||||
int i, mem_type;
|
||||
|
||||
|
||||
@@ -327,7 +327,7 @@ static void dump_pat_on_error(struct xe_gt *gt)
|
||||
char prefix[32];
|
||||
|
||||
snprintf(prefix, sizeof(prefix), "[GT%u Error]", gt->info.id);
|
||||
p = drm_debug_printer(prefix);
|
||||
p = drm_dbg_printer(>_to_xe(gt)->drm, DRM_UT_DRIVER, prefix);
|
||||
|
||||
xe_pat_dump(gt, &p);
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ int xe_gt_tlb_invalidation_wait(struct xe_gt *gt, int seqno)
|
||||
{
|
||||
struct xe_device *xe = gt_to_xe(gt);
|
||||
struct xe_guc *guc = >->uc.guc;
|
||||
struct drm_printer p = drm_err_printer(__func__);
|
||||
struct drm_printer p = drm_err_printer(&xe->drm, __func__);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
||||
@@ -84,7 +84,7 @@ void
|
||||
xe_gt_topology_init(struct xe_gt *gt)
|
||||
{
|
||||
struct xe_device *xe = gt_to_xe(gt);
|
||||
struct drm_printer p = drm_debug_printer("GT topology");
|
||||
struct drm_printer p;
|
||||
int num_geometry_regs, num_compute_regs;
|
||||
|
||||
get_num_dss_regs(xe, &num_geometry_regs, &num_compute_regs);
|
||||
@@ -107,6 +107,8 @@ xe_gt_topology_init(struct xe_gt *gt)
|
||||
XE2_GT_COMPUTE_DSS_2);
|
||||
load_eu_mask(gt, gt->fuse_topo.eu_mask_per_dss);
|
||||
|
||||
p = drm_dbg_printer(>_to_xe(gt)->drm, DRM_UT_DRIVER, "GT topology");
|
||||
|
||||
xe_gt_topology_dump(gt, &p);
|
||||
}
|
||||
|
||||
|
||||
@@ -811,7 +811,8 @@ static void guc_exec_queue_print(struct xe_exec_queue *q, struct drm_printer *p)
|
||||
static void simple_error_capture(struct xe_exec_queue *q)
|
||||
{
|
||||
struct xe_guc *guc = exec_queue_to_guc(q);
|
||||
struct drm_printer p = drm_err_printer("");
|
||||
struct xe_device *xe = guc_to_xe(guc);
|
||||
struct drm_printer p = drm_err_printer(&xe->drm, NULL);
|
||||
struct xe_hw_engine *hwe;
|
||||
enum xe_hw_engine_id id;
|
||||
u32 adj_logical_mask = q->logical_mask;
|
||||
|
||||
@@ -231,7 +231,7 @@ void xe_reg_sr_apply_whitelist(struct xe_hw_engine *hwe)
|
||||
if (err)
|
||||
goto err_force_wake;
|
||||
|
||||
p = drm_debug_printer(KBUILD_MODNAME);
|
||||
p = drm_dbg_printer(&xe->drm, DRM_UT_DRIVER, NULL);
|
||||
xa_for_each(&sr->xa, reg, entry) {
|
||||
if (slot == RING_MAX_NONPRIV_SLOTS) {
|
||||
xe_gt_err(gt,
|
||||
|
||||
@@ -1560,12 +1560,12 @@ disconnected:
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
static struct edid *zynqmp_dp_bridge_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
static const struct drm_edid *zynqmp_dp_bridge_edid_read(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct zynqmp_dp *dp = bridge_to_dp(bridge);
|
||||
|
||||
return drm_get_edid(connector, &dp->aux.ddc);
|
||||
return drm_edid_read_ddc(connector, &dp->aux.ddc);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs zynqmp_dp_bridge_funcs = {
|
||||
@@ -1579,7 +1579,7 @@ static const struct drm_bridge_funcs zynqmp_dp_bridge_funcs = {
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
.atomic_check = zynqmp_dp_bridge_atomic_check,
|
||||
.detect = zynqmp_dp_bridge_detect,
|
||||
.get_edid = zynqmp_dp_bridge_get_edid,
|
||||
.edid_read = zynqmp_dp_bridge_edid_read,
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
||||
@@ -365,7 +365,7 @@ static const struct dev_pm_ops host1x_device_pm_ops = {
|
||||
.restore = pm_generic_restore,
|
||||
};
|
||||
|
||||
struct bus_type host1x_bus_type = {
|
||||
const struct bus_type host1x_bus_type = {
|
||||
.name = "host1x",
|
||||
.match = host1x_device_match,
|
||||
.uevent = host1x_device_uevent,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
struct bus_type;
|
||||
struct host1x;
|
||||
|
||||
extern struct bus_type host1x_bus_type;
|
||||
extern const struct bus_type host1x_bus_type;
|
||||
|
||||
int host1x_register(struct host1x *host1x);
|
||||
int host1x_unregister(struct host1x *host1x);
|
||||
|
||||
@@ -11,6 +11,10 @@ config APERTURE_HELPERS
|
||||
Support tracking and hand-over of aperture ownership. Required
|
||||
by graphics drivers for firmware-provided framebuffers.
|
||||
|
||||
config SCREEN_INFO
|
||||
bool
|
||||
default n
|
||||
|
||||
config STI_CORE
|
||||
bool
|
||||
depends on PARISC
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_APERTURE_HELPERS) += aperture.o
|
||||
obj-$(CONFIG_SCREEN_INFO) += screen_info.o
|
||||
obj-$(CONFIG_STI_CORE) += sticore.o
|
||||
obj-$(CONFIG_VGASTATE) += vgastate.o
|
||||
obj-$(CONFIG_VIDEO) += cmdline.o nomodeset.o
|
||||
obj-$(CONFIG_HDMI) += hdmi.o
|
||||
|
||||
screen_info-y := screen_info_generic.o
|
||||
screen_info-$(CONFIG_PCI) += screen_info_pci.o
|
||||
|
||||
obj-$(CONFIG_VT) += console/
|
||||
obj-$(CONFIG_FB_STI) += console/
|
||||
obj-$(CONFIG_LOGO) += logo/
|
||||
|
||||
@@ -13,11 +13,9 @@
|
||||
#include <linux/efi-bgrt.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <video/vga.h>
|
||||
#include <asm/efi.h>
|
||||
#include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */
|
||||
@@ -48,8 +46,6 @@ static bool use_bgrt = true;
|
||||
static bool request_mem_succeeded = false;
|
||||
static u64 mem_flags = EFI_MEMORY_WC | EFI_MEMORY_UC;
|
||||
|
||||
static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */
|
||||
|
||||
struct efifb_par {
|
||||
u32 pseudo_palette[16];
|
||||
resource_size_t base;
|
||||
@@ -258,9 +254,6 @@ static void efifb_destroy(struct fb_info *info)
|
||||
{
|
||||
struct efifb_par *par = info->par;
|
||||
|
||||
if (efifb_pci_dev)
|
||||
pm_runtime_put(&efifb_pci_dev->dev);
|
||||
|
||||
if (info->screen_base) {
|
||||
if (mem_flags & (EFI_MEMORY_UC | EFI_MEMORY_WC))
|
||||
iounmap(info->screen_base);
|
||||
@@ -352,11 +345,6 @@ static struct attribute *efifb_attrs[] = {
|
||||
};
|
||||
ATTRIBUTE_GROUPS(efifb);
|
||||
|
||||
static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */
|
||||
|
||||
static struct resource *bar_resource;
|
||||
static u64 bar_offset;
|
||||
|
||||
static int efifb_probe(struct platform_device *dev)
|
||||
{
|
||||
struct screen_info *si;
|
||||
@@ -381,7 +369,7 @@ static int efifb_probe(struct platform_device *dev)
|
||||
if (!si)
|
||||
return -ENOMEM;
|
||||
|
||||
if (si->orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
|
||||
if (si->orig_video_isVGA != VIDEO_TYPE_EFI)
|
||||
return -ENODEV;
|
||||
|
||||
if (fb_get_options("efifb", &option))
|
||||
@@ -417,21 +405,7 @@ static int efifb_probe(struct platform_device *dev)
|
||||
si->rsvd_pos = 24;
|
||||
}
|
||||
|
||||
efifb_fix.smem_start = si->lfb_base;
|
||||
|
||||
if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
|
||||
u64 ext_lfb_base;
|
||||
|
||||
ext_lfb_base = (u64)(unsigned long)si->ext_lfb_base << 32;
|
||||
efifb_fix.smem_start |= ext_lfb_base;
|
||||
}
|
||||
|
||||
if (bar_resource &&
|
||||
bar_resource->start + bar_offset != efifb_fix.smem_start) {
|
||||
dev_info(&efifb_pci_dev->dev,
|
||||
"BAR has moved, updating efifb address\n");
|
||||
efifb_fix.smem_start = bar_resource->start + bar_offset;
|
||||
}
|
||||
efifb_fix.smem_start = __screen_info_lfb_base(si);
|
||||
|
||||
efifb_defined.bits_per_pixel = si->lfb_depth;
|
||||
efifb_defined.xres = si->lfb_width;
|
||||
@@ -598,26 +572,20 @@ static int efifb_probe(struct platform_device *dev)
|
||||
goto err_groups;
|
||||
}
|
||||
|
||||
if (efifb_pci_dev)
|
||||
WARN_ON(pm_runtime_get_sync(&efifb_pci_dev->dev) < 0);
|
||||
|
||||
err = devm_aperture_acquire_for_platform_device(dev, par->base, par->size);
|
||||
if (err) {
|
||||
pr_err("efifb: cannot acquire aperture\n");
|
||||
goto err_put_rpm_ref;
|
||||
goto err_fb_dealloc_cmap;
|
||||
}
|
||||
err = register_framebuffer(info);
|
||||
if (err < 0) {
|
||||
pr_err("efifb: cannot register framebuffer\n");
|
||||
goto err_put_rpm_ref;
|
||||
goto err_fb_dealloc_cmap;
|
||||
}
|
||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||
return 0;
|
||||
|
||||
err_put_rpm_ref:
|
||||
if (efifb_pci_dev)
|
||||
pm_runtime_put(&efifb_pci_dev->dev);
|
||||
|
||||
err_fb_dealloc_cmap:
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
err_groups:
|
||||
sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
|
||||
@@ -652,58 +620,3 @@ static struct platform_driver efifb_driver = {
|
||||
};
|
||||
|
||||
builtin_platform_driver(efifb_driver);
|
||||
|
||||
#if defined(CONFIG_PCI)
|
||||
|
||||
static void record_efifb_bar_resource(struct pci_dev *dev, int idx, u64 offset)
|
||||
{
|
||||
u16 word;
|
||||
|
||||
efifb_pci_dev = dev;
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &word);
|
||||
if (!(word & PCI_COMMAND_MEMORY)) {
|
||||
pci_dev_disabled = true;
|
||||
dev_err(&dev->dev,
|
||||
"BAR %d: assigned to efifb but device is disabled!\n",
|
||||
idx);
|
||||
return;
|
||||
}
|
||||
|
||||
bar_resource = &dev->resource[idx];
|
||||
bar_offset = offset;
|
||||
|
||||
dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx);
|
||||
}
|
||||
|
||||
static void efifb_fixup_resources(struct pci_dev *dev)
|
||||
{
|
||||
u64 base = screen_info.lfb_base;
|
||||
u64 size = screen_info.lfb_size;
|
||||
int i;
|
||||
|
||||
if (efifb_pci_dev || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
|
||||
return;
|
||||
|
||||
if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
|
||||
base |= (u64)screen_info.ext_lfb_base << 32;
|
||||
|
||||
if (!base)
|
||||
return;
|
||||
|
||||
for (i = 0; i < PCI_STD_NUM_BARS; i++) {
|
||||
struct resource *res = &dev->resource[i];
|
||||
|
||||
if (!(res->flags & IORESOURCE_MEM))
|
||||
continue;
|
||||
|
||||
if (res->start <= base && res->end >= base + size - 1) {
|
||||
record_efifb_bar_resource(dev, i, base - res->start);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY,
|
||||
16, efifb_fixup_resources);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
static void resource_init_named(struct resource *r,
|
||||
resource_size_t start, resource_size_t size,
|
||||
const char *name, unsigned int flags)
|
||||
{
|
||||
memset(r, 0, sizeof(*r));
|
||||
|
||||
r->start = start;
|
||||
r->end = start + size - 1;
|
||||
r->name = name;
|
||||
r->flags = flags;
|
||||
}
|
||||
|
||||
static void resource_init_io_named(struct resource *r,
|
||||
resource_size_t start, resource_size_t size,
|
||||
const char *name)
|
||||
{
|
||||
resource_init_named(r, start, size, name, IORESOURCE_IO);
|
||||
}
|
||||
|
||||
static void resource_init_mem_named(struct resource *r,
|
||||
resource_size_t start, resource_size_t size,
|
||||
const char *name)
|
||||
{
|
||||
resource_init_named(r, start, size, name, IORESOURCE_MEM);
|
||||
}
|
||||
|
||||
static inline bool __screen_info_has_ega_gfx(unsigned int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case 0x0d: /* 320x200-4 */
|
||||
case 0x0e: /* 640x200-4 */
|
||||
case 0x0f: /* 640x350-1 */
|
||||
case 0x10: /* 640x350-4 */
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool __screen_info_has_vga_gfx(unsigned int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case 0x10: /* 640x480-1 */
|
||||
case 0x12: /* 640x480-4 */
|
||||
case 0x13: /* 320-200-8 */
|
||||
case 0x6a: /* 800x600-4 (VESA) */
|
||||
return true;
|
||||
default:
|
||||
return __screen_info_has_ega_gfx(mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* screen_info_resources() - Get resources from screen_info structure
|
||||
* @si: the screen_info
|
||||
* @r: pointer to an array of resource structures
|
||||
* @num: number of elements in @r:
|
||||
*
|
||||
* Returns:
|
||||
* The number of resources stored in @r on success, or a negative errno code otherwise.
|
||||
*
|
||||
* A call to screen_info_resources() returns the resources consumed by the
|
||||
* screen_info's device or framebuffer. The result is stored in the caller-supplied
|
||||
* array @r with up to @num elements. The function returns the number of
|
||||
* initialized elements.
|
||||
*/
|
||||
ssize_t screen_info_resources(const struct screen_info *si, struct resource *r, size_t num)
|
||||
{
|
||||
struct resource *pos = r;
|
||||
unsigned int type = screen_info_video_type(si);
|
||||
u64 base, size;
|
||||
|
||||
switch (type) {
|
||||
case VIDEO_TYPE_MDA:
|
||||
if (num > 0)
|
||||
resource_init_io_named(pos++, 0x3b0, 12, "mda");
|
||||
if (num > 1)
|
||||
resource_init_io_named(pos++, 0x3bf, 0x01, "mda");
|
||||
if (num > 2)
|
||||
resource_init_mem_named(pos++, 0xb0000, 0x2000, "mda");
|
||||
break;
|
||||
case VIDEO_TYPE_CGA:
|
||||
if (num > 0)
|
||||
resource_init_io_named(pos++, 0x3d4, 0x02, "cga");
|
||||
if (num > 1)
|
||||
resource_init_mem_named(pos++, 0xb8000, 0x2000, "cga");
|
||||
break;
|
||||
case VIDEO_TYPE_EGAM:
|
||||
if (num > 0)
|
||||
resource_init_io_named(pos++, 0x3bf, 0x10, "ega");
|
||||
if (num > 1)
|
||||
resource_init_mem_named(pos++, 0xb0000, 0x8000, "ega");
|
||||
break;
|
||||
case VIDEO_TYPE_EGAC:
|
||||
if (num > 0)
|
||||
resource_init_io_named(pos++, 0x3c0, 0x20, "ega");
|
||||
if (num > 1) {
|
||||
if (__screen_info_has_ega_gfx(si->orig_video_mode))
|
||||
resource_init_mem_named(pos++, 0xa0000, 0x10000, "ega");
|
||||
else
|
||||
resource_init_mem_named(pos++, 0xb8000, 0x8000, "ega");
|
||||
}
|
||||
break;
|
||||
case VIDEO_TYPE_VGAC:
|
||||
if (num > 0)
|
||||
resource_init_io_named(pos++, 0x3c0, 0x20, "vga+");
|
||||
if (num > 1) {
|
||||
if (__screen_info_has_vga_gfx(si->orig_video_mode))
|
||||
resource_init_mem_named(pos++, 0xa0000, 0x10000, "vga+");
|
||||
else
|
||||
resource_init_mem_named(pos++, 0xb8000, 0x8000, "vga+");
|
||||
}
|
||||
break;
|
||||
case VIDEO_TYPE_VLFB:
|
||||
case VIDEO_TYPE_EFI:
|
||||
base = __screen_info_lfb_base(si);
|
||||
if (!base)
|
||||
break;
|
||||
size = __screen_info_lfb_size(si, type);
|
||||
if (!size)
|
||||
break;
|
||||
if (num > 0)
|
||||
resource_init_mem_named(pos++, base, size, "lfb");
|
||||
break;
|
||||
case VIDEO_TYPE_PICA_S3:
|
||||
case VIDEO_TYPE_MIPS_G364:
|
||||
case VIDEO_TYPE_SGI:
|
||||
case VIDEO_TYPE_TGAC:
|
||||
case VIDEO_TYPE_SUN:
|
||||
case VIDEO_TYPE_SUNPCI:
|
||||
case VIDEO_TYPE_PMAC:
|
||||
default:
|
||||
/* not supported */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return pos - r;
|
||||
}
|
||||
EXPORT_SYMBOL(screen_info_resources);
|
||||
@@ -0,0 +1,136 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
static struct pci_dev *screen_info_lfb_pdev;
|
||||
static size_t screen_info_lfb_bar;
|
||||
static resource_size_t screen_info_lfb_offset;
|
||||
static struct resource screen_info_lfb_res = DEFINE_RES_MEM(0, 0);
|
||||
|
||||
static bool __screen_info_relocation_is_valid(const struct screen_info *si, struct resource *pr)
|
||||
{
|
||||
u64 size = __screen_info_lfb_size(si, screen_info_video_type(si));
|
||||
|
||||
if (screen_info_lfb_offset > resource_size(pr))
|
||||
return false;
|
||||
if (size > resource_size(pr))
|
||||
return false;
|
||||
if (resource_size(pr) - size < screen_info_lfb_offset)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void screen_info_apply_fixups(void)
|
||||
{
|
||||
struct screen_info *si = &screen_info;
|
||||
|
||||
if (screen_info_lfb_pdev) {
|
||||
struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar];
|
||||
|
||||
if (pr->start != screen_info_lfb_res.start) {
|
||||
if (__screen_info_relocation_is_valid(si, pr)) {
|
||||
/*
|
||||
* Only update base if we have an actual
|
||||
* relocation to a valid I/O range.
|
||||
*/
|
||||
__screen_info_set_lfb_base(si, pr->start + screen_info_lfb_offset);
|
||||
pr_info("Relocating firmware framebuffer to offset %pa[d] within %pr\n",
|
||||
&screen_info_lfb_offset, pr);
|
||||
} else {
|
||||
pr_warn("Invalid relocating, disabling firmware framebuffer\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void screen_info_fixup_lfb(struct pci_dev *pdev)
|
||||
{
|
||||
unsigned int type;
|
||||
struct resource res[SCREEN_INFO_MAX_RESOURCES];
|
||||
size_t i, numres;
|
||||
int ret;
|
||||
const struct screen_info *si = &screen_info;
|
||||
|
||||
if (screen_info_lfb_pdev)
|
||||
return; // already found
|
||||
|
||||
type = screen_info_video_type(si);
|
||||
if (type != VIDEO_TYPE_EFI)
|
||||
return; // only applies to EFI
|
||||
|
||||
ret = screen_info_resources(si, res, ARRAY_SIZE(res));
|
||||
if (ret < 0)
|
||||
return;
|
||||
numres = ret;
|
||||
|
||||
for (i = 0; i < numres; ++i) {
|
||||
struct resource *r = &res[i];
|
||||
const struct resource *pr;
|
||||
|
||||
if (!(r->flags & IORESOURCE_MEM))
|
||||
continue;
|
||||
pr = pci_find_resource(pdev, r);
|
||||
if (!pr)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We've found a PCI device with the framebuffer
|
||||
* resource. Store away the parameters to track
|
||||
* relocation of the framebuffer aperture.
|
||||
*/
|
||||
screen_info_lfb_pdev = pdev;
|
||||
screen_info_lfb_bar = pr - pdev->resource;
|
||||
screen_info_lfb_offset = r->start - pr->start;
|
||||
memcpy(&screen_info_lfb_res, r, sizeof(screen_info_lfb_res));
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 16,
|
||||
screen_info_fixup_lfb);
|
||||
|
||||
static struct pci_dev *__screen_info_pci_dev(struct resource *res)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
const struct resource *r = NULL;
|
||||
|
||||
if (!(res->flags & IORESOURCE_MEM))
|
||||
return NULL;
|
||||
|
||||
while (!r && (pdev = pci_get_base_class(PCI_BASE_CLASS_DISPLAY, pdev))) {
|
||||
r = pci_find_resource(pdev, res);
|
||||
}
|
||||
|
||||
return pdev;
|
||||
}
|
||||
|
||||
/**
|
||||
* screen_info_pci_dev() - Return PCI parent device that contains screen_info's framebuffer
|
||||
* @si: the screen_info
|
||||
*
|
||||
* Returns:
|
||||
* The screen_info's parent device or NULL on success, or a pointer-encoded
|
||||
* errno value otherwise. The value NULL is not an error. It signals that no
|
||||
* PCI device has been found.
|
||||
*/
|
||||
struct pci_dev *screen_info_pci_dev(const struct screen_info *si)
|
||||
{
|
||||
struct resource res[SCREEN_INFO_MAX_RESOURCES];
|
||||
ssize_t i, numres;
|
||||
|
||||
numres = screen_info_resources(si, res, ARRAY_SIZE(res));
|
||||
if (numres < 0)
|
||||
return ERR_PTR(numres);
|
||||
|
||||
for (i = 0; i < numres; ++i) {
|
||||
struct pci_dev *pdev = __screen_info_pci_dev(&res[i]);
|
||||
|
||||
if (pdev)
|
||||
return pdev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(screen_info_pci_dev);
|
||||
@@ -98,8 +98,7 @@ struct drm_dp_vsc_sdp {
|
||||
enum dp_content_type content_type;
|
||||
};
|
||||
|
||||
void drm_dp_vsc_sdp_log(const char *level, struct device *dev,
|
||||
const struct drm_dp_vsc_sdp *vsc);
|
||||
void drm_dp_vsc_sdp_log(struct drm_printer *p, const struct drm_dp_vsc_sdp *vsc);
|
||||
|
||||
int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE]);
|
||||
|
||||
|
||||
@@ -588,36 +588,6 @@ struct drm_bridge_funcs {
|
||||
const struct drm_edid *(*edid_read)(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector);
|
||||
|
||||
/**
|
||||
* @get_edid:
|
||||
*
|
||||
* Read and parse the EDID data of the connected display.
|
||||
*
|
||||
* The @get_edid callback is the preferred way of reporting mode
|
||||
* information for a display connected to the bridge output. Bridges
|
||||
* that support reading EDID shall implement this callback and leave
|
||||
* the @get_modes callback unimplemented.
|
||||
*
|
||||
* The caller of this operation shall first verify the output
|
||||
* connection status and refrain from reading EDID from a disconnected
|
||||
* output.
|
||||
*
|
||||
* This callback is optional. Bridges that implement it shall set the
|
||||
* DRM_BRIDGE_OP_EDID flag in their &drm_bridge->ops.
|
||||
*
|
||||
* The connector parameter shall be used for the sole purpose of EDID
|
||||
* retrieval and parsing, and shall not be stored internally by bridge
|
||||
* drivers for future usage.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* An edid structure newly allocated with kmalloc() (or similar) on
|
||||
* success, or NULL otherwise. The caller is responsible for freeing
|
||||
* the returned edid structure with kfree().
|
||||
*/
|
||||
struct edid *(*get_edid)(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector);
|
||||
|
||||
/**
|
||||
* @hpd_notify:
|
||||
*
|
||||
|
||||
+116
-104
@@ -35,6 +35,8 @@
|
||||
|
||||
#include <drm/drm.h>
|
||||
|
||||
struct drm_device;
|
||||
|
||||
/* Do *not* use outside of drm_print.[ch]! */
|
||||
extern unsigned long __drm_debug;
|
||||
|
||||
@@ -67,6 +69,101 @@ extern unsigned long __drm_debug;
|
||||
* }
|
||||
*/
|
||||
|
||||
/**
|
||||
* enum drm_debug_category - The DRM debug categories
|
||||
*
|
||||
* Each of the DRM debug logging macros use a specific category, and the logging
|
||||
* is filtered by the drm.debug module parameter. This enum specifies the values
|
||||
* for the interface.
|
||||
*
|
||||
* Each DRM_DEBUG_<CATEGORY> macro logs to DRM_UT_<CATEGORY> category, except
|
||||
* DRM_DEBUG() logs to DRM_UT_CORE.
|
||||
*
|
||||
* Enabling verbose debug messages is done through the drm.debug parameter, each
|
||||
* category being enabled by a bit:
|
||||
*
|
||||
* - drm.debug=0x1 will enable CORE messages
|
||||
* - drm.debug=0x2 will enable DRIVER messages
|
||||
* - drm.debug=0x3 will enable CORE and DRIVER messages
|
||||
* - ...
|
||||
* - drm.debug=0x1ff will enable all messages
|
||||
*
|
||||
* An interesting feature is that it's possible to enable verbose logging at
|
||||
* run-time by echoing the debug value in its sysfs node::
|
||||
*
|
||||
* # echo 0xf > /sys/module/drm/parameters/debug
|
||||
*
|
||||
*/
|
||||
enum drm_debug_category {
|
||||
/* These names must match those in DYNAMIC_DEBUG_CLASSBITS */
|
||||
/**
|
||||
* @DRM_UT_CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c,
|
||||
* drm_memory.c, ...
|
||||
*/
|
||||
DRM_UT_CORE,
|
||||
/**
|
||||
* @DRM_UT_DRIVER: Used in the vendor specific part of the driver: i915,
|
||||
* radeon, ... macro.
|
||||
*/
|
||||
DRM_UT_DRIVER,
|
||||
/**
|
||||
* @DRM_UT_KMS: Used in the modesetting code.
|
||||
*/
|
||||
DRM_UT_KMS,
|
||||
/**
|
||||
* @DRM_UT_PRIME: Used in the prime code.
|
||||
*/
|
||||
DRM_UT_PRIME,
|
||||
/**
|
||||
* @DRM_UT_ATOMIC: Used in the atomic code.
|
||||
*/
|
||||
DRM_UT_ATOMIC,
|
||||
/**
|
||||
* @DRM_UT_VBL: Used for verbose debug message in the vblank code.
|
||||
*/
|
||||
DRM_UT_VBL,
|
||||
/**
|
||||
* @DRM_UT_STATE: Used for verbose atomic state debugging.
|
||||
*/
|
||||
DRM_UT_STATE,
|
||||
/**
|
||||
* @DRM_UT_LEASE: Used in the lease code.
|
||||
*/
|
||||
DRM_UT_LEASE,
|
||||
/**
|
||||
* @DRM_UT_DP: Used in the DP code.
|
||||
*/
|
||||
DRM_UT_DP,
|
||||
/**
|
||||
* @DRM_UT_DRMRES: Used in the drm managed resources code.
|
||||
*/
|
||||
DRM_UT_DRMRES
|
||||
};
|
||||
|
||||
static inline bool drm_debug_enabled_raw(enum drm_debug_category category)
|
||||
{
|
||||
return unlikely(__drm_debug & BIT(category));
|
||||
}
|
||||
|
||||
#define drm_debug_enabled_instrumented(category) \
|
||||
({ \
|
||||
pr_debug("todo: is this frequent enough to optimize ?\n"); \
|
||||
drm_debug_enabled_raw(category); \
|
||||
})
|
||||
|
||||
#if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
|
||||
/*
|
||||
* the drm.debug API uses dyndbg, so each drm_*dbg macro/callsite gets
|
||||
* a descriptor, and only enabled callsites are reachable. They use
|
||||
* the private macro to avoid re-testing the enable-bit.
|
||||
*/
|
||||
#define __drm_debug_enabled(category) true
|
||||
#define drm_debug_enabled(category) drm_debug_enabled_instrumented(category)
|
||||
#else
|
||||
#define __drm_debug_enabled(category) drm_debug_enabled_raw(category)
|
||||
#define drm_debug_enabled(category) drm_debug_enabled_raw(category)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct drm_printer - drm output "stream"
|
||||
*
|
||||
@@ -79,6 +176,7 @@ struct drm_printer {
|
||||
void (*puts)(struct drm_printer *p, const char *str);
|
||||
void *arg;
|
||||
const char *prefix;
|
||||
enum drm_debug_category category;
|
||||
};
|
||||
|
||||
void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf);
|
||||
@@ -86,7 +184,7 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str);
|
||||
void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf);
|
||||
void __drm_puts_seq_file(struct drm_printer *p, const char *str);
|
||||
void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
|
||||
void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf);
|
||||
void __drm_printfn_dbg(struct drm_printer *p, struct va_format *vaf);
|
||||
void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf);
|
||||
|
||||
__printf(2, 3)
|
||||
@@ -219,132 +317,46 @@ static inline struct drm_printer drm_info_printer(struct device *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_debug_printer - construct a &drm_printer that outputs to pr_debug()
|
||||
* @prefix: debug output prefix
|
||||
* drm_dbg_printer - construct a &drm_printer for drm device specific output
|
||||
* @drm: the &struct drm_device pointer, or NULL
|
||||
* @category: the debug category to use
|
||||
* @prefix: debug output prefix, or NULL for no prefix
|
||||
*
|
||||
* RETURNS:
|
||||
* The &drm_printer object
|
||||
*/
|
||||
static inline struct drm_printer drm_debug_printer(const char *prefix)
|
||||
static inline struct drm_printer drm_dbg_printer(struct drm_device *drm,
|
||||
enum drm_debug_category category,
|
||||
const char *prefix)
|
||||
{
|
||||
struct drm_printer p = {
|
||||
.printfn = __drm_printfn_debug,
|
||||
.prefix = prefix
|
||||
.printfn = __drm_printfn_dbg,
|
||||
.arg = drm,
|
||||
.prefix = prefix,
|
||||
.category = category,
|
||||
};
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_err_printer - construct a &drm_printer that outputs to pr_err()
|
||||
* @prefix: debug output prefix
|
||||
* drm_err_printer - construct a &drm_printer that outputs to drm_err()
|
||||
* @drm: the &struct drm_device pointer
|
||||
* @prefix: debug output prefix, or NULL for no prefix
|
||||
*
|
||||
* RETURNS:
|
||||
* The &drm_printer object
|
||||
*/
|
||||
static inline struct drm_printer drm_err_printer(const char *prefix)
|
||||
static inline struct drm_printer drm_err_printer(struct drm_device *drm,
|
||||
const char *prefix)
|
||||
{
|
||||
struct drm_printer p = {
|
||||
.printfn = __drm_printfn_err,
|
||||
.arg = drm,
|
||||
.prefix = prefix
|
||||
};
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* enum drm_debug_category - The DRM debug categories
|
||||
*
|
||||
* Each of the DRM debug logging macros use a specific category, and the logging
|
||||
* is filtered by the drm.debug module parameter. This enum specifies the values
|
||||
* for the interface.
|
||||
*
|
||||
* Each DRM_DEBUG_<CATEGORY> macro logs to DRM_UT_<CATEGORY> category, except
|
||||
* DRM_DEBUG() logs to DRM_UT_CORE.
|
||||
*
|
||||
* Enabling verbose debug messages is done through the drm.debug parameter, each
|
||||
* category being enabled by a bit:
|
||||
*
|
||||
* - drm.debug=0x1 will enable CORE messages
|
||||
* - drm.debug=0x2 will enable DRIVER messages
|
||||
* - drm.debug=0x3 will enable CORE and DRIVER messages
|
||||
* - ...
|
||||
* - drm.debug=0x1ff will enable all messages
|
||||
*
|
||||
* An interesting feature is that it's possible to enable verbose logging at
|
||||
* run-time by echoing the debug value in its sysfs node::
|
||||
*
|
||||
* # echo 0xf > /sys/module/drm/parameters/debug
|
||||
*
|
||||
*/
|
||||
enum drm_debug_category {
|
||||
/* These names must match those in DYNAMIC_DEBUG_CLASSBITS */
|
||||
/**
|
||||
* @DRM_UT_CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c,
|
||||
* drm_memory.c, ...
|
||||
*/
|
||||
DRM_UT_CORE,
|
||||
/**
|
||||
* @DRM_UT_DRIVER: Used in the vendor specific part of the driver: i915,
|
||||
* radeon, ... macro.
|
||||
*/
|
||||
DRM_UT_DRIVER,
|
||||
/**
|
||||
* @DRM_UT_KMS: Used in the modesetting code.
|
||||
*/
|
||||
DRM_UT_KMS,
|
||||
/**
|
||||
* @DRM_UT_PRIME: Used in the prime code.
|
||||
*/
|
||||
DRM_UT_PRIME,
|
||||
/**
|
||||
* @DRM_UT_ATOMIC: Used in the atomic code.
|
||||
*/
|
||||
DRM_UT_ATOMIC,
|
||||
/**
|
||||
* @DRM_UT_VBL: Used for verbose debug message in the vblank code.
|
||||
*/
|
||||
DRM_UT_VBL,
|
||||
/**
|
||||
* @DRM_UT_STATE: Used for verbose atomic state debugging.
|
||||
*/
|
||||
DRM_UT_STATE,
|
||||
/**
|
||||
* @DRM_UT_LEASE: Used in the lease code.
|
||||
*/
|
||||
DRM_UT_LEASE,
|
||||
/**
|
||||
* @DRM_UT_DP: Used in the DP code.
|
||||
*/
|
||||
DRM_UT_DP,
|
||||
/**
|
||||
* @DRM_UT_DRMRES: Used in the drm managed resources code.
|
||||
*/
|
||||
DRM_UT_DRMRES
|
||||
};
|
||||
|
||||
static inline bool drm_debug_enabled_raw(enum drm_debug_category category)
|
||||
{
|
||||
return unlikely(__drm_debug & BIT(category));
|
||||
}
|
||||
|
||||
#define drm_debug_enabled_instrumented(category) \
|
||||
({ \
|
||||
pr_debug("todo: is this frequent enough to optimize ?\n"); \
|
||||
drm_debug_enabled_raw(category); \
|
||||
})
|
||||
|
||||
#if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
|
||||
/*
|
||||
* the drm.debug API uses dyndbg, so each drm_*dbg macro/callsite gets
|
||||
* a descriptor, and only enabled callsites are reachable. They use
|
||||
* the private macro to avoid re-testing the enable-bit.
|
||||
*/
|
||||
#define __drm_debug_enabled(category) true
|
||||
#define drm_debug_enabled(category) drm_debug_enabled_instrumented(category)
|
||||
#else
|
||||
#define __drm_debug_enabled(category) drm_debug_enabled_raw(category)
|
||||
#define drm_debug_enabled(category) drm_debug_enabled_raw(category)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* struct device based logging
|
||||
*
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
* the same driver for allocation, read and write operations.
|
||||
*
|
||||
* Open-coding access to :c:type:`struct iosys_map <iosys_map>` is considered
|
||||
* bad style. Rather then accessing its fields directly, use one of the provided
|
||||
* bad style. Rather than accessing its fields directly, use one of the provided
|
||||
* helper functions, or implement your own. For example, instances of
|
||||
* :c:type:`struct iosys_map <iosys_map>` can be initialized statically with
|
||||
* IOSYS_MAP_INIT_VADDR(), or at runtime with iosys_map_set_vaddr(). These
|
||||
|
||||
@@ -4,6 +4,132 @@
|
||||
|
||||
#include <uapi/linux/screen_info.h>
|
||||
|
||||
#include <linux/bits.h>
|
||||
|
||||
/**
|
||||
* SCREEN_INFO_MAX_RESOURCES - maximum number of resources per screen_info
|
||||
*/
|
||||
#define SCREEN_INFO_MAX_RESOURCES 3
|
||||
|
||||
struct pci_dev;
|
||||
struct resource;
|
||||
|
||||
static inline bool __screen_info_has_lfb(unsigned int type)
|
||||
{
|
||||
return (type == VIDEO_TYPE_VLFB) || (type == VIDEO_TYPE_EFI);
|
||||
}
|
||||
|
||||
static inline u64 __screen_info_lfb_base(const struct screen_info *si)
|
||||
{
|
||||
u64 lfb_base = si->lfb_base;
|
||||
|
||||
if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE)
|
||||
lfb_base |= (u64)si->ext_lfb_base << 32;
|
||||
|
||||
return lfb_base;
|
||||
}
|
||||
|
||||
static inline void __screen_info_set_lfb_base(struct screen_info *si, u64 lfb_base)
|
||||
{
|
||||
si->lfb_base = lfb_base & GENMASK_ULL(31, 0);
|
||||
si->ext_lfb_base = (lfb_base & GENMASK_ULL(63, 32)) >> 32;
|
||||
|
||||
if (si->ext_lfb_base)
|
||||
si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
|
||||
else
|
||||
si->capabilities &= ~VIDEO_CAPABILITY_64BIT_BASE;
|
||||
}
|
||||
|
||||
static inline u64 __screen_info_lfb_size(const struct screen_info *si, unsigned int type)
|
||||
{
|
||||
u64 lfb_size = si->lfb_size;
|
||||
|
||||
if (type == VIDEO_TYPE_VLFB)
|
||||
lfb_size <<= 16;
|
||||
return lfb_size;
|
||||
}
|
||||
|
||||
static inline unsigned int __screen_info_video_type(unsigned int type)
|
||||
{
|
||||
switch (type) {
|
||||
case VIDEO_TYPE_MDA:
|
||||
case VIDEO_TYPE_CGA:
|
||||
case VIDEO_TYPE_EGAM:
|
||||
case VIDEO_TYPE_EGAC:
|
||||
case VIDEO_TYPE_VGAC:
|
||||
case VIDEO_TYPE_VLFB:
|
||||
case VIDEO_TYPE_PICA_S3:
|
||||
case VIDEO_TYPE_MIPS_G364:
|
||||
case VIDEO_TYPE_SGI:
|
||||
case VIDEO_TYPE_TGAC:
|
||||
case VIDEO_TYPE_SUN:
|
||||
case VIDEO_TYPE_SUNPCI:
|
||||
case VIDEO_TYPE_PMAC:
|
||||
case VIDEO_TYPE_EFI:
|
||||
return type;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* screen_info_video_type() - Decodes the video type from struct screen_info
|
||||
* @si: an instance of struct screen_info
|
||||
*
|
||||
* Returns:
|
||||
* A VIDEO_TYPE_ constant representing si's type of video display, or 0 otherwise.
|
||||
*/
|
||||
static inline unsigned int screen_info_video_type(const struct screen_info *si)
|
||||
{
|
||||
unsigned int type;
|
||||
|
||||
// check if display output is on
|
||||
if (!si->orig_video_isVGA)
|
||||
return 0;
|
||||
|
||||
// check for a known VIDEO_TYPE_ constant
|
||||
type = __screen_info_video_type(si->orig_video_isVGA);
|
||||
if (type)
|
||||
return si->orig_video_isVGA;
|
||||
|
||||
// check if text mode has been initialized
|
||||
if (!si->orig_video_lines || !si->orig_video_cols)
|
||||
return 0;
|
||||
|
||||
// 80x25 text, mono
|
||||
if (si->orig_video_mode == 0x07) {
|
||||
if ((si->orig_video_ega_bx & 0xff) != 0x10)
|
||||
return VIDEO_TYPE_EGAM;
|
||||
else
|
||||
return VIDEO_TYPE_MDA;
|
||||
}
|
||||
|
||||
// EGA/VGA, 16 colors
|
||||
if ((si->orig_video_ega_bx & 0xff) != 0x10) {
|
||||
if (si->orig_video_isVGA)
|
||||
return VIDEO_TYPE_VGAC;
|
||||
else
|
||||
return VIDEO_TYPE_EGAC;
|
||||
}
|
||||
|
||||
// the rest...
|
||||
return VIDEO_TYPE_CGA;
|
||||
}
|
||||
|
||||
ssize_t screen_info_resources(const struct screen_info *si, struct resource *r, size_t num);
|
||||
|
||||
#if defined(CONFIG_PCI)
|
||||
void screen_info_apply_fixups(void);
|
||||
struct pci_dev *screen_info_pci_dev(const struct screen_info *si);
|
||||
#else
|
||||
static inline void screen_info_apply_fixups(void)
|
||||
{ }
|
||||
static inline struct pci_dev *screen_info_pci_dev(const struct screen_info *si)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern struct screen_info screen_info;
|
||||
|
||||
#endif /* _SCREEN_INFO_H */
|
||||
|
||||
@@ -91,7 +91,8 @@ static inline void sysfb_set_efifb_fwnode(struct platform_device *pd)
|
||||
bool sysfb_parse_mode(const struct screen_info *si,
|
||||
struct simplefb_platform_data *mode);
|
||||
struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
|
||||
const struct simplefb_platform_data *mode);
|
||||
const struct simplefb_platform_data *mode,
|
||||
struct device *parent);
|
||||
|
||||
#else /* CONFIG_SYSFB_SIMPLE */
|
||||
|
||||
@@ -102,7 +103,8 @@ static inline bool sysfb_parse_mode(const struct screen_info *si,
|
||||
}
|
||||
|
||||
static inline struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
|
||||
const struct simplefb_platform_data *mode)
|
||||
const struct simplefb_platform_data *mode,
|
||||
struct device *parent)
|
||||
{
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user