Merge tag 'topic/drm-misc-2016-04-21' of git://anongit.freedesktop.org/drm-intel into drm-next
misc pull req all over. Biggest thing is the drm_connector_(un)register_all cleanup from Alexey for drivers without the load/unload midlayer hooks. I.e. all the new ones, and a bunch of the pending new atomic drivers depend upon this. Or at least I asked them to rebase ;-) * tag 'topic/drm-misc-2016-04-21' of git://anongit.freedesktop.org/drm-intel: drm: Make drm.debug parameter description more helpful drm: Remove warning from drm_connector_unregister_all() drm: probe_helper: Hide ugly ifdef drm: rcar-du: Use generic drm_connector_register_all() helper drm: atmel_hldc: Use generic drm_connector_register_all() helper drm: Introduce drm_connector_register_all() helper drm: fix lut value extraction function drm/atomic-helper: Print an error if vblank wait times out drm/dp/mst: Restore primary hub guid on resume drm: Release driver references to handle before making it available again drm/i915/dp/mst: Add source port info to debugfs output drm/dp/mst: Enhance DP MST debugfs output drm/edid: Add drm_edid_get_monitor_name() include/drm: Reword debug categories comment. drm/crtc_helper: Reset empty plane state in drm_helper_crtc_mode_set_base() drm/virtio: Drop dummy gamma table support drm/bochs: Drop fake gamma support drm/core: Fix ordering in drm_mode_config_cleanup.
This commit is contained in:
commit
d57d47735e
|
@ -584,34 +584,6 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
|
||||||
destroy_workqueue(dc->wq);
|
destroy_workqueue(dc->wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_hlcdc_dc_connector_plug_all(struct drm_device *dev)
|
|
||||||
{
|
|
||||||
struct drm_connector *connector, *failed;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mutex_lock(&dev->mode_config.mutex);
|
|
||||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
||||||
ret = drm_connector_register(connector);
|
|
||||||
if (ret) {
|
|
||||||
failed = connector;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex_unlock(&dev->mode_config.mutex);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
||||||
if (failed == connector)
|
|
||||||
break;
|
|
||||||
|
|
||||||
drm_connector_unregister(connector);
|
|
||||||
}
|
|
||||||
mutex_unlock(&dev->mode_config.mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void atmel_hlcdc_dc_connector_unplug_all(struct drm_device *dev)
|
static void atmel_hlcdc_dc_connector_unplug_all(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
mutex_lock(&dev->mode_config.mutex);
|
mutex_lock(&dev->mode_config.mutex);
|
||||||
|
@ -736,7 +708,7 @@ static int atmel_hlcdc_dc_drm_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_unload;
|
goto err_unload;
|
||||||
|
|
||||||
ret = atmel_hlcdc_dc_connector_plug_all(ddev);
|
ret = drm_connector_register_all(ddev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_unregister;
|
goto err_unregister;
|
||||||
|
|
||||||
|
|
|
@ -162,22 +162,7 @@ static int bochs_fbdev_destroy(struct bochs_device *bochs)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bochs_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
|
||||||
u16 blue, int regno)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void bochs_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
|
|
||||||
u16 *blue, int regno)
|
|
||||||
{
|
|
||||||
*red = regno;
|
|
||||||
*green = regno;
|
|
||||||
*blue = regno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct drm_fb_helper_funcs bochs_fb_helper_funcs = {
|
static const struct drm_fb_helper_funcs bochs_fb_helper_funcs = {
|
||||||
.gamma_set = bochs_fb_gamma_set,
|
|
||||||
.gamma_get = bochs_fb_gamma_get,
|
|
||||||
.fb_probe = bochsfb_create,
|
.fb_probe = bochsfb_create,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -93,11 +93,6 @@ static void bochs_crtc_commit(struct drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bochs_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
|
||||||
u16 *blue, uint32_t start, uint32_t size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bochs_crtc_page_flip(struct drm_crtc *crtc,
|
static int bochs_crtc_page_flip(struct drm_crtc *crtc,
|
||||||
struct drm_framebuffer *fb,
|
struct drm_framebuffer *fb,
|
||||||
struct drm_pending_vblank_event *event,
|
struct drm_pending_vblank_event *event,
|
||||||
|
@ -120,7 +115,6 @@ static int bochs_crtc_page_flip(struct drm_crtc *crtc,
|
||||||
|
|
||||||
/* These provide the minimum set of functions required to handle a CRTC */
|
/* These provide the minimum set of functions required to handle a CRTC */
|
||||||
static const struct drm_crtc_funcs bochs_crtc_funcs = {
|
static const struct drm_crtc_funcs bochs_crtc_funcs = {
|
||||||
.gamma_set = bochs_crtc_gamma_set,
|
|
||||||
.set_config = drm_crtc_helper_set_config,
|
.set_config = drm_crtc_helper_set_config,
|
||||||
.destroy = drm_crtc_cleanup,
|
.destroy = drm_crtc_cleanup,
|
||||||
.page_flip = bochs_crtc_page_flip,
|
.page_flip = bochs_crtc_page_flip,
|
||||||
|
@ -140,7 +134,6 @@ static void bochs_crtc_init(struct drm_device *dev)
|
||||||
struct drm_crtc *crtc = &bochs->crtc;
|
struct drm_crtc *crtc = &bochs->crtc;
|
||||||
|
|
||||||
drm_crtc_init(dev, crtc, &bochs_crtc_funcs);
|
drm_crtc_init(dev, crtc, &bochs_crtc_funcs);
|
||||||
drm_mode_crtc_set_gamma_size(crtc, 256);
|
|
||||||
drm_crtc_helper_add(crtc, &bochs_helper_funcs);
|
drm_crtc_helper_add(crtc, &bochs_helper_funcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1103,6 +1103,8 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
|
||||||
drm_crtc_vblank_count(crtc),
|
drm_crtc_vblank_count(crtc),
|
||||||
msecs_to_jiffies(50));
|
msecs_to_jiffies(50));
|
||||||
|
|
||||||
|
WARN(!ret, "[CRTC:%d] vblank wait timed out\n", crtc->base.id);
|
||||||
|
|
||||||
drm_crtc_vblank_put(crtc);
|
drm_crtc_vblank_put(crtc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1067,6 +1067,46 @@ void drm_connector_unregister(struct drm_connector *connector)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_connector_unregister);
|
EXPORT_SYMBOL(drm_connector_unregister);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_connector_register_all - register all connectors
|
||||||
|
* @dev: drm device
|
||||||
|
*
|
||||||
|
* This function registers all connectors in sysfs and other places so that
|
||||||
|
* userspace can start to access them. Drivers can call it after calling
|
||||||
|
* drm_dev_register() to complete the device registration, if they don't call
|
||||||
|
* drm_connector_register() on each connector individually.
|
||||||
|
*
|
||||||
|
* When a device is unplugged and should be removed from userspace access,
|
||||||
|
* call drm_connector_unregister_all(), which is the inverse of this
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Zero on success, error code on failure.
|
||||||
|
*/
|
||||||
|
int drm_connector_register_all(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_connector *connector;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&dev->mode_config.mutex);
|
||||||
|
|
||||||
|
drm_for_each_connector(connector, dev) {
|
||||||
|
ret = drm_connector_register(connector);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&dev->mode_config.mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
mutex_unlock(&dev->mode_config.mutex);
|
||||||
|
drm_connector_unregister_all(dev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_connector_register_all);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_connector_unregister_all - unregister connector userspace interfaces
|
* drm_connector_unregister_all - unregister connector userspace interfaces
|
||||||
* @dev: drm device
|
* @dev: drm device
|
||||||
|
@ -1082,7 +1122,7 @@ void drm_connector_unregister_all(struct drm_device *dev)
|
||||||
struct drm_connector *connector;
|
struct drm_connector *connector;
|
||||||
|
|
||||||
/* FIXME: taking the mode config mutex ends up in a clash with sysfs */
|
/* FIXME: taking the mode config mutex ends up in a clash with sysfs */
|
||||||
drm_for_each_connector(connector, dev)
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
||||||
drm_connector_unregister(connector);
|
drm_connector_unregister(connector);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_connector_unregister_all);
|
EXPORT_SYMBOL(drm_connector_unregister_all);
|
||||||
|
@ -5914,6 +5954,15 @@ void drm_mode_config_cleanup(struct drm_device *dev)
|
||||||
drm_property_destroy(dev, property);
|
drm_property_destroy(dev, property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
|
||||||
|
head) {
|
||||||
|
plane->funcs->destroy(plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
|
||||||
|
crtc->funcs->destroy(crtc);
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
|
list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
|
||||||
head_global) {
|
head_global) {
|
||||||
drm_property_unreference_blob(blob);
|
drm_property_unreference_blob(blob);
|
||||||
|
@ -5932,15 +5981,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
|
||||||
drm_framebuffer_free(&fb->refcount);
|
drm_framebuffer_free(&fb->refcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
|
|
||||||
head) {
|
|
||||||
plane->funcs->destroy(plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
|
|
||||||
crtc->funcs->destroy(crtc);
|
|
||||||
}
|
|
||||||
|
|
||||||
ida_destroy(&dev->mode_config.connector_ida);
|
ida_destroy(&dev->mode_config.connector_ida);
|
||||||
idr_destroy(&dev->mode_config.tile_idr);
|
idr_destroy(&dev->mode_config.tile_idr);
|
||||||
idr_destroy(&dev->mode_config.crtc_idr);
|
idr_destroy(&dev->mode_config.crtc_idr);
|
||||||
|
|
|
@ -1053,10 +1053,12 @@ int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
|
||||||
|
|
||||||
if (plane->funcs->atomic_duplicate_state)
|
if (plane->funcs->atomic_duplicate_state)
|
||||||
plane_state = plane->funcs->atomic_duplicate_state(plane);
|
plane_state = plane->funcs->atomic_duplicate_state(plane);
|
||||||
else if (plane->state)
|
else {
|
||||||
|
if (!plane->state)
|
||||||
|
drm_atomic_helper_plane_reset(plane);
|
||||||
|
|
||||||
plane_state = drm_atomic_helper_plane_duplicate_state(plane);
|
plane_state = drm_atomic_helper_plane_duplicate_state(plane);
|
||||||
else
|
}
|
||||||
plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
|
|
||||||
if (!plane_state)
|
if (!plane_state)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
plane_state->plane = plane;
|
plane_state->plane = plane;
|
||||||
|
|
|
@ -2121,6 +2121,8 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr)
|
||||||
|
|
||||||
if (mgr->mst_primary) {
|
if (mgr->mst_primary) {
|
||||||
int sret;
|
int sret;
|
||||||
|
u8 guid[16];
|
||||||
|
|
||||||
sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
|
sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
|
||||||
if (sret != DP_RECEIVER_CAP_SIZE) {
|
if (sret != DP_RECEIVER_CAP_SIZE) {
|
||||||
DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
|
DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
|
||||||
|
@ -2135,6 +2137,16 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some hubs forget their guids after they resume */
|
||||||
|
sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
|
||||||
|
if (sret != 16) {
|
||||||
|
DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
|
||||||
|
ret = -1;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
drm_dp_check_mstb_guid(mgr->mst_primary, guid);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else
|
} else
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -2729,7 +2741,7 @@ static void drm_dp_mst_dump_mstb(struct seq_file *m,
|
||||||
|
|
||||||
seq_printf(m, "%smst: %p, %d\n", prefix, mstb, mstb->num_ports);
|
seq_printf(m, "%smst: %p, %d\n", prefix, mstb, mstb->num_ports);
|
||||||
list_for_each_entry(port, &mstb->ports, next) {
|
list_for_each_entry(port, &mstb->ports, next) {
|
||||||
seq_printf(m, "%sport: %d: ddps: %d ldps: %d, sdp: %d/%d, %p, conn: %p\n", prefix, port->port_num, port->ddps, port->ldps, port->num_sdp_streams, port->num_sdp_stream_sinks, port, port->connector);
|
seq_printf(m, "%sport: %d: input: %d: pdt: %d, ddps: %d ldps: %d, sdp: %d/%d, %p, conn: %p\n", prefix, port->port_num, port->input, port->pdt, port->ddps, port->ldps, port->num_sdp_streams, port->num_sdp_stream_sinks, port, port->connector);
|
||||||
if (port->mstb)
|
if (port->mstb)
|
||||||
drm_dp_mst_dump_mstb(m, port->mstb);
|
drm_dp_mst_dump_mstb(m, port->mstb);
|
||||||
}
|
}
|
||||||
|
@ -2750,6 +2762,16 @@ static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fetch_monitor_name(struct drm_dp_mst_topology_mgr *mgr,
|
||||||
|
struct drm_dp_mst_port *port, char *name,
|
||||||
|
int namelen)
|
||||||
|
{
|
||||||
|
struct edid *mst_edid;
|
||||||
|
|
||||||
|
mst_edid = drm_dp_mst_get_edid(port->connector, mgr, port);
|
||||||
|
drm_edid_get_monitor_name(mst_edid, name, namelen);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_dp_mst_dump_topology(): dump topology to seq file.
|
* drm_dp_mst_dump_topology(): dump topology to seq file.
|
||||||
* @m: seq_file to dump output to
|
* @m: seq_file to dump output to
|
||||||
|
@ -2762,6 +2784,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct drm_dp_mst_port *port;
|
struct drm_dp_mst_port *port;
|
||||||
|
|
||||||
mutex_lock(&mgr->lock);
|
mutex_lock(&mgr->lock);
|
||||||
if (mgr->mst_primary)
|
if (mgr->mst_primary)
|
||||||
drm_dp_mst_dump_mstb(m, mgr->mst_primary);
|
drm_dp_mst_dump_mstb(m, mgr->mst_primary);
|
||||||
|
@ -2770,14 +2793,21 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
|
||||||
mutex_unlock(&mgr->lock);
|
mutex_unlock(&mgr->lock);
|
||||||
|
|
||||||
mutex_lock(&mgr->payload_lock);
|
mutex_lock(&mgr->payload_lock);
|
||||||
seq_printf(m, "vcpi: %lx %lx\n", mgr->payload_mask, mgr->vcpi_mask);
|
seq_printf(m, "vcpi: %lx %lx %d\n", mgr->payload_mask, mgr->vcpi_mask,
|
||||||
|
mgr->max_payloads);
|
||||||
|
|
||||||
for (i = 0; i < mgr->max_payloads; i++) {
|
for (i = 0; i < mgr->max_payloads; i++) {
|
||||||
if (mgr->proposed_vcpis[i]) {
|
if (mgr->proposed_vcpis[i]) {
|
||||||
|
char name[14];
|
||||||
|
|
||||||
port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
|
port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
|
||||||
seq_printf(m, "vcpi %d: %d %d %d\n", i, port->port_num, port->vcpi.vcpi, port->vcpi.num_slots);
|
fetch_monitor_name(mgr, port, name, sizeof(name));
|
||||||
|
seq_printf(m, "vcpi %d: %d %d %d sink name: %s\n", i,
|
||||||
|
port->port_num, port->vcpi.vcpi,
|
||||||
|
port->vcpi.num_slots,
|
||||||
|
(*name != 0) ? name : "Unknown");
|
||||||
} else
|
} else
|
||||||
seq_printf(m, "vcpi %d:unsed\n", i);
|
seq_printf(m, "vcpi %d:unused\n", i);
|
||||||
}
|
}
|
||||||
for (i = 0; i < mgr->max_payloads; i++) {
|
for (i = 0; i < mgr->max_payloads; i++) {
|
||||||
seq_printf(m, "payload %d: %d, %d, %d\n",
|
seq_printf(m, "payload %d: %d, %d, %d\n",
|
||||||
|
@ -2817,8 +2847,9 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
|
||||||
for (i = 0; i < 0x3; i++)
|
for (i = 0; i < 0x3; i++)
|
||||||
seq_printf(m, "%02x", buf[i]);
|
seq_printf(m, "%02x", buf[i]);
|
||||||
seq_printf(m, " devid: ");
|
seq_printf(m, " devid: ");
|
||||||
for (i = 0x3; i < 0x8; i++)
|
for (i = 0x3; i < 0x8 && buf[i]; i++)
|
||||||
seq_printf(m, "%c", buf[i]);
|
seq_printf(m, "%c", buf[i]);
|
||||||
|
|
||||||
seq_printf(m, " revision: hw: %x.%x sw: %x.%x", buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]);
|
seq_printf(m, " revision: hw: %x.%x sw: %x.%x", buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]);
|
||||||
seq_printf(m, "\n");
|
seq_printf(m, "\n");
|
||||||
bret = dump_dp_payload_table(mgr, buf);
|
bret = dump_dp_payload_table(mgr, buf);
|
||||||
|
|
|
@ -37,13 +37,23 @@
|
||||||
#include "drm_legacy.h"
|
#include "drm_legacy.h"
|
||||||
#include "drm_internal.h"
|
#include "drm_internal.h"
|
||||||
|
|
||||||
unsigned int drm_debug = 0; /* bitmask of DRM_UT_x */
|
/*
|
||||||
|
* drm_debug: Enable debug output.
|
||||||
|
* Bitmask of DRM_UT_x. See include/drm/drmP.h for details.
|
||||||
|
*/
|
||||||
|
unsigned int drm_debug = 0;
|
||||||
EXPORT_SYMBOL(drm_debug);
|
EXPORT_SYMBOL(drm_debug);
|
||||||
|
|
||||||
MODULE_AUTHOR(CORE_AUTHOR);
|
MODULE_AUTHOR(CORE_AUTHOR);
|
||||||
MODULE_DESCRIPTION(CORE_DESC);
|
MODULE_DESCRIPTION(CORE_DESC);
|
||||||
MODULE_LICENSE("GPL and additional rights");
|
MODULE_LICENSE("GPL and additional rights");
|
||||||
MODULE_PARM_DESC(debug, "Enable debug output");
|
MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug category.\n"
|
||||||
|
"\t\tBit 0 (0x01) will enable CORE messages (drm core code)\n"
|
||||||
|
"\t\tBit 1 (0x02) will enable DRIVER messages (drm controller code)\n"
|
||||||
|
"\t\tBit 2 (0x04) will enable KMS messages (modesetting code)\n"
|
||||||
|
"\t\tBit 3 (0x08) will enable PRIME messages (prime code)\n"
|
||||||
|
"\t\tBit 4 (0x10) will enable ATOMIC messages (atomic code)\n"
|
||||||
|
"\t\tBit 5 (0x20) will enable VBL messages (vblank code)");
|
||||||
module_param_named(debug, drm_debug, int, 0600);
|
module_param_named(debug, drm_debug, int, 0600);
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(drm_minor_lock);
|
static DEFINE_SPINLOCK(drm_minor_lock);
|
||||||
|
@ -715,7 +725,11 @@ EXPORT_SYMBOL(drm_dev_unref);
|
||||||
*
|
*
|
||||||
* Register the DRM device @dev with the system, advertise device to user-space
|
* Register the DRM device @dev with the system, advertise device to user-space
|
||||||
* and start normal device operation. @dev must be allocated via drm_dev_alloc()
|
* and start normal device operation. @dev must be allocated via drm_dev_alloc()
|
||||||
* previously.
|
* previously. Right after drm_dev_register() the driver should call
|
||||||
|
* drm_connector_register_all() to register all connectors in sysfs. This is
|
||||||
|
* a separate call for backward compatibility with drivers still using
|
||||||
|
* the deprecated ->load() callback, where connectors are registered from within
|
||||||
|
* the ->load() callback.
|
||||||
*
|
*
|
||||||
* Never call this twice on any device!
|
* Never call this twice on any device!
|
||||||
*
|
*
|
||||||
|
|
|
@ -3293,6 +3293,46 @@ monitor_name(struct detailed_timing *t, void *data)
|
||||||
*(u8 **)data = t->data.other_data.data.str.str;
|
*(u8 **)data = t->data.other_data.data.str.str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_monitor_name(struct edid *edid, char name[13])
|
||||||
|
{
|
||||||
|
char *edid_name = NULL;
|
||||||
|
int mnl;
|
||||||
|
|
||||||
|
if (!edid || !name)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
drm_for_each_detailed_block((u8 *)edid, monitor_name, &edid_name);
|
||||||
|
for (mnl = 0; edid_name && mnl < 13; mnl++) {
|
||||||
|
if (edid_name[mnl] == 0x0a)
|
||||||
|
break;
|
||||||
|
|
||||||
|
name[mnl] = edid_name[mnl];
|
||||||
|
}
|
||||||
|
|
||||||
|
return mnl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_edid_get_monitor_name - fetch the monitor name from the edid
|
||||||
|
* @edid: monitor EDID information
|
||||||
|
* @name: pointer to a character array to hold the name of the monitor
|
||||||
|
* @bufsize: The size of the name buffer (should be at least 14 chars.)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void drm_edid_get_monitor_name(struct edid *edid, char *name, int bufsize)
|
||||||
|
{
|
||||||
|
int name_length;
|
||||||
|
char buf[13];
|
||||||
|
|
||||||
|
if (bufsize <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
name_length = min(get_monitor_name(edid, buf), bufsize - 1);
|
||||||
|
memcpy(name, buf, name_length);
|
||||||
|
name[name_length] = '\0';
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_edid_get_monitor_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_edid_to_eld - build ELD from EDID
|
* drm_edid_to_eld - build ELD from EDID
|
||||||
* @connector: connector corresponding to the HDMI/DP sink
|
* @connector: connector corresponding to the HDMI/DP sink
|
||||||
|
@ -3306,7 +3346,6 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
|
||||||
{
|
{
|
||||||
uint8_t *eld = connector->eld;
|
uint8_t *eld = connector->eld;
|
||||||
u8 *cea;
|
u8 *cea;
|
||||||
u8 *name;
|
|
||||||
u8 *db;
|
u8 *db;
|
||||||
int total_sad_count = 0;
|
int total_sad_count = 0;
|
||||||
int mnl;
|
int mnl;
|
||||||
|
@ -3320,14 +3359,8 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = NULL;
|
mnl = get_monitor_name(edid, eld + 20);
|
||||||
drm_for_each_detailed_block((u8 *)edid, monitor_name, &name);
|
|
||||||
/* max: 13 bytes EDID, 16 bytes ELD */
|
|
||||||
for (mnl = 0; name && mnl < 13; mnl++) {
|
|
||||||
if (name[mnl] == 0x0a)
|
|
||||||
break;
|
|
||||||
eld[20 + mnl] = name[mnl];
|
|
||||||
}
|
|
||||||
eld[4] = (cea[1] << 5) | mnl;
|
eld[4] = (cea[1] << 5) | mnl;
|
||||||
DRM_DEBUG_KMS("ELD monitor %s\n", eld + 20);
|
DRM_DEBUG_KMS("ELD monitor %s\n", eld + 20);
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,6 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
|
||||||
int
|
int
|
||||||
drm_gem_handle_delete(struct drm_file *filp, u32 handle)
|
drm_gem_handle_delete(struct drm_file *filp, u32 handle)
|
||||||
{
|
{
|
||||||
struct drm_device *dev;
|
|
||||||
struct drm_gem_object *obj;
|
struct drm_gem_object *obj;
|
||||||
|
|
||||||
/* This is gross. The idr system doesn't let us try a delete and
|
/* This is gross. The idr system doesn't let us try a delete and
|
||||||
|
@ -294,18 +293,19 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
|
||||||
spin_lock(&filp->table_lock);
|
spin_lock(&filp->table_lock);
|
||||||
|
|
||||||
/* Check if we currently have a reference on the object */
|
/* Check if we currently have a reference on the object */
|
||||||
obj = idr_find(&filp->object_idr, handle);
|
obj = idr_replace(&filp->object_idr, NULL, handle);
|
||||||
if (obj == NULL) {
|
spin_unlock(&filp->table_lock);
|
||||||
spin_unlock(&filp->table_lock);
|
if (IS_ERR_OR_NULL(obj))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
|
||||||
dev = obj->dev;
|
|
||||||
|
|
||||||
/* Release reference and decrement refcount. */
|
/* Release driver's reference and decrement refcount. */
|
||||||
|
drm_gem_object_release_handle(handle, obj, filp);
|
||||||
|
|
||||||
|
/* And finally make the handle available for future allocations. */
|
||||||
|
spin_lock(&filp->table_lock);
|
||||||
idr_remove(&filp->object_idr, handle);
|
idr_remove(&filp->object_idr, handle);
|
||||||
spin_unlock(&filp->table_lock);
|
spin_unlock(&filp->table_lock);
|
||||||
|
|
||||||
drm_gem_object_release_handle(handle, obj, filp);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_gem_handle_delete);
|
EXPORT_SYMBOL(drm_gem_handle_delete);
|
||||||
|
|
|
@ -264,10 +264,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
||||||
count = drm_add_edid_modes(connector, edid);
|
count = drm_add_edid_modes(connector, edid);
|
||||||
drm_edid_to_eld(connector, edid);
|
drm_edid_to_eld(connector, edid);
|
||||||
} else {
|
} else {
|
||||||
#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
|
|
||||||
count = drm_load_edid_firmware(connector);
|
count = drm_load_edid_firmware(connector);
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
#endif
|
|
||||||
count = (*connector_funcs->get_modes)(connector);
|
count = (*connector_funcs->get_modes)(connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3434,7 +3434,8 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused)
|
||||||
intel_dig_port = enc_to_dig_port(encoder);
|
intel_dig_port = enc_to_dig_port(encoder);
|
||||||
if (!intel_dig_port->dp.can_mst)
|
if (!intel_dig_port->dp.can_mst)
|
||||||
continue;
|
continue;
|
||||||
|
seq_printf(m, "MST Source Port %c\n",
|
||||||
|
port_name(intel_dig_port->port));
|
||||||
drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr);
|
drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr);
|
||||||
}
|
}
|
||||||
drm_modeset_unlock_all(dev);
|
drm_modeset_unlock_all(dev);
|
||||||
|
|
|
@ -361,14 +361,7 @@ static int rcar_du_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
mutex_lock(&ddev->mode_config.mutex);
|
ret = drm_connector_register_all(ddev);
|
||||||
drm_for_each_connector(connector, ddev) {
|
|
||||||
ret = drm_connector_register(connector);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mutex_unlock(&ddev->mode_config.mutex);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
|
@ -38,13 +38,6 @@
|
||||||
#define XRES_MAX 8192
|
#define XRES_MAX 8192
|
||||||
#define YRES_MAX 8192
|
#define YRES_MAX 8192
|
||||||
|
|
||||||
static void virtio_gpu_crtc_gamma_set(struct drm_crtc *crtc,
|
|
||||||
u16 *red, u16 *green, u16 *blue,
|
|
||||||
uint32_t start, uint32_t size)
|
|
||||||
{
|
|
||||||
/* TODO */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virtio_gpu_hide_cursor(struct virtio_gpu_device *vgdev,
|
virtio_gpu_hide_cursor(struct virtio_gpu_device *vgdev,
|
||||||
struct virtio_gpu_output *output)
|
struct virtio_gpu_output *output)
|
||||||
|
@ -173,7 +166,6 @@ static int virtio_gpu_page_flip(struct drm_crtc *crtc,
|
||||||
static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
|
static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
|
||||||
.cursor_set2 = virtio_gpu_crtc_cursor_set,
|
.cursor_set2 = virtio_gpu_crtc_cursor_set,
|
||||||
.cursor_move = virtio_gpu_crtc_cursor_move,
|
.cursor_move = virtio_gpu_crtc_cursor_move,
|
||||||
.gamma_set = virtio_gpu_crtc_gamma_set,
|
|
||||||
.set_config = drm_atomic_helper_set_config,
|
.set_config = drm_atomic_helper_set_config,
|
||||||
.destroy = drm_crtc_cleanup,
|
.destroy = drm_crtc_cleanup,
|
||||||
|
|
||||||
|
@ -416,7 +408,6 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
|
||||||
return PTR_ERR(plane);
|
return PTR_ERR(plane);
|
||||||
drm_crtc_init_with_planes(dev, crtc, plane, NULL,
|
drm_crtc_init_with_planes(dev, crtc, plane, NULL,
|
||||||
&virtio_gpu_crtc_funcs, NULL);
|
&virtio_gpu_crtc_funcs, NULL);
|
||||||
drm_mode_crtc_set_gamma_size(crtc, 256);
|
|
||||||
drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs);
|
drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs);
|
||||||
plane->crtc = crtc;
|
plane->crtc = crtc;
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ struct reservation_object;
|
||||||
struct dma_buf_attachment;
|
struct dma_buf_attachment;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 4 debug categories are defined:
|
* The following categories are defined:
|
||||||
*
|
*
|
||||||
* CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c, drm_memory.c, ...
|
* CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c, drm_memory.c, ...
|
||||||
* This is the category used by the DRM_DEBUG() macro.
|
* This is the category used by the DRM_DEBUG() macro.
|
||||||
|
|
|
@ -2249,7 +2249,8 @@ static inline unsigned drm_connector_index(struct drm_connector *connector)
|
||||||
return connector->connector_id;
|
return connector->connector_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* helper to unregister all connectors from sysfs for device */
|
/* helpers to {un}register all connectors from sysfs for device */
|
||||||
|
extern int drm_connector_register_all(struct drm_device *dev);
|
||||||
extern void drm_connector_unregister_all(struct drm_device *dev);
|
extern void drm_connector_unregister_all(struct drm_device *dev);
|
||||||
|
|
||||||
extern int drm_bridge_add(struct drm_bridge *bridge);
|
extern int drm_bridge_add(struct drm_bridge *bridge);
|
||||||
|
@ -2500,6 +2501,8 @@ extern int drm_edid_header_is_valid(const u8 *raw_edid);
|
||||||
extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
|
extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
|
||||||
bool *edid_corrupt);
|
bool *edid_corrupt);
|
||||||
extern bool drm_edid_is_valid(struct edid *edid);
|
extern bool drm_edid_is_valid(struct edid *edid);
|
||||||
|
extern void drm_edid_get_monitor_name(struct edid *edid, char *name,
|
||||||
|
int buflen);
|
||||||
|
|
||||||
extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
|
extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
|
||||||
char topology[8]);
|
char topology[8]);
|
||||||
|
@ -2590,10 +2593,14 @@ static inline struct drm_property *drm_property_find(struct drm_device *dev,
|
||||||
static inline uint32_t drm_color_lut_extract(uint32_t user_input,
|
static inline uint32_t drm_color_lut_extract(uint32_t user_input,
|
||||||
uint32_t bit_precision)
|
uint32_t bit_precision)
|
||||||
{
|
{
|
||||||
uint32_t val = user_input + (1 << (16 - bit_precision - 1));
|
uint32_t val = user_input;
|
||||||
uint32_t max = 0xffff >> (16 - bit_precision);
|
uint32_t max = 0xffff >> (16 - bit_precision);
|
||||||
|
|
||||||
val >>= 16 - bit_precision;
|
/* Round only if we're not using full precision. */
|
||||||
|
if (bit_precision < 16) {
|
||||||
|
val += 1UL << (16 - bit_precision - 1);
|
||||||
|
val >>= 16 - bit_precision;
|
||||||
|
}
|
||||||
|
|
||||||
return clamp_val(val, 0, max);
|
return clamp_val(val, 0, max);
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,7 +328,15 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
|
||||||
int drm_av_sync_delay(struct drm_connector *connector,
|
int drm_av_sync_delay(struct drm_connector *connector,
|
||||||
const struct drm_display_mode *mode);
|
const struct drm_display_mode *mode);
|
||||||
struct drm_connector *drm_select_eld(struct drm_encoder *encoder);
|
struct drm_connector *drm_select_eld(struct drm_encoder *encoder);
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
|
||||||
int drm_load_edid_firmware(struct drm_connector *connector);
|
int drm_load_edid_firmware(struct drm_connector *connector);
|
||||||
|
#else
|
||||||
|
static inline int drm_load_edid_firmware(struct drm_connector *connector)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
|
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
|
||||||
|
|
Loading…
Reference in New Issue