Commit 425a9a3a authored by Dave Airlie's avatar Dave Airlie

Merge tag 'topic/core-stuff-2014-05-05' of git://anongit.freedesktop.org/drm-intel into drm-next

Update pull request with drm core patches. Mostly some polish for the
primary plane stuff and a pile of patches all over from Thierry. Has
survived a few days in drm-intel-nightly without causing ill.

I've frobbed my scripts a bit to also tag my topic branches so that you
have something stable to pull - I've accidentally pushed a bunch more
patches onto this branch before you've taken the old pull request.

* tag 'topic/core-stuff-2014-05-05' of git://anongit.freedesktop.org/drm-intel:
  drm: Make drm_crtc_helper_disable() return void
  drm: Fix indentation of closing brace
  drm/dp: Fix typo in comment
  drm: Fixup flip-work kerneldoc
  drm/fb: Fix typos
  drm/edid: Cleanup kerneldoc
  drm/edid: Drop revision argument for drm_mode_std()
  drm: Try to acquire modeset lock on panic or sysrq
  drm: remove unused argument from drm_open_helper
  drm: Handle ->disable_plane failures correctly
  drm: Simplify fb refcounting rules around ->update_plane
  drm/crtc-helper: gc usless connector loop in disable_unused_functions
  drm/plane_helper: don't disable plane in destroy function
  drm/plane-helper: Fix primary plane scaling check
  drm: make mode_valid callback optional
  drm/edid: Fill PAR in AVI infoframe based on CEA mode list
