Merge tag 'drm-misc-next-2018-07-18' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 4.19: Core Changes: - add support for DisplayPort CEC-Tunneling-over-AUX (Hans Verkuil) - more doc updates (Daniel Vetter) - fourcc: Add is_yuv field to drm_format_info (Ayan Kumar Halder) - dma-buf: correctly place BUG_ON (Michel Dänzer) Driver Changes: - more vkms support(Rodrigo Siqueira) - many fixes and small improments to all drivers Signed-off-by: Dave Airlie <airlied@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180718200826.GA20165@juma
This commit is contained in:
@@ -109,6 +109,15 @@ Framebuffer CMA Helper Functions Reference
|
|||||||
|
|
||||||
.. _drm_bridges:
|
.. _drm_bridges:
|
||||||
|
|
||||||
|
Framebuffer GEM Helper Reference
|
||||||
|
================================
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c
|
||||||
|
:doc: overview
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c
|
||||||
|
:export:
|
||||||
|
|
||||||
Bridges
|
Bridges
|
||||||
=======
|
=======
|
||||||
|
|
||||||
@@ -169,6 +178,15 @@ Display Port Helper Functions Reference
|
|||||||
.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c
|
.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c
|
||||||
:export:
|
:export:
|
||||||
|
|
||||||
|
Display Port CEC Helper Functions Reference
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/drm_dp_cec.c
|
||||||
|
:doc: dp cec helpers
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/drm_dp_cec.c
|
||||||
|
:export:
|
||||||
|
|
||||||
Display Port Dual Mode Adaptor Helper Functions Reference
|
Display Port Dual Mode Adaptor Helper Functions Reference
|
||||||
=========================================================
|
=========================================================
|
||||||
|
|
||||||
@@ -282,13 +300,13 @@ Auxiliary Modeset Helpers
|
|||||||
.. kernel-doc:: drivers/gpu/drm/drm_modeset_helper.c
|
.. kernel-doc:: drivers/gpu/drm/drm_modeset_helper.c
|
||||||
:export:
|
:export:
|
||||||
|
|
||||||
Framebuffer GEM Helper Reference
|
OF/DT Helpers
|
||||||
================================
|
=============
|
||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c
|
.. kernel-doc:: drivers/gpu/drm/drm_of.c
|
||||||
:doc: overview
|
:doc: overview
|
||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c
|
.. kernel-doc:: drivers/gpu/drm/drm_of.c
|
||||||
:export:
|
:export:
|
||||||
|
|
||||||
Legacy Plane Helper Reference
|
Legacy Plane Helper Reference
|
||||||
|
|||||||
@@ -56,11 +56,12 @@ Overview
|
|||||||
|
|
||||||
The basic object structure KMS presents to userspace is fairly simple.
|
The basic object structure KMS presents to userspace is fairly simple.
|
||||||
Framebuffers (represented by :c:type:`struct drm_framebuffer <drm_framebuffer>`,
|
Framebuffers (represented by :c:type:`struct drm_framebuffer <drm_framebuffer>`,
|
||||||
see `Frame Buffer Abstraction`_) feed into planes. One or more (or even no)
|
see `Frame Buffer Abstraction`_) feed into planes. Planes are represented by
|
||||||
planes feed their pixel data into a CRTC (represented by :c:type:`struct
|
:c:type:`struct drm_plane <drm_plane>`, see `Plane Abstraction`_ for more
|
||||||
drm_crtc <drm_crtc>`, see `CRTC Abstraction`_) for blending. The precise
|
details. One or more (or even no) planes feed their pixel data into a CRTC
|
||||||
blending step is explained in more detail in `Plane Composition Properties`_ and
|
(represented by :c:type:`struct drm_crtc <drm_crtc>`, see `CRTC Abstraction`_)
|
||||||
related chapters.
|
for blending. The precise blending step is explained in more detail in `Plane
|
||||||
|
Composition Properties`_ and related chapters.
|
||||||
|
|
||||||
For the output routing the first step is encoders (represented by
|
For the output routing the first step is encoders (represented by
|
||||||
:c:type:`struct drm_encoder <drm_encoder>`, see `Encoder Abstraction`_). Those
|
:c:type:`struct drm_encoder <drm_encoder>`, see `Encoder Abstraction`_). Those
|
||||||
@@ -466,7 +467,7 @@ Output discovery and initialization example
|
|||||||
drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
|
drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
|
||||||
DRM_MODE_ENCODER_DAC);
|
DRM_MODE_ENCODER_DAC);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(&intel_output->base,
|
drm_connector_attach_encoder(&intel_output->base,
|
||||||
&intel_output->enc);
|
&intel_output->enc);
|
||||||
|
|
||||||
/* Set up the DDC bus. */
|
/* Set up the DDC bus. */
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ reservation_object_add_shared_inplace(struct reservation_object *obj,
|
|||||||
if (signaled) {
|
if (signaled) {
|
||||||
RCU_INIT_POINTER(fobj->shared[signaled_idx], fence);
|
RCU_INIT_POINTER(fobj->shared[signaled_idx], fence);
|
||||||
} else {
|
} else {
|
||||||
|
BUG_ON(fobj->shared_count >= fobj->shared_max);
|
||||||
RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
|
RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
|
||||||
fobj->shared_count++;
|
fobj->shared_count++;
|
||||||
}
|
}
|
||||||
@@ -230,10 +231,9 @@ void reservation_object_add_shared_fence(struct reservation_object *obj,
|
|||||||
old = reservation_object_get_list(obj);
|
old = reservation_object_get_list(obj);
|
||||||
obj->staged = NULL;
|
obj->staged = NULL;
|
||||||
|
|
||||||
if (!fobj) {
|
if (!fobj)
|
||||||
BUG_ON(old->shared_count >= old->shared_max);
|
|
||||||
reservation_object_add_shared_inplace(obj, old, fence);
|
reservation_object_add_shared_inplace(obj, old, fence);
|
||||||
} else
|
else
|
||||||
reservation_object_add_shared_replace(obj, old, fobj, fence);
|
reservation_object_add_shared_replace(obj, old, fobj, fence);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(reservation_object_add_shared_fence);
|
EXPORT_SYMBOL(reservation_object_add_shared_fence);
|
||||||
|
|||||||
@@ -122,6 +122,16 @@ config DRM_LOAD_EDID_FIRMWARE
|
|||||||
default case is N. Details and instructions how to build your own
|
default case is N. Details and instructions how to build your own
|
||||||
EDID data are given in Documentation/EDID/HOWTO.txt.
|
EDID data are given in Documentation/EDID/HOWTO.txt.
|
||||||
|
|
||||||
|
config DRM_DP_CEC
|
||||||
|
bool "Enable DisplayPort CEC-Tunneling-over-AUX HDMI support"
|
||||||
|
select CEC_CORE
|
||||||
|
help
|
||||||
|
Choose this option if you want to enable HDMI CEC support for
|
||||||
|
DisplayPort/USB-C to HDMI adapters.
|
||||||
|
|
||||||
|
Note: not all adapters support this feature, and even for those
|
||||||
|
that do support this they often do not hook up the CEC pin.
|
||||||
|
|
||||||
config DRM_TTM
|
config DRM_TTM
|
||||||
tristate
|
tristate
|
||||||
depends on DRM && MMU
|
depends on DRM && MMU
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
|
|||||||
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
|
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
|
||||||
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
|
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
|
||||||
drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
|
drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
|
||||||
|
drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
|
||||||
|
|
||||||
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
|
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
|
||||||
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
|
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
|
||||||
|
|||||||
@@ -334,11 +334,11 @@ static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (amdgpu_connector->edid) {
|
if (amdgpu_connector->edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, amdgpu_connector->edid);
|
drm_connector_update_edid_property(connector, amdgpu_connector->edid);
|
||||||
ret = drm_add_edid_modes(connector, amdgpu_connector->edid);
|
ret = drm_add_edid_modes(connector, amdgpu_connector->edid);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
drm_mode_connector_update_edid_property(connector, NULL);
|
drm_connector_update_edid_property(connector, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ amdgpu_link_encoder_connector(struct drm_device *dev)
|
|||||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||||
amdgpu_encoder = to_amdgpu_encoder(encoder);
|
amdgpu_encoder = to_amdgpu_encoder(encoder);
|
||||||
if (amdgpu_encoder->devices & amdgpu_connector->devices) {
|
if (amdgpu_encoder->devices & amdgpu_connector->devices) {
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||||
amdgpu_atombios_encoder_init_backlight(amdgpu_encoder, connector);
|
amdgpu_atombios_encoder_init_backlight(amdgpu_encoder, connector);
|
||||||
adev->mode_info.bl_encoder = amdgpu_encoder;
|
adev->mode_info.bl_encoder = amdgpu_encoder;
|
||||||
|
|||||||
@@ -627,7 +627,7 @@ static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
|
|||||||
drm_connector_register(connector);
|
drm_connector_register(connector);
|
||||||
|
|
||||||
/* link them */
|
/* link them */
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -903,14 +903,14 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
|
|||||||
(struct edid *) sink->dc_edid.raw_edid;
|
(struct edid *) sink->dc_edid.raw_edid;
|
||||||
|
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector,
|
drm_connector_update_edid_property(connector,
|
||||||
aconnector->edid);
|
aconnector->edid);
|
||||||
}
|
}
|
||||||
amdgpu_dm_add_sink_to_freesync_module(connector, aconnector->edid);
|
amdgpu_dm_add_sink_to_freesync_module(connector, aconnector->edid);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
amdgpu_dm_remove_sink_from_freesync_module(connector);
|
amdgpu_dm_remove_sink_from_freesync_module(connector);
|
||||||
drm_mode_connector_update_edid_property(connector, NULL);
|
drm_connector_update_edid_property(connector, NULL);
|
||||||
aconnector->num_modes = 0;
|
aconnector->num_modes = 0;
|
||||||
aconnector->dc_sink = NULL;
|
aconnector->dc_sink = NULL;
|
||||||
aconnector->edid = NULL;
|
aconnector->edid = NULL;
|
||||||
@@ -3663,7 +3663,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
|
|||||||
link,
|
link,
|
||||||
link_index);
|
link_index);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(
|
drm_connector_attach_encoder(
|
||||||
&aconnector->base, &aencoder->base);
|
&aconnector->base, &aencoder->base);
|
||||||
|
|
||||||
drm_connector_register(&aconnector->base);
|
drm_connector_register(&aconnector->base);
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
|||||||
edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
|
edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
|
||||||
|
|
||||||
if (!edid) {
|
if (!edid) {
|
||||||
drm_mode_connector_update_edid_property(
|
drm_connector_update_edid_property(
|
||||||
&aconnector->base,
|
&aconnector->base,
|
||||||
NULL);
|
NULL);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -261,7 +261,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
|||||||
connector, aconnector->edid);
|
connector, aconnector->edid);
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(
|
drm_connector_update_edid_property(
|
||||||
&aconnector->base, aconnector->edid);
|
&aconnector->base, aconnector->edid);
|
||||||
|
|
||||||
ret = drm_add_edid_modes(connector, aconnector->edid);
|
ret = drm_add_edid_modes(connector, aconnector->edid);
|
||||||
@@ -345,7 +345,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|||||||
aconnector, connector->base.id, aconnector->mst_port);
|
aconnector, connector->base.id, aconnector->mst_port);
|
||||||
|
|
||||||
aconnector->port = port;
|
aconnector->port = port;
|
||||||
drm_mode_connector_set_path_property(connector, pathprop);
|
drm_connector_set_path_property(connector, pathprop);
|
||||||
|
|
||||||
drm_connector_list_iter_end(&conn_iter);
|
drm_connector_list_iter_end(&conn_iter);
|
||||||
aconnector->mst_connected = true;
|
aconnector->mst_connected = true;
|
||||||
@@ -393,7 +393,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|||||||
dev->mode_config.tile_property,
|
dev->mode_config.tile_property,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
drm_mode_connector_set_path_property(connector, pathprop);
|
drm_connector_set_path_property(connector, pathprop);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize connector state before adding the connectror to drm and
|
* Initialize connector state before adding the connectror to drm and
|
||||||
@@ -441,7 +441,7 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
|
|||||||
static void dm_dp_mst_link_status_reset(struct drm_connector *connector)
|
static void dm_dp_mst_link_status_reset(struct drm_connector *connector)
|
||||||
{
|
{
|
||||||
mutex_lock(&connector->dev->mode_config.mutex);
|
mutex_lock(&connector->dev->mode_config.mutex);
|
||||||
drm_mode_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD);
|
drm_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD);
|
||||||
mutex_unlock(&connector->dev->mode_config.mutex);
|
mutex_unlock(&connector->dev->mode_config.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ int arcpgu_drm_sim_init(struct drm_device *drm, struct device_node *np)
|
|||||||
goto error_encoder_cleanup;
|
goto error_encoder_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drm_mode_connector_attach_encoder(connector, encoder);
|
ret = drm_connector_attach_encoder(connector, encoder);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(drm->dev, "could not attach connector to encoder\n");
|
dev_err(drm->dev, "could not attach connector to encoder\n");
|
||||||
drm_connector_unregister(connector);
|
drm_connector_unregister(connector);
|
||||||
|
|||||||
@@ -790,12 +790,12 @@ static int ast_get_modes(struct drm_connector *connector)
|
|||||||
if (!flags)
|
if (!flags)
|
||||||
edid = drm_get_edid(connector, &ast_connector->i2c->adapter);
|
edid = drm_get_edid(connector, &ast_connector->i2c->adapter);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
drm_mode_connector_update_edid_property(&ast_connector->base, edid);
|
drm_connector_update_edid_property(&ast_connector->base, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
return ret;
|
return ret;
|
||||||
} else
|
} else
|
||||||
drm_mode_connector_update_edid_property(&ast_connector->base, NULL);
|
drm_connector_update_edid_property(&ast_connector->base, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,7 +900,7 @@ static int ast_connector_init(struct drm_device *dev)
|
|||||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||||
|
|
||||||
encoder = list_first_entry(&dev->mode_config.encoder_list, struct drm_encoder, head);
|
encoder = list_first_entry(&dev->mode_config.encoder_list, struct drm_encoder, head);
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
ast_connector->i2c = ast_i2c_create(dev);
|
ast_connector->i2c = ast_i2c_create(dev);
|
||||||
if (!ast_connector->i2c)
|
if (!ast_connector->i2c)
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ int bochs_kms_init(struct bochs_device *bochs)
|
|||||||
bochs_crtc_init(bochs->dev);
|
bochs_crtc_init(bochs->dev);
|
||||||
bochs_encoder_init(bochs->dev);
|
bochs_encoder_init(bochs->dev);
|
||||||
bochs_connector_init(bochs->dev);
|
bochs_connector_init(bochs->dev);
|
||||||
drm_mode_connector_attach_encoder(&bochs->connector,
|
drm_connector_attach_encoder(&bochs->connector,
|
||||||
&bochs->encoder);
|
&bochs->encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -601,7 +601,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
|
|||||||
__adv7511_power_off(adv7511);
|
__adv7511_power_off(adv7511);
|
||||||
|
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
count = drm_add_edid_modes(connector, edid);
|
count = drm_add_edid_modes(connector, edid);
|
||||||
|
|
||||||
adv7511_set_config_csc(adv7511, connector, adv7511->rgb,
|
adv7511_set_config_csc(adv7511, connector, adv7511->rgb,
|
||||||
@@ -860,7 +860,7 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge)
|
|||||||
}
|
}
|
||||||
drm_connector_helper_add(&adv->connector,
|
drm_connector_helper_add(&adv->connector,
|
||||||
&adv7511_connector_helper_funcs);
|
&adv7511_connector_helper_funcs);
|
||||||
drm_mode_connector_attach_encoder(&adv->connector, bridge->encoder);
|
drm_connector_attach_encoder(&adv->connector, bridge->encoder);
|
||||||
|
|
||||||
if (adv->type == ADV7533)
|
if (adv->type == ADV7533)
|
||||||
ret = adv7533_attach_dsi(adv);
|
ret = adv7533_attach_dsi(adv);
|
||||||
|
|||||||
@@ -969,8 +969,8 @@ static int anx78xx_get_modes(struct drm_connector *connector)
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = drm_mode_connector_update_edid_property(connector,
|
err = drm_connector_update_edid_property(connector,
|
||||||
anx78xx->edid);
|
anx78xx->edid);
|
||||||
if (err) {
|
if (err) {
|
||||||
DRM_ERROR("Failed to update EDID property: %d\n", err);
|
DRM_ERROR("Failed to update EDID property: %d\n", err);
|
||||||
goto unlock;
|
goto unlock;
|
||||||
@@ -1048,8 +1048,8 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge)
|
|||||||
|
|
||||||
anx78xx->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
anx78xx->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
||||||
|
|
||||||
err = drm_mode_connector_attach_encoder(&anx78xx->connector,
|
err = drm_connector_attach_encoder(&anx78xx->connector,
|
||||||
bridge->encoder);
|
bridge->encoder);
|
||||||
if (err) {
|
if (err) {
|
||||||
DRM_ERROR("Failed to link up connector to encoder: %d\n", err);
|
DRM_ERROR("Failed to link up connector to encoder: %d\n", err);
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -1119,8 +1119,8 @@ static int analogix_dp_get_modes(struct drm_connector *connector)
|
|||||||
edid = drm_get_edid(connector, &dp->aux.ddc);
|
edid = drm_get_edid(connector, &dp->aux.ddc);
|
||||||
pm_runtime_put(dp->dev);
|
pm_runtime_put(dp->dev);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
drm_mode_connector_update_edid_property(&dp->connector,
|
drm_connector_update_edid_property(&dp->connector,
|
||||||
edid);
|
edid);
|
||||||
num_modes += drm_add_edid_modes(&dp->connector, edid);
|
num_modes += drm_add_edid_modes(&dp->connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
}
|
}
|
||||||
@@ -1210,7 +1210,7 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge)
|
|||||||
|
|
||||||
drm_connector_helper_add(connector,
|
drm_connector_helper_add(connector,
|
||||||
&analogix_dp_connector_helper_funcs);
|
&analogix_dp_connector_helper_funcs);
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ static int dumb_vga_get_modes(struct drm_connector *connector)
|
|||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -122,7 +122,7 @@ static int dumb_vga_attach(struct drm_bridge *bridge)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(&vga->connector,
|
drm_connector_attach_encoder(&vga->connector,
|
||||||
bridge->encoder);
|
bridge->encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)
|
|||||||
ge_b850v3_lvds_ptr->edid = (struct edid *)stdp2690_get_edid(client);
|
ge_b850v3_lvds_ptr->edid = (struct edid *)stdp2690_get_edid(client);
|
||||||
|
|
||||||
if (ge_b850v3_lvds_ptr->edid) {
|
if (ge_b850v3_lvds_ptr->edid) {
|
||||||
drm_mode_connector_update_edid_property(connector,
|
drm_connector_update_edid_property(connector,
|
||||||
ge_b850v3_lvds_ptr->edid);
|
ge_b850v3_lvds_ptr->edid);
|
||||||
num_modes = drm_add_edid_modes(connector,
|
num_modes = drm_add_edid_modes(connector,
|
||||||
ge_b850v3_lvds_ptr->edid);
|
ge_b850v3_lvds_ptr->edid);
|
||||||
@@ -241,7 +241,7 @@ static int ge_b850v3_lvds_attach(struct drm_bridge *bridge)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drm_mode_connector_attach_encoder(connector, bridge->encoder);
|
ret = drm_connector_attach_encoder(connector, bridge->encoder);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ static int ptn3460_get_modes(struct drm_connector *connector)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ptn_bridge->edid = (struct edid *)edid;
|
ptn_bridge->edid = (struct edid *)edid;
|
||||||
drm_mode_connector_update_edid_property(connector, ptn_bridge->edid);
|
drm_connector_update_edid_property(connector, ptn_bridge->edid);
|
||||||
|
|
||||||
num_modes = drm_add_edid_modes(connector, ptn_bridge->edid);
|
num_modes = drm_add_edid_modes(connector, ptn_bridge->edid);
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ static int ptn3460_bridge_attach(struct drm_bridge *bridge)
|
|||||||
drm_connector_helper_add(&ptn_bridge->connector,
|
drm_connector_helper_add(&ptn_bridge->connector,
|
||||||
&ptn3460_connector_helper_funcs);
|
&ptn3460_connector_helper_funcs);
|
||||||
drm_connector_register(&ptn_bridge->connector);
|
drm_connector_register(&ptn_bridge->connector);
|
||||||
drm_mode_connector_attach_encoder(&ptn_bridge->connector,
|
drm_connector_attach_encoder(&ptn_bridge->connector,
|
||||||
bridge->encoder);
|
bridge->encoder);
|
||||||
|
|
||||||
if (ptn_bridge->panel)
|
if (ptn_bridge->panel)
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ static int panel_bridge_attach(struct drm_bridge *bridge)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(&panel_bridge->connector,
|
drm_connector_attach_encoder(&panel_bridge->connector,
|
||||||
bridge->encoder);
|
bridge->encoder);
|
||||||
|
|
||||||
ret = drm_panel_attach(panel_bridge->panel, &panel_bridge->connector);
|
ret = drm_panel_attach(panel_bridge->panel, &panel_bridge->connector);
|
||||||
|
|||||||
@@ -503,7 +503,7 @@ static int ps8622_attach(struct drm_bridge *bridge)
|
|||||||
drm_connector_helper_add(&ps8622->connector,
|
drm_connector_helper_add(&ps8622->connector,
|
||||||
&ps8622_connector_helper_funcs);
|
&ps8622_connector_helper_funcs);
|
||||||
drm_connector_register(&ps8622->connector);
|
drm_connector_register(&ps8622->connector);
|
||||||
drm_mode_connector_attach_encoder(&ps8622->connector,
|
drm_connector_attach_encoder(&ps8622->connector,
|
||||||
bridge->encoder);
|
bridge->encoder);
|
||||||
|
|
||||||
if (ps8622->panel)
|
if (ps8622->panel)
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ static int sii902x_get_modes(struct drm_connector *connector)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
edid = drm_get_edid(connector, sii902x->i2c->adapter);
|
edid = drm_get_edid(connector, sii902x->i2c->adapter);
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
num = drm_add_edid_modes(connector, edid);
|
num = drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
@@ -324,7 +324,7 @@ static int sii902x_bridge_attach(struct drm_bridge *bridge)
|
|||||||
else
|
else
|
||||||
sii902x->connector.polled = DRM_CONNECTOR_POLL_CONNECT;
|
sii902x->connector.polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(&sii902x->connector, bridge->encoder);
|
drm_connector_attach_encoder(&sii902x->connector, bridge->encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1922,7 +1922,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
|
|||||||
|
|
||||||
hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
|
hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
|
||||||
hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
|
hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
|
cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
@@ -1974,7 +1974,7 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)
|
|||||||
drm_connector_init(bridge->dev, connector, &dw_hdmi_connector_funcs,
|
drm_connector_init(bridge->dev, connector, &dw_hdmi_connector_funcs,
|
||||||
DRM_MODE_CONNECTOR_HDMIA);
|
DRM_MODE_CONNECTOR_HDMIA);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1140,7 +1140,7 @@ static int tc_connector_get_modes(struct drm_connector *connector)
|
|||||||
if (!edid)
|
if (!edid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
count = drm_add_edid_modes(connector, edid);
|
count = drm_add_edid_modes(connector, edid);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@@ -1195,7 +1195,7 @@ static int tc_bridge_attach(struct drm_bridge *bridge)
|
|||||||
|
|
||||||
drm_display_info_set_bus_formats(&tc->connector.display_info,
|
drm_display_info_set_bus_formats(&tc->connector.display_info,
|
||||||
&bus_format, 1);
|
&bus_format, 1);
|
||||||
drm_mode_connector_attach_encoder(&tc->connector, tc->bridge.encoder);
|
drm_connector_attach_encoder(&tc->connector, tc->bridge.encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ static int tfp410_get_modes(struct drm_connector *connector)
|
|||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
|
|
||||||
return drm_add_edid_modes(connector, edid);
|
return drm_add_edid_modes(connector, edid);
|
||||||
fallback:
|
fallback:
|
||||||
@@ -132,7 +132,7 @@ static int tfp410_attach(struct drm_bridge *bridge)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(&dvi->connector,
|
drm_connector_attach_encoder(&dvi->connector,
|
||||||
bridge->encoder);
|
bridge->encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -530,7 +530,7 @@ int cirrus_modeset_init(struct cirrus_device *cdev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
ret = cirrus_fbdev_init(cdev);
|
ret = cirrus_fbdev_init(cdev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
@@ -2867,7 +2867,7 @@ static int update_output_state(struct drm_atomic_state *state,
|
|||||||
* resets the "link-status" property to GOOD, to force any link
|
* resets the "link-status" property to GOOD, to force any link
|
||||||
* re-training. The SETCRTC ioctl does not define whether an update does
|
* re-training. The SETCRTC ioctl does not define whether an update does
|
||||||
* need a full modeset or just a plane update, hence we're allowed to do
|
* need a full modeset or just a plane update, hence we're allowed to do
|
||||||
* that. See also drm_mode_connector_set_link_status_property().
|
* that. See also drm_connector_set_link_status_property().
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* Returns 0 on success, negative errno numbers on failure.
|
* Returns 0 on success, negative errno numbers on failure.
|
||||||
|
|||||||
@@ -218,7 +218,9 @@ static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
|
|||||||
if (buffer->gem)
|
if (buffer->gem)
|
||||||
drm_gem_object_put_unlocked(buffer->gem);
|
drm_gem_object_put_unlocked(buffer->gem);
|
||||||
|
|
||||||
drm_mode_destroy_dumb(dev, buffer->handle, buffer->client->file);
|
if (buffer->handle)
|
||||||
|
drm_mode_destroy_dumb(dev, buffer->handle, buffer->client->file);
|
||||||
|
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +245,7 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
|
|||||||
dumb_args.bpp = drm_format_plane_cpp(format, 0) * 8;
|
dumb_args.bpp = drm_format_plane_cpp(format, 0) * 8;
|
||||||
ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
|
ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_delete;
|
||||||
|
|
||||||
buffer->handle = dumb_args.handle;
|
buffer->handle = dumb_args.handle;
|
||||||
buffer->pitch = dumb_args.pitch;
|
buffer->pitch = dumb_args.pitch;
|
||||||
@@ -276,8 +278,6 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
|
|||||||
|
|
||||||
err_delete:
|
err_delete:
|
||||||
drm_client_buffer_delete(buffer);
|
drm_client_buffer_delete(buffer);
|
||||||
err_free:
|
|
||||||
kfree(buffer);
|
|
||||||
|
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
*
|
*
|
||||||
* Connectors must be attached to an encoder to be used. For devices that map
|
* Connectors must be attached to an encoder to be used. For devices that map
|
||||||
* connectors to encoders 1:1, the connector should be attached at
|
* connectors to encoders 1:1, the connector should be attached at
|
||||||
* initialization time with a call to drm_mode_connector_attach_encoder(). The
|
* initialization time with a call to drm_connector_attach_encoder(). The
|
||||||
* driver must also set the &drm_connector.encoder field to point to the
|
* driver must also set the &drm_connector.encoder field to point to the
|
||||||
* attached encoder.
|
* attached encoder.
|
||||||
*
|
*
|
||||||
@@ -291,7 +291,7 @@ out_put:
|
|||||||
EXPORT_SYMBOL(drm_connector_init);
|
EXPORT_SYMBOL(drm_connector_init);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_connector_attach_encoder - attach a connector to an encoder
|
* drm_connector_attach_encoder - attach a connector to an encoder
|
||||||
* @connector: connector to attach
|
* @connector: connector to attach
|
||||||
* @encoder: encoder to attach @connector to
|
* @encoder: encoder to attach @connector to
|
||||||
*
|
*
|
||||||
@@ -302,8 +302,8 @@ EXPORT_SYMBOL(drm_connector_init);
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Zero on success, negative errno on failure.
|
* Zero on success, negative errno on failure.
|
||||||
*/
|
*/
|
||||||
int drm_mode_connector_attach_encoder(struct drm_connector *connector,
|
int drm_connector_attach_encoder(struct drm_connector *connector,
|
||||||
struct drm_encoder *encoder)
|
struct drm_encoder *encoder)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -329,7 +329,7 @@ int drm_mode_connector_attach_encoder(struct drm_connector *connector,
|
|||||||
}
|
}
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
|
EXPORT_SYMBOL(drm_connector_attach_encoder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_connector_has_possible_encoder - check if the connector and encoder are assosicated with each other
|
* drm_connector_has_possible_encoder - check if the connector and encoder are assosicated with each other
|
||||||
@@ -606,7 +606,7 @@ __drm_connector_put_safe(struct drm_connector *conn)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_connector_list_iter_next - return next connector
|
* drm_connector_list_iter_next - return next connector
|
||||||
* @iter: connectr_list iterator
|
* @iter: connector_list iterator
|
||||||
*
|
*
|
||||||
* Returns the next connector for @iter, or NULL when the list walk has
|
* Returns the next connector for @iter, or NULL when the list walk has
|
||||||
* completed.
|
* completed.
|
||||||
@@ -814,7 +814,7 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
|
|||||||
* Blob property which contains the current EDID read from the sink. This
|
* Blob property which contains the current EDID read from the sink. This
|
||||||
* is useful to parse sink identification information like vendor, model
|
* is useful to parse sink identification information like vendor, model
|
||||||
* and serial. Drivers should update this property by calling
|
* and serial. Drivers should update this property by calling
|
||||||
* drm_mode_connector_update_edid_property(), usually after having parsed
|
* drm_connector_update_edid_property(), usually after having parsed
|
||||||
* the EDID using drm_add_edid_modes(). Userspace cannot change this
|
* the EDID using drm_add_edid_modes(). Userspace cannot change this
|
||||||
* property.
|
* property.
|
||||||
* DPMS:
|
* DPMS:
|
||||||
@@ -852,7 +852,7 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
|
|||||||
* PATH:
|
* PATH:
|
||||||
* Connector path property to identify how this sink is physically
|
* Connector path property to identify how this sink is physically
|
||||||
* connected. Used by DP MST. This should be set by calling
|
* connected. Used by DP MST. This should be set by calling
|
||||||
* drm_mode_connector_set_path_property(), in the case of DP MST with the
|
* drm_connector_set_path_property(), in the case of DP MST with the
|
||||||
* path property the MST manager created. Userspace cannot change this
|
* path property the MST manager created. Userspace cannot change this
|
||||||
* property.
|
* property.
|
||||||
* TILE:
|
* TILE:
|
||||||
@@ -863,14 +863,14 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
|
|||||||
* are not gen-locked. Note that for tiled panels which are genlocked, like
|
* are not gen-locked. Note that for tiled panels which are genlocked, like
|
||||||
* dual-link LVDS or dual-link DSI, the driver should try to not expose the
|
* dual-link LVDS or dual-link DSI, the driver should try to not expose the
|
||||||
* tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
|
* tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
|
||||||
* should update this value using drm_mode_connector_set_tile_property().
|
* should update this value using drm_connector_set_tile_property().
|
||||||
* Userspace cannot change this property.
|
* Userspace cannot change this property.
|
||||||
* link-status:
|
* link-status:
|
||||||
* Connector link-status property to indicate the status of link. The
|
* Connector link-status property to indicate the status of link. The
|
||||||
* default value of link-status is "GOOD". If something fails during or
|
* default value of link-status is "GOOD". If something fails during or
|
||||||
* after modeset, the kernel driver may set this to "BAD" and issue a
|
* after modeset, the kernel driver may set this to "BAD" and issue a
|
||||||
* hotplug uevent. Drivers should update this value using
|
* hotplug uevent. Drivers should update this value using
|
||||||
* drm_mode_connector_set_link_status_property().
|
* drm_connector_set_link_status_property().
|
||||||
* non_desktop:
|
* non_desktop:
|
||||||
* Indicates the output should be ignored for purposes of displaying a
|
* Indicates the output should be ignored for purposes of displaying a
|
||||||
* standard desktop environment or console. This is most likely because
|
* standard desktop environment or console. This is most likely because
|
||||||
@@ -1425,7 +1425,7 @@ int drm_mode_create_suggested_offset_properties(struct drm_device *dev)
|
|||||||
EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);
|
EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_connector_set_path_property - set tile property on connector
|
* drm_connector_set_path_property - set tile property on connector
|
||||||
* @connector: connector to set property on.
|
* @connector: connector to set property on.
|
||||||
* @path: path to use for property; must not be NULL.
|
* @path: path to use for property; must not be NULL.
|
||||||
*
|
*
|
||||||
@@ -1437,8 +1437,8 @@ EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Zero on success, negative errno on failure.
|
* Zero on success, negative errno on failure.
|
||||||
*/
|
*/
|
||||||
int drm_mode_connector_set_path_property(struct drm_connector *connector,
|
int drm_connector_set_path_property(struct drm_connector *connector,
|
||||||
const char *path)
|
const char *path)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -1451,10 +1451,10 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector,
|
|||||||
dev->mode_config.path_property);
|
dev->mode_config.path_property);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_mode_connector_set_path_property);
|
EXPORT_SYMBOL(drm_connector_set_path_property);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_connector_set_tile_property - set tile property on connector
|
* drm_connector_set_tile_property - set tile property on connector
|
||||||
* @connector: connector to set property on.
|
* @connector: connector to set property on.
|
||||||
*
|
*
|
||||||
* This looks up the tile information for a connector, and creates a
|
* This looks up the tile information for a connector, and creates a
|
||||||
@@ -1464,7 +1464,7 @@ EXPORT_SYMBOL(drm_mode_connector_set_path_property);
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Zero on success, errno on failure.
|
* Zero on success, errno on failure.
|
||||||
*/
|
*/
|
||||||
int drm_mode_connector_set_tile_property(struct drm_connector *connector)
|
int drm_connector_set_tile_property(struct drm_connector *connector)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
char tile[256];
|
char tile[256];
|
||||||
@@ -1494,10 +1494,10 @@ int drm_mode_connector_set_tile_property(struct drm_connector *connector)
|
|||||||
dev->mode_config.tile_property);
|
dev->mode_config.tile_property);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_mode_connector_set_tile_property);
|
EXPORT_SYMBOL(drm_connector_set_tile_property);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_connector_update_edid_property - update the edid property of a connector
|
* drm_connector_update_edid_property - update the edid property of a connector
|
||||||
* @connector: drm connector
|
* @connector: drm connector
|
||||||
* @edid: new value of the edid property
|
* @edid: new value of the edid property
|
||||||
*
|
*
|
||||||
@@ -1507,8 +1507,8 @@ EXPORT_SYMBOL(drm_mode_connector_set_tile_property);
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Zero on success, negative errno on failure.
|
* Zero on success, negative errno on failure.
|
||||||
*/
|
*/
|
||||||
int drm_mode_connector_update_edid_property(struct drm_connector *connector,
|
int drm_connector_update_edid_property(struct drm_connector *connector,
|
||||||
const struct edid *edid)
|
const struct edid *edid)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
@@ -1546,10 +1546,10 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
|
|||||||
dev->mode_config.edid_property);
|
dev->mode_config.edid_property);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
|
EXPORT_SYMBOL(drm_connector_update_edid_property);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_connector_set_link_status_property - Set link status property of a connector
|
* drm_connector_set_link_status_property - Set link status property of a connector
|
||||||
* @connector: drm connector
|
* @connector: drm connector
|
||||||
* @link_status: new value of link status property (0: Good, 1: Bad)
|
* @link_status: new value of link status property (0: Good, 1: Bad)
|
||||||
*
|
*
|
||||||
@@ -1567,8 +1567,8 @@ EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
|
|||||||
* it is not limited to DP or link training. For example, if we implement
|
* it is not limited to DP or link training. For example, if we implement
|
||||||
* asynchronous setcrtc, this property can be used to report any failures in that.
|
* asynchronous setcrtc, this property can be used to report any failures in that.
|
||||||
*/
|
*/
|
||||||
void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
|
void drm_connector_set_link_status_property(struct drm_connector *connector,
|
||||||
uint64_t link_status)
|
uint64_t link_status)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
|
|
||||||
@@ -1576,7 +1576,7 @@ void drm_mode_connector_set_link_status_property(struct drm_connector *connector
|
|||||||
connector->state->link_status = link_status;
|
connector->state->link_status = link_status;
|
||||||
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
|
EXPORT_SYMBOL(drm_connector_set_link_status_property);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_connector_init_panel_orientation_property -
|
* drm_connector_init_panel_orientation_property -
|
||||||
@@ -1629,7 +1629,7 @@ int drm_connector_init_panel_orientation_property(
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_connector_init_panel_orientation_property);
|
EXPORT_SYMBOL(drm_connector_init_panel_orientation_property);
|
||||||
|
|
||||||
int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
|
int drm_connector_set_obj_prop(struct drm_mode_object *obj,
|
||||||
struct drm_property *property,
|
struct drm_property *property,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
@@ -1647,8 +1647,8 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
|
int drm_connector_property_set_ioctl(struct drm_device *dev,
|
||||||
void *data, struct drm_file *file_priv)
|
void *data, struct drm_file *file_priv)
|
||||||
{
|
{
|
||||||
struct drm_mode_connector_set_property *conn_set_prop = data;
|
struct drm_mode_connector_set_property *conn_set_prop = data;
|
||||||
struct drm_mode_obj_set_property obj_set_prop = {
|
struct drm_mode_obj_set_property obj_set_prop = {
|
||||||
|
|||||||
@@ -461,6 +461,8 @@ static int __drm_mode_set_config_internal(struct drm_mode_set *set,
|
|||||||
struct drm_crtc *tmp;
|
struct drm_crtc *tmp;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: ->set_config can also disable other crtcs (if we steal all
|
* NOTE: ->set_config can also disable other crtcs (if we steal all
|
||||||
* connectors from it), hence we need to refcount the fbs across all
|
* connectors from it), hence we need to refcount the fbs across all
|
||||||
@@ -478,10 +480,8 @@ static int __drm_mode_set_config_internal(struct drm_mode_set *set,
|
|||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
struct drm_plane *plane = crtc->primary;
|
struct drm_plane *plane = crtc->primary;
|
||||||
|
|
||||||
if (!plane->state) {
|
plane->crtc = fb ? crtc : NULL;
|
||||||
plane->crtc = fb ? crtc : NULL;
|
plane->fb = fb;
|
||||||
plane->fb = fb;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_for_each_crtc(tmp, crtc->dev) {
|
drm_for_each_crtc(tmp, crtc->dev) {
|
||||||
@@ -496,6 +496,7 @@ static int __drm_mode_set_config_internal(struct drm_mode_set *set,
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
|
* drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
|
||||||
* @set: modeset config to set
|
* @set: modeset config to set
|
||||||
@@ -740,7 +741,11 @@ retry:
|
|||||||
set.connectors = connector_set;
|
set.connectors = connector_set;
|
||||||
set.num_connectors = crtc_req->count_connectors;
|
set.num_connectors = crtc_req->count_connectors;
|
||||||
set.fb = fb;
|
set.fb = fb;
|
||||||
ret = __drm_mode_set_config_internal(&set, &ctx);
|
|
||||||
|
if (drm_drv_uses_atomic_modeset(dev))
|
||||||
|
ret = crtc->funcs->set_config(&set, &ctx);
|
||||||
|
else
|
||||||
|
ret = __drm_mode_set_config_internal(&set, &ctx);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (fb)
|
if (fb)
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ void drm_connector_ida_init(void);
|
|||||||
void drm_connector_ida_destroy(void);
|
void drm_connector_ida_destroy(void);
|
||||||
void drm_connector_unregister_all(struct drm_device *dev);
|
void drm_connector_unregister_all(struct drm_device *dev);
|
||||||
int drm_connector_register_all(struct drm_device *dev);
|
int drm_connector_register_all(struct drm_device *dev);
|
||||||
int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
|
int drm_connector_set_obj_prop(struct drm_mode_object *obj,
|
||||||
struct drm_property *property,
|
struct drm_property *property,
|
||||||
uint64_t value);
|
uint64_t value);
|
||||||
int drm_connector_create_standard_properties(struct drm_device *dev);
|
int drm_connector_create_standard_properties(struct drm_device *dev);
|
||||||
@@ -156,8 +156,8 @@ const char *drm_get_connector_force_name(enum drm_connector_force force);
|
|||||||
void drm_connector_free_work_fn(struct work_struct *work);
|
void drm_connector_free_work_fn(struct work_struct *work);
|
||||||
|
|
||||||
/* IOCTL */
|
/* IOCTL */
|
||||||
int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
|
int drm_connector_property_set_ioctl(struct drm_device *dev,
|
||||||
void *data, struct drm_file *file_priv);
|
void *data, struct drm_file *file_priv);
|
||||||
int drm_mode_getconnector(struct drm_device *dev,
|
int drm_mode_getconnector(struct drm_device *dev,
|
||||||
void *data, struct drm_file *file_priv);
|
void *data, struct drm_file *file_priv);
|
||||||
|
|
||||||
|
|||||||
@@ -314,13 +314,13 @@ static ssize_t edid_write(struct file *file, const char __user *ubuf,
|
|||||||
|
|
||||||
if (len == 5 && !strncmp(buf, "reset", 5)) {
|
if (len == 5 && !strncmp(buf, "reset", 5)) {
|
||||||
connector->override_edid = false;
|
connector->override_edid = false;
|
||||||
ret = drm_mode_connector_update_edid_property(connector, NULL);
|
ret = drm_connector_update_edid_property(connector, NULL);
|
||||||
} else if (len < EDID_LENGTH ||
|
} else if (len < EDID_LENGTH ||
|
||||||
EDID_LENGTH * (1 + edid->extensions) > len)
|
EDID_LENGTH * (1 + edid->extensions) > len)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
else {
|
else {
|
||||||
connector->override_edid = false;
|
connector->override_edid = false;
|
||||||
ret = drm_mode_connector_update_edid_property(connector, edid);
|
ret = drm_connector_update_edid_property(connector, edid);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
connector->override_edid = true;
|
connector->override_edid = true;
|
||||||
}
|
}
|
||||||
|
|||||||
428
drivers/gpu/drm/drm_dp_cec.c
Normal file
428
drivers/gpu/drm/drm_dp_cec.c
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* DisplayPort CEC-Tunneling-over-AUX support
|
||||||
|
*
|
||||||
|
* Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <drm/drm_dp_helper.h>
|
||||||
|
#include <media/cec.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unfortunately it turns out that we have a chicken-and-egg situation
|
||||||
|
* here. Quite a few active (mini-)DP-to-HDMI or USB-C-to-HDMI adapters
|
||||||
|
* have a converter chip that supports CEC-Tunneling-over-AUX (usually the
|
||||||
|
* Parade PS176), but they do not wire up the CEC pin, thus making CEC
|
||||||
|
* useless.
|
||||||
|
*
|
||||||
|
* Sadly there is no way for this driver to know this. What happens is
|
||||||
|
* that a /dev/cecX device is created that is isolated and unable to see
|
||||||
|
* any of the other CEC devices. Quite literally the CEC wire is cut
|
||||||
|
* (or in this case, never connected in the first place).
|
||||||
|
*
|
||||||
|
* The reason so few adapters support this is that this tunneling protocol
|
||||||
|
* was never supported by any OS. So there was no easy way of testing it,
|
||||||
|
* and no incentive to correctly wire up the CEC pin.
|
||||||
|
*
|
||||||
|
* Hopefully by creating this driver it will be easier for vendors to
|
||||||
|
* finally fix their adapters and test the CEC functionality.
|
||||||
|
*
|
||||||
|
* I keep a list of known working adapters here:
|
||||||
|
*
|
||||||
|
* https://hverkuil.home.xs4all.nl/cec-status.txt
|
||||||
|
*
|
||||||
|
* Please mail me (hverkuil@xs4all.nl) if you find an adapter that works
|
||||||
|
* and is not yet listed there.
|
||||||
|
*
|
||||||
|
* Note that the current implementation does not support CEC over an MST hub.
|
||||||
|
* As far as I can see there is no mechanism defined in the DisplayPort
|
||||||
|
* standard to transport CEC interrupts over an MST device. It might be
|
||||||
|
* possible to do this through polling, but I have not been able to get that
|
||||||
|
* to work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOC: dp cec helpers
|
||||||
|
*
|
||||||
|
* These functions take care of supporting the CEC-Tunneling-over-AUX
|
||||||
|
* feature of DisplayPort-to-HDMI adapters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the EDID is unset because the HPD went low, then the CEC DPCD registers
|
||||||
|
* typically can no longer be read (true for a DP-to-HDMI adapter since it is
|
||||||
|
* powered by the HPD). However, some displays toggle the HPD off and on for a
|
||||||
|
* short period for one reason or another, and that would cause the CEC adapter
|
||||||
|
* to be removed and added again, even though nothing else changed.
|
||||||
|
*
|
||||||
|
* This module parameter sets a delay in seconds before the CEC adapter is
|
||||||
|
* actually unregistered. Only if the HPD does not return within that time will
|
||||||
|
* the CEC adapter be unregistered.
|
||||||
|
*
|
||||||
|
* If it is set to a value >= NEVER_UNREG_DELAY, then the CEC adapter will never
|
||||||
|
* be unregistered for as long as the connector remains registered.
|
||||||
|
*
|
||||||
|
* If it is set to 0, then the CEC adapter will be unregistered immediately as
|
||||||
|
* soon as the HPD disappears.
|
||||||
|
*
|
||||||
|
* The default is one second to prevent short HPD glitches from unregistering
|
||||||
|
* the CEC adapter.
|
||||||
|
*
|
||||||
|
* Note that for integrated HDMI branch devices that support CEC the DPCD
|
||||||
|
* registers remain available even if the HPD goes low since it is not powered
|
||||||
|
* by the HPD. In that case the CEC adapter will never be unregistered during
|
||||||
|
* the life time of the connector. At least, this is the theory since I do not
|
||||||
|
* have hardware with an integrated HDMI branch device that supports CEC.
|
||||||
|
*/
|
||||||
|
#define NEVER_UNREG_DELAY 1000
|
||||||
|
static unsigned int drm_dp_cec_unregister_delay = 1;
|
||||||
|
module_param(drm_dp_cec_unregister_delay, uint, 0600);
|
||||||
|
MODULE_PARM_DESC(drm_dp_cec_unregister_delay,
|
||||||
|
"CEC unregister delay in seconds, 0: no delay, >= 1000: never unregister");
|
||||||
|
|
||||||
|
static int drm_dp_cec_adap_enable(struct cec_adapter *adap, bool enable)
|
||||||
|
{
|
||||||
|
struct drm_dp_aux *aux = cec_get_drvdata(adap);
|
||||||
|
u32 val = enable ? DP_CEC_TUNNELING_ENABLE : 0;
|
||||||
|
ssize_t err = 0;
|
||||||
|
|
||||||
|
err = drm_dp_dpcd_writeb(aux, DP_CEC_TUNNELING_CONTROL, val);
|
||||||
|
return (enable && err < 0) ? err : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int drm_dp_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
|
||||||
|
{
|
||||||
|
struct drm_dp_aux *aux = cec_get_drvdata(adap);
|
||||||
|
/* Bit 15 (logical address 15) should always be set */
|
||||||
|
u16 la_mask = 1 << CEC_LOG_ADDR_BROADCAST;
|
||||||
|
u8 mask[2];
|
||||||
|
ssize_t err;
|
||||||
|
|
||||||
|
if (addr != CEC_LOG_ADDR_INVALID)
|
||||||
|
la_mask |= adap->log_addrs.log_addr_mask | (1 << addr);
|
||||||
|
mask[0] = la_mask & 0xff;
|
||||||
|
mask[1] = la_mask >> 8;
|
||||||
|
err = drm_dp_dpcd_write(aux, DP_CEC_LOGICAL_ADDRESS_MASK, mask, 2);
|
||||||
|
return (addr != CEC_LOG_ADDR_INVALID && err < 0) ? err : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int drm_dp_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
|
||||||
|
u32 signal_free_time, struct cec_msg *msg)
|
||||||
|
{
|
||||||
|
struct drm_dp_aux *aux = cec_get_drvdata(adap);
|
||||||
|
unsigned int retries = min(5, attempts - 1);
|
||||||
|
ssize_t err;
|
||||||
|
|
||||||
|
err = drm_dp_dpcd_write(aux, DP_CEC_TX_MESSAGE_BUFFER,
|
||||||
|
msg->msg, msg->len);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = drm_dp_dpcd_writeb(aux, DP_CEC_TX_MESSAGE_INFO,
|
||||||
|
(msg->len - 1) | (retries << 4) |
|
||||||
|
DP_CEC_TX_MESSAGE_SEND);
|
||||||
|
return err < 0 ? err : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int drm_dp_cec_adap_monitor_all_enable(struct cec_adapter *adap,
|
||||||
|
bool enable)
|
||||||
|
{
|
||||||
|
struct drm_dp_aux *aux = cec_get_drvdata(adap);
|
||||||
|
ssize_t err;
|
||||||
|
u8 val;
|
||||||
|
|
||||||
|
if (!(adap->capabilities & CEC_CAP_MONITOR_ALL))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err = drm_dp_dpcd_readb(aux, DP_CEC_TUNNELING_CONTROL, &val);
|
||||||
|
if (err >= 0) {
|
||||||
|
if (enable)
|
||||||
|
val |= DP_CEC_SNOOPING_ENABLE;
|
||||||
|
else
|
||||||
|
val &= ~DP_CEC_SNOOPING_ENABLE;
|
||||||
|
err = drm_dp_dpcd_writeb(aux, DP_CEC_TUNNELING_CONTROL, val);
|
||||||
|
}
|
||||||
|
return (enable && err < 0) ? err : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drm_dp_cec_adap_status(struct cec_adapter *adap,
|
||||||
|
struct seq_file *file)
|
||||||
|
{
|
||||||
|
struct drm_dp_aux *aux = cec_get_drvdata(adap);
|
||||||
|
struct drm_dp_desc desc;
|
||||||
|
struct drm_dp_dpcd_ident *id = &desc.ident;
|
||||||
|
|
||||||
|
if (drm_dp_read_desc(aux, &desc, true))
|
||||||
|
return;
|
||||||
|
seq_printf(file, "OUI: %*pdH\n",
|
||||||
|
(int)sizeof(id->oui), id->oui);
|
||||||
|
seq_printf(file, "ID: %*pE\n",
|
||||||
|
(int)strnlen(id->device_id, sizeof(id->device_id)),
|
||||||
|
id->device_id);
|
||||||
|
seq_printf(file, "HW Rev: %d.%d\n", id->hw_rev >> 4, id->hw_rev & 0xf);
|
||||||
|
/*
|
||||||
|
* Show this both in decimal and hex: at least one vendor
|
||||||
|
* always reports this in hex.
|
||||||
|
*/
|
||||||
|
seq_printf(file, "FW/SW Rev: %d.%d (0x%02x.0x%02x)\n",
|
||||||
|
id->sw_major_rev, id->sw_minor_rev,
|
||||||
|
id->sw_major_rev, id->sw_minor_rev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct cec_adap_ops drm_dp_cec_adap_ops = {
|
||||||
|
.adap_enable = drm_dp_cec_adap_enable,
|
||||||
|
.adap_log_addr = drm_dp_cec_adap_log_addr,
|
||||||
|
.adap_transmit = drm_dp_cec_adap_transmit,
|
||||||
|
.adap_monitor_all_enable = drm_dp_cec_adap_monitor_all_enable,
|
||||||
|
.adap_status = drm_dp_cec_adap_status,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int drm_dp_cec_received(struct drm_dp_aux *aux)
|
||||||
|
{
|
||||||
|
struct cec_adapter *adap = aux->cec.adap;
|
||||||
|
struct cec_msg msg;
|
||||||
|
u8 rx_msg_info;
|
||||||
|
ssize_t err;
|
||||||
|
|
||||||
|
err = drm_dp_dpcd_readb(aux, DP_CEC_RX_MESSAGE_INFO, &rx_msg_info);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (!(rx_msg_info & DP_CEC_RX_MESSAGE_ENDED))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
msg.len = (rx_msg_info & DP_CEC_RX_MESSAGE_LEN_MASK) + 1;
|
||||||
|
err = drm_dp_dpcd_read(aux, DP_CEC_RX_MESSAGE_BUFFER, msg.msg, msg.len);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
cec_received_msg(adap, &msg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drm_dp_cec_handle_irq(struct drm_dp_aux *aux)
|
||||||
|
{
|
||||||
|
struct cec_adapter *adap = aux->cec.adap;
|
||||||
|
u8 flags;
|
||||||
|
|
||||||
|
if (drm_dp_dpcd_readb(aux, DP_CEC_TUNNELING_IRQ_FLAGS, &flags) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (flags & DP_CEC_RX_MESSAGE_INFO_VALID)
|
||||||
|
drm_dp_cec_received(aux);
|
||||||
|
|
||||||
|
if (flags & DP_CEC_TX_MESSAGE_SENT)
|
||||||
|
cec_transmit_attempt_done(adap, CEC_TX_STATUS_OK);
|
||||||
|
else if (flags & DP_CEC_TX_LINE_ERROR)
|
||||||
|
cec_transmit_attempt_done(adap, CEC_TX_STATUS_ERROR |
|
||||||
|
CEC_TX_STATUS_MAX_RETRIES);
|
||||||
|
else if (flags &
|
||||||
|
(DP_CEC_TX_ADDRESS_NACK_ERROR | DP_CEC_TX_DATA_NACK_ERROR))
|
||||||
|
cec_transmit_attempt_done(adap, CEC_TX_STATUS_NACK |
|
||||||
|
CEC_TX_STATUS_MAX_RETRIES);
|
||||||
|
drm_dp_dpcd_writeb(aux, DP_CEC_TUNNELING_IRQ_FLAGS, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_dp_cec_irq() - handle CEC interrupt, if any
|
||||||
|
* @aux: DisplayPort AUX channel
|
||||||
|
*
|
||||||
|
* Should be called when handling an IRQ_HPD request. If CEC-tunneling-over-AUX
|
||||||
|
* is present, then it will check for a CEC_IRQ and handle it accordingly.
|
||||||
|
*/
|
||||||
|
void drm_dp_cec_irq(struct drm_dp_aux *aux)
|
||||||
|
{
|
||||||
|
u8 cec_irq;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&aux->cec.lock);
|
||||||
|
if (!aux->cec.adap)
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
|
ret = drm_dp_dpcd_readb(aux, DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1,
|
||||||
|
&cec_irq);
|
||||||
|
if (ret < 0 || !(cec_irq & DP_CEC_IRQ))
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
|
drm_dp_cec_handle_irq(aux);
|
||||||
|
drm_dp_dpcd_writeb(aux, DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1, DP_CEC_IRQ);
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&aux->cec.lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_dp_cec_irq);
|
||||||
|
|
||||||
|
static bool drm_dp_cec_cap(struct drm_dp_aux *aux, u8 *cec_cap)
|
||||||
|
{
|
||||||
|
u8 cap = 0;
|
||||||
|
|
||||||
|
if (drm_dp_dpcd_readb(aux, DP_CEC_TUNNELING_CAPABILITY, &cap) != 1 ||
|
||||||
|
!(cap & DP_CEC_TUNNELING_CAPABLE))
|
||||||
|
return false;
|
||||||
|
if (cec_cap)
|
||||||
|
*cec_cap = cap;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called if the HPD was low for more than drm_dp_cec_unregister_delay
|
||||||
|
* seconds. This unregisters the CEC adapter.
|
||||||
|
*/
|
||||||
|
static void drm_dp_cec_unregister_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct drm_dp_aux *aux = container_of(work, struct drm_dp_aux,
|
||||||
|
cec.unregister_work.work);
|
||||||
|
|
||||||
|
mutex_lock(&aux->cec.lock);
|
||||||
|
cec_unregister_adapter(aux->cec.adap);
|
||||||
|
aux->cec.adap = NULL;
|
||||||
|
mutex_unlock(&aux->cec.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A new EDID is set. If there is no CEC adapter, then create one. If
|
||||||
|
* there was a CEC adapter, then check if the CEC adapter properties
|
||||||
|
* were unchanged and just update the CEC physical address. Otherwise
|
||||||
|
* unregister the old CEC adapter and create a new one.
|
||||||
|
*/
|
||||||
|
void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
|
||||||
|
{
|
||||||
|
u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD;
|
||||||
|
unsigned int num_las = 1;
|
||||||
|
u8 cap;
|
||||||
|
|
||||||
|
#ifndef CONFIG_MEDIA_CEC_RC
|
||||||
|
/*
|
||||||
|
* CEC_CAP_RC is part of CEC_CAP_DEFAULTS, but it is stripped by
|
||||||
|
* cec_allocate_adapter() if CONFIG_MEDIA_CEC_RC is undefined.
|
||||||
|
*
|
||||||
|
* Do this here as well to ensure the tests against cec_caps are
|
||||||
|
* correct.
|
||||||
|
*/
|
||||||
|
cec_caps &= ~CEC_CAP_RC;
|
||||||
|
#endif
|
||||||
|
cancel_delayed_work_sync(&aux->cec.unregister_work);
|
||||||
|
|
||||||
|
mutex_lock(&aux->cec.lock);
|
||||||
|
if (!drm_dp_cec_cap(aux, &cap)) {
|
||||||
|
/* CEC is not supported, unregister any existing adapter */
|
||||||
|
cec_unregister_adapter(aux->cec.adap);
|
||||||
|
aux->cec.adap = NULL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cap & DP_CEC_SNOOPING_CAPABLE)
|
||||||
|
cec_caps |= CEC_CAP_MONITOR_ALL;
|
||||||
|
if (cap & DP_CEC_MULTIPLE_LA_CAPABLE)
|
||||||
|
num_las = CEC_MAX_LOG_ADDRS;
|
||||||
|
|
||||||
|
if (aux->cec.adap) {
|
||||||
|
if (aux->cec.adap->capabilities == cec_caps &&
|
||||||
|
aux->cec.adap->available_log_addrs == num_las) {
|
||||||
|
/* Unchanged, so just set the phys addr */
|
||||||
|
cec_s_phys_addr_from_edid(aux->cec.adap, edid);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* The capabilities changed, so unregister the old
|
||||||
|
* adapter first.
|
||||||
|
*/
|
||||||
|
cec_unregister_adapter(aux->cec.adap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new adapter */
|
||||||
|
aux->cec.adap = cec_allocate_adapter(&drm_dp_cec_adap_ops,
|
||||||
|
aux, aux->cec.name, cec_caps,
|
||||||
|
num_las);
|
||||||
|
if (IS_ERR(aux->cec.adap)) {
|
||||||
|
aux->cec.adap = NULL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
if (cec_register_adapter(aux->cec.adap, aux->cec.parent)) {
|
||||||
|
cec_delete_adapter(aux->cec.adap);
|
||||||
|
aux->cec.adap = NULL;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Update the phys addr for the new CEC adapter. When called
|
||||||
|
* from drm_dp_cec_register_connector() edid == NULL, so in
|
||||||
|
* that case the phys addr is just invalidated.
|
||||||
|
*/
|
||||||
|
cec_s_phys_addr_from_edid(aux->cec.adap, edid);
|
||||||
|
}
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&aux->cec.lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_dp_cec_set_edid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The EDID disappeared (likely because of the HPD going down).
|
||||||
|
*/
|
||||||
|
void drm_dp_cec_unset_edid(struct drm_dp_aux *aux)
|
||||||
|
{
|
||||||
|
cancel_delayed_work_sync(&aux->cec.unregister_work);
|
||||||
|
|
||||||
|
mutex_lock(&aux->cec.lock);
|
||||||
|
if (!aux->cec.adap)
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
|
cec_phys_addr_invalidate(aux->cec.adap);
|
||||||
|
/*
|
||||||
|
* We're done if we want to keep the CEC device
|
||||||
|
* (drm_dp_cec_unregister_delay is >= NEVER_UNREG_DELAY) or if the
|
||||||
|
* DPCD still indicates the CEC capability (expected for an integrated
|
||||||
|
* HDMI branch device).
|
||||||
|
*/
|
||||||
|
if (drm_dp_cec_unregister_delay < NEVER_UNREG_DELAY &&
|
||||||
|
!drm_dp_cec_cap(aux, NULL)) {
|
||||||
|
/*
|
||||||
|
* Unregister the CEC adapter after drm_dp_cec_unregister_delay
|
||||||
|
* seconds. This to debounce short HPD off-and-on cycles from
|
||||||
|
* displays.
|
||||||
|
*/
|
||||||
|
schedule_delayed_work(&aux->cec.unregister_work,
|
||||||
|
drm_dp_cec_unregister_delay * HZ);
|
||||||
|
}
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&aux->cec.lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_dp_cec_unset_edid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_dp_cec_register_connector() - register a new connector
|
||||||
|
* @aux: DisplayPort AUX channel
|
||||||
|
* @name: name of the CEC device
|
||||||
|
* @parent: parent device
|
||||||
|
*
|
||||||
|
* A new connector was registered with associated CEC adapter name and
|
||||||
|
* CEC adapter parent device. After registering the name and parent
|
||||||
|
* drm_dp_cec_set_edid() is called to check if the connector supports
|
||||||
|
* CEC and to register a CEC adapter if that is the case.
|
||||||
|
*/
|
||||||
|
void drm_dp_cec_register_connector(struct drm_dp_aux *aux, const char *name,
|
||||||
|
struct device *parent)
|
||||||
|
{
|
||||||
|
WARN_ON(aux->cec.adap);
|
||||||
|
aux->cec.name = name;
|
||||||
|
aux->cec.parent = parent;
|
||||||
|
INIT_DELAYED_WORK(&aux->cec.unregister_work,
|
||||||
|
drm_dp_cec_unregister_work);
|
||||||
|
|
||||||
|
drm_dp_cec_set_edid(aux, NULL);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_dp_cec_register_connector);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_dp_cec_unregister_connector() - unregister the CEC adapter, if any
|
||||||
|
* @aux: DisplayPort AUX channel
|
||||||
|
*/
|
||||||
|
void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux)
|
||||||
|
{
|
||||||
|
if (!aux->cec.adap)
|
||||||
|
return;
|
||||||
|
cancel_delayed_work_sync(&aux->cec.unregister_work);
|
||||||
|
cec_unregister_adapter(aux->cec.adap);
|
||||||
|
aux->cec.adap = NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_dp_cec_unregister_connector);
|
||||||
@@ -185,6 +185,20 @@ EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate);
|
|||||||
|
|
||||||
#define AUX_RETRY_INTERVAL 500 /* us */
|
#define AUX_RETRY_INTERVAL 500 /* us */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
drm_dp_dump_access(const struct drm_dp_aux *aux,
|
||||||
|
u8 request, uint offset, void *buffer, int ret)
|
||||||
|
{
|
||||||
|
const char *arrow = request == DP_AUX_NATIVE_READ ? "->" : "<-";
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
drm_dbg(DRM_UT_DP, "%s: 0x%05x AUX %s (ret=%3d) %*ph\n",
|
||||||
|
aux->name, offset, arrow, ret, min(ret, 20), buffer);
|
||||||
|
else
|
||||||
|
drm_dbg(DRM_UT_DP, "%s: 0x%05x AUX %s (ret=%3d)\n",
|
||||||
|
aux->name, offset, arrow, ret);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOC: dp helpers
|
* DOC: dp helpers
|
||||||
*
|
*
|
||||||
@@ -288,10 +302,14 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
|
|||||||
ret = drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, DP_DPCD_REV, buffer,
|
ret = drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, DP_DPCD_REV, buffer,
|
||||||
1);
|
1);
|
||||||
if (ret != 1)
|
if (ret != 1)
|
||||||
return ret;
|
goto out;
|
||||||
|
|
||||||
return drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, offset, buffer,
|
ret = drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, offset, buffer,
|
||||||
size);
|
size);
|
||||||
|
|
||||||
|
out:
|
||||||
|
drm_dp_dump_access(aux, DP_AUX_NATIVE_READ, offset, buffer, ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_dp_dpcd_read);
|
EXPORT_SYMBOL(drm_dp_dpcd_read);
|
||||||
|
|
||||||
@@ -312,8 +330,12 @@ EXPORT_SYMBOL(drm_dp_dpcd_read);
|
|||||||
ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
|
ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
|
||||||
void *buffer, size_t size)
|
void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
return drm_dp_dpcd_access(aux, DP_AUX_NATIVE_WRITE, offset, buffer,
|
int ret;
|
||||||
size);
|
|
||||||
|
ret = drm_dp_dpcd_access(aux, DP_AUX_NATIVE_WRITE, offset, buffer,
|
||||||
|
size);
|
||||||
|
drm_dp_dump_access(aux, DP_AUX_NATIVE_WRITE, offset, buffer, ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_dp_dpcd_write);
|
EXPORT_SYMBOL(drm_dp_dpcd_write);
|
||||||
|
|
||||||
@@ -1087,6 +1109,7 @@ static void drm_dp_aux_crc_work(struct work_struct *work)
|
|||||||
void drm_dp_aux_init(struct drm_dp_aux *aux)
|
void drm_dp_aux_init(struct drm_dp_aux *aux)
|
||||||
{
|
{
|
||||||
mutex_init(&aux->hw_mutex);
|
mutex_init(&aux->hw_mutex);
|
||||||
|
mutex_init(&aux->cec.lock);
|
||||||
INIT_WORK(&aux->crc_work, drm_dp_aux_crc_work);
|
INIT_WORK(&aux->crc_work, drm_dp_aux_crc_work);
|
||||||
|
|
||||||
aux->ddc.algo = &drm_dp_i2c_algo;
|
aux->ddc.algo = &drm_dp_i2c_algo;
|
||||||
|
|||||||
@@ -1215,7 +1215,7 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
|
|||||||
port->pdt == DP_PEER_DEVICE_SST_SINK) &&
|
port->pdt == DP_PEER_DEVICE_SST_SINK) &&
|
||||||
port->port_num >= DP_MST_LOGICAL_PORT_0) {
|
port->port_num >= DP_MST_LOGICAL_PORT_0) {
|
||||||
port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc);
|
port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc);
|
||||||
drm_mode_connector_set_tile_property(port->connector);
|
drm_connector_set_tile_property(port->connector);
|
||||||
}
|
}
|
||||||
(*mstb->mgr->cbs->register_connector)(port->connector);
|
(*mstb->mgr->cbs->register_connector)(port->connector);
|
||||||
}
|
}
|
||||||
@@ -2559,7 +2559,7 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_
|
|||||||
edid = drm_edid_duplicate(port->cached_edid);
|
edid = drm_edid_duplicate(port->cached_edid);
|
||||||
else {
|
else {
|
||||||
edid = drm_get_edid(connector, &port->aux.ddc);
|
edid = drm_get_edid(connector, &port->aux.ddc);
|
||||||
drm_mode_connector_set_tile_property(connector);
|
drm_connector_set_tile_property(connector);
|
||||||
}
|
}
|
||||||
port->has_audio = drm_detect_monitor_audio(edid);
|
port->has_audio = drm_detect_monitor_audio(edid);
|
||||||
drm_dp_put_port(port);
|
drm_dp_put_port(port);
|
||||||
|
|||||||
@@ -54,13 +54,14 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl");
|
|||||||
MODULE_DESCRIPTION("DRM shared core routines");
|
MODULE_DESCRIPTION("DRM shared core routines");
|
||||||
MODULE_LICENSE("GPL and additional rights");
|
MODULE_LICENSE("GPL and additional rights");
|
||||||
MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug category.\n"
|
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 0 (0x01) will enable CORE messages (drm core code)\n"
|
||||||
"\t\tBit 1 (0x02) will enable DRIVER messages (drm controller 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 2 (0x04) will enable KMS messages (modesetting code)\n"
|
||||||
"\t\tBit 3 (0x08) will enable PRIME messages (prime 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 4 (0x10) will enable ATOMIC messages (atomic code)\n"
|
||||||
"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n"
|
"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n"
|
||||||
"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)");
|
"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)\n"
|
||||||
|
"\t\tBit 8 (0x100) will enable DP messages (displayport 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);
|
||||||
|
|||||||
@@ -152,27 +152,27 @@ const struct drm_format_info *__drm_format_info(u32 format)
|
|||||||
{ .format = DRM_FORMAT_XBGR8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
|
{ .format = DRM_FORMAT_XBGR8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
|
||||||
{ .format = DRM_FORMAT_RGBX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
|
{ .format = DRM_FORMAT_RGBX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
|
||||||
{ .format = DRM_FORMAT_BGRX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
|
{ .format = DRM_FORMAT_BGRX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
|
||||||
{ .format = DRM_FORMAT_YUV410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4 },
|
{ .format = DRM_FORMAT_YUV410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YVU410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4 },
|
{ .format = DRM_FORMAT_YVU410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YUV411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1 },
|
{ .format = DRM_FORMAT_YUV411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YVU411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1 },
|
{ .format = DRM_FORMAT_YVU411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YUV420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2 },
|
{ .format = DRM_FORMAT_YUV420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YVU420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2 },
|
{ .format = DRM_FORMAT_YVU420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YUV422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1 },
|
{ .format = DRM_FORMAT_YUV422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1 },
|
{ .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1 },
|
{ .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1 },
|
{ .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
|
{ .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
|
{ .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1 },
|
{ .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1 },
|
{ .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1 },
|
{ .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1 },
|
{ .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
|
{ .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
|
{ .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
|
{ .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
|
{ .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
|
||||||
{ .format = DRM_FORMAT_AYUV, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
|
{ .format = DRM_FORMAT_AYUV, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true },
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|||||||
@@ -641,7 +641,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
|
|||||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_UNLOCKED),
|
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_UNLOCKED),
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_UNLOCKED),
|
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_UNLOCKED),
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_UNLOCKED),
|
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_UNLOCKED),
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
|
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_connector_property_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_UNLOCKED),
|
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_UNLOCKED),
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_UNLOCKED),
|
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_UNLOCKED),
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, DRM_UNLOCKED),
|
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, DRM_UNLOCKED),
|
||||||
|
|||||||
@@ -433,8 +433,7 @@ static int set_property_legacy(struct drm_mode_object *obj,
|
|||||||
drm_modeset_lock_all(dev);
|
drm_modeset_lock_all(dev);
|
||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case DRM_MODE_OBJECT_CONNECTOR:
|
case DRM_MODE_OBJECT_CONNECTOR:
|
||||||
ret = drm_mode_connector_set_obj_prop(obj, prop,
|
ret = drm_connector_set_obj_prop(obj, prop, prop_value);
|
||||||
prop_value);
|
|
||||||
break;
|
break;
|
||||||
case DRM_MODE_OBJECT_CRTC:
|
case DRM_MODE_OBJECT_CRTC:
|
||||||
ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
|
ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
|
||||||
|
|||||||
@@ -1353,7 +1353,7 @@ void drm_mode_sort(struct list_head *mode_list)
|
|||||||
EXPORT_SYMBOL(drm_mode_sort);
|
EXPORT_SYMBOL(drm_mode_sort);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_connector_list_update - update the mode list for the connector
|
* drm_connector_list_update - update the mode list for the connector
|
||||||
* @connector: the connector to update
|
* @connector: the connector to update
|
||||||
*
|
*
|
||||||
* This moves the modes from the @connector probed_modes list
|
* This moves the modes from the @connector probed_modes list
|
||||||
@@ -1363,7 +1363,7 @@ EXPORT_SYMBOL(drm_mode_sort);
|
|||||||
* This is just a helper functions doesn't validate any modes itself and also
|
* This is just a helper functions doesn't validate any modes itself and also
|
||||||
* doesn't prune any invalid modes. Callers need to do that themselves.
|
* doesn't prune any invalid modes. Callers need to do that themselves.
|
||||||
*/
|
*/
|
||||||
void drm_mode_connector_list_update(struct drm_connector *connector)
|
void drm_connector_list_update(struct drm_connector *connector)
|
||||||
{
|
{
|
||||||
struct drm_display_mode *pmode, *pt;
|
struct drm_display_mode *pmode, *pt;
|
||||||
|
|
||||||
@@ -1412,7 +1412,7 @@ void drm_mode_connector_list_update(struct drm_connector *connector)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_mode_connector_list_update);
|
EXPORT_SYMBOL(drm_connector_list_update);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_parse_command_line_for_connector - parse command line modeline for connector
|
* drm_mode_parse_command_line_for_connector - parse command line modeline for connector
|
||||||
|
|||||||
@@ -9,6 +9,13 @@
|
|||||||
#include <drm/drm_panel.h>
|
#include <drm/drm_panel.h>
|
||||||
#include <drm/drm_of.h>
|
#include <drm/drm_of.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOC: overview
|
||||||
|
*
|
||||||
|
* A set of helper functions to aid DRM drivers in parsing standard DT
|
||||||
|
* properties.
|
||||||
|
*/
|
||||||
|
|
||||||
static void drm_release_of(struct device *dev, void *data)
|
static void drm_release_of(struct device *dev, void *data)
|
||||||
{
|
{
|
||||||
of_node_put(data);
|
of_node_put(data);
|
||||||
@@ -94,7 +101,7 @@ EXPORT_SYMBOL_GPL(drm_of_component_match_add);
|
|||||||
* drm_of_component_probe - Generic probe function for a component based master
|
* drm_of_component_probe - Generic probe function for a component based master
|
||||||
* @dev: master device containing the OF node
|
* @dev: master device containing the OF node
|
||||||
* @compare_of: compare function used for matching components
|
* @compare_of: compare function used for matching components
|
||||||
* @master_ops: component master ops to be used
|
* @m_ops: component master ops to be used
|
||||||
*
|
*
|
||||||
* Parse the platform device OF node and bind all the components associated
|
* Parse the platform device OF node and bind all the components associated
|
||||||
* with the master. Interface ports are added before the encoders in order to
|
* with the master. Interface ports are added before the encoders in order to
|
||||||
|
|||||||
@@ -583,6 +583,52 @@ int drm_plane_check_pixel_format(struct drm_plane *plane,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __setplane_check(struct drm_plane *plane,
|
||||||
|
struct drm_crtc *crtc,
|
||||||
|
struct drm_framebuffer *fb,
|
||||||
|
int32_t crtc_x, int32_t crtc_y,
|
||||||
|
uint32_t crtc_w, uint32_t crtc_h,
|
||||||
|
uint32_t src_x, uint32_t src_y,
|
||||||
|
uint32_t src_w, uint32_t src_h)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Check whether this plane is usable on this CRTC */
|
||||||
|
if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
|
||||||
|
DRM_DEBUG_KMS("Invalid crtc for plane\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether this plane supports the fb pixel format. */
|
||||||
|
ret = drm_plane_check_pixel_format(plane, fb->format->format,
|
||||||
|
fb->modifier);
|
||||||
|
if (ret) {
|
||||||
|
struct drm_format_name_buf format_name;
|
||||||
|
|
||||||
|
DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
|
||||||
|
drm_get_format_name(fb->format->format,
|
||||||
|
&format_name),
|
||||||
|
fb->modifier);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Give drivers some help against integer overflows */
|
||||||
|
if (crtc_w > INT_MAX ||
|
||||||
|
crtc_x > INT_MAX - (int32_t) crtc_w ||
|
||||||
|
crtc_h > INT_MAX ||
|
||||||
|
crtc_y > INT_MAX - (int32_t) crtc_h) {
|
||||||
|
DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
|
||||||
|
crtc_w, crtc_h, crtc_x, crtc_y);
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __setplane_internal - setplane handler for internal callers
|
* __setplane_internal - setplane handler for internal callers
|
||||||
*
|
*
|
||||||
@@ -603,6 +649,8 @@ static int __setplane_internal(struct drm_plane *plane,
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
|
||||||
|
|
||||||
/* No fb means shut it down */
|
/* No fb means shut it down */
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
plane->old_fb = plane->fb;
|
plane->old_fb = plane->fb;
|
||||||
@@ -616,37 +664,9 @@ static int __setplane_internal(struct drm_plane *plane,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether this plane is usable on this CRTC */
|
ret = __setplane_check(plane, crtc, fb,
|
||||||
if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
|
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||||
DRM_DEBUG_KMS("Invalid crtc for plane\n");
|
src_x, src_y, src_w, src_h);
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether this plane supports the fb pixel format. */
|
|
||||||
ret = drm_plane_check_pixel_format(plane, fb->format->format,
|
|
||||||
fb->modifier);
|
|
||||||
if (ret) {
|
|
||||||
struct drm_format_name_buf format_name;
|
|
||||||
DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
|
|
||||||
drm_get_format_name(fb->format->format,
|
|
||||||
&format_name),
|
|
||||||
fb->modifier);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Give drivers some help against integer overflows */
|
|
||||||
if (crtc_w > INT_MAX ||
|
|
||||||
crtc_x > INT_MAX - (int32_t) crtc_w ||
|
|
||||||
crtc_h > INT_MAX ||
|
|
||||||
crtc_y > INT_MAX - (int32_t) crtc_h) {
|
|
||||||
DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
|
|
||||||
crtc_w, crtc_h, crtc_x, crtc_y);
|
|
||||||
ret = -ERANGE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -655,11 +675,9 @@ static int __setplane_internal(struct drm_plane *plane,
|
|||||||
crtc_x, crtc_y, crtc_w, crtc_h,
|
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||||
src_x, src_y, src_w, src_h, ctx);
|
src_x, src_y, src_w, src_h, ctx);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (!plane->state) {
|
plane->crtc = crtc;
|
||||||
plane->crtc = crtc;
|
plane->fb = fb;
|
||||||
plane->fb = fb;
|
drm_framebuffer_get(plane->fb);
|
||||||
drm_framebuffer_get(plane->fb);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
plane->old_fb = NULL;
|
plane->old_fb = NULL;
|
||||||
}
|
}
|
||||||
@@ -672,6 +690,41 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __setplane_atomic(struct drm_plane *plane,
|
||||||
|
struct drm_crtc *crtc,
|
||||||
|
struct drm_framebuffer *fb,
|
||||||
|
int32_t crtc_x, int32_t crtc_y,
|
||||||
|
uint32_t crtc_w, uint32_t crtc_h,
|
||||||
|
uint32_t src_x, uint32_t src_y,
|
||||||
|
uint32_t src_w, uint32_t src_h,
|
||||||
|
struct drm_modeset_acquire_ctx *ctx)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
|
||||||
|
|
||||||
|
/* No fb means shut it down */
|
||||||
|
if (!fb)
|
||||||
|
return plane->funcs->disable_plane(plane, ctx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: This is redundant with drm_atomic_plane_check(),
|
||||||
|
* but the legacy cursor/"async" .update_plane() tricks
|
||||||
|
* don't call that so we still need this here. Should remove
|
||||||
|
* this when all .update_plane() implementations have been
|
||||||
|
* fixed to call drm_atomic_plane_check().
|
||||||
|
*/
|
||||||
|
ret = __setplane_check(plane, crtc, fb,
|
||||||
|
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||||
|
src_x, src_y, src_w, src_h);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return plane->funcs->update_plane(plane, crtc, fb,
|
||||||
|
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||||
|
src_x, src_y, src_w, src_h, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static int setplane_internal(struct drm_plane *plane,
|
static int setplane_internal(struct drm_plane *plane,
|
||||||
struct drm_crtc *crtc,
|
struct drm_crtc *crtc,
|
||||||
struct drm_framebuffer *fb,
|
struct drm_framebuffer *fb,
|
||||||
@@ -689,9 +742,15 @@ retry:
|
|||||||
ret = drm_modeset_lock_all_ctx(plane->dev, &ctx);
|
ret = drm_modeset_lock_all_ctx(plane->dev, &ctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
ret = __setplane_internal(plane, crtc, fb,
|
|
||||||
crtc_x, crtc_y, crtc_w, crtc_h,
|
if (drm_drv_uses_atomic_modeset(plane->dev))
|
||||||
src_x, src_y, src_w, src_h, &ctx);
|
ret = __setplane_atomic(plane, crtc, fb,
|
||||||
|
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||||
|
src_x, src_y, src_w, src_h, &ctx);
|
||||||
|
else
|
||||||
|
ret = __setplane_internal(plane, crtc, fb,
|
||||||
|
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||||
|
src_x, src_y, src_w, src_h, &ctx);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (ret == -EDEADLK) {
|
if (ret == -EDEADLK) {
|
||||||
@@ -823,9 +882,14 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
|
|||||||
src_h = fb->height << 16;
|
src_h = fb->height << 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = __setplane_internal(plane, crtc, fb,
|
if (drm_drv_uses_atomic_modeset(dev))
|
||||||
crtc_x, crtc_y, crtc_w, crtc_h,
|
ret = __setplane_atomic(plane, crtc, fb,
|
||||||
0, 0, src_w, src_h, ctx);
|
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||||
|
0, 0, src_w, src_h, ctx);
|
||||||
|
else
|
||||||
|
ret = __setplane_internal(plane, crtc, fb,
|
||||||
|
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||||
|
0, 0, src_w, src_h, ctx);
|
||||||
|
|
||||||
if (fb)
|
if (fb)
|
||||||
drm_framebuffer_put(fb);
|
drm_framebuffer_put(fb);
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ EXPORT_SYMBOL(drm_helper_probe_detect);
|
|||||||
* using the VESA GTF/CVT formulas.
|
* using the VESA GTF/CVT formulas.
|
||||||
*
|
*
|
||||||
* 3. Modes are moved from the probed_modes list to the modes list. Potential
|
* 3. Modes are moved from the probed_modes list to the modes list. Potential
|
||||||
* duplicates are merged together (see drm_mode_connector_list_update()).
|
* duplicates are merged together (see drm_connector_list_update()).
|
||||||
* After this step the probed_modes list will be empty again.
|
* After this step the probed_modes list will be empty again.
|
||||||
*
|
*
|
||||||
* 4. Any non-stale mode on the modes list then undergoes validation
|
* 4. Any non-stale mode on the modes list then undergoes validation
|
||||||
@@ -472,7 +472,7 @@ retry:
|
|||||||
if (connector->status == connector_status_disconnected) {
|
if (connector->status == connector_status_disconnected) {
|
||||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
|
||||||
connector->base.id, connector->name);
|
connector->base.id, connector->name);
|
||||||
drm_mode_connector_update_edid_property(connector, NULL);
|
drm_connector_update_edid_property(connector, NULL);
|
||||||
verbose_prune = false;
|
verbose_prune = false;
|
||||||
goto prune;
|
goto prune;
|
||||||
}
|
}
|
||||||
@@ -485,7 +485,7 @@ retry:
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
goto prune;
|
goto prune;
|
||||||
|
|
||||||
drm_mode_connector_list_update(connector);
|
drm_connector_list_update(connector);
|
||||||
|
|
||||||
if (connector->interlace_allowed)
|
if (connector->interlace_allowed)
|
||||||
mode_flags |= DRM_MODE_FLAG_INTERLACE;
|
mode_flags |= DRM_MODE_FLAG_INTERLACE;
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
|
|||||||
if (ret || !connector)
|
if (ret || !connector)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return drm_mode_connector_attach_encoder(connector, encoder);
|
return drm_connector_attach_encoder(connector, encoder);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_simple_display_pipe_init);
|
EXPORT_SYMBOL(drm_simple_display_pipe_init);
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
*
|
*
|
||||||
* * Writeback connectors don't provide a way to output visually to the user.
|
* * Writeback connectors don't provide a way to output visually to the user.
|
||||||
*
|
*
|
||||||
* * Writeback connectors should always report as "disconnected" (so that
|
* * Writeback connectors are visible to userspace only when the client sets
|
||||||
* clients which don't understand them will ignore them).
|
* DRM_CLIENT_CAP_WRITEBACK_CONNECTORS.
|
||||||
*
|
*
|
||||||
* * Writeback connectors don't have EDID.
|
* * Writeback connectors don't have EDID.
|
||||||
*
|
*
|
||||||
@@ -202,7 +202,7 @@ int drm_writeback_connector_init(struct drm_device *dev,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto connector_fail;
|
goto connector_fail;
|
||||||
|
|
||||||
ret = drm_mode_connector_attach_encoder(connector,
|
ret = drm_connector_attach_encoder(connector,
|
||||||
&wb_connector->encoder);
|
&wb_connector->encoder);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto attach_fail;
|
goto attach_fail;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ static int exynos_dpi_create_connector(struct drm_encoder *encoder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
drm_connector_helper_add(connector, &exynos_dpi_connector_helper_funcs);
|
drm_connector_helper_add(connector, &exynos_dpi_connector_helper_funcs);
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1479,7 +1479,7 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder)
|
|||||||
|
|
||||||
connector->status = connector_status_disconnected;
|
connector->status = connector_status_disconnected;
|
||||||
drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
|
drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ static int vidi_get_modes(struct drm_connector *connector)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
|
|
||||||
return drm_add_edid_modes(connector, edid);
|
return drm_add_edid_modes(connector, edid);
|
||||||
}
|
}
|
||||||
@@ -344,7 +344,7 @@ static int vidi_create_connector(struct drm_encoder *encoder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
drm_connector_helper_add(connector, &vidi_connector_helper_funcs);
|
drm_connector_helper_add(connector, &vidi_connector_helper_funcs);
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -888,7 +888,7 @@ static int hdmi_get_modes(struct drm_connector *connector)
|
|||||||
(hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
|
(hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
|
||||||
edid->width_cm, edid->height_cm);
|
edid->width_cm, edid->height_cm);
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
|
cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
|
||||||
|
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
@@ -951,7 +951,7 @@ static int hdmi_create_connector(struct drm_encoder *encoder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
|
drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
if (hdata->bridge) {
|
if (hdata->bridge) {
|
||||||
ret = drm_bridge_attach(encoder, hdata->bridge, NULL);
|
ret = drm_bridge_attach(encoder, hdata->bridge, NULL);
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ static int fsl_dcu_attach_panel(struct fsl_dcu_drm_device *fsl_dev,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_cleanup;
|
goto err_cleanup;
|
||||||
|
|
||||||
ret = drm_mode_connector_attach_encoder(connector, encoder);
|
ret = drm_connector_attach_encoder(connector, encoder);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_sysfs;
|
goto err_sysfs;
|
||||||
|
|
||||||
|
|||||||
@@ -1770,7 +1770,7 @@ static int cdv_intel_dp_get_modes(struct drm_connector *connector)
|
|||||||
|
|
||||||
edid = drm_get_edid(connector, &intel_dp->adapter);
|
edid = drm_get_edid(connector, &intel_dp->adapter);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ static int cdv_hdmi_get_modes(struct drm_connector *connector)
|
|||||||
|
|
||||||
edid = drm_get_edid(connector, &gma_encoder->i2c_bus->adapter);
|
edid = drm_get_edid(connector, &gma_encoder->i2c_bus->adapter);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -665,7 +665,7 @@ void gma_connector_attach_encoder(struct gma_connector *connector,
|
|||||||
struct gma_encoder *encoder)
|
struct gma_encoder *encoder)
|
||||||
{
|
{
|
||||||
connector->encoder = encoder;
|
connector->encoder = encoder;
|
||||||
drm_mode_connector_attach_encoder(&connector->base,
|
drm_connector_attach_encoder(&connector->base,
|
||||||
&encoder->base);
|
&encoder->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ struct vbt_header {
|
|||||||
u8 reserved0;
|
u8 reserved0;
|
||||||
u32 bdb_offset; /**< from beginning of VBT */
|
u32 bdb_offset; /**< from beginning of VBT */
|
||||||
u32 aim_offset[4]; /**< from beginning of VBT */
|
u32 aim_offset[4]; /**< from beginning of VBT */
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
struct bdb_header {
|
struct bdb_header {
|
||||||
@@ -61,7 +61,7 @@ struct vbios_data {
|
|||||||
u8 rsvd4; /* popup memory size */
|
u8 rsvd4; /* popup memory size */
|
||||||
u8 resize_pci_bios;
|
u8 resize_pci_bios;
|
||||||
u8 rsvd5; /* is crt already on ddc2 */
|
u8 rsvd5; /* is crt already on ddc2 */
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are several types of BIOS data blocks (BDBs), each block has
|
* There are several types of BIOS data blocks (BDBs), each block has
|
||||||
@@ -133,7 +133,7 @@ struct bdb_general_features {
|
|||||||
u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */
|
u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */
|
||||||
u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */
|
u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */
|
||||||
u8 rsvd11:3; /* finish byte */
|
u8 rsvd11:3; /* finish byte */
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
/* pre-915 */
|
/* pre-915 */
|
||||||
#define GPIO_PIN_DVI_LVDS 0x03 /* "DVI/LVDS DDC GPIO pins" */
|
#define GPIO_PIN_DVI_LVDS 0x03 /* "DVI/LVDS DDC GPIO pins" */
|
||||||
@@ -213,7 +213,7 @@ struct child_device_config {
|
|||||||
u8 dvo2_wiring;
|
u8 dvo2_wiring;
|
||||||
u16 extended_type;
|
u16 extended_type;
|
||||||
u8 dvo_function;
|
u8 dvo_function;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
struct bdb_general_definitions {
|
struct bdb_general_definitions {
|
||||||
@@ -256,7 +256,7 @@ struct bdb_lvds_options {
|
|||||||
u8 lvds_edid:1;
|
u8 lvds_edid:1;
|
||||||
u8 rsvd2:1;
|
u8 rsvd2:1;
|
||||||
u8 rsvd4;
|
u8 rsvd4;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct bdb_lvds_backlight {
|
struct bdb_lvds_backlight {
|
||||||
u8 type:2;
|
u8 type:2;
|
||||||
@@ -268,7 +268,7 @@ struct bdb_lvds_backlight {
|
|||||||
u8 i2caddr;
|
u8 i2caddr;
|
||||||
u8 brightnesscmd;
|
u8 brightnesscmd;
|
||||||
/*FIXME: more...*/
|
/*FIXME: more...*/
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
/* LFP pointer table contains entries to the struct below */
|
/* LFP pointer table contains entries to the struct below */
|
||||||
struct bdb_lvds_lfp_data_ptr {
|
struct bdb_lvds_lfp_data_ptr {
|
||||||
@@ -278,12 +278,12 @@ struct bdb_lvds_lfp_data_ptr {
|
|||||||
u8 dvo_table_size;
|
u8 dvo_table_size;
|
||||||
u16 panel_pnp_id_offset;
|
u16 panel_pnp_id_offset;
|
||||||
u8 pnp_table_size;
|
u8 pnp_table_size;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct bdb_lvds_lfp_data_ptrs {
|
struct bdb_lvds_lfp_data_ptrs {
|
||||||
u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
|
u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
|
||||||
struct bdb_lvds_lfp_data_ptr ptr[16];
|
struct bdb_lvds_lfp_data_ptr ptr[16];
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
/* LFP data has 3 blocks per entry */
|
/* LFP data has 3 blocks per entry */
|
||||||
struct lvds_fp_timing {
|
struct lvds_fp_timing {
|
||||||
@@ -300,7 +300,7 @@ struct lvds_fp_timing {
|
|||||||
u32 pfit_reg;
|
u32 pfit_reg;
|
||||||
u32 pfit_reg_val;
|
u32 pfit_reg_val;
|
||||||
u16 terminator;
|
u16 terminator;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct lvds_dvo_timing {
|
struct lvds_dvo_timing {
|
||||||
u16 clock; /**< In 10khz */
|
u16 clock; /**< In 10khz */
|
||||||
@@ -328,7 +328,7 @@ struct lvds_dvo_timing {
|
|||||||
u8 vsync_positive:1;
|
u8 vsync_positive:1;
|
||||||
u8 hsync_positive:1;
|
u8 hsync_positive:1;
|
||||||
u8 rsvd2:1;
|
u8 rsvd2:1;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct lvds_pnp_id {
|
struct lvds_pnp_id {
|
||||||
u16 mfg_name;
|
u16 mfg_name;
|
||||||
@@ -336,17 +336,17 @@ struct lvds_pnp_id {
|
|||||||
u32 serial;
|
u32 serial;
|
||||||
u8 mfg_week;
|
u8 mfg_week;
|
||||||
u8 mfg_year;
|
u8 mfg_year;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct bdb_lvds_lfp_data_entry {
|
struct bdb_lvds_lfp_data_entry {
|
||||||
struct lvds_fp_timing fp_timing;
|
struct lvds_fp_timing fp_timing;
|
||||||
struct lvds_dvo_timing dvo_timing;
|
struct lvds_dvo_timing dvo_timing;
|
||||||
struct lvds_pnp_id pnp_id;
|
struct lvds_pnp_id pnp_id;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct bdb_lvds_lfp_data {
|
struct bdb_lvds_lfp_data {
|
||||||
struct bdb_lvds_lfp_data_entry data[16];
|
struct bdb_lvds_lfp_data_entry data[16];
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct aimdb_header {
|
struct aimdb_header {
|
||||||
char signature[16];
|
char signature[16];
|
||||||
@@ -354,12 +354,12 @@ struct aimdb_header {
|
|||||||
u16 aimdb_version;
|
u16 aimdb_version;
|
||||||
u16 aimdb_header_size;
|
u16 aimdb_header_size;
|
||||||
u16 aimdb_size;
|
u16 aimdb_size;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct aimdb_block {
|
struct aimdb_block {
|
||||||
u8 aimdb_id;
|
u8 aimdb_id;
|
||||||
u16 aimdb_size;
|
u16 aimdb_size;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct vch_panel_data {
|
struct vch_panel_data {
|
||||||
u16 fp_timing_offset;
|
u16 fp_timing_offset;
|
||||||
@@ -370,12 +370,12 @@ struct vch_panel_data {
|
|||||||
u8 text_fitting_size;
|
u8 text_fitting_size;
|
||||||
u16 graphics_fitting_offset;
|
u16 graphics_fitting_offset;
|
||||||
u8 graphics_fitting_size;
|
u8 graphics_fitting_size;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct vch_bdb_22 {
|
struct vch_bdb_22 {
|
||||||
struct aimdb_block aimdb_block;
|
struct aimdb_block aimdb_block;
|
||||||
struct vch_panel_data panels[16];
|
struct vch_panel_data panels[16];
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
struct bdb_sdvo_lvds_options {
|
struct bdb_sdvo_lvds_options {
|
||||||
u8 panel_backlight;
|
u8 panel_backlight;
|
||||||
@@ -391,7 +391,7 @@ struct bdb_sdvo_lvds_options {
|
|||||||
u8 panel_misc_bits_2;
|
u8 panel_misc_bits_2;
|
||||||
u8 panel_misc_bits_3;
|
u8 panel_misc_bits_3;
|
||||||
u8 panel_misc_bits_4;
|
u8 panel_misc_bits_4;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
#define BDB_DRIVER_FEATURE_NO_LVDS 0
|
#define BDB_DRIVER_FEATURE_NO_LVDS 0
|
||||||
#define BDB_DRIVER_FEATURE_INT_LVDS 1
|
#define BDB_DRIVER_FEATURE_INT_LVDS 1
|
||||||
@@ -436,7 +436,7 @@ struct bdb_driver_features {
|
|||||||
|
|
||||||
u8 hdmi_termination;
|
u8 hdmi_termination;
|
||||||
u8 custom_vbt_version;
|
u8 custom_vbt_version;
|
||||||
} __attribute__((packed));
|
} __packed;
|
||||||
|
|
||||||
#define EDP_18BPP 0
|
#define EDP_18BPP 0
|
||||||
#define EDP_24BPP 1
|
#define EDP_24BPP 1
|
||||||
|
|||||||
@@ -999,7 +999,7 @@ struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
|
|||||||
p_funcs->encoder_helper_funcs);
|
p_funcs->encoder_helper_funcs);
|
||||||
|
|
||||||
/*attach to given connector*/
|
/*attach to given connector*/
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
/*set possible crtcs and clones*/
|
/*set possible crtcs and clones*/
|
||||||
if (dsi_connector->pipe) {
|
if (dsi_connector->pipe) {
|
||||||
|
|||||||
@@ -578,7 +578,7 @@ static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (edid) {
|
if (edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ void oaktrail_lvds_init(struct drm_device *dev,
|
|||||||
* preferred mode is the right one.
|
* preferred mode is the right one.
|
||||||
*/
|
*/
|
||||||
if (edid) {
|
if (edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
drm_add_edid_modes(connector, edid);
|
drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ int psb_intel_ddc_get_modes(struct drm_connector *connector,
|
|||||||
|
|
||||||
edid = drm_get_edid(connector, adapter);
|
edid = drm_get_edid(connector, adapter);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1472,7 +1472,7 @@ static void psb_intel_sdvo_get_ddc_modes(struct drm_connector *connector)
|
|||||||
bool connector_is_digital = !!IS_TMDS(psb_intel_sdvo_connector);
|
bool connector_is_digital = !!IS_TMDS(psb_intel_sdvo_connector);
|
||||||
|
|
||||||
if (connector_is_digital == monitor_is_digital) {
|
if (connector_is_digital == monitor_is_digital) {
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
drm_add_edid_modes(connector, edid);
|
drm_add_edid_modes(connector, edid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
|
drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1243,7 +1243,7 @@ static int tda998x_connector_get_modes(struct drm_connector *connector)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
n = drm_add_edid_modes(connector, edid);
|
n = drm_add_edid_modes(connector, edid);
|
||||||
|
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
@@ -1301,7 +1301,7 @@ static int tda998x_connector_init(struct tda998x_priv *priv,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder);
|
drm_connector_attach_encoder(&priv->connector, &priv->encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3657,7 +3657,7 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
|
|||||||
plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
|
plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
|
||||||
plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
|
plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
|
||||||
|
|
||||||
if (intel_format_is_yuv(fb->format->format)) {
|
if (fb->format->is_yuv) {
|
||||||
if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
|
if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
|
||||||
plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
|
plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
|
||||||
else
|
else
|
||||||
@@ -15933,8 +15933,7 @@ void intel_connector_attach_encoder(struct intel_connector *connector,
|
|||||||
struct intel_encoder *encoder)
|
struct intel_encoder *encoder)
|
||||||
{
|
{
|
||||||
connector->encoder = encoder;
|
connector->encoder = encoder;
|
||||||
drm_mode_connector_attach_encoder(&connector->base,
|
drm_connector_attach_encoder(&connector->base, &encoder->base);
|
||||||
&encoder->base);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -4487,6 +4487,9 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
|
|||||||
DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
|
DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle CEC interrupts, if any */
|
||||||
|
drm_dp_cec_irq(&intel_dp->aux);
|
||||||
|
|
||||||
/* defer to the hotplug work for link retraining if needed */
|
/* defer to the hotplug work for link retraining if needed */
|
||||||
if (intel_dp_needs_link_retrain(intel_dp))
|
if (intel_dp_needs_link_retrain(intel_dp))
|
||||||
return false;
|
return false;
|
||||||
@@ -4803,6 +4806,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
|
|||||||
intel_connector->detect_edid = edid;
|
intel_connector->detect_edid = edid;
|
||||||
|
|
||||||
intel_dp->has_audio = drm_detect_monitor_audio(edid);
|
intel_dp->has_audio = drm_detect_monitor_audio(edid);
|
||||||
|
drm_dp_cec_set_edid(&intel_dp->aux, edid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4810,6 +4814,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
|
|||||||
{
|
{
|
||||||
struct intel_connector *intel_connector = intel_dp->attached_connector;
|
struct intel_connector *intel_connector = intel_dp->attached_connector;
|
||||||
|
|
||||||
|
drm_dp_cec_unset_edid(&intel_dp->aux);
|
||||||
kfree(intel_connector->detect_edid);
|
kfree(intel_connector->detect_edid);
|
||||||
intel_connector->detect_edid = NULL;
|
intel_connector->detect_edid = NULL;
|
||||||
|
|
||||||
@@ -4998,6 +5003,7 @@ static int
|
|||||||
intel_dp_connector_register(struct drm_connector *connector)
|
intel_dp_connector_register(struct drm_connector *connector)
|
||||||
{
|
{
|
||||||
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
||||||
|
struct drm_device *dev = connector->dev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = intel_connector_register(connector);
|
ret = intel_connector_register(connector);
|
||||||
@@ -5010,13 +5016,20 @@ intel_dp_connector_register(struct drm_connector *connector)
|
|||||||
intel_dp->aux.name, connector->kdev->kobj.name);
|
intel_dp->aux.name, connector->kdev->kobj.name);
|
||||||
|
|
||||||
intel_dp->aux.dev = connector->kdev;
|
intel_dp->aux.dev = connector->kdev;
|
||||||
return drm_dp_aux_register(&intel_dp->aux);
|
ret = drm_dp_aux_register(&intel_dp->aux);
|
||||||
|
if (!ret)
|
||||||
|
drm_dp_cec_register_connector(&intel_dp->aux,
|
||||||
|
connector->name, dev->dev);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
intel_dp_connector_unregister(struct drm_connector *connector)
|
intel_dp_connector_unregister(struct drm_connector *connector)
|
||||||
{
|
{
|
||||||
drm_dp_aux_unregister(&intel_attached_dp(connector)->aux);
|
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
||||||
|
|
||||||
|
drm_dp_cec_unregister_connector(&intel_dp->aux);
|
||||||
|
drm_dp_aux_unregister(&intel_dp->aux);
|
||||||
intel_connector_unregister(connector);
|
intel_connector_unregister(connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6212,7 +6225,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|||||||
edid = drm_get_edid(connector, &intel_dp->aux.ddc);
|
edid = drm_get_edid(connector, &intel_dp->aux.ddc);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
if (drm_add_edid_modes(connector, edid)) {
|
if (drm_add_edid_modes(connector, edid)) {
|
||||||
drm_mode_connector_update_edid_property(connector,
|
drm_connector_update_edid_property(connector,
|
||||||
edid);
|
edid);
|
||||||
} else {
|
} else {
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
@@ -6301,8 +6314,8 @@ static void intel_dp_modeset_retry_work_fn(struct work_struct *work)
|
|||||||
/* Set connector link status to BAD and send a Uevent to notify
|
/* Set connector link status to BAD and send a Uevent to notify
|
||||||
* userspace to do a modeset.
|
* userspace to do a modeset.
|
||||||
*/
|
*/
|
||||||
drm_mode_connector_set_link_status_property(connector,
|
drm_connector_set_link_status_property(connector,
|
||||||
DRM_MODE_LINK_STATUS_BAD);
|
DRM_MODE_LINK_STATUS_BAD);
|
||||||
mutex_unlock(&connector->dev->mode_config.mutex);
|
mutex_unlock(&connector->dev->mode_config.mutex);
|
||||||
/* Send Hotplug uevent so userspace can reprobe */
|
/* Send Hotplug uevent so userspace can reprobe */
|
||||||
drm_kms_helper_hotplug_event(connector->dev);
|
drm_kms_helper_hotplug_event(connector->dev);
|
||||||
|
|||||||
@@ -466,8 +466,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
|
|||||||
struct drm_encoder *enc =
|
struct drm_encoder *enc =
|
||||||
&intel_dp->mst_encoders[pipe]->base.base;
|
&intel_dp->mst_encoders[pipe]->base.base;
|
||||||
|
|
||||||
ret = drm_mode_connector_attach_encoder(&intel_connector->base,
|
ret = drm_connector_attach_encoder(&intel_connector->base, enc);
|
||||||
enc);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -475,7 +474,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
|
|||||||
drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
|
drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
|
||||||
drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
|
drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
|
||||||
|
|
||||||
ret = drm_mode_connector_set_path_property(connector, pathprop);
|
ret = drm_connector_set_path_property(connector, pathprop);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
|||||||
@@ -2072,7 +2072,6 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
|
|||||||
|
|
||||||
|
|
||||||
/* intel_sprite.c */
|
/* intel_sprite.c */
|
||||||
bool intel_format_is_yuv(u32 format);
|
|
||||||
int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
|
int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
|
||||||
int usecs);
|
int usecs);
|
||||||
struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
|
struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
|
||||||
@@ -2088,7 +2087,6 @@ void skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc);
|
|||||||
bool skl_plane_get_hw_state(struct intel_plane *plane, enum pipe *pipe);
|
bool skl_plane_get_hw_state(struct intel_plane *plane, enum pipe *pipe);
|
||||||
bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
|
bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
|
||||||
enum pipe pipe, enum plane_id plane_id);
|
enum pipe pipe, enum plane_id plane_id);
|
||||||
bool intel_format_is_yuv(uint32_t format);
|
|
||||||
bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
|
bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
|
||||||
enum pipe pipe, enum plane_id plane_id);
|
enum pipe pipe, enum plane_id plane_id);
|
||||||
|
|
||||||
|
|||||||
@@ -1131,7 +1131,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
|||||||
intel_gmbus_get_adapter(dev_priv, pin));
|
intel_gmbus_get_adapter(dev_priv, pin));
|
||||||
if (edid) {
|
if (edid) {
|
||||||
if (drm_add_edid_modes(connector, edid)) {
|
if (drm_add_edid_modes(connector, edid)) {
|
||||||
drm_mode_connector_update_edid_property(connector,
|
drm_connector_update_edid_property(connector,
|
||||||
edid);
|
edid);
|
||||||
} else {
|
} else {
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ int intel_connector_update_modes(struct drm_connector *connector,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -1911,7 +1911,7 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
|
|||||||
if (edid != NULL) {
|
if (edid != NULL) {
|
||||||
if (intel_sdvo_connector_matches_edid(to_intel_sdvo_connector(connector),
|
if (intel_sdvo_connector_matches_edid(to_intel_sdvo_connector(connector),
|
||||||
edid)) {
|
edid)) {
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
drm_add_edid_modes(connector, edid);
|
drm_add_edid_modes(connector, edid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,20 +41,6 @@
|
|||||||
#include <drm/i915_drm.h>
|
#include <drm/i915_drm.h>
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
|
|
||||||
bool intel_format_is_yuv(u32 format)
|
|
||||||
{
|
|
||||||
switch (format) {
|
|
||||||
case DRM_FORMAT_YUYV:
|
|
||||||
case DRM_FORMAT_UYVY:
|
|
||||||
case DRM_FORMAT_VYUY:
|
|
||||||
case DRM_FORMAT_YVYU:
|
|
||||||
case DRM_FORMAT_NV12:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
|
int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
|
||||||
int usecs)
|
int usecs)
|
||||||
{
|
{
|
||||||
@@ -416,7 +402,7 @@ chv_update_csc(const struct intel_plane_state *plane_state)
|
|||||||
const s16 *csc = csc_matrix[plane_state->base.color_encoding];
|
const s16 *csc = csc_matrix[plane_state->base.color_encoding];
|
||||||
|
|
||||||
/* Seems RGB data bypasses the CSC always */
|
/* Seems RGB data bypasses the CSC always */
|
||||||
if (!intel_format_is_yuv(fb->format->format))
|
if (!fb->format->is_yuv)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
|
I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
|
||||||
@@ -451,7 +437,7 @@ vlv_update_clrc(const struct intel_plane_state *plane_state)
|
|||||||
enum plane_id plane_id = plane->id;
|
enum plane_id plane_id = plane->id;
|
||||||
int contrast, brightness, sh_scale, sh_sin, sh_cos;
|
int contrast, brightness, sh_scale, sh_sin, sh_cos;
|
||||||
|
|
||||||
if (intel_format_is_yuv(fb->format->format) &&
|
if (fb->format->is_yuv &&
|
||||||
plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
|
plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
|
||||||
/*
|
/*
|
||||||
* Expand limited range to full range:
|
* Expand limited range to full range:
|
||||||
@@ -1052,7 +1038,7 @@ intel_check_sprite_plane(struct intel_plane *plane,
|
|||||||
src->y1 = src_y << 16;
|
src->y1 = src_y << 16;
|
||||||
src->y2 = (src_y + src_h) << 16;
|
src->y2 = (src_y + src_h) << 16;
|
||||||
|
|
||||||
if (intel_format_is_yuv(fb->format->format) &&
|
if (fb->format->is_yuv &&
|
||||||
fb->format->format != DRM_FORMAT_NV12 &&
|
fb->format->format != DRM_FORMAT_NV12 &&
|
||||||
(src_x % 2 || src_w % 2)) {
|
(src_x % 2 || src_w % 2)) {
|
||||||
DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
|
DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
|
|||||||
imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc);
|
imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc);
|
||||||
|
|
||||||
if (imx_ldb_ch->edid) {
|
if (imx_ldb_ch->edid) {
|
||||||
drm_mode_connector_update_edid_property(connector,
|
drm_connector_update_edid_property(connector,
|
||||||
imx_ldb_ch->edid);
|
imx_ldb_ch->edid);
|
||||||
num_modes = drm_add_edid_modes(connector, imx_ldb_ch->edid);
|
num_modes = drm_add_edid_modes(connector, imx_ldb_ch->edid);
|
||||||
}
|
}
|
||||||
@@ -471,8 +471,7 @@ static int imx_ldb_register(struct drm_device *drm,
|
|||||||
drm_connector_init(drm, &imx_ldb_ch->connector,
|
drm_connector_init(drm, &imx_ldb_ch->connector,
|
||||||
&imx_ldb_connector_funcs,
|
&imx_ldb_connector_funcs,
|
||||||
DRM_MODE_CONNECTOR_LVDS);
|
DRM_MODE_CONNECTOR_LVDS);
|
||||||
drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
|
drm_connector_attach_encoder(&imx_ldb_ch->connector, encoder);
|
||||||
encoder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imx_ldb_ch->panel) {
|
if (imx_ldb_ch->panel) {
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ static int imx_tve_connector_get_modes(struct drm_connector *connector)
|
|||||||
|
|
||||||
edid = drm_get_edid(connector, tve->ddc);
|
edid = drm_get_edid(connector, tve->ddc);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
}
|
}
|
||||||
@@ -493,7 +493,7 @@ static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve)
|
|||||||
drm_connector_init(drm, &tve->connector, &imx_tve_connector_funcs,
|
drm_connector_init(drm, &tve->connector, &imx_tve_connector_funcs,
|
||||||
DRM_MODE_CONNECTOR_VGA);
|
DRM_MODE_CONNECTOR_VGA);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(&tve->connector, &tve->encoder);
|
drm_connector_attach_encoder(&tve->connector, &tve->encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (imxpd->edid) {
|
if (imxpd->edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, imxpd->edid);
|
drm_connector_update_edid_property(connector, imxpd->edid);
|
||||||
num_modes = drm_add_edid_modes(connector, imxpd->edid);
|
num_modes = drm_add_edid_modes(connector, imxpd->edid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ static int imx_pd_register(struct drm_device *drm,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
drm_mode_connector_attach_encoder(&imxpd->connector, encoder);
|
drm_connector_attach_encoder(&imxpd->connector, encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -782,7 +782,7 @@ static int mtk_dsi_create_connector(struct drm_device *drm, struct mtk_dsi *dsi)
|
|||||||
drm_connector_helper_add(&dsi->conn, &mtk_dsi_connector_helper_funcs);
|
drm_connector_helper_add(&dsi->conn, &mtk_dsi_connector_helper_funcs);
|
||||||
|
|
||||||
dsi->conn.dpms = DRM_MODE_DPMS_OFF;
|
dsi->conn.dpms = DRM_MODE_DPMS_OFF;
|
||||||
drm_mode_connector_attach_encoder(&dsi->conn, &dsi->encoder);
|
drm_connector_attach_encoder(&dsi->conn, &dsi->encoder);
|
||||||
|
|
||||||
if (dsi->panel) {
|
if (dsi->panel) {
|
||||||
ret = drm_panel_attach(dsi->panel, &dsi->conn);
|
ret = drm_panel_attach(dsi->panel, &dsi->conn);
|
||||||
|
|||||||
@@ -1220,7 +1220,7 @@ static int mtk_hdmi_conn_get_modes(struct drm_connector *conn)
|
|||||||
|
|
||||||
hdmi->dvi_mode = !drm_detect_monitor_audio(edid);
|
hdmi->dvi_mode = !drm_detect_monitor_audio(edid);
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(conn, edid);
|
drm_connector_update_edid_property(conn, edid);
|
||||||
|
|
||||||
ret = drm_add_edid_modes(conn, edid);
|
ret = drm_add_edid_modes(conn, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
@@ -1306,7 +1306,7 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge)
|
|||||||
hdmi->conn.interlace_allowed = true;
|
hdmi->conn.interlace_allowed = true;
|
||||||
hdmi->conn.doublescan_allowed = false;
|
hdmi->conn.doublescan_allowed = false;
|
||||||
|
|
||||||
ret = drm_mode_connector_attach_encoder(&hdmi->conn,
|
ret = drm_connector_attach_encoder(&hdmi->conn,
|
||||||
bridge->encoder);
|
bridge->encoder);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(hdmi->dev,
|
dev_err(hdmi->dev,
|
||||||
|
|||||||
@@ -329,6 +329,12 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
|
|||||||
|
|
||||||
vclk_freq = mode->clock;
|
vclk_freq = mode->clock;
|
||||||
|
|
||||||
|
if (!vic) {
|
||||||
|
meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq,
|
||||||
|
vclk_freq, vclk_freq, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||||
vclk_freq *= 2;
|
vclk_freq *= 2;
|
||||||
|
|
||||||
@@ -542,10 +548,12 @@ static enum drm_mode_status
|
|||||||
dw_hdmi_mode_valid(struct drm_connector *connector,
|
dw_hdmi_mode_valid(struct drm_connector *connector,
|
||||||
const struct drm_display_mode *mode)
|
const struct drm_display_mode *mode)
|
||||||
{
|
{
|
||||||
|
struct meson_drm *priv = connector->dev->dev_private;
|
||||||
unsigned int vclk_freq;
|
unsigned int vclk_freq;
|
||||||
unsigned int venc_freq;
|
unsigned int venc_freq;
|
||||||
unsigned int hdmi_freq;
|
unsigned int hdmi_freq;
|
||||||
int vic = drm_match_cea_mode(mode);
|
int vic = drm_match_cea_mode(mode);
|
||||||
|
enum drm_mode_status status;
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
|
DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
|
||||||
mode->base.id, mode->name, mode->vrefresh, mode->clock,
|
mode->base.id, mode->name, mode->vrefresh, mode->clock,
|
||||||
@@ -556,8 +564,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
|
|||||||
|
|
||||||
/* Check against non-VIC supported modes */
|
/* Check against non-VIC supported modes */
|
||||||
if (!vic) {
|
if (!vic) {
|
||||||
if (!meson_venc_hdmi_supported_mode(mode))
|
status = meson_venc_hdmi_supported_mode(mode);
|
||||||
return MODE_BAD;
|
if (status != MODE_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return meson_vclk_dmt_supported_freq(priv, mode->clock);
|
||||||
/* Check against supported VIC modes */
|
/* Check against supported VIC modes */
|
||||||
} else if (!meson_venc_hdmi_supported_vic(vic))
|
} else if (!meson_venc_hdmi_supported_vic(vic))
|
||||||
return MODE_BAD;
|
return MODE_BAD;
|
||||||
@@ -583,16 +594,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
|
|||||||
dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__,
|
dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__,
|
||||||
vclk_freq, venc_freq, hdmi_freq);
|
vclk_freq, venc_freq, hdmi_freq);
|
||||||
|
|
||||||
/* Finally filter by configurable vclk frequencies */
|
/* Finally filter by configurable vclk frequencies for VIC modes */
|
||||||
switch (vclk_freq) {
|
switch (vclk_freq) {
|
||||||
case 25175:
|
|
||||||
case 40000:
|
|
||||||
case 54000:
|
case 54000:
|
||||||
case 65000:
|
|
||||||
case 74250:
|
case 74250:
|
||||||
case 108000:
|
|
||||||
case 148500:
|
case 148500:
|
||||||
case 162000:
|
|
||||||
case 297000:
|
case 297000:
|
||||||
case 594000:
|
case 594000:
|
||||||
return MODE_OK;
|
return MODE_OK;
|
||||||
|
|||||||
@@ -320,32 +320,23 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
|
|||||||
CTS_VDAC_EN, CTS_VDAC_EN);
|
CTS_VDAC_EN, CTS_VDAC_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
/* PLL O1 O2 O3 VP DV EN TX */
|
/* PLL O1 O2 O3 VP DV EN TX */
|
||||||
/* 4320 /4 /4 /1 /5 /1 => /2 /2 */
|
/* 4320 /4 /4 /1 /5 /1 => /2 /2 */
|
||||||
#define MESON_VCLK_HDMI_ENCI_54000 1
|
MESON_VCLK_HDMI_ENCI_54000 = 1,
|
||||||
/* 4320 /4 /4 /1 /5 /1 => /1 /2 */
|
/* 4320 /4 /4 /1 /5 /1 => /1 /2 */
|
||||||
#define MESON_VCLK_HDMI_DDR_54000 2
|
MESON_VCLK_HDMI_DDR_54000,
|
||||||
/* 2970 /4 /1 /1 /5 /1 => /1 /2 */
|
/* 2970 /4 /1 /1 /5 /1 => /1 /2 */
|
||||||
#define MESON_VCLK_HDMI_DDR_148500 3
|
MESON_VCLK_HDMI_DDR_148500,
|
||||||
/* 4028 /4 /4 /1 /5 /2 => /1 /1 */
|
|
||||||
#define MESON_VCLK_HDMI_25175 4
|
|
||||||
/* 3200 /4 /2 /1 /5 /2 => /1 /1 */
|
|
||||||
#define MESON_VCLK_HDMI_40000 5
|
|
||||||
/* 5200 /4 /2 /1 /5 /2 => /1 /1 */
|
|
||||||
#define MESON_VCLK_HDMI_65000 6
|
|
||||||
/* 2970 /2 /2 /2 /5 /1 => /1 /1 */
|
/* 2970 /2 /2 /2 /5 /1 => /1 /1 */
|
||||||
#define MESON_VCLK_HDMI_74250 7
|
MESON_VCLK_HDMI_74250,
|
||||||
/* 4320 /4 /1 /1 /5 /2 => /1 /1 */
|
|
||||||
#define MESON_VCLK_HDMI_108000 8
|
|
||||||
/* 2970 /1 /2 /2 /5 /1 => /1 /1 */
|
/* 2970 /1 /2 /2 /5 /1 => /1 /1 */
|
||||||
#define MESON_VCLK_HDMI_148500 9
|
MESON_VCLK_HDMI_148500,
|
||||||
/* 3240 /2 /1 /1 /5 /2 => /1 /1 */
|
|
||||||
#define MESON_VCLK_HDMI_162000 10
|
|
||||||
/* 2970 /1 /1 /1 /5 /2 => /1 /1 */
|
/* 2970 /1 /1 /1 /5 /2 => /1 /1 */
|
||||||
#define MESON_VCLK_HDMI_297000 11
|
MESON_VCLK_HDMI_297000,
|
||||||
/* 5940 /1 /1 /2 /5 /1 => /1 /1 */
|
/* 5940 /1 /1 /2 /5 /1 => /1 /1 */
|
||||||
#define MESON_VCLK_HDMI_594000 12
|
MESON_VCLK_HDMI_594000
|
||||||
|
};
|
||||||
|
|
||||||
struct meson_vclk_params {
|
struct meson_vclk_params {
|
||||||
unsigned int pll_base_freq;
|
unsigned int pll_base_freq;
|
||||||
@@ -411,46 +402,6 @@ struct meson_vclk_params {
|
|||||||
.vid_pll_div = VID_PLL_DIV_5,
|
.vid_pll_div = VID_PLL_DIV_5,
|
||||||
.vclk_div = 1,
|
.vclk_div = 1,
|
||||||
},
|
},
|
||||||
[MESON_VCLK_HDMI_25175] = {
|
|
||||||
.pll_base_freq = 4028000,
|
|
||||||
.pll_od1 = 4,
|
|
||||||
.pll_od2 = 4,
|
|
||||||
.pll_od3 = 1,
|
|
||||||
.vid_pll_div = VID_PLL_DIV_5,
|
|
||||||
.vclk_div = 2,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_40000] = {
|
|
||||||
.pll_base_freq = 3200000,
|
|
||||||
.pll_od1 = 4,
|
|
||||||
.pll_od2 = 2,
|
|
||||||
.pll_od3 = 1,
|
|
||||||
.vid_pll_div = VID_PLL_DIV_5,
|
|
||||||
.vclk_div = 2,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_65000] = {
|
|
||||||
.pll_base_freq = 5200000,
|
|
||||||
.pll_od1 = 4,
|
|
||||||
.pll_od2 = 2,
|
|
||||||
.pll_od3 = 1,
|
|
||||||
.vid_pll_div = VID_PLL_DIV_5,
|
|
||||||
.vclk_div = 2,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_108000] = {
|
|
||||||
.pll_base_freq = 4320000,
|
|
||||||
.pll_od1 = 4,
|
|
||||||
.pll_od2 = 1,
|
|
||||||
.pll_od3 = 1,
|
|
||||||
.vid_pll_div = VID_PLL_DIV_5,
|
|
||||||
.vclk_div = 2,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_162000] = {
|
|
||||||
.pll_base_freq = 3240000,
|
|
||||||
.pll_od1 = 2,
|
|
||||||
.pll_od2 = 1,
|
|
||||||
.pll_od3 = 1,
|
|
||||||
.vid_pll_div = VID_PLL_DIV_5,
|
|
||||||
.vclk_div = 2,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline unsigned int pll_od_to_reg(unsigned int od)
|
static inline unsigned int pll_od_to_reg(unsigned int od)
|
||||||
@@ -470,358 +421,217 @@ static inline unsigned int pll_od_to_reg(unsigned int od)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void meson_hdmi_pll_set(struct meson_drm *priv,
|
void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
|
||||||
unsigned int base,
|
unsigned int frac, unsigned int od1,
|
||||||
unsigned int od1,
|
unsigned int od2, unsigned int od3)
|
||||||
unsigned int od2,
|
|
||||||
unsigned int od3)
|
|
||||||
{
|
{
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
|
|
||||||
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
|
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
|
||||||
switch (base) {
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000200 | m);
|
||||||
case 2970000:
|
if (frac)
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
|
0x00004000 | frac);
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
|
else
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
|
0x00000000);
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
|
||||||
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
|
||||||
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
|
||||||
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
|
||||||
|
|
||||||
/* Enable and unreset */
|
/* Enable and unreset */
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
||||||
0x7 << 28, 0x4 << 28);
|
0x7 << 28, 0x4 << 28);
|
||||||
|
|
||||||
/* Poll for lock bit */
|
/* Poll for lock bit */
|
||||||
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
|
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
|
||||||
val, (val & HDMI_PLL_LOCK), 10, 0);
|
val, (val & HDMI_PLL_LOCK), 10, 0);
|
||||||
|
|
||||||
/* div_frac */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
|
||||||
0xFFFF, 0x4e00);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3200000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000242);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
|
|
||||||
|
|
||||||
/* unreset */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
BIT(28), 0);
|
|
||||||
|
|
||||||
/* Poll for lock bit */
|
|
||||||
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
val, (val & HDMI_PLL_LOCK), 10, 0);
|
|
||||||
|
|
||||||
/* div_frac */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
|
||||||
0xFFFF, 0x4aab);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3240000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000243);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
|
|
||||||
|
|
||||||
/* unreset */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
BIT(28), 0);
|
|
||||||
|
|
||||||
/* Poll for lock bit */
|
|
||||||
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
val, (val & HDMI_PLL_LOCK), 10, 0);
|
|
||||||
|
|
||||||
/* div_frac */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
|
||||||
0xFFFF, 0x4800);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3865000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000250);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
|
|
||||||
|
|
||||||
/* unreset */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
BIT(28), 0);
|
|
||||||
|
|
||||||
/* Poll for lock bit */
|
|
||||||
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
val, (val & HDMI_PLL_LOCK), 10, 0);
|
|
||||||
|
|
||||||
/* div_frac */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
|
||||||
0xFFFF, 0x4855);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4028000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000253);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
|
|
||||||
|
|
||||||
/* unreset */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
BIT(28), 0);
|
|
||||||
|
|
||||||
/* Poll for lock bit */
|
|
||||||
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
val, (val & HDMI_PLL_LOCK), 10, 0);
|
|
||||||
|
|
||||||
/* div_frac */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
|
||||||
0xFFFF, 0x4eab);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4320000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
|
|
||||||
|
|
||||||
/* unreset */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
BIT(28), 0);
|
|
||||||
|
|
||||||
/* Poll for lock bit */
|
|
||||||
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
val, (val & HDMI_PLL_LOCK), 10, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5940000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800027b);
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
|
||||||
0xFFFF, 0x4c00);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
|
|
||||||
|
|
||||||
/* unreset */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
BIT(28), 0);
|
|
||||||
|
|
||||||
/* Poll for lock bit */
|
|
||||||
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
val, (val & HDMI_PLL_LOCK), 10, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5200000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800026c);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
|
|
||||||
|
|
||||||
/* unreset */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
BIT(28), 0);
|
|
||||||
|
|
||||||
/* Poll for lock bit */
|
|
||||||
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
|
|
||||||
val, (val & HDMI_PLL_LOCK), 10, 0);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
||||||
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
|
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
|
||||||
switch (base) {
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000200 | m);
|
||||||
case 2970000:
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac);
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
|
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3200000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000285);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb155);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3240000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000287);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3865000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a1);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb02b);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4028000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a7);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb355);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4320000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5940000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002f7);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5200000:
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002d8);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb2ab);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
|
|
||||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
|
|
||||||
break;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Reset PLL */
|
/* Reset PLL */
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
||||||
HDMI_PLL_RESET, HDMI_PLL_RESET);
|
HDMI_PLL_RESET, HDMI_PLL_RESET);
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
|
||||||
HDMI_PLL_RESET, 0);
|
HDMI_PLL_RESET, 0);
|
||||||
|
|
||||||
/* Poll for lock bit */
|
/* Poll for lock bit */
|
||||||
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
|
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
|
||||||
(val & HDMI_PLL_LOCK), 10, 0);
|
(val & HDMI_PLL_LOCK), 10, 0);
|
||||||
};
|
}
|
||||||
|
|
||||||
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
|
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
||||||
3 << 16, pll_od_to_reg(od1) << 16);
|
3 << 16, pll_od_to_reg(od1) << 16);
|
||||||
else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
||||||
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
|
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
|
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
|
||||||
3 << 21, pll_od_to_reg(od1) << 21);
|
3 << 21, pll_od_to_reg(od1) << 21);
|
||||||
|
|
||||||
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
|
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
||||||
3 << 22, pll_od_to_reg(od2) << 22);
|
3 << 22, pll_od_to_reg(od2) << 22);
|
||||||
else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
||||||
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
|
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
|
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
|
||||||
3 << 23, pll_od_to_reg(od2) << 23);
|
3 << 23, pll_od_to_reg(od2) << 23);
|
||||||
|
|
||||||
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
|
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
|
||||||
3 << 18, pll_od_to_reg(od3) << 18);
|
3 << 18, pll_od_to_reg(od3) << 18);
|
||||||
else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
||||||
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
|
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
|
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
|
||||||
3 << 19, pll_od_to_reg(od3) << 19);
|
3 << 19, pll_od_to_reg(od3) << 19);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
#define XTAL_FREQ 24000
|
||||||
unsigned int vclk_freq, unsigned int venc_freq,
|
|
||||||
unsigned int dac_freq, bool hdmi_use_enci)
|
static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
|
||||||
|
unsigned int pll_freq)
|
||||||
{
|
{
|
||||||
unsigned int freq;
|
/* The GXBB PLL has a /2 pre-multiplier */
|
||||||
unsigned int hdmi_tx_div;
|
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
|
||||||
unsigned int venc_div;
|
pll_freq /= 2;
|
||||||
|
|
||||||
|
return pll_freq / XTAL_FREQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HDMI_FRAC_MAX_GXBB 4096
|
||||||
|
#define HDMI_FRAC_MAX_GXL 1024
|
||||||
|
|
||||||
|
static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
|
||||||
|
unsigned int m,
|
||||||
|
unsigned int pll_freq)
|
||||||
|
{
|
||||||
|
unsigned int parent_freq = XTAL_FREQ;
|
||||||
|
unsigned int frac_max = HDMI_FRAC_MAX_GXL;
|
||||||
|
unsigned int frac_m;
|
||||||
|
unsigned int frac;
|
||||||
|
|
||||||
|
/* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */
|
||||||
|
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
|
||||||
|
frac_max = HDMI_FRAC_MAX_GXBB;
|
||||||
|
parent_freq *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We can have a perfect match !*/
|
||||||
|
if (pll_freq / m == parent_freq &&
|
||||||
|
pll_freq % m == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
|
||||||
|
frac_m = m * frac_max;
|
||||||
|
if (frac_m > frac)
|
||||||
|
return frac_max;
|
||||||
|
frac -= frac_m;
|
||||||
|
|
||||||
|
return min((u16)frac, (u16)(frac_max - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
|
||||||
|
unsigned int m,
|
||||||
|
unsigned int frac)
|
||||||
|
{
|
||||||
|
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
|
||||||
|
/* Empiric supported min/max dividers */
|
||||||
|
if (m < 53 || m > 123)
|
||||||
|
return false;
|
||||||
|
if (frac >= HDMI_FRAC_MAX_GXBB)
|
||||||
|
return false;
|
||||||
|
} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
||||||
|
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
|
||||||
|
/* Empiric supported min/max dividers */
|
||||||
|
if (m < 106 || m > 247)
|
||||||
|
return false;
|
||||||
|
if (frac >= HDMI_FRAC_MAX_GXL)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
|
||||||
|
unsigned int freq,
|
||||||
|
unsigned int *m,
|
||||||
|
unsigned int *frac,
|
||||||
|
unsigned int *od)
|
||||||
|
{
|
||||||
|
/* Cycle from /16 to /2 */
|
||||||
|
for (*od = 16 ; *od > 1 ; *od >>= 1) {
|
||||||
|
*m = meson_hdmi_pll_get_m(priv, freq * *od);
|
||||||
|
if (!*m)
|
||||||
|
continue;
|
||||||
|
*frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
|
||||||
|
|
||||||
|
DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n",
|
||||||
|
freq, *m, *frac, *od);
|
||||||
|
|
||||||
|
if (meson_hdmi_pll_validate_params(priv, *m, *frac))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pll_freq is the frequency after the OD dividers */
|
||||||
|
enum drm_mode_status
|
||||||
|
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq)
|
||||||
|
{
|
||||||
|
unsigned int od, m, frac;
|
||||||
|
|
||||||
|
/* In DMT mode, path after PLL is always /10 */
|
||||||
|
freq *= 10;
|
||||||
|
|
||||||
|
if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
|
||||||
|
return MODE_OK;
|
||||||
|
|
||||||
|
return MODE_CLOCK_RANGE;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq);
|
||||||
|
|
||||||
|
/* pll_freq is the frequency after the OD dividers */
|
||||||
|
static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
|
||||||
|
unsigned int pll_freq)
|
||||||
|
{
|
||||||
|
unsigned int od, m, frac, od1, od2, od3;
|
||||||
|
|
||||||
|
if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
|
||||||
|
od3 = 1;
|
||||||
|
if (od < 4) {
|
||||||
|
od1 = 2;
|
||||||
|
od2 = 1;
|
||||||
|
} else {
|
||||||
|
od2 = od / 4;
|
||||||
|
od1 = od / od2;
|
||||||
|
}
|
||||||
|
|
||||||
|
DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
|
||||||
|
pll_freq, m, frac, od1, od2, od3);
|
||||||
|
|
||||||
|
meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
|
||||||
|
|
||||||
if (target == MESON_VCLK_TARGET_CVBS) {
|
|
||||||
meson_venci_cvbs_clock_config(priv);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdmi_tx_div = vclk_freq / dac_freq;
|
DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n",
|
||||||
|
pll_freq);
|
||||||
if (hdmi_tx_div == 0) {
|
}
|
||||||
pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
|
|
||||||
dac_freq);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
venc_div = vclk_freq / venc_freq;
|
|
||||||
|
|
||||||
if (venc_div == 0) {
|
|
||||||
pr_err("Fatal Error, invalid HDMI venc freq %d\n",
|
|
||||||
venc_freq);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (vclk_freq) {
|
|
||||||
case 54000:
|
|
||||||
if (hdmi_use_enci)
|
|
||||||
freq = MESON_VCLK_HDMI_ENCI_54000;
|
|
||||||
else
|
|
||||||
freq = MESON_VCLK_HDMI_DDR_54000;
|
|
||||||
break;
|
|
||||||
case 25175:
|
|
||||||
freq = MESON_VCLK_HDMI_25175;
|
|
||||||
break;
|
|
||||||
case 40000:
|
|
||||||
freq = MESON_VCLK_HDMI_40000;
|
|
||||||
break;
|
|
||||||
case 65000:
|
|
||||||
freq = MESON_VCLK_HDMI_65000;
|
|
||||||
break;
|
|
||||||
case 74250:
|
|
||||||
freq = MESON_VCLK_HDMI_74250;
|
|
||||||
break;
|
|
||||||
case 108000:
|
|
||||||
freq = MESON_VCLK_HDMI_108000;
|
|
||||||
break;
|
|
||||||
case 148500:
|
|
||||||
if (dac_freq != 148500)
|
|
||||||
freq = MESON_VCLK_HDMI_DDR_148500;
|
|
||||||
else
|
|
||||||
freq = MESON_VCLK_HDMI_148500;
|
|
||||||
break;
|
|
||||||
case 162000:
|
|
||||||
freq = MESON_VCLK_HDMI_162000;
|
|
||||||
break;
|
|
||||||
case 297000:
|
|
||||||
freq = MESON_VCLK_HDMI_297000;
|
|
||||||
break;
|
|
||||||
case 594000:
|
|
||||||
freq = MESON_VCLK_HDMI_594000;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pr_err("Fatal Error, invalid HDMI vclk freq %d\n",
|
|
||||||
vclk_freq);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
||||||
|
unsigned int od1, unsigned int od2, unsigned int od3,
|
||||||
|
unsigned int vid_pll_div, unsigned int vclk_div,
|
||||||
|
unsigned int hdmi_tx_div, unsigned int venc_div,
|
||||||
|
bool hdmi_use_enci)
|
||||||
|
{
|
||||||
/* Set HDMI-TX sys clock */
|
/* Set HDMI-TX sys clock */
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
|
regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
|
||||||
CTS_HDMI_SYS_SEL_MASK, 0);
|
CTS_HDMI_SYS_SEL_MASK, 0);
|
||||||
@@ -831,19 +641,49 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|||||||
CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
|
CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
|
||||||
|
|
||||||
/* Set HDMI PLL rate */
|
/* Set HDMI PLL rate */
|
||||||
meson_hdmi_pll_set(priv, params[freq].pll_base_freq,
|
if (!od1 && !od2 && !od3) {
|
||||||
params[freq].pll_od1,
|
meson_hdmi_pll_generic_set(priv, pll_base_freq);
|
||||||
params[freq].pll_od2,
|
} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
|
||||||
params[freq].pll_od3);
|
switch (pll_base_freq) {
|
||||||
|
case 2970000:
|
||||||
|
meson_hdmi_pll_set_params(priv, 0x3d, 0xe00,
|
||||||
|
od1, od2, od3);
|
||||||
|
break;
|
||||||
|
case 4320000:
|
||||||
|
meson_hdmi_pll_set_params(priv, 0x5a, 0,
|
||||||
|
od1, od2, od3);
|
||||||
|
break;
|
||||||
|
case 5940000:
|
||||||
|
meson_hdmi_pll_set_params(priv, 0x7b, 0xc00,
|
||||||
|
od1, od2, od3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
|
||||||
|
meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
|
||||||
|
switch (pll_base_freq) {
|
||||||
|
case 2970000:
|
||||||
|
meson_hdmi_pll_set_params(priv, 0x7b, 0x300,
|
||||||
|
od1, od2, od3);
|
||||||
|
break;
|
||||||
|
case 4320000:
|
||||||
|
meson_hdmi_pll_set_params(priv, 0xb4, 0,
|
||||||
|
od1, od2, od3);
|
||||||
|
break;
|
||||||
|
case 5940000:
|
||||||
|
meson_hdmi_pll_set_params(priv, 0xf7, 0x200,
|
||||||
|
od1, od2, od3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup vid_pll divider */
|
/* Setup vid_pll divider */
|
||||||
meson_vid_pll_set(priv, params[freq].vid_pll_div);
|
meson_vid_pll_set(priv, vid_pll_div);
|
||||||
|
|
||||||
/* Set VCLK div */
|
/* Set VCLK div */
|
||||||
regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
|
regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
|
||||||
VCLK_SEL_MASK, 0);
|
VCLK_SEL_MASK, 0);
|
||||||
regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
|
regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
|
||||||
VCLK_DIV_MASK, params[freq].vclk_div - 1);
|
VCLK_DIV_MASK, vclk_div - 1);
|
||||||
|
|
||||||
/* Set HDMI-TX source */
|
/* Set HDMI-TX source */
|
||||||
switch (hdmi_tx_div) {
|
switch (hdmi_tx_div) {
|
||||||
@@ -981,4 +821,80 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|||||||
|
|
||||||
regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
|
regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
||||||
|
unsigned int vclk_freq, unsigned int venc_freq,
|
||||||
|
unsigned int dac_freq, bool hdmi_use_enci)
|
||||||
|
{
|
||||||
|
unsigned int freq;
|
||||||
|
unsigned int hdmi_tx_div;
|
||||||
|
unsigned int venc_div;
|
||||||
|
|
||||||
|
if (target == MESON_VCLK_TARGET_CVBS) {
|
||||||
|
meson_venci_cvbs_clock_config(priv);
|
||||||
|
return;
|
||||||
|
} else if (target == MESON_VCLK_TARGET_DMT) {
|
||||||
|
/* The DMT clock path is fixed after the PLL:
|
||||||
|
* - automatic PLL freq + OD management
|
||||||
|
* - vid_pll_div = VID_PLL_DIV_5
|
||||||
|
* - vclk_div = 2
|
||||||
|
* - hdmi_tx_div = 1
|
||||||
|
* - venc_div = 1
|
||||||
|
* - encp encoder
|
||||||
|
*/
|
||||||
|
meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
|
||||||
|
VID_PLL_DIV_5, 2, 1, 1, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdmi_tx_div = vclk_freq / dac_freq;
|
||||||
|
|
||||||
|
if (hdmi_tx_div == 0) {
|
||||||
|
pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
|
||||||
|
dac_freq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
venc_div = vclk_freq / venc_freq;
|
||||||
|
|
||||||
|
if (venc_div == 0) {
|
||||||
|
pr_err("Fatal Error, invalid HDMI venc freq %d\n",
|
||||||
|
venc_freq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (vclk_freq) {
|
||||||
|
case 54000:
|
||||||
|
if (hdmi_use_enci)
|
||||||
|
freq = MESON_VCLK_HDMI_ENCI_54000;
|
||||||
|
else
|
||||||
|
freq = MESON_VCLK_HDMI_DDR_54000;
|
||||||
|
break;
|
||||||
|
case 74250:
|
||||||
|
freq = MESON_VCLK_HDMI_74250;
|
||||||
|
break;
|
||||||
|
case 148500:
|
||||||
|
if (dac_freq != 148500)
|
||||||
|
freq = MESON_VCLK_HDMI_DDR_148500;
|
||||||
|
else
|
||||||
|
freq = MESON_VCLK_HDMI_148500;
|
||||||
|
break;
|
||||||
|
case 297000:
|
||||||
|
freq = MESON_VCLK_HDMI_297000;
|
||||||
|
break;
|
||||||
|
case 594000:
|
||||||
|
freq = MESON_VCLK_HDMI_594000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("Fatal Error, invalid HDMI vclk freq %d\n",
|
||||||
|
vclk_freq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
meson_vclk_set(priv, params[freq].pll_base_freq,
|
||||||
|
params[freq].pll_od1, params[freq].pll_od2,
|
||||||
|
params[freq].pll_od3, params[freq].vid_pll_div,
|
||||||
|
params[freq].vclk_div, hdmi_tx_div, venc_div,
|
||||||
|
hdmi_use_enci);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL_GPL(meson_vclk_setup);
|
EXPORT_SYMBOL_GPL(meson_vclk_setup);
|
||||||
|
|||||||
@@ -24,11 +24,15 @@
|
|||||||
enum {
|
enum {
|
||||||
MESON_VCLK_TARGET_CVBS = 0,
|
MESON_VCLK_TARGET_CVBS = 0,
|
||||||
MESON_VCLK_TARGET_HDMI = 1,
|
MESON_VCLK_TARGET_HDMI = 1,
|
||||||
|
MESON_VCLK_TARGET_DMT = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 27MHz is the CVBS Pixel Clock */
|
/* 27MHz is the CVBS Pixel Clock */
|
||||||
#define MESON_VCLK_CVBS 27000
|
#define MESON_VCLK_CVBS 27000
|
||||||
|
|
||||||
|
enum drm_mode_status
|
||||||
|
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq);
|
||||||
|
|
||||||
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
||||||
unsigned int vclk_freq, unsigned int venc_freq,
|
unsigned int vclk_freq, unsigned int venc_freq,
|
||||||
unsigned int dac_freq, bool hdmi_use_enci);
|
unsigned int dac_freq, bool hdmi_use_enci);
|
||||||
|
|||||||
@@ -697,314 +697,6 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
union meson_hdmi_venc_mode meson_hdmi_encp_mode_640x480_60 = {
|
|
||||||
.encp = {
|
|
||||||
.dvi_settings = 0x21,
|
|
||||||
.video_mode = 0x4040,
|
|
||||||
.video_mode_adv = 0x18,
|
|
||||||
/* video_prog_mode */
|
|
||||||
/* video_sync_mode */
|
|
||||||
/* video_yc_dly */
|
|
||||||
/* video_rgb_ctrl */
|
|
||||||
/* video_filt_ctrl */
|
|
||||||
/* video_ofld_voav_ofst */
|
|
||||||
/* yfp1_htime */
|
|
||||||
/* yfp2_htime */
|
|
||||||
.max_pxcnt = 0x31f,
|
|
||||||
/* hspuls_begin */
|
|
||||||
/* hspuls_end */
|
|
||||||
/* hspuls_switch */
|
|
||||||
/* vspuls_begin */
|
|
||||||
/* vspuls_end */
|
|
||||||
/* vspuls_bline */
|
|
||||||
/* vspuls_eline */
|
|
||||||
.havon_begin = 0x90,
|
|
||||||
.havon_end = 0x30f,
|
|
||||||
.vavon_bline = 0x23,
|
|
||||||
.vavon_eline = 0x202,
|
|
||||||
/* eqpuls_begin */
|
|
||||||
/* eqpuls_end */
|
|
||||||
/* eqpuls_bline */
|
|
||||||
/* eqpuls_eline */
|
|
||||||
.hso_begin = 0,
|
|
||||||
.hso_end = 0x60,
|
|
||||||
.vso_begin = 0x1e,
|
|
||||||
.vso_end = 0x32,
|
|
||||||
.vso_bline = 0,
|
|
||||||
.vso_eline = 2,
|
|
||||||
.vso_eline_present = true,
|
|
||||||
/* sy_val */
|
|
||||||
/* sy2_val */
|
|
||||||
.max_lncnt = 0x20c,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
union meson_hdmi_venc_mode meson_hdmi_encp_mode_800x600_60 = {
|
|
||||||
.encp = {
|
|
||||||
.dvi_settings = 0x21,
|
|
||||||
.video_mode = 0x4040,
|
|
||||||
.video_mode_adv = 0x18,
|
|
||||||
/* video_prog_mode */
|
|
||||||
/* video_sync_mode */
|
|
||||||
/* video_yc_dly */
|
|
||||||
/* video_rgb_ctrl */
|
|
||||||
/* video_filt_ctrl */
|
|
||||||
/* video_ofld_voav_ofst */
|
|
||||||
/* yfp1_htime */
|
|
||||||
/* yfp2_htime */
|
|
||||||
.max_pxcnt = 0x41f,
|
|
||||||
/* hspuls_begin */
|
|
||||||
/* hspuls_end */
|
|
||||||
/* hspuls_switch */
|
|
||||||
/* vspuls_begin */
|
|
||||||
/* vspuls_end */
|
|
||||||
/* vspuls_bline */
|
|
||||||
/* vspuls_eline */
|
|
||||||
.havon_begin = 0xD8,
|
|
||||||
.havon_end = 0x3f7,
|
|
||||||
.vavon_bline = 0x1b,
|
|
||||||
.vavon_eline = 0x272,
|
|
||||||
/* eqpuls_begin */
|
|
||||||
/* eqpuls_end */
|
|
||||||
/* eqpuls_bline */
|
|
||||||
/* eqpuls_eline */
|
|
||||||
.hso_begin = 0,
|
|
||||||
.hso_end = 0x80,
|
|
||||||
.vso_begin = 0x1e,
|
|
||||||
.vso_end = 0x32,
|
|
||||||
.vso_bline = 0,
|
|
||||||
.vso_eline = 4,
|
|
||||||
.vso_eline_present = true,
|
|
||||||
/* sy_val */
|
|
||||||
/* sy2_val */
|
|
||||||
.max_lncnt = 0x273,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1024x768_60 = {
|
|
||||||
.encp = {
|
|
||||||
.dvi_settings = 0x21,
|
|
||||||
.video_mode = 0x4040,
|
|
||||||
.video_mode_adv = 0x18,
|
|
||||||
/* video_prog_mode */
|
|
||||||
/* video_sync_mode */
|
|
||||||
/* video_yc_dly */
|
|
||||||
/* video_rgb_ctrl */
|
|
||||||
/* video_filt_ctrl */
|
|
||||||
/* video_ofld_voav_ofst */
|
|
||||||
/* yfp1_htime */
|
|
||||||
/* yfp2_htime */
|
|
||||||
.max_pxcnt = 1343,
|
|
||||||
/* hspuls_begin */
|
|
||||||
/* hspuls_end */
|
|
||||||
/* hspuls_switch */
|
|
||||||
/* vspuls_begin */
|
|
||||||
/* vspuls_end */
|
|
||||||
/* vspuls_bline */
|
|
||||||
/* vspuls_eline */
|
|
||||||
.havon_begin = 296,
|
|
||||||
.havon_end = 1319,
|
|
||||||
.vavon_bline = 35,
|
|
||||||
.vavon_eline = 802,
|
|
||||||
/* eqpuls_begin */
|
|
||||||
/* eqpuls_end */
|
|
||||||
/* eqpuls_bline */
|
|
||||||
/* eqpuls_eline */
|
|
||||||
.hso_begin = 0,
|
|
||||||
.hso_end = 136,
|
|
||||||
.vso_begin = 30,
|
|
||||||
.vso_end = 50,
|
|
||||||
.vso_bline = 0,
|
|
||||||
.vso_eline = 6,
|
|
||||||
.vso_eline_present = true,
|
|
||||||
/* sy_val */
|
|
||||||
/* sy2_val */
|
|
||||||
.max_lncnt = 805,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1152x864_75 = {
|
|
||||||
.encp = {
|
|
||||||
.dvi_settings = 0x21,
|
|
||||||
.video_mode = 0x4040,
|
|
||||||
.video_mode_adv = 0x18,
|
|
||||||
/* video_prog_mode */
|
|
||||||
/* video_sync_mode */
|
|
||||||
/* video_yc_dly */
|
|
||||||
/* video_rgb_ctrl */
|
|
||||||
/* video_filt_ctrl */
|
|
||||||
/* video_ofld_voav_ofst */
|
|
||||||
/* yfp1_htime */
|
|
||||||
/* yfp2_htime */
|
|
||||||
.max_pxcnt = 0x63f,
|
|
||||||
/* hspuls_begin */
|
|
||||||
/* hspuls_end */
|
|
||||||
/* hspuls_switch */
|
|
||||||
/* vspuls_begin */
|
|
||||||
/* vspuls_end */
|
|
||||||
/* vspuls_bline */
|
|
||||||
/* vspuls_eline */
|
|
||||||
.havon_begin = 0x180,
|
|
||||||
.havon_end = 0x5ff,
|
|
||||||
.vavon_bline = 0x23,
|
|
||||||
.vavon_eline = 0x382,
|
|
||||||
/* eqpuls_begin */
|
|
||||||
/* eqpuls_end */
|
|
||||||
/* eqpuls_bline */
|
|
||||||
/* eqpuls_eline */
|
|
||||||
.hso_begin = 0,
|
|
||||||
.hso_end = 0x80,
|
|
||||||
.vso_begin = 0x1e,
|
|
||||||
.vso_end = 0x32,
|
|
||||||
.vso_bline = 0,
|
|
||||||
.vso_eline = 3,
|
|
||||||
.vso_eline_present = true,
|
|
||||||
/* sy_val */
|
|
||||||
/* sy2_val */
|
|
||||||
.max_lncnt = 0x383,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1280x1024_60 = {
|
|
||||||
.encp = {
|
|
||||||
.dvi_settings = 0x21,
|
|
||||||
.video_mode = 0x4040,
|
|
||||||
.video_mode_adv = 0x18,
|
|
||||||
/* video_prog_mode */
|
|
||||||
/* video_sync_mode */
|
|
||||||
/* video_yc_dly */
|
|
||||||
/* video_rgb_ctrl */
|
|
||||||
/* video_filt_ctrl */
|
|
||||||
/* video_ofld_voav_ofst */
|
|
||||||
/* yfp1_htime */
|
|
||||||
/* yfp2_htime */
|
|
||||||
.max_pxcnt = 0x697,
|
|
||||||
/* hspuls_begin */
|
|
||||||
/* hspuls_end */
|
|
||||||
/* hspuls_switch */
|
|
||||||
/* vspuls_begin */
|
|
||||||
/* vspuls_end */
|
|
||||||
/* vspuls_bline */
|
|
||||||
/* vspuls_eline */
|
|
||||||
.havon_begin = 0x168,
|
|
||||||
.havon_end = 0x667,
|
|
||||||
.vavon_bline = 0x29,
|
|
||||||
.vavon_eline = 0x428,
|
|
||||||
/* eqpuls_begin */
|
|
||||||
/* eqpuls_end */
|
|
||||||
/* eqpuls_bline */
|
|
||||||
/* eqpuls_eline */
|
|
||||||
.hso_begin = 0,
|
|
||||||
.hso_end = 0x70,
|
|
||||||
.vso_begin = 0x1e,
|
|
||||||
.vso_end = 0x32,
|
|
||||||
.vso_bline = 0,
|
|
||||||
.vso_eline = 3,
|
|
||||||
.vso_eline_present = true,
|
|
||||||
/* sy_val */
|
|
||||||
/* sy2_val */
|
|
||||||
.max_lncnt = 0x429,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1600x1200_60 = {
|
|
||||||
.encp = {
|
|
||||||
.dvi_settings = 0x21,
|
|
||||||
.video_mode = 0x4040,
|
|
||||||
.video_mode_adv = 0x18,
|
|
||||||
/* video_prog_mode */
|
|
||||||
/* video_sync_mode */
|
|
||||||
/* video_yc_dly */
|
|
||||||
/* video_rgb_ctrl */
|
|
||||||
/* video_filt_ctrl */
|
|
||||||
/* video_ofld_voav_ofst */
|
|
||||||
/* yfp1_htime */
|
|
||||||
/* yfp2_htime */
|
|
||||||
.max_pxcnt = 0x86f,
|
|
||||||
/* hspuls_begin */
|
|
||||||
/* hspuls_end */
|
|
||||||
/* hspuls_switch */
|
|
||||||
/* vspuls_begin */
|
|
||||||
/* vspuls_end */
|
|
||||||
/* vspuls_bline */
|
|
||||||
/* vspuls_eline */
|
|
||||||
.havon_begin = 0x1f0,
|
|
||||||
.havon_end = 0x82f,
|
|
||||||
.vavon_bline = 0x31,
|
|
||||||
.vavon_eline = 0x4e0,
|
|
||||||
/* eqpuls_begin */
|
|
||||||
/* eqpuls_end */
|
|
||||||
/* eqpuls_bline */
|
|
||||||
/* eqpuls_eline */
|
|
||||||
.hso_begin = 0,
|
|
||||||
.hso_end = 0xc0,
|
|
||||||
.vso_begin = 0x1e,
|
|
||||||
.vso_end = 0x32,
|
|
||||||
.vso_bline = 0,
|
|
||||||
.vso_eline = 3,
|
|
||||||
.vso_eline_present = true,
|
|
||||||
/* sy_val */
|
|
||||||
/* sy2_val */
|
|
||||||
.max_lncnt = 0x4e1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct meson_hdmi_venc_dmt_mode {
|
|
||||||
struct drm_display_mode drm_mode;
|
|
||||||
union meson_hdmi_venc_mode *mode;
|
|
||||||
} meson_hdmi_venc_dmt_modes[] = {
|
|
||||||
/* 640x480@60Hz */
|
|
||||||
{
|
|
||||||
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
|
|
||||||
752, 800, 0, 480, 490, 492, 525, 0,
|
|
||||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
|
|
||||||
&meson_hdmi_encp_mode_640x480_60,
|
|
||||||
},
|
|
||||||
/* 800x600@60Hz */
|
|
||||||
{
|
|
||||||
{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
|
|
||||||
968, 1056, 0, 600, 601, 605, 628, 0,
|
|
||||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
|
|
||||||
&meson_hdmi_encp_mode_800x600_60,
|
|
||||||
},
|
|
||||||
/* 1024x768@60Hz */
|
|
||||||
{
|
|
||||||
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024,
|
|
||||||
1048, 1184, 1344, 0, 768, 771, 777, 806, 0,
|
|
||||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
|
|
||||||
&meson_hdmi_encp_mode_1024x768_60,
|
|
||||||
},
|
|
||||||
/* 1152x864@75Hz */
|
|
||||||
{
|
|
||||||
{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152,
|
|
||||||
1216, 1344, 1600, 0, 864, 865, 868, 900, 0,
|
|
||||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
|
|
||||||
&meson_hdmi_encp_mode_1152x864_75,
|
|
||||||
},
|
|
||||||
/* 1280x1024@60Hz */
|
|
||||||
{
|
|
||||||
{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280,
|
|
||||||
1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
|
|
||||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
|
|
||||||
&meson_hdmi_encp_mode_1280x1024_60,
|
|
||||||
},
|
|
||||||
/* 1600x1200@60Hz */
|
|
||||||
{
|
|
||||||
{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600,
|
|
||||||
1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
|
|
||||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
|
|
||||||
&meson_hdmi_encp_mode_1600x1200_60,
|
|
||||||
},
|
|
||||||
/* 1920x1080@60Hz */
|
|
||||||
{
|
|
||||||
{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920,
|
|
||||||
2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
|
|
||||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
|
|
||||||
&meson_hdmi_encp_mode_1080p60
|
|
||||||
},
|
|
||||||
{ }, /* sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct meson_hdmi_venc_vic_mode {
|
struct meson_hdmi_venc_vic_mode {
|
||||||
unsigned int vic;
|
unsigned int vic;
|
||||||
union meson_hdmi_venc_mode *mode;
|
union meson_hdmi_venc_mode *mode;
|
||||||
@@ -1044,17 +736,20 @@ static unsigned long modulo(unsigned long a, unsigned long b)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
|
enum drm_mode_status
|
||||||
|
meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
|
||||||
{
|
{
|
||||||
struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes;
|
if (mode->flags & ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
|
||||||
|
DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))
|
||||||
|
return MODE_BAD;
|
||||||
|
|
||||||
while (vmode->mode) {
|
if (mode->hdisplay < 640 || mode->hdisplay > 1920)
|
||||||
if (drm_mode_equal(&vmode->drm_mode, mode))
|
return MODE_BAD_HVALUE;
|
||||||
return true;
|
|
||||||
vmode++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
if (mode->vdisplay < 480 || mode->vdisplay > 1200)
|
||||||
|
return MODE_BAD_VVALUE;
|
||||||
|
|
||||||
|
return MODE_OK;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
|
EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
|
||||||
|
|
||||||
@@ -1072,18 +767,29 @@ bool meson_venc_hdmi_supported_vic(int vic)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
|
EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
|
||||||
|
|
||||||
static union meson_hdmi_venc_mode
|
void meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode,
|
||||||
*meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode)
|
union meson_hdmi_venc_mode *dmt_mode)
|
||||||
{
|
{
|
||||||
struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes;
|
memset(dmt_mode, 0, sizeof(*dmt_mode));
|
||||||
|
|
||||||
while (vmode->mode) {
|
dmt_mode->encp.dvi_settings = 0x21;
|
||||||
if (drm_mode_equal(&vmode->drm_mode, mode))
|
dmt_mode->encp.video_mode = 0x4040;
|
||||||
return vmode->mode;
|
dmt_mode->encp.video_mode_adv = 0x18;
|
||||||
vmode++;
|
dmt_mode->encp.max_pxcnt = mode->htotal - 1;
|
||||||
}
|
dmt_mode->encp.havon_begin = mode->htotal - mode->hsync_start;
|
||||||
|
dmt_mode->encp.havon_end = dmt_mode->encp.havon_begin +
|
||||||
return NULL;
|
mode->hdisplay - 1;
|
||||||
|
dmt_mode->encp.vavon_bline = mode->vtotal - mode->vsync_start;
|
||||||
|
dmt_mode->encp.vavon_eline = dmt_mode->encp.vavon_bline +
|
||||||
|
mode->vdisplay - 1;
|
||||||
|
dmt_mode->encp.hso_begin = 0;
|
||||||
|
dmt_mode->encp.hso_end = mode->hsync_end - mode->hsync_start;
|
||||||
|
dmt_mode->encp.vso_begin = 30;
|
||||||
|
dmt_mode->encp.vso_end = 50;
|
||||||
|
dmt_mode->encp.vso_bline = 0;
|
||||||
|
dmt_mode->encp.vso_eline = mode->vsync_end - mode->vsync_start;
|
||||||
|
dmt_mode->encp.vso_eline_present = true;
|
||||||
|
dmt_mode->encp.max_lncnt = mode->vtotal - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
|
static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
|
||||||
@@ -1120,6 +826,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
|
|||||||
struct drm_display_mode *mode)
|
struct drm_display_mode *mode)
|
||||||
{
|
{
|
||||||
union meson_hdmi_venc_mode *vmode = NULL;
|
union meson_hdmi_venc_mode *vmode = NULL;
|
||||||
|
union meson_hdmi_venc_mode vmode_dmt;
|
||||||
bool use_enci = false;
|
bool use_enci = false;
|
||||||
bool venc_repeat = false;
|
bool venc_repeat = false;
|
||||||
bool hdmi_repeat = false;
|
bool hdmi_repeat = false;
|
||||||
@@ -1147,14 +854,17 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
|
|||||||
unsigned int sof_lines;
|
unsigned int sof_lines;
|
||||||
unsigned int vsync_lines;
|
unsigned int vsync_lines;
|
||||||
|
|
||||||
if (meson_venc_hdmi_supported_vic(vic))
|
if (meson_venc_hdmi_supported_vic(vic)) {
|
||||||
vmode = meson_venc_hdmi_get_vic_vmode(vic);
|
vmode = meson_venc_hdmi_get_vic_vmode(vic);
|
||||||
else
|
if (!vmode) {
|
||||||
vmode = meson_venc_hdmi_get_dmt_vmode(mode);
|
dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
|
||||||
if (!vmode) {
|
DRM_MODE_FMT "\n", __func__,
|
||||||
dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
|
DRM_MODE_ARG(mode));
|
||||||
DRM_MODE_FMT "\n", __func__, DRM_MODE_ARG(mode));
|
return;
|
||||||
return;
|
}
|
||||||
|
} else {
|
||||||
|
meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt);
|
||||||
|
vmode = &vmode_dmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use VENCI for 480i and 576i and double HDMI pixels */
|
/* Use VENCI for 480i and 576i and double HDMI pixels */
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ struct meson_cvbs_enci_mode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* HDMI Clock parameters */
|
/* HDMI Clock parameters */
|
||||||
bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
|
enum drm_mode_status
|
||||||
|
meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
|
||||||
bool meson_venc_hdmi_supported_vic(int vic);
|
bool meson_venc_hdmi_supported_vic(int vic);
|
||||||
bool meson_venc_hdmi_venc_repeat(int vic);
|
bool meson_venc_hdmi_venc_repeat(int vic);
|
||||||
|
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ int meson_venc_cvbs_create(struct meson_drm *priv)
|
|||||||
|
|
||||||
encoder->possible_crtcs = BIT(0);
|
encoder->possible_crtcs = BIT(0);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1553,7 +1553,7 @@ static int mga_vga_get_modes(struct drm_connector *connector)
|
|||||||
|
|
||||||
edid = drm_get_edid(connector, &mga_connector->i2c->adapter);
|
edid = drm_get_edid(connector, &mga_connector->i2c->adapter);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
}
|
}
|
||||||
@@ -1747,7 +1747,7 @@ int mgag200_modeset_init(struct mga_device *mdev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
ret = mgag200_fbdev_init(mdev);
|
ret = mgag200_fbdev_init(mdev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,
|
|||||||
connector->interlace_allowed = 0;
|
connector->interlace_allowed = 0;
|
||||||
connector->doublescan_allowed = 0;
|
connector->doublescan_allowed = 0;
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return connector;
|
return connector;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ static int dsi_mgr_connector_get_modes(struct drm_connector *connector)
|
|||||||
ret = dsi_dual_connector_tile_init(connector, id);
|
ret = dsi_dual_connector_tile_init(connector, id);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = drm_mode_connector_set_tile_property(connector);
|
ret = drm_connector_set_tile_property(connector);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%s: set tile property failed, %d\n",
|
pr_err("%s: set tile property failed, %d\n",
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
@@ -684,7 +684,7 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id)
|
|||||||
connector->interlace_allowed = 0;
|
connector->interlace_allowed = 0;
|
||||||
connector->doublescan_allowed = 0;
|
connector->doublescan_allowed = 0;
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, msm_dsi->encoder);
|
drm_connector_attach_encoder(connector, msm_dsi->encoder);
|
||||||
|
|
||||||
return connector;
|
return connector;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ static int edp_connector_get_modes(struct drm_connector *connector)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, drm_edid);
|
drm_connector_update_edid_property(connector, drm_edid);
|
||||||
if (drm_edid)
|
if (drm_edid)
|
||||||
ret = drm_add_edid_modes(connector, drm_edid);
|
ret = drm_add_edid_modes(connector, drm_edid);
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ struct drm_connector *msm_edp_connector_init(struct msm_edp *edp)
|
|||||||
connector->interlace_allowed = false;
|
connector->interlace_allowed = false;
|
||||||
connector->doublescan_allowed = false;
|
connector->doublescan_allowed = false;
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, edp->encoder);
|
drm_connector_attach_encoder(connector, edp->encoder);
|
||||||
|
|
||||||
return connector;
|
return connector;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ static int msm_hdmi_connector_get_modes(struct drm_connector *connector)
|
|||||||
hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);
|
hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);
|
||||||
|
|
||||||
hdmi->hdmi_mode = drm_detect_hdmi_monitor(edid);
|
hdmi->hdmi_mode = drm_detect_hdmi_monitor(edid);
|
||||||
drm_mode_connector_update_edid_property(connector, edid);
|
drm_connector_update_edid_property(connector, edid);
|
||||||
|
|
||||||
if (edid) {
|
if (edid) {
|
||||||
ret = drm_add_edid_modes(connector, edid);
|
ret = drm_add_edid_modes(connector, edid);
|
||||||
@@ -477,7 +477,7 @@ struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi)
|
|||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, hdmi->encoder);
|
drm_connector_attach_encoder(connector, hdmi->encoder);
|
||||||
|
|
||||||
return connector;
|
return connector;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -556,6 +556,6 @@ nv04_dac_create(struct drm_connector *connector, struct dcb_output *entry)
|
|||||||
encoder->possible_crtcs = entry->heads;
|
encoder->possible_crtcs = entry->heads;
|
||||||
encoder->possible_clones = 0;
|
encoder->possible_clones = 0;
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -716,6 +716,6 @@ nv04_dfp_create(struct drm_connector *connector, struct dcb_output *entry)
|
|||||||
entry->location != DCB_LOC_ON_CHIP)
|
entry->location != DCB_LOC_ON_CHIP)
|
||||||
nv04_tmds_slave_init(encoder);
|
nv04_tmds_slave_init(encoder);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_output *entry)
|
|||||||
|
|
||||||
/* Attach it to the specified connector. */
|
/* Attach it to the specified connector. */
|
||||||
get_slave_funcs(encoder)->create_resources(encoder, connector);
|
get_slave_funcs(encoder)->create_resources(encoder, connector);
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -821,6 +821,6 @@ nv17_tv_create(struct drm_connector *connector, struct dcb_output *entry)
|
|||||||
encoder->possible_clones = 0;
|
encoder->possible_clones = 0;
|
||||||
|
|
||||||
nv17_tv_create_resources(encoder, connector);
|
nv17_tv_create_resources(encoder, connector);
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
|
|||||||
"dac-%04x-%04x", dcbe->hasht, dcbe->hashm);
|
"dac-%04x-%04x", dcbe->hasht, dcbe->hashm);
|
||||||
drm_encoder_helper_add(encoder, &nv50_dac_help);
|
drm_encoder_helper_add(encoder, &nv50_dac_help);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -875,7 +875,7 @@ nv50_mstc_get_modes(struct drm_connector *connector)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mstc->edid = drm_dp_mst_get_edid(&mstc->connector, mstc->port->mgr, mstc->port);
|
mstc->edid = drm_dp_mst_get_edid(&mstc->connector, mstc->port->mgr, mstc->port);
|
||||||
drm_mode_connector_update_edid_property(&mstc->connector, mstc->edid);
|
drm_connector_update_edid_property(&mstc->connector, mstc->edid);
|
||||||
if (mstc->edid)
|
if (mstc->edid)
|
||||||
ret = drm_add_edid_modes(&mstc->connector, mstc->edid);
|
ret = drm_add_edid_modes(&mstc->connector, mstc->edid);
|
||||||
|
|
||||||
@@ -952,11 +952,11 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
|
|||||||
nouveau_conn_attach_properties(&mstc->connector);
|
nouveau_conn_attach_properties(&mstc->connector);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto[i]; i++)
|
for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto[i]; i++)
|
||||||
drm_mode_connector_attach_encoder(&mstc->connector, &mstm->msto[i]->encoder);
|
drm_connector_attach_encoder(&mstc->connector, &mstm->msto[i]->encoder);
|
||||||
|
|
||||||
drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0);
|
drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0);
|
||||||
drm_object_attach_property(&mstc->connector.base, dev->mode_config.tile_property, 0);
|
drm_object_attach_property(&mstc->connector.base, dev->mode_config.tile_property, 0);
|
||||||
drm_mode_connector_set_path_property(&mstc->connector, path);
|
drm_connector_set_path_property(&mstc->connector, path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1443,7 +1443,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
|
|||||||
"sor-%04x-%04x", dcbe->hasht, dcbe->hashm);
|
"sor-%04x-%04x", dcbe->hasht, dcbe->hashm);
|
||||||
drm_encoder_helper_add(encoder, &nv50_sor_help);
|
drm_encoder_helper_add(encoder, &nv50_sor_help);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
if (dcbe->type == DCB_OUTPUT_DP) {
|
if (dcbe->type == DCB_OUTPUT_DP) {
|
||||||
struct nv50_disp *disp = nv50_disp(encoder->dev);
|
struct nv50_disp *disp = nv50_disp(encoder->dev);
|
||||||
@@ -1601,7 +1601,7 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
|
|||||||
"pior-%04x-%04x", dcbe->hasht, dcbe->hashm);
|
"pior-%04x-%04x", dcbe->hasht, dcbe->hashm);
|
||||||
drm_encoder_helper_add(encoder, &nv50_pior_help);
|
drm_encoder_helper_add(encoder, &nv50_pior_help);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -550,7 +550,7 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
|
|||||||
|
|
||||||
/* Cleanup the previous EDID block. */
|
/* Cleanup the previous EDID block. */
|
||||||
if (nv_connector->edid) {
|
if (nv_connector->edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, NULL);
|
drm_connector_update_edid_property(connector, NULL);
|
||||||
kfree(nv_connector->edid);
|
kfree(nv_connector->edid);
|
||||||
nv_connector->edid = NULL;
|
nv_connector->edid = NULL;
|
||||||
}
|
}
|
||||||
@@ -575,7 +575,7 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
|
|||||||
else
|
else
|
||||||
nv_connector->edid = drm_get_edid(connector, i2c);
|
nv_connector->edid = drm_get_edid(connector, i2c);
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector,
|
drm_connector_update_edid_property(connector,
|
||||||
nv_connector->edid);
|
nv_connector->edid);
|
||||||
if (!nv_connector->edid) {
|
if (!nv_connector->edid) {
|
||||||
NV_ERROR(drm, "DDC responded, but no EDID for %s\n",
|
NV_ERROR(drm, "DDC responded, but no EDID for %s\n",
|
||||||
@@ -657,7 +657,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
|
|||||||
|
|
||||||
/* Cleanup the previous EDID block. */
|
/* Cleanup the previous EDID block. */
|
||||||
if (nv_connector->edid) {
|
if (nv_connector->edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, NULL);
|
drm_connector_update_edid_property(connector, NULL);
|
||||||
kfree(nv_connector->edid);
|
kfree(nv_connector->edid);
|
||||||
nv_connector->edid = NULL;
|
nv_connector->edid = NULL;
|
||||||
}
|
}
|
||||||
@@ -721,7 +721,7 @@ out:
|
|||||||
status = connector_status_unknown;
|
status = connector_status_unknown;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
drm_mode_connector_update_edid_property(connector, nv_connector->edid);
|
drm_connector_update_edid_property(connector, nv_connector->edid);
|
||||||
nouveau_connector_set_encoder(connector, nv_encoder);
|
nouveau_connector_set_encoder(connector, nv_encoder);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,14 +126,14 @@ static int omap_connector_get_modes(struct drm_connector *connector)
|
|||||||
|
|
||||||
if ((dssdrv->read_edid(dssdev, edid, MAX_EDID) > 0) &&
|
if ((dssdrv->read_edid(dssdev, edid, MAX_EDID) > 0) &&
|
||||||
drm_edid_is_valid(edid)) {
|
drm_edid_is_valid(edid)) {
|
||||||
drm_mode_connector_update_edid_property(
|
drm_connector_update_edid_property(
|
||||||
connector, edid);
|
connector, edid);
|
||||||
n = drm_add_edid_modes(connector, edid);
|
n = drm_add_edid_modes(connector, edid);
|
||||||
|
|
||||||
omap_connector->hdmi_mode =
|
omap_connector->hdmi_mode =
|
||||||
drm_detect_hdmi_monitor(edid);
|
drm_detect_hdmi_monitor(edid);
|
||||||
} else {
|
} else {
|
||||||
drm_mode_connector_update_edid_property(
|
drm_connector_update_edid_property(
|
||||||
connector, NULL);
|
connector, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ static int omap_modeset_init(struct drm_device *dev)
|
|||||||
if (IS_ERR(crtc))
|
if (IS_ERR(crtc))
|
||||||
return PTR_ERR(crtc);
|
return PTR_ERR(crtc);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
encoder->possible_crtcs = (1 << crtc_idx);
|
encoder->possible_crtcs = (1 << crtc_idx);
|
||||||
|
|
||||||
priv->crtcs[priv->num_crtcs++] = crtc;
|
priv->crtcs[priv->num_crtcs++] = crtc;
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ static int panel_simple_get_modes(struct drm_panel *panel)
|
|||||||
/* probe EDID if a DDC bus is available */
|
/* probe EDID if a DDC bus is available */
|
||||||
if (p->ddc) {
|
if (p->ddc) {
|
||||||
struct edid *edid = drm_get_edid(panel->connector, p->ddc);
|
struct edid *edid = drm_get_edid(panel->connector, p->ddc);
|
||||||
drm_mode_connector_update_edid_property(panel->connector, edid);
|
drm_connector_update_edid_property(panel->connector, edid);
|
||||||
if (edid) {
|
if (edid) {
|
||||||
num += drm_add_edid_modes(panel->connector, edid);
|
num += drm_add_edid_modes(panel->connector, edid);
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ pl111_mode_valid(struct drm_crtc *crtc,
|
|||||||
* We use the pixelclock to also account for interlaced modes, the
|
* We use the pixelclock to also account for interlaced modes, the
|
||||||
* resulting bandwidth is in bytes per second.
|
* resulting bandwidth is in bytes per second.
|
||||||
*/
|
*/
|
||||||
bw = mode->clock * 1000; /* In Hz */
|
bw = mode->clock * 1000ULL; /* In Hz */
|
||||||
bw = bw * mode->hdisplay * mode->vdisplay * cpp;
|
bw = bw * mode->hdisplay * mode->vdisplay * cpp;
|
||||||
bw = div_u64(bw, mode->htotal * mode->vtotal);
|
bw = div_u64(bw, mode->htotal * mode->vtotal);
|
||||||
|
|
||||||
|
|||||||
@@ -304,13 +304,14 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
|
|||||||
if (IS_ERR(priv->regs)) {
|
if (IS_ERR(priv->regs)) {
|
||||||
dev_err(dev, "%s failed mmio\n", __func__);
|
dev_err(dev, "%s failed mmio\n", __func__);
|
||||||
ret = PTR_ERR(priv->regs);
|
ret = PTR_ERR(priv->regs);
|
||||||
goto dev_unref;
|
goto dev_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This may override some variant settings */
|
/* This may override some variant settings */
|
||||||
ret = pl111_versatile_init(dev, priv);
|
ret = pl111_versatile_init(dev, priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto dev_unref;
|
goto dev_put;
|
||||||
|
|
||||||
pl111_nomadik_init(dev);
|
pl111_nomadik_init(dev);
|
||||||
|
|
||||||
/* turn off interrupts before requesting the irq */
|
/* turn off interrupts before requesting the irq */
|
||||||
@@ -325,16 +326,16 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
|
|||||||
|
|
||||||
ret = pl111_modeset_init(drm);
|
ret = pl111_modeset_init(drm);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto dev_unref;
|
goto dev_put;
|
||||||
|
|
||||||
ret = drm_dev_register(drm, 0);
|
ret = drm_dev_register(drm, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto dev_unref;
|
goto dev_put;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev_unref:
|
dev_put:
|
||||||
drm_dev_unref(drm);
|
drm_dev_put(drm);
|
||||||
of_reserved_mem_device_release(dev);
|
of_reserved_mem_device_release(dev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -351,7 +352,7 @@ static int pl111_amba_remove(struct amba_device *amba_dev)
|
|||||||
if (priv->panel)
|
if (priv->panel)
|
||||||
drm_panel_bridge_remove(priv->bridge);
|
drm_panel_bridge_remove(priv->bridge);
|
||||||
drm_mode_config_cleanup(drm);
|
drm_mode_config_cleanup(drm);
|
||||||
drm_dev_unref(drm);
|
drm_dev_put(drm);
|
||||||
of_reserved_mem_device_release(dev);
|
of_reserved_mem_device_release(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1086,7 +1086,7 @@ static int qdev_output_init(struct drm_device *dev, int num_output)
|
|||||||
/* we get HPD via client monitors config */
|
/* we get HPD via client monitors config */
|
||||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||||
encoder->possible_crtcs = 1 << num_output;
|
encoder->possible_crtcs = 1 << num_output;
|
||||||
drm_mode_connector_attach_encoder(&qxl_output->base,
|
drm_connector_attach_encoder(&qxl_output->base,
|
||||||
&qxl_output->enc);
|
&qxl_output->enc);
|
||||||
drm_encoder_helper_add(encoder, &qxl_enc_helper_funcs);
|
drm_encoder_helper_add(encoder, &qxl_enc_helper_funcs);
|
||||||
drm_connector_helper_add(connector, &qxl_connector_helper_funcs);
|
drm_connector_helper_add(connector, &qxl_connector_helper_funcs);
|
||||||
|
|||||||
@@ -368,11 +368,11 @@ static int radeon_ddc_get_modes(struct drm_connector *connector)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (radeon_connector->edid) {
|
if (radeon_connector->edid) {
|
||||||
drm_mode_connector_update_edid_property(connector, radeon_connector->edid);
|
drm_connector_update_edid_property(connector, radeon_connector->edid);
|
||||||
ret = drm_add_edid_modes(connector, radeon_connector->edid);
|
ret = drm_add_edid_modes(connector, radeon_connector->edid);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
drm_mode_connector_update_edid_property(connector, NULL);
|
drm_connector_update_edid_property(connector, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,11 +195,11 @@ static int radeon_dp_mst_get_ddc_modes(struct drm_connector *connector)
|
|||||||
radeon_connector->edid = edid;
|
radeon_connector->edid = edid;
|
||||||
DRM_DEBUG_KMS("edid retrieved %p\n", edid);
|
DRM_DEBUG_KMS("edid retrieved %p\n", edid);
|
||||||
if (radeon_connector->edid) {
|
if (radeon_connector->edid) {
|
||||||
drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
|
drm_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
|
||||||
ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
|
ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
|
drm_connector_update_edid_property(&radeon_connector->base, NULL);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -290,7 +290,7 @@ static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topol
|
|||||||
|
|
||||||
drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
|
drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
|
||||||
drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
|
drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
|
||||||
drm_mode_connector_set_path_property(connector, pathprop);
|
drm_connector_set_path_property(connector, pathprop);
|
||||||
|
|
||||||
return connector;
|
return connector;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ radeon_link_encoder_connector(struct drm_device *dev)
|
|||||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||||
radeon_encoder = to_radeon_encoder(encoder);
|
radeon_encoder = to_radeon_encoder(encoder);
|
||||||
if (radeon_encoder->devices & radeon_connector->devices) {
|
if (radeon_encoder->devices & radeon_connector->devices) {
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
|
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
|
||||||
radeon_encoder_add_backlight(radeon_encoder, connector);
|
radeon_encoder_add_backlight(radeon_encoder, connector);
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user