From 03dd4cb26d967f9588437b0fc9cc0e8353322bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Fabian=20Silva=20Delgado?= Date: Fri, 25 Mar 2016 03:53:42 -0300 Subject: Linux-libre 4.5-gnu --- drivers/gpu/drm/tegra/Kconfig | 12 ---- drivers/gpu/drm/tegra/dc.c | 15 +++-- drivers/gpu/drm/tegra/dpaux.c | 41 ++++++------ drivers/gpu/drm/tegra/drm.c | 94 +++++++++++---------------- drivers/gpu/drm/tegra/drm.h | 35 +++++----- drivers/gpu/drm/tegra/dsi.c | 15 ++--- drivers/gpu/drm/tegra/fb.c | 42 +++++++++--- drivers/gpu/drm/tegra/gem.c | 15 +---- drivers/gpu/drm/tegra/hdmi.c | 2 +- drivers/gpu/drm/tegra/rgb.c | 2 +- drivers/gpu/drm/tegra/sor.c | 147 +++++++++++++++++++----------------------- 11 files changed, 198 insertions(+), 222 deletions(-) (limited to 'drivers/gpu/drm/tegra') diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index 74d9d6214..63ebb154b 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig @@ -16,18 +16,6 @@ config DRM_TEGRA if DRM_TEGRA -config DRM_TEGRA_FBDEV - bool "Enable legacy fbdev support" - select DRM_KMS_FB_HELPER - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - default y - help - Choose this option if you have a need for the legacy fbdev support. - Note that this support also provides the Linux console on top of - the Tegra modesetting driver. - config DRM_TEGRA_DEBUG bool "NVIDIA Tegra DRM debug support" help diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index e9f24a85a..dde6f208c 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -660,7 +660,8 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm, err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, &tegra_primary_plane_funcs, formats, - num_formats, DRM_PLANE_TYPE_PRIMARY); + num_formats, DRM_PLANE_TYPE_PRIMARY, + NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); @@ -827,7 +828,8 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe, &tegra_cursor_plane_funcs, formats, - num_formats, DRM_PLANE_TYPE_CURSOR); + num_formats, DRM_PLANE_TYPE_CURSOR, + NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); @@ -890,7 +892,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe, &tegra_overlay_plane_funcs, formats, - num_formats, DRM_PLANE_TYPE_OVERLAY); + num_formats, DRM_PLANE_TYPE_OVERLAY, + NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); @@ -1732,7 +1735,7 @@ static int tegra_dc_init(struct host1x_client *client) } err = drm_crtc_init_with_planes(drm, &dc->base, primary, cursor, - &tegra_crtc_funcs); + &tegra_crtc_funcs, NULL); if (err < 0) goto cleanup; @@ -1952,8 +1955,10 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc) * cases where only a single display controller is used. */ for_each_matching_node(np, tegra_dc_of_match) { - if (np == dc->dev->of_node) + if (np == dc->dev->of_node) { + of_node_put(np); break; + } value++; } diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index 6aecb6647..b24a0f148 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -436,7 +436,7 @@ struct platform_driver tegra_dpaux_driver = { .remove = tegra_dpaux_remove, }; -struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np) +struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np) { struct tegra_dpaux *dpaux; @@ -445,7 +445,7 @@ struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np) list_for_each_entry(dpaux, &dpaux_list, list) if (np == dpaux->dev->of_node) { mutex_unlock(&dpaux_lock); - return dpaux; + return &dpaux->aux; } mutex_unlock(&dpaux_lock); @@ -453,8 +453,9 @@ struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np) return NULL; } -int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output) +int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output) { + struct tegra_dpaux *dpaux = to_dpaux(aux); unsigned long timeout; int err; @@ -470,7 +471,7 @@ int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output) while (time_before(jiffies, timeout)) { enum drm_connector_status status; - status = tegra_dpaux_detect(dpaux); + status = drm_dp_aux_detect(aux); if (status == connector_status_connected) { enable_irq(dpaux->irq); return 0; @@ -482,8 +483,9 @@ int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output) return -ETIMEDOUT; } -int tegra_dpaux_detach(struct tegra_dpaux *dpaux) +int drm_dp_aux_detach(struct drm_dp_aux *aux) { + struct tegra_dpaux *dpaux = to_dpaux(aux); unsigned long timeout; int err; @@ -498,7 +500,7 @@ int tegra_dpaux_detach(struct tegra_dpaux *dpaux) while (time_before(jiffies, timeout)) { enum drm_connector_status status; - status = tegra_dpaux_detect(dpaux); + status = drm_dp_aux_detect(aux); if (status == connector_status_disconnected) { dpaux->output = NULL; return 0; @@ -510,8 +512,9 @@ int tegra_dpaux_detach(struct tegra_dpaux *dpaux) return -ETIMEDOUT; } -enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux) +enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux) { + struct tegra_dpaux *dpaux = to_dpaux(aux); u32 value; value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT); @@ -522,8 +525,9 @@ enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux) return connector_status_disconnected; } -int tegra_dpaux_enable(struct tegra_dpaux *dpaux) +int drm_dp_aux_enable(struct drm_dp_aux *aux) { + struct tegra_dpaux *dpaux = to_dpaux(aux); u32 value; value = DPAUX_HYBRID_PADCTL_AUX_CMH(2) | @@ -540,8 +544,9 @@ int tegra_dpaux_enable(struct tegra_dpaux *dpaux) return 0; } -int tegra_dpaux_disable(struct tegra_dpaux *dpaux) +int drm_dp_aux_disable(struct drm_dp_aux *aux) { + struct tegra_dpaux *dpaux = to_dpaux(aux); u32 value; value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE); @@ -551,11 +556,11 @@ int tegra_dpaux_disable(struct tegra_dpaux *dpaux) return 0; } -int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding) +int drm_dp_aux_prepare(struct drm_dp_aux *aux, u8 encoding) { int err; - err = drm_dp_dpcd_writeb(&dpaux->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, + err = drm_dp_dpcd_writeb(aux, DP_MAIN_LINK_CHANNEL_CODING_SET, encoding); if (err < 0) return err; @@ -563,15 +568,15 @@ int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding) return 0; } -int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link, - u8 pattern) +int drm_dp_aux_train(struct drm_dp_aux *aux, struct drm_dp_link *link, + u8 pattern) { u8 tp = pattern & DP_TRAINING_PATTERN_MASK; u8 status[DP_LINK_STATUS_SIZE], values[4]; unsigned int i; int err; - err = drm_dp_dpcd_writeb(&dpaux->aux, DP_TRAINING_PATTERN_SET, pattern); + err = drm_dp_dpcd_writeb(aux, DP_TRAINING_PATTERN_SET, pattern); if (err < 0) return err; @@ -584,14 +589,14 @@ int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link, DP_TRAIN_MAX_SWING_REACHED | DP_TRAIN_VOLTAGE_SWING_LEVEL_0; - err = drm_dp_dpcd_write(&dpaux->aux, DP_TRAINING_LANE0_SET, values, + err = drm_dp_dpcd_write(aux, DP_TRAINING_LANE0_SET, values, link->num_lanes); if (err < 0) return err; usleep_range(500, 1000); - err = drm_dp_dpcd_read_link_status(&dpaux->aux, status); + err = drm_dp_dpcd_read_link_status(aux, status); if (err < 0) return err; @@ -609,11 +614,11 @@ int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link, break; default: - dev_err(dpaux->dev, "unsupported training pattern %u\n", tp); + dev_err(aux->dev, "unsupported training pattern %u\n", tp); return -EINVAL; } - err = drm_dp_dpcd_writeb(&dpaux->aux, DP_EDP_CONFIGURATION_SET, 0); + err = drm_dp_dpcd_writeb(aux, DP_EDP_CONFIGURATION_SET, 0); if (err < 0) return err; diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 159ef515c..c5c856a08 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -106,7 +106,7 @@ static int tegra_atomic_commit(struct drm_device *drm, static const struct drm_mode_config_funcs tegra_drm_mode_funcs = { .fb_create = tegra_fb_create, -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION .output_poll_changed = tegra_fb_output_poll_changed, #endif .atomic_check = drm_atomic_helper_check, @@ -137,8 +137,8 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) start = geometry->aperture_start; end = geometry->aperture_end; - DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n", - start, end); + DRM_DEBUG_DRIVER("IOMMU aperture initialized (%#llx-%#llx)\n", + start, end); drm_mm_init(&tegra->mm, start, end - start + 1); } @@ -260,7 +260,7 @@ static void tegra_drm_context_free(struct tegra_drm_context *context) static void tegra_drm_lastclose(struct drm_device *drm) { -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION struct tegra_drm *tegra = drm->dev_private; tegra_fbdev_restore_mode(tegra->fbdev); @@ -277,9 +277,7 @@ host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle) if (!gem) return NULL; - mutex_lock(&drm->struct_mutex); - drm_gem_object_unreference(gem); - mutex_unlock(&drm->struct_mutex); + drm_gem_object_unreference_unlocked(gem); bo = to_tegra_bo(gem); return &bo->base; @@ -473,7 +471,7 @@ static int tegra_gem_mmap(struct drm_device *drm, void *data, args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node); - drm_gem_object_unreference(gem); + drm_gem_object_unreference_unlocked(gem); return 0; } @@ -683,7 +681,7 @@ static int tegra_gem_set_tiling(struct drm_device *drm, void *data, bo->tiling.mode = mode; bo->tiling.value = value; - drm_gem_object_unreference(gem); + drm_gem_object_unreference_unlocked(gem); return 0; } @@ -723,7 +721,7 @@ static int tegra_gem_get_tiling(struct drm_device *drm, void *data, break; } - drm_gem_object_unreference(gem); + drm_gem_object_unreference_unlocked(gem); return err; } @@ -748,7 +746,7 @@ static int tegra_gem_set_flags(struct drm_device *drm, void *data, if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP) bo->flags |= TEGRA_BO_BOTTOM_UP; - drm_gem_object_unreference(gem); + drm_gem_object_unreference_unlocked(gem); return 0; } @@ -770,7 +768,7 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data, if (bo->flags & TEGRA_BO_BOTTOM_UP) args->flags |= DRM_TEGRA_GEM_BOTTOM_UP; - drm_gem_object_unreference(gem); + drm_gem_object_unreference_unlocked(gem); return 0; } @@ -921,7 +919,8 @@ static void tegra_debugfs_cleanup(struct drm_minor *minor) #endif static struct drm_driver tegra_drm_driver = { - .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, + .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | + DRIVER_ATOMIC, .load = tegra_drm_load, .unload = tegra_drm_unload, .open = tegra_drm_open, @@ -991,7 +990,6 @@ static int host1x_drm_probe(struct host1x_device *dev) if (!drm) return -ENOMEM; - drm_dev_set_unique(drm, dev_name(&dev->dev)); dev_set_drvdata(&dev->dev, drm); err = drm_dev_register(drm, 0); @@ -1023,8 +1021,17 @@ static int host1x_drm_remove(struct host1x_device *dev) static int host1x_drm_suspend(struct device *dev) { struct drm_device *drm = dev_get_drvdata(dev); + struct tegra_drm *tegra = drm->dev_private; drm_kms_helper_poll_disable(drm); + tegra_drm_fb_suspend(drm); + + tegra->state = drm_atomic_helper_suspend(drm); + if (IS_ERR(tegra->state)) { + tegra_drm_fb_resume(drm); + drm_kms_helper_poll_enable(drm); + return PTR_ERR(tegra->state); + } return 0; } @@ -1032,7 +1039,10 @@ static int host1x_drm_suspend(struct device *dev) static int host1x_drm_resume(struct device *dev) { struct drm_device *drm = dev_get_drvdata(dev); + struct tegra_drm *tegra = drm->dev_private; + drm_atomic_helper_resume(drm, tegra->state); + tegra_drm_fb_resume(drm); drm_kms_helper_poll_enable(drm); return 0; @@ -1076,6 +1086,16 @@ static struct host1x_driver host1x_drm_driver = { .subdevs = host1x_drm_subdevs, }; +static struct platform_driver * const drivers[] = { + &tegra_dc_driver, + &tegra_hdmi_driver, + &tegra_dsi_driver, + &tegra_dpaux_driver, + &tegra_sor_driver, + &tegra_gr2d_driver, + &tegra_gr3d_driver, +}; + static int __init host1x_drm_init(void) { int err; @@ -1084,48 +1104,12 @@ static int __init host1x_drm_init(void) if (err < 0) return err; - err = platform_driver_register(&tegra_dc_driver); + err = platform_register_drivers(drivers, ARRAY_SIZE(drivers)); if (err < 0) goto unregister_host1x; - err = platform_driver_register(&tegra_dsi_driver); - if (err < 0) - goto unregister_dc; - - err = platform_driver_register(&tegra_sor_driver); - if (err < 0) - goto unregister_dsi; - - err = platform_driver_register(&tegra_hdmi_driver); - if (err < 0) - goto unregister_sor; - - err = platform_driver_register(&tegra_dpaux_driver); - if (err < 0) - goto unregister_hdmi; - - err = platform_driver_register(&tegra_gr2d_driver); - if (err < 0) - goto unregister_dpaux; - - err = platform_driver_register(&tegra_gr3d_driver); - if (err < 0) - goto unregister_gr2d; - return 0; -unregister_gr2d: - platform_driver_unregister(&tegra_gr2d_driver); -unregister_dpaux: - platform_driver_unregister(&tegra_dpaux_driver); -unregister_hdmi: - platform_driver_unregister(&tegra_hdmi_driver); -unregister_sor: - platform_driver_unregister(&tegra_sor_driver); -unregister_dsi: - platform_driver_unregister(&tegra_dsi_driver); -unregister_dc: - platform_driver_unregister(&tegra_dc_driver); unregister_host1x: host1x_driver_unregister(&host1x_drm_driver); return err; @@ -1134,13 +1118,7 @@ module_init(host1x_drm_init); static void __exit host1x_drm_exit(void) { - platform_driver_unregister(&tegra_gr3d_driver); - platform_driver_unregister(&tegra_gr2d_driver); - platform_driver_unregister(&tegra_dpaux_driver); - platform_driver_unregister(&tegra_hdmi_driver); - platform_driver_unregister(&tegra_sor_driver); - platform_driver_unregister(&tegra_dsi_driver); - platform_driver_unregister(&tegra_dc_driver); + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); host1x_driver_unregister(&host1x_drm_driver); } module_exit(host1x_drm_exit); diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index ec49275ff..c088f2f67 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -30,7 +30,7 @@ struct tegra_fb { unsigned int num_planes; }; -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION struct tegra_fbdev { struct drm_fb_helper base; struct tegra_fb *fb; @@ -46,7 +46,7 @@ struct tegra_drm { struct mutex clients_lock; struct list_head clients; -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION struct tegra_fbdev *fbdev; #endif @@ -57,6 +57,8 @@ struct tegra_drm { struct work_struct work; struct mutex lock; } commit; + + struct drm_atomic_state *state; }; struct tegra_drm_client; @@ -247,18 +249,17 @@ void tegra_output_connector_destroy(struct drm_connector *connector); void tegra_output_encoder_destroy(struct drm_encoder *encoder); /* from dpaux.c */ -struct tegra_dpaux; struct drm_dp_link; -struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np); -enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux); -int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output); -int tegra_dpaux_detach(struct tegra_dpaux *dpaux); -int tegra_dpaux_enable(struct tegra_dpaux *dpaux); -int tegra_dpaux_disable(struct tegra_dpaux *dpaux); -int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding); -int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link, - u8 pattern); +struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np); +enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux); +int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output); +int drm_dp_aux_detach(struct drm_dp_aux *aux); +int drm_dp_aux_enable(struct drm_dp_aux *aux); +int drm_dp_aux_disable(struct drm_dp_aux *aux); +int drm_dp_aux_prepare(struct drm_dp_aux *aux, u8 encoding); +int drm_dp_aux_train(struct drm_dp_aux *aux, struct drm_dp_link *link, + u8 pattern); /* from fb.c */ struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer, @@ -268,21 +269,23 @@ int tegra_fb_get_tiling(struct drm_framebuffer *framebuffer, struct tegra_bo_tiling *tiling); struct drm_framebuffer *tegra_fb_create(struct drm_device *drm, struct drm_file *file, - struct drm_mode_fb_cmd2 *cmd); + const struct drm_mode_fb_cmd2 *cmd); int tegra_drm_fb_prepare(struct drm_device *drm); void tegra_drm_fb_free(struct drm_device *drm); int tegra_drm_fb_init(struct drm_device *drm); void tegra_drm_fb_exit(struct drm_device *drm); -#ifdef CONFIG_DRM_TEGRA_FBDEV +void tegra_drm_fb_suspend(struct drm_device *drm); +void tegra_drm_fb_resume(struct drm_device *drm); +#ifdef CONFIG_DRM_FBDEV_EMULATION void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev); void tegra_fb_output_poll_changed(struct drm_device *drm); #endif extern struct platform_driver tegra_dc_driver; -extern struct platform_driver tegra_dsi_driver; -extern struct platform_driver tegra_sor_driver; extern struct platform_driver tegra_hdmi_driver; +extern struct platform_driver tegra_dsi_driver; extern struct platform_driver tegra_dpaux_driver; +extern struct platform_driver tegra_sor_driver; extern struct platform_driver tegra_gr2d_driver; extern struct platform_driver tegra_gr3d_driver; diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index f0a138ef6..44e102799 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -745,14 +745,13 @@ static void tegra_dsi_soft_reset(struct tegra_dsi *dsi) static void tegra_dsi_connector_reset(struct drm_connector *connector) { - struct tegra_dsi_state *state; - - kfree(connector->state); - connector->state = NULL; + struct tegra_dsi_state *state = + kzalloc(sizeof(*state), GFP_KERNEL); - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (state) - connector->state = &state->base; + if (state) { + kfree(connector->state); + __drm_atomic_helper_connector_reset(connector, &state->base); + } } static struct drm_connector_state * @@ -1023,7 +1022,7 @@ static int tegra_dsi_init(struct host1x_client *client) drm_encoder_init(drm, &dsi->output.encoder, &tegra_dsi_encoder_funcs, - DRM_MODE_ENCODER_DSI); + DRM_MODE_ENCODER_DSI, NULL); drm_encoder_helper_add(&dsi->output.encoder, &tegra_dsi_encoder_helper_funcs); diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 1004075fd..ca84de9cc 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -10,6 +10,8 @@ * published by the Free Software Foundation. */ +#include + #include "drm.h" #include "gem.h" @@ -18,7 +20,7 @@ static inline struct tegra_fb *to_tegra_fb(struct drm_framebuffer *fb) return container_of(fb, struct tegra_fb, base); } -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION static inline struct tegra_fbdev *to_tegra_fbdev(struct drm_fb_helper *helper) { return container_of(helper, struct tegra_fbdev, base); @@ -86,13 +88,13 @@ static int tegra_fb_create_handle(struct drm_framebuffer *framebuffer, return drm_gem_handle_create(file, &fb->planes[0]->gem, handle); } -static struct drm_framebuffer_funcs tegra_fb_funcs = { +static const struct drm_framebuffer_funcs tegra_fb_funcs = { .destroy = tegra_fb_destroy, .create_handle = tegra_fb_create_handle, }; static struct tegra_fb *tegra_fb_alloc(struct drm_device *drm, - struct drm_mode_fb_cmd2 *mode_cmd, + const struct drm_mode_fb_cmd2 *mode_cmd, struct tegra_bo **planes, unsigned int num_planes) { @@ -131,7 +133,7 @@ static struct tegra_fb *tegra_fb_alloc(struct drm_device *drm, struct drm_framebuffer *tegra_fb_create(struct drm_device *drm, struct drm_file *file, - struct drm_mode_fb_cmd2 *cmd) + const struct drm_mode_fb_cmd2 *cmd) { unsigned int hsub, vsub, i; struct tegra_bo *planes[4]; @@ -181,7 +183,7 @@ unreference: return ERR_PTR(err); } -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION static struct fb_ops tegra_fb_ops = { .owner = THIS_MODULE, .fb_fillrect = drm_fb_helper_sys_fillrect, @@ -370,7 +372,7 @@ void tegra_fb_output_poll_changed(struct drm_device *drm) int tegra_drm_fb_prepare(struct drm_device *drm) { -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION struct tegra_drm *tegra = drm->dev_private; tegra->fbdev = tegra_fbdev_create(drm); @@ -383,7 +385,7 @@ int tegra_drm_fb_prepare(struct drm_device *drm) void tegra_drm_fb_free(struct drm_device *drm) { -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION struct tegra_drm *tegra = drm->dev_private; tegra_fbdev_free(tegra->fbdev); @@ -392,7 +394,7 @@ void tegra_drm_fb_free(struct drm_device *drm) int tegra_drm_fb_init(struct drm_device *drm) { -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION struct tegra_drm *tegra = drm->dev_private; int err; @@ -407,9 +409,31 @@ int tegra_drm_fb_init(struct drm_device *drm) void tegra_drm_fb_exit(struct drm_device *drm) { -#ifdef CONFIG_DRM_TEGRA_FBDEV +#ifdef CONFIG_DRM_FBDEV_EMULATION struct tegra_drm *tegra = drm->dev_private; tegra_fbdev_exit(tegra->fbdev); #endif } + +void tegra_drm_fb_suspend(struct drm_device *drm) +{ +#ifdef CONFIG_DRM_FBDEV_EMULATION + struct tegra_drm *tegra = drm->dev_private; + + console_lock(); + drm_fb_helper_set_suspend(&tegra->fbdev->base, 1); + console_unlock(); +#endif +} + +void tegra_drm_fb_resume(struct drm_device *drm) +{ +#ifdef CONFIG_DRM_FBDEV_EMULATION + struct tegra_drm *tegra = drm->dev_private; + + console_lock(); + drm_fb_helper_set_suspend(&tegra->fbdev->base, 0); + console_unlock(); +#endif +} diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 01e16e146..33add93b4 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -28,11 +28,8 @@ static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo) static void tegra_bo_put(struct host1x_bo *bo) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); - struct drm_device *drm = obj->gem.dev; - mutex_lock(&drm->struct_mutex); - drm_gem_object_unreference(&obj->gem); - mutex_unlock(&drm->struct_mutex); + drm_gem_object_unreference_unlocked(&obj->gem); } static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt) @@ -72,11 +69,8 @@ static void tegra_bo_kunmap(struct host1x_bo *bo, unsigned int page, static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); - struct drm_device *drm = obj->gem.dev; - mutex_lock(&drm->struct_mutex); drm_gem_object_reference(&obj->gem); - mutex_unlock(&drm->struct_mutex); return bo; } @@ -408,12 +402,9 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, struct drm_gem_object *gem; struct tegra_bo *bo; - mutex_lock(&drm->struct_mutex); - gem = drm_gem_object_lookup(drm, file, handle); if (!gem) { dev_err(drm->dev, "failed to lookup GEM object\n"); - mutex_unlock(&drm->struct_mutex); return -EINVAL; } @@ -421,9 +412,7 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, *offset = drm_vma_node_offset_addr(&bo->gem.vma_node); - drm_gem_object_unreference(gem); - - mutex_unlock(&drm->struct_mutex); + drm_gem_object_unreference_unlocked(gem); return 0; } diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 52b32cbd9..b7ef4929e 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -1320,7 +1320,7 @@ static int tegra_hdmi_init(struct host1x_client *client) hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF; drm_encoder_init(drm, &hdmi->output.encoder, &tegra_hdmi_encoder_funcs, - DRM_MODE_ENCODER_TMDS); + DRM_MODE_ENCODER_TMDS, NULL); drm_encoder_helper_add(&hdmi->output.encoder, &tegra_hdmi_encoder_helper_funcs); diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index bc9735b4a..e246334e0 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c @@ -287,7 +287,7 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc) output->connector.dpms = DRM_MODE_DPMS_OFF; drm_encoder_init(drm, &output->encoder, &tegra_rgb_encoder_funcs, - DRM_MODE_ENCODER_LVDS); + DRM_MODE_ENCODER_LVDS, NULL); drm_encoder_helper_add(&output->encoder, &tegra_rgb_encoder_helper_funcs); diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 3eff7cf75..757c6e860 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -173,7 +173,7 @@ struct tegra_sor { struct clk *clk_dp; struct clk *clk; - struct tegra_dpaux *dpaux; + struct drm_dp_aux *aux; struct drm_info_list *debugfs_files; struct drm_minor *minor; @@ -273,7 +273,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor, SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0); tegra_sor_writel(sor, value, SOR_DP_PADCTL0); - err = tegra_dpaux_prepare(sor->dpaux, DP_SET_ANSI_8B10B); + err = drm_dp_aux_prepare(sor->aux, DP_SET_ANSI_8B10B); if (err < 0) return err; @@ -288,7 +288,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor, pattern = DP_TRAINING_PATTERN_1; - err = tegra_dpaux_train(sor->dpaux, link, pattern); + err = drm_dp_aux_train(sor->aux, link, pattern); if (err < 0) return err; @@ -309,7 +309,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor, pattern = DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_2; - err = tegra_dpaux_train(sor->dpaux, link, pattern); + err = drm_dp_aux_train(sor->aux, link, pattern); if (err < 0) return err; @@ -324,7 +324,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor, pattern = DP_TRAINING_PATTERN_DISABLE; - err = tegra_dpaux_train(sor->dpaux, link, pattern); + err = drm_dp_aux_train(sor->aux, link, pattern); if (err < 0) return err; @@ -1044,8 +1044,8 @@ tegra_sor_connector_detect(struct drm_connector *connector, bool force) struct tegra_output *output = connector_to_output(connector); struct tegra_sor *sor = to_sor(output); - if (sor->dpaux) - return tegra_dpaux_detect(sor->dpaux); + if (sor->aux) + return drm_dp_aux_detect(sor->aux); return tegra_output_connector_detect(connector, force); } @@ -1066,13 +1066,13 @@ static int tegra_sor_connector_get_modes(struct drm_connector *connector) struct tegra_sor *sor = to_sor(output); int err; - if (sor->dpaux) - tegra_dpaux_enable(sor->dpaux); + if (sor->aux) + drm_dp_aux_enable(sor->aux); err = tegra_output_connector_get_modes(connector); - if (sor->dpaux) - tegra_dpaux_disable(sor->dpaux); + if (sor->aux) + drm_dp_aux_disable(sor->aux); return err; } @@ -1128,8 +1128,8 @@ static void tegra_sor_edp_disable(struct drm_encoder *encoder) if (err < 0) dev_err(sor->dev, "failed to power down SOR: %d\n", err); - if (sor->dpaux) { - err = tegra_dpaux_disable(sor->dpaux); + if (sor->aux) { + err = drm_dp_aux_disable(sor->aux); if (err < 0) dev_err(sor->dev, "failed to disable DP: %d\n", err); } @@ -1196,7 +1196,7 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder) struct tegra_sor *sor = to_sor(output); struct tegra_sor_config config; struct drm_dp_link link; - struct drm_dp_aux *aux; + u8 rate, lanes; int err = 0; u32 value; @@ -1209,20 +1209,14 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder) if (output->panel) drm_panel_prepare(output->panel); - /* FIXME: properly convert to struct drm_dp_aux */ - aux = (struct drm_dp_aux *)sor->dpaux; - - if (sor->dpaux) { - err = tegra_dpaux_enable(sor->dpaux); - if (err < 0) - dev_err(sor->dev, "failed to enable DP: %d\n", err); + err = drm_dp_aux_enable(sor->aux); + if (err < 0) + dev_err(sor->dev, "failed to enable DP: %d\n", err); - err = drm_dp_link_probe(aux, &link); - if (err < 0) { - dev_err(sor->dev, "failed to probe eDP link: %d\n", - err); - return; - } + err = drm_dp_link_probe(sor->aux, &link); + if (err < 0) { + dev_err(sor->dev, "failed to probe eDP link: %d\n", err); + return; } err = clk_set_parent(sor->clk, sor->clk_safe); @@ -1434,60 +1428,51 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder) value |= SOR_DP_PADCTL_PAD_CAL_PD; tegra_sor_writel(sor, value, SOR_DP_PADCTL0); - if (sor->dpaux) { - u8 rate, lanes; - - err = drm_dp_link_probe(aux, &link); - if (err < 0) - dev_err(sor->dev, "failed to probe eDP link: %d\n", - err); + err = drm_dp_link_probe(sor->aux, &link); + if (err < 0) + dev_err(sor->dev, "failed to probe eDP link: %d\n", err); - err = drm_dp_link_power_up(aux, &link); - if (err < 0) - dev_err(sor->dev, "failed to power up eDP link: %d\n", - err); + err = drm_dp_link_power_up(sor->aux, &link); + if (err < 0) + dev_err(sor->dev, "failed to power up eDP link: %d\n", err); - err = drm_dp_link_configure(aux, &link); - if (err < 0) - dev_err(sor->dev, "failed to configure eDP link: %d\n", - err); + err = drm_dp_link_configure(sor->aux, &link); + if (err < 0) + dev_err(sor->dev, "failed to configure eDP link: %d\n", err); - rate = drm_dp_link_rate_to_bw_code(link.rate); - lanes = link.num_lanes; + rate = drm_dp_link_rate_to_bw_code(link.rate); + lanes = link.num_lanes; - value = tegra_sor_readl(sor, SOR_CLK_CNTRL); - value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK; - value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate); - tegra_sor_writel(sor, value, SOR_CLK_CNTRL); + value = tegra_sor_readl(sor, SOR_CLK_CNTRL); + value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK; + value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate); + tegra_sor_writel(sor, value, SOR_CLK_CNTRL); - value = tegra_sor_readl(sor, SOR_DP_LINKCTL0); - value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK; - value |= SOR_DP_LINKCTL_LANE_COUNT(lanes); + value = tegra_sor_readl(sor, SOR_DP_LINKCTL0); + value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK; + value |= SOR_DP_LINKCTL_LANE_COUNT(lanes); - if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING) - value |= SOR_DP_LINKCTL_ENHANCED_FRAME; + if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING) + value |= SOR_DP_LINKCTL_ENHANCED_FRAME; - tegra_sor_writel(sor, value, SOR_DP_LINKCTL0); + tegra_sor_writel(sor, value, SOR_DP_LINKCTL0); - /* disable training pattern generator */ + /* disable training pattern generator */ - for (i = 0; i < link.num_lanes; i++) { - unsigned long lane = SOR_DP_TPG_CHANNEL_CODING | - SOR_DP_TPG_SCRAMBLER_GALIOS | - SOR_DP_TPG_PATTERN_NONE; - value = (value << 8) | lane; - } + for (i = 0; i < link.num_lanes; i++) { + unsigned long lane = SOR_DP_TPG_CHANNEL_CODING | + SOR_DP_TPG_SCRAMBLER_GALIOS | + SOR_DP_TPG_PATTERN_NONE; + value = (value << 8) | lane; + } - tegra_sor_writel(sor, value, SOR_DP_TPG); + tegra_sor_writel(sor, value, SOR_DP_TPG); - err = tegra_sor_dp_train_fast(sor, &link); - if (err < 0) { - dev_err(sor->dev, "DP fast link training failed: %d\n", - err); - } + err = tegra_sor_dp_train_fast(sor, &link); + if (err < 0) + dev_err(sor->dev, "DP fast link training failed: %d\n", err); - dev_dbg(sor->dev, "fast link training succeeded\n"); - } + dev_dbg(sor->dev, "fast link training succeeded\n"); err = tegra_sor_power_up(sor, 250); if (err < 0) @@ -1961,9 +1946,9 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder) /* production settings */ settings = tegra_sor_hdmi_find_settings(sor, mode->clock * 1000); - if (IS_ERR(settings)) { - dev_err(sor->dev, "no settings for pixel clock %d Hz: %ld\n", - mode->clock * 1000, PTR_ERR(settings)); + if (!settings) { + dev_err(sor->dev, "no settings for pixel clock %d Hz\n", + mode->clock * 1000); return; } @@ -2148,7 +2133,7 @@ static int tegra_sor_init(struct host1x_client *client) int encoder = DRM_MODE_ENCODER_NONE; int err; - if (!sor->dpaux) { + if (!sor->aux) { if (sor->soc->supports_hdmi) { connector = DRM_MODE_CONNECTOR_HDMIA; encoder = DRM_MODE_ENCODER_TMDS; @@ -2178,7 +2163,7 @@ static int tegra_sor_init(struct host1x_client *client) sor->output.connector.dpms = DRM_MODE_DPMS_OFF; drm_encoder_init(drm, &sor->output.encoder, &tegra_sor_encoder_funcs, - encoder); + encoder, NULL); drm_encoder_helper_add(&sor->output.encoder, helpers); drm_mode_connector_attach_encoder(&sor->output.connector, @@ -2199,8 +2184,8 @@ static int tegra_sor_init(struct host1x_client *client) dev_err(sor->dev, "debugfs setup failed: %d\n", err); } - if (sor->dpaux) { - err = tegra_dpaux_attach(sor->dpaux, &sor->output); + if (sor->aux) { + err = drm_dp_aux_attach(sor->aux, &sor->output); if (err < 0) { dev_err(sor->dev, "failed to attach DP: %d\n", err); return err; @@ -2249,8 +2234,8 @@ static int tegra_sor_exit(struct host1x_client *client) tegra_output_exit(&sor->output); - if (sor->dpaux) { - err = tegra_dpaux_detach(sor->dpaux); + if (sor->aux) { + err = drm_dp_aux_detach(sor->aux); if (err < 0) { dev_err(sor->dev, "failed to detach DP: %d\n", err); return err; @@ -2399,14 +2384,14 @@ static int tegra_sor_probe(struct platform_device *pdev) np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0); if (np) { - sor->dpaux = tegra_dpaux_find_by_of_node(np); + sor->aux = drm_dp_aux_find_by_of_node(np); of_node_put(np); - if (!sor->dpaux) + if (!sor->aux) return -EPROBE_DEFER; } - if (!sor->dpaux) { + if (!sor->aux) { if (sor->soc->supports_hdmi) { sor->ops = &tegra_sor_hdmi_ops; } else if (sor->soc->supports_lvds) { -- cgit v1.2.3