parents ad222799 a74591d7
......@@ -1895,8 +1895,8 @@ void intel_crt_init(struct drm_device *dev)
<para>
The function filters out modes larger than
<parameter>max_width</parameter> and <parameter>max_height</parameter>
if specified. It then calls the connector
<methodname>mode_valid</methodname> helper operation for each mode in
if specified. It then calls the optional connector
<methodname>mode_valid</methodname> helper operation for each mode in
the probed list to check whether the mode is valid for the connector.
</para>
</listitem>
......@@ -2257,7 +2257,7 @@ void intel_crt_init(struct drm_device *dev)
<para>
Verify whether a mode is valid for the connector. Return MODE_OK for
supported modes and one of the enum drm_mode_status values (MODE_*)
for unsupported modes. This operation is mandatory.
for unsupported modes. This operation is optional.
</para>
<para>
As the mode rejection reason is currently not used beside for
......
......@@ -743,12 +743,6 @@ static int ast_get_modes(struct drm_connector *connector)
return 0;
}
static int ast_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static void ast_connector_destroy(struct drm_connector *connector)
{
struct ast_connector *ast_connector = to_ast_connector(connector);
......@@ -765,7 +759,6 @@ ast_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
.mode_valid = ast_mode_valid,
.get_modes = ast_get_modes,
.best_encoder = ast_best_single_encoder,
};
......
......@@ -225,12 +225,6 @@ int ptn3460_get_modes(struct drm_connector *connector)
return num_modes;
}
static int ptn3460_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
{
struct ptn3460_bridge *ptn_bridge;
......@@ -242,7 +236,6 @@ struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
.get_modes = ptn3460_get_modes,
.mode_valid = ptn3460_mode_valid,
.best_encoder = ptn3460_best_encoder,
};
......
......@@ -505,13 +505,6 @@ static int cirrus_vga_get_modes(struct drm_connector *connector)
return count;
}
static int cirrus_vga_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
/* Any mode we've added is valid */
return MODE_OK;
}
static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
*connector)
{
......@@ -546,7 +539,6 @@ static void cirrus_connector_destroy(struct drm_connector *connector)
struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs = {
.get_modes = cirrus_vga_get_modes,
.mode_valid = cirrus_vga_mode_valid,
.best_encoder = cirrus_connector_best_encoder,
};
......
......@@ -363,7 +363,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
list->master = dev->primary->master;
*maplist = list;
return 0;
}
}
int drm_addmap(struct drm_device * dev, resource_size_t offset,
unsigned int size, enum drm_map_type type,
......
......@@ -1145,16 +1145,19 @@ EXPORT_SYMBOL(drm_plane_cleanup);
*/
void drm_plane_force_disable(struct drm_plane *plane)
{
struct drm_framebuffer *old_fb = plane->fb;
int ret;
if (!plane->fb)
if (!old_fb)
return;
ret = plane->funcs->disable_plane(plane);
if (ret)
if (ret) {
DRM_ERROR("failed to disable plane with busy fb\n");
return;
}
/* disconnect the plane from the fb and crtc: */
__drm_framebuffer_unreference(plane->fb);
__drm_framebuffer_unreference(old_fb);
plane->fb = NULL;
plane->crtc = NULL;
}
......@@ -2122,9 +2125,13 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
if (!plane_req->fb_id) {
drm_modeset_lock_all(dev);
old_fb = plane->fb;
plane->funcs->disable_plane(plane);
plane->crtc = NULL;
plane->fb = NULL;
ret = plane->funcs->disable_plane(plane);
if (!ret) {
plane->crtc = NULL;
plane->fb = NULL;
} else {
old_fb = NULL;
}
drm_modeset_unlock_all(dev);
goto out;
}
......@@ -2193,16 +2200,18 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
}
drm_modeset_lock_all(dev);
old_fb = plane->fb;
ret = plane->funcs->update_plane(plane, crtc, fb,
plane_req->crtc_x, plane_req->crtc_y,
plane_req->crtc_w, plane_req->crtc_h,
plane_req->src_x, plane_req->src_y,
plane_req->src_w, plane_req->src_h);
if (!ret) {
old_fb = plane->fb;
plane->crtc = crtc;
plane->fb = fb;
fb = NULL;
} else {
old_fb = NULL;
}
drm_modeset_unlock_all(dev);
......@@ -2245,9 +2254,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
ret = crtc->funcs->set_config(set);
if (ret == 0) {
crtc->primary->crtc = crtc;
/* crtc->fb must be updated by ->set_config, enforces this. */
WARN_ON(fb != crtc->primary->fb);
crtc->primary->fb = fb;
}
list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
......
......@@ -140,16 +140,10 @@ drm_encoder_disable(struct drm_encoder *encoder)
static void __drm_helper_disable_unused_functions(struct drm_device *dev)
{
struct drm_encoder *encoder;
struct drm_connector *connector;
struct drm_crtc *crtc;
drm_warn_on_modeset_not_all_locked(dev);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (!connector->encoder)
continue;
}
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (!drm_helper_encoder_in_use(encoder)) {
drm_encoder_disable(encoder);
......@@ -387,8 +381,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
}
EXPORT_SYMBOL(drm_crtc_helper_set_mode);
static int
static void
drm_crtc_helper_disable(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
......@@ -417,7 +410,6 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
}
__drm_helper_disable_unused_functions(dev);
return 0;
}
/**
......@@ -468,7 +460,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
(int)set->num_connectors, set->x, set->y);
} else {
DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
return drm_crtc_helper_disable(set->crtc);
drm_crtc_helper_disable(set->crtc);
return 0;
}
dev = set->crtc->dev;
......
......@@ -206,7 +206,7 @@ i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
* i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper
* @adapter: i2c adapter to register
*
* This registers an i2c adapater that uses dp aux channel as it's underlaying
* This registers an i2c adapter that uses dp aux channel as it's underlaying
* transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure
* and store it in the algo_data member of the @adapter argument. This will be
* used by the i2c over dp aux algorithm to drive the hardware.
......
This diff is collapsed.
......@@ -45,13 +45,13 @@ static LIST_HEAD(kernel_fb_helper_list);
* DOC: fbdev helpers
*
* The fb helper functions are useful to provide an fbdev on top of a drm kernel
* mode setting driver. They can be used mostly independantely from the crtc
* mode setting driver. They can be used mostly independently from the crtc
* helper functions used by many drivers to implement the kernel mode setting
* interfaces.
*
* Initialization is done as a three-step process with drm_fb_helper_init(),
* drm_fb_helper_single_add_all_connectors() and drm_fb_helper_initial_config().
* Drivers with fancier requirements than the default beheviour can override the
* Drivers with fancier requirements than the default behaviour can override the
* second step with their own code. Teardown is done with drm_fb_helper_fini().
*
* At runtime drivers should restore the fbdev console by calling
......@@ -59,7 +59,7 @@ static LIST_HEAD(kernel_fb_helper_list);
* should also notify the fb helper code from updates to the output
* configuration by calling drm_fb_helper_hotplug_event(). For easier
* integration with the output polling code in drm_crtc_helper.c the modeset
* code proves a ->output_poll_changed callback.
* code provides a ->output_poll_changed callback.
*
* All other functions exported by the fb helper library can be used to
* implement the fbdev driver interface by the driver.
......@@ -326,12 +326,21 @@ static bool drm_fb_helper_force_kernel_mode(void)
return false;
list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF)
struct drm_device *dev = helper->dev;
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
continue;
if (!mutex_trylock(&dev->mode_config.mutex)) {
error = true;
continue;
}
ret = drm_fb_helper_restore_fbdev_mode(helper);
if (ret)
error = true;
mutex_unlock(&dev->mode_config.mutex);
}
return error;
}
......
......@@ -43,8 +43,7 @@
DEFINE_MUTEX(drm_global_mutex);
EXPORT_SYMBOL(drm_global_mutex);
static int drm_open_helper(struct inode *inode, struct file *filp,
struct drm_minor *minor);
static int drm_open_helper(struct file *filp, struct drm_minor *minor);
static int drm_setup(struct drm_device * dev)
{
......@@ -95,7 +94,7 @@ int drm_open(struct inode *inode, struct file *filp)
/* share address_space across all char-devs of a single device */
filp->f_mapping = dev->anon_inode->i_mapping;
retcode = drm_open_helper(inode, filp, minor);
retcode = drm_open_helper(filp, minor);
if (retcode)
goto err_undo;
if (need_setup) {
......@@ -171,7 +170,6 @@ static int drm_cpu_valid(void)
/**
* Called whenever a process opens /dev/drm.
*
* \param inode device inode.
* \param filp file pointer.
* \param minor acquired minor-object.
* \return zero on success or a negative number on failure.
......@@ -179,8 +177,7 @@ static int drm_cpu_valid(void)
* Creates and initializes a drm_file structure for the file private data in \p
* filp and add it into the double linked list in \p dev.
*/
static int drm_open_helper(struct inode *inode, struct file *filp,
struct drm_minor *minor)
static int drm_open_helper(struct file *filp, struct drm_minor *minor)
{
struct drm_device *dev = minor->dev;
struct drm_file *priv;
......
......@@ -124,7 +124,6 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
.y2 = crtc->mode.vdisplay,
};
struct drm_connector **connector_list;
struct drm_framebuffer *tmpfb;
int num_connectors, ret;
if (!crtc->enabled) {
......@@ -145,6 +144,8 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
}
/* Disallow scaling */
src_w >>= 16;
src_h >>= 16;
if (crtc_w != src_w || crtc_h != src_h) {
DRM_DEBUG_KMS("Can't scale primary plane\n");
return -EINVAL;
......@@ -176,21 +177,14 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
set.num_connectors = num_connectors;
/*
* set_config() adjusts crtc->primary->fb; however the DRM setplane
* code that called us expects to handle the framebuffer update and
* reference counting; save and restore the current fb before
* calling it.
*
* N.B., we call set_config() directly here rather than using
* We call set_config() directly here rather than using
* drm_mode_set_config_internal. We're reprogramming the same
* connectors that were already in use, so we shouldn't need the extra
* cross-CRTC fb refcounting to accomodate stealing connectors.
* drm_mode_setplane() already handles the basic refcounting for the
* framebuffers involved in this operation.
*/
tmpfb = plane->fb;
ret = crtc->funcs->set_config(&set);
plane->fb = tmpfb;
kfree(connector_list);
return ret;
......@@ -232,7 +226,6 @@ EXPORT_SYMBOL(drm_primary_helper_disable);
*/
void drm_primary_helper_destroy(struct drm_plane *plane)
{
plane->funcs->disable_plane(plane);
drm_plane_cleanup(plane);
kfree(plane);
}
......
......@@ -151,7 +151,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
drm_mode_validate_flag(connector, mode_flags);
list_for_each_entry(mode, &connector->modes, head) {
if (mode->status == MODE_OK)
if (mode->status == MODE_OK && connector_funcs->mode_valid)
mode->status = connector_funcs->mode_valid(connector,
mode);
}
......
......@@ -949,12 +949,6 @@ static int exynos_dp_get_modes(struct drm_connector *connector)
return 1;
}
static int exynos_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static struct drm_encoder *exynos_dp_best_encoder(
struct drm_connector *connector)
{
......@@ -965,7 +959,6 @@ static struct drm_encoder *exynos_dp_best_encoder(
static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
.get_modes = exynos_dp_get_modes,
.mode_valid = exynos_dp_mode_valid,
.best_encoder = exynos_dp_best_encoder,
};
......
......@@ -94,12 +94,6 @@ static int exynos_dpi_get_modes(struct drm_connector *connector)
return 0;
}
static int exynos_dpi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static struct drm_encoder *
exynos_dpi_best_encoder(struct drm_connector *connector)
{
......@@ -110,7 +104,6 @@ exynos_dpi_best_encoder(struct drm_connector *connector)
static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
.get_modes = exynos_dpi_get_modes,
.mode_valid = exynos_dpi_mode_valid,
.best_encoder = exynos_dpi_best_encoder,
};
......
......@@ -533,12 +533,6 @@ static int vidi_get_modes(struct drm_connector *connector)
return drm_add_edid_modes(connector, edid);
}
static int vidi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
{
struct vidi_context *ctx = ctx_from_connector(connector);
......@@ -548,7 +542,6 @@ static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
.get_modes = vidi_get_modes,
.mode_valid = vidi_mode_valid,
.best_encoder = vidi_best_encoder,
};
......
......@@ -57,15 +57,8 @@ static int rcar_du_lvds_connector_get_modes(struct drm_connector *connector)
return 1;
}
static int rcar_du_lvds_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static const struct drm_connector_helper_funcs connector_helper_funcs = {
.get_modes = rcar_du_lvds_connector_get_modes,
.mode_valid = rcar_du_lvds_connector_mode_valid,
.best_encoder = rcar_du_connector_best_encoder,
};
......
......@@ -25,15 +25,8 @@ static int rcar_du_vga_connector_get_modes(struct drm_connector *connector)
return 0;
}
static int rcar_du_vga_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static const struct drm_connector_helper_funcs connector_helper_funcs = {
.get_modes = rcar_du_vga_connector_get_modes,
.mode_valid = rcar_du_vga_connector_mode_valid,
.best_encoder = rcar_du_connector_best_encoder,
};
......
......@@ -674,12 +674,6 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector)
return 1;
}
static int shmob_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static struct drm_encoder *
shmob_drm_connector_best_encoder(struct drm_connector *connector)
{
......@@ -690,7 +684,6 @@ shmob_drm_connector_best_encoder(struct drm_connector *connector)
static const struct drm_connector_helper_funcs connector_helper_funcs = {
.get_modes = shmob_drm_connector_get_modes,
.mode_valid = shmob_drm_connector_mode_valid,
.best_encoder = shmob_drm_connector_best_encoder,
};
......
......@@ -200,13 +200,6 @@ static const struct file_operations imx_drm_driver_fops = {
.llseek = noop_llseek,
};
int imx_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
EXPORT_SYMBOL(imx_drm_connector_mode_valid);
void imx_drm_connector_destroy(struct drm_connector *connector)
{
drm_sysfs_connector_remove(connector);
......
......@@ -50,8 +50,6 @@ int imx_drm_encoder_get_mux_id(struct device_node *node,
int imx_drm_encoder_parse_of(struct drm_device *drm,
struct drm_encoder *encoder, struct device_node *np);
int imx_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode);
void imx_drm_connector_destroy(struct drm_connector *connector);
void imx_drm_encoder_destroy(struct drm_encoder *encoder);
......
......@@ -1492,7 +1492,6 @@ static struct drm_connector_funcs imx_hdmi_connector_funcs = {
static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
.get_modes = imx_hdmi_connector_get_modes,
.mode_valid = imx_drm_connector_mode_valid,
.best_encoder = imx_hdmi_connector_best_encoder,
};
......
......@@ -317,7 +317,6 @@ static struct drm_connector_funcs imx_ldb_connector_funcs = {
static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = {
.get_modes = imx_ldb_connector_get_modes,
.best_encoder = imx_ldb_connector_best_encoder,
.mode_valid = imx_drm_connector_mode_valid,
};
static struct drm_encoder_funcs imx_ldb_encoder_funcs = {
......
......@@ -251,10 +251,6 @@ static int imx_tve_connector_mode_valid(struct drm_connector *connector,
unsigned long rate;
int ret;
ret = imx_drm_connector_mode_valid(connector, mode);
if (ret != MODE_OK)
return ret;
/* pixel clock with 2x oversampling */
rate = clk_round_rate(tve->clk, 2000UL * mode->clock) / 2000;
if (rate == mode->clock)
......
......@@ -148,7 +148,6 @@ static struct drm_connector_funcs imx_pd_connector_funcs = {
static struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
.get_modes = imx_pd_connector_get_modes,
.best_encoder = imx_pd_connector_best_encoder,
.mode_valid = imx_drm_connector_mode_valid,
};
static struct drm_encoder_funcs imx_pd_encoder_funcs = {
......
......@@ -1021,6 +1021,7 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
extern enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code);
extern bool drm_detect_hdmi_monitor(struct edid *edid);
extern bool drm_detect_monitor_audio(struct edid *edid);
extern bool drm_rgb_quant_range_selectable(struct edid *edid);
......
......@@ -114,7 +114,7 @@ struct drm_encoder_helper_funcs {
/**
* drm_connector_helper_funcs - helper operations for connectors
* @get_modes: get mode list for this connector
* @mode_valid: is this mode valid on the given connector?
* @mode_valid (optional): is this mode valid on the given connector?
*
* The helper operations are called by the mid-layer CRTC helper.
*/
......
......@@ -57,6 +57,7 @@ typedef void (*drm_flip_func_t)(struct drm_flip_work *work, void *val);
* @count: number of committed items
* @func: callback fxn called for each committed item
* @worker: worker which calls @func
* @fifo: queue of committed items
*/
struct drm_flip_work {
const char *name;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment