diff options
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
| -rw-r--r-- | drivers/gpu/drm/tilcdc/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 24 | ||||
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_drv.c | 120 | ||||
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_drv.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_external.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_panel.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_plane.c | 14 |
7 files changed, 101 insertions, 89 deletions
diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig index 9f505a149990..24f9a245ba59 100644 --- a/drivers/gpu/drm/tilcdc/Kconfig +++ b/drivers/gpu/drm/tilcdc/Kconfig @@ -2,9 +2,9 @@ config DRM_TILCDC tristate "DRM Support for TI LCDC Display Controller" depends on DRM && OF && ARM + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER - select DRM_KMS_CMA_HELPER - select DRM_GEM_CMA_HELPER + select DRM_GEM_DMA_HELPER select DRM_BRIDGE select DRM_PANEL_BRIDGE select VIDEOMODE_HELPERS diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 29890d704cb4..5718d9d83a49 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -12,9 +12,10 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> -#include <drm/drm_fb_cma_helper.h> +#include <drm/drm_fb_dma_helper.h> #include <drm/drm_fourcc.h> -#include <drm/drm_gem_cma_helper.h> +#include <drm/drm_framebuffer.h> +#include <drm/drm_gem_dma_helper.h> #include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_print.h> #include <drm/drm_vblank.h> @@ -63,13 +64,13 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb) { struct drm_device *dev = crtc->dev; struct tilcdc_drm_private *priv = dev->dev_private; - struct drm_gem_cma_object *gem; + struct drm_gem_dma_object *gem; dma_addr_t start, end; u64 dma_base_and_ceiling; - gem = drm_fb_cma_get_gem_obj(fb, 0); + gem = drm_fb_dma_get_gem_obj(fb, 0); - start = gem->paddr + fb->offsets[0] + + start = gem->dma_addr + fb->offsets[0] + crtc->y * fb->pitches[0] + crtc->x * fb->format->cpp[0]; @@ -433,7 +434,7 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc) set_scanout(crtc, fb); - crtc->hwmode = crtc->state->adjusted_mode; + drm_mode_copy(&crtc->hwmode, &crtc->state->adjusted_mode); tilcdc_crtc->hvtotal_us = tilcdc_mode_hvtotal(&crtc->hwmode); @@ -675,14 +676,7 @@ static int tilcdc_crtc_atomic_check(struct drm_crtc *crtc, if (!crtc_state->active) return 0; - if (state->planes[0].ptr != crtc->primary || - state->planes[0].state == NULL || - state->planes[0].state->crtc != crtc) { - dev_dbg(crtc->dev->dev, "CRTC primary plane must be present"); - return -EINVAL; - } - - return 0; + return drm_atomic_helper_check_crtc_primary_plane(crtc_state); } static int tilcdc_crtc_enable_vblank(struct drm_crtc *crtc) @@ -996,7 +990,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) if (stat & LCDC_FRAME_DONE) { tilcdc_crtc->frame_done = true; wake_up(&tilcdc_crtc->frame_done_wq); - /* rev 1 lcdc appears to hang if irq is not disbaled here */ + /* rev 1 lcdc appears to hang if irq is not disabled here */ if (priv->rev == 1) tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_FRAME_DONE_INT_ENA); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index f1d3a9f919fd..7caec4d38ddf 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -13,14 +13,14 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <drm/clients/drm_client_setup.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_dma.h> #include <drm/drm_fourcc.h> -#include <drm/drm_gem_cma_helper.h> +#include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> -#include <drm/drm_irq.h> #include <drm/drm_mm.h> #include <drm/drm_probe_helper.h> #include <drm/drm_vblank.h> @@ -61,8 +61,6 @@ void tilcdc_module_cleanup(struct tilcdc_module *mod) list_del(&mod->list); } -static struct of_device_id tilcdc_of_match[]; - static int tilcdc_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) { @@ -124,6 +122,39 @@ static int cpufreq_transition(struct notifier_block *nb, } #endif +static irqreturn_t tilcdc_irq(int irq, void *arg) +{ + struct drm_device *dev = arg; + struct tilcdc_drm_private *priv = dev->dev_private; + + return tilcdc_crtc_irq(priv->crtc); +} + +static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq) +{ + struct tilcdc_drm_private *priv = dev->dev_private; + int ret; + + ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev); + if (ret) + return ret; + + priv->irq_enabled = true; + + return 0; +} + +static void tilcdc_irq_uninstall(struct drm_device *dev) +{ + struct tilcdc_drm_private *priv = dev->dev_private; + + if (!priv->irq_enabled) + return; + + free_irq(priv->irq, dev); + priv->irq_enabled = false; +} + /* * DRM operations: */ @@ -145,19 +176,15 @@ static void tilcdc_fini(struct drm_device *dev) drm_dev_unregister(dev); drm_kms_helper_poll_fini(dev); - drm_irq_uninstall(dev); + drm_atomic_helper_shutdown(dev); + tilcdc_irq_uninstall(dev); drm_mode_config_cleanup(dev); if (priv->clk) clk_put(priv->clk); - if (priv->mmio) - iounmap(priv->mmio); - - if (priv->wq) { - flush_workqueue(priv->wq); + if (priv->wq) destroy_workqueue(priv->wq); - } dev->dev_private = NULL; @@ -172,7 +199,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct device_node *node = dev->of_node; struct tilcdc_drm_private *priv; - struct resource *res; u32 bpp = 0; int ret; @@ -197,17 +223,10 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) goto init_failed; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "failed to get memory resource\n"); - ret = -EINVAL; - goto init_failed; - } - - priv->mmio = ioremap(res->start, resource_size(res)); - if (!priv->mmio) { - dev_err(dev, "failed to ioremap\n"); - ret = -ENOMEM; + priv->mmio = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->mmio)) { + dev_err(dev, "failed to request / ioremap\n"); + ret = PTR_ERR(priv->mmio); goto init_failed; } @@ -336,7 +355,12 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) goto init_failed; } - ret = drm_irq_install(ddev, platform_get_irq(pdev, 0)); + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto init_failed; + priv->irq = ret; + + ret = tilcdc_irq_install(ddev, priv->irq); if (ret < 0) { dev_err(dev, "failed to install IRQ handler\n"); goto init_failed; @@ -351,22 +375,17 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) goto init_failed; priv->is_registered = true; - drm_fbdev_generic_setup(ddev, bpp); + drm_client_setup_with_color_mode(ddev, bpp); + return 0; init_failed: tilcdc_fini(ddev); + platform_set_drvdata(pdev, NULL); return ret; } -static irqreturn_t tilcdc_irq(int irq, void *arg) -{ - struct drm_device *dev = arg; - struct tilcdc_drm_private *priv = dev->dev_private; - return tilcdc_crtc_irq(priv->crtc); -} - #if defined(CONFIG_DEBUG_FS) static const struct { const char *name; @@ -450,19 +469,18 @@ static void tilcdc_debugfs_init(struct drm_minor *minor) } #endif -DEFINE_DRM_GEM_CMA_FOPS(fops); +DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver tilcdc_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, - .irq_handler = tilcdc_irq, - DRM_GEM_CMA_DRIVER_OPS, + DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, #ifdef CONFIG_DEBUG_FS .debugfs_init = tilcdc_debugfs_init, #endif .fops = &fops, .name = "tilcdc", .desc = "TI LCD Controller DRM", - .date = "20121205", .major = 1, .minor = 0, }; @@ -471,7 +489,6 @@ static const struct drm_driver tilcdc_driver = { * Power management: */ -#ifdef CONFIG_PM_SLEEP static int tilcdc_pm_suspend(struct device *dev) { struct drm_device *ddev = dev_get_drvdata(dev); @@ -493,11 +510,9 @@ static int tilcdc_pm_resume(struct device *dev) pinctrl_pm_select_default_state(dev); return drm_mode_config_helper_resume(ddev); } -#endif -static const struct dev_pm_ops tilcdc_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(tilcdc_pm_suspend, tilcdc_pm_resume) -}; +static DEFINE_SIMPLE_DEV_PM_OPS(tilcdc_pm_ops, + tilcdc_pm_suspend, tilcdc_pm_resume); /* * Platform driver: @@ -515,7 +530,8 @@ static void tilcdc_unbind(struct device *dev) if (!ddev->dev_private) return; - tilcdc_fini(dev_get_drvdata(dev)); + tilcdc_fini(ddev); + dev_set_drvdata(dev, NULL); } static const struct component_master_ops tilcdc_comp_ops = { @@ -545,22 +561,26 @@ static int tilcdc_pdev_probe(struct platform_device *pdev) match); } -static int tilcdc_pdev_remove(struct platform_device *pdev) +static void tilcdc_pdev_remove(struct platform_device *pdev) { int ret; ret = tilcdc_get_external_components(&pdev->dev, NULL); if (ret < 0) - return ret; + dev_err(&pdev->dev, "tilcdc_get_external_components() failed (%pe)\n", + ERR_PTR(ret)); else if (ret == 0) tilcdc_fini(platform_get_drvdata(pdev)); else component_master_del(&pdev->dev, &tilcdc_comp_ops); +} - return 0; +static void tilcdc_pdev_shutdown(struct platform_device *pdev) +{ + drm_atomic_helper_shutdown(platform_get_drvdata(pdev)); } -static struct of_device_id tilcdc_of_match[] = { +static const struct of_device_id tilcdc_of_match[] = { { .compatible = "ti,am33xx-tilcdc", }, { .compatible = "ti,da850-tilcdc", }, { }, @@ -570,15 +590,19 @@ MODULE_DEVICE_TABLE(of, tilcdc_of_match); static struct platform_driver tilcdc_platform_driver = { .probe = tilcdc_pdev_probe, .remove = tilcdc_pdev_remove, + .shutdown = tilcdc_pdev_shutdown, .driver = { .name = "tilcdc", - .pm = &tilcdc_pm_ops, + .pm = pm_sleep_ptr(&tilcdc_pm_ops), .of_match_table = tilcdc_of_match, }, }; static int __init tilcdc_drm_init(void) { + if (drm_firmware_drivers_only()) + return -ENODEV; + DBG("init"); tilcdc_panel_init(); return platform_driver_register(&tilcdc_platform_driver); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index d29806ca8817..b818448c83f6 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -46,6 +46,8 @@ struct tilcdc_drm_private { struct clk *clk; /* functional clock */ int rev; /* IP revision */ + unsigned int irq; + /* don't attempt resolutions w/ higher W * H * Hz: */ uint32_t max_bandwidth; /* @@ -82,6 +84,7 @@ struct tilcdc_drm_private { bool is_registered; bool is_componentized; + bool irq_enabled; }; /* Sub-module for display. Since we don't know at compile time what panels diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_external.c index b177525588c1..3b86d002ef62 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_external.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c @@ -60,11 +60,13 @@ struct drm_connector *tilcdc_encoder_find_connector(struct drm_device *ddev, int tilcdc_add_component_encoder(struct drm_device *ddev) { struct tilcdc_drm_private *priv = ddev->dev_private; - struct drm_encoder *encoder; + struct drm_encoder *encoder = NULL, *iter; - list_for_each_entry(encoder, &ddev->mode_config.encoder_list, head) - if (encoder->possible_crtcs & (1 << priv->crtc->index)) + list_for_each_entry(iter, &ddev->mode_config.encoder_list, head) + if (iter->possible_crtcs & (1 << priv->crtc->index)) { + encoder = iter; break; + } if (!encoder) { dev_err(ddev->dev, "%s: No suitable encoder found\n", __func__); @@ -93,10 +95,8 @@ int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge) priv->external_encoder->possible_crtcs = BIT(0); ret = drm_bridge_attach(priv->external_encoder, bridge, NULL, 0); - if (ret) { - dev_err(ddev->dev, "drm_bridge_attach() failed %d\n", ret); + if (ret) return ret; - } tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_default); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 42357808eaf2..262f290d85d9 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -4,8 +4,8 @@ * Author: Rob Clark <robdclark@gmail.com> */ +#include <linux/backlight.h> #include <linux/gpio/consumer.h> -#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <video/display_timing.h> @@ -49,7 +49,7 @@ static void panel_encoder_dpms(struct drm_encoder *encoder, int mode) if (backlight) { backlight->props.power = mode == DRM_MODE_DPMS_ON ? - FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; + BACKLIGHT_POWER_ON : BACKLIGHT_POWER_OFF; backlight_update_status(backlight); } @@ -307,7 +307,6 @@ static int panel_probe(struct platform_device *pdev) struct backlight_device *backlight; struct panel_module *panel_mod; struct tilcdc_module *mod; - struct pinctrl *pinctrl; int ret; /* bail out early if no DT data: */ @@ -341,10 +340,6 @@ static int panel_probe(struct platform_device *pdev) tilcdc_module_init(mod, "panel", &panel_module_ops); - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) - dev_warn(&pdev->dev, "pins are not configured\n"); - panel_mod->timings = of_get_display_timings(node); if (!panel_mod->timings) { dev_err(&pdev->dev, "could not get panel timings\n"); @@ -373,7 +368,7 @@ fail_backlight: return ret; } -static int panel_remove(struct platform_device *pdev) +static void panel_remove(struct platform_device *pdev) { struct tilcdc_module *mod = dev_get_platdata(&pdev->dev); struct panel_module *panel_mod = to_panel_module(mod); @@ -386,8 +381,6 @@ static int panel_remove(struct platform_device *pdev) tilcdc_module_cleanup(mod); kfree(panel_mod->info); - - return 0; } static const struct of_device_id panel_of_match[] = { diff --git a/drivers/gpu/drm/tilcdc/tilcdc_plane.c b/drivers/gpu/drm/tilcdc/tilcdc_plane.c index 74a5c8832229..aa72ca679598 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_plane.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_plane.c @@ -5,9 +5,9 @@ */ #include <drm/drm_atomic.h> -#include <drm/drm_plane_helper.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_framebuffer.h> #include "tilcdc_drv.h" @@ -42,8 +42,7 @@ static int tilcdc_plane_atomic_check(struct drm_plane *plane, return -EINVAL; } - crtc_state = drm_atomic_get_existing_crtc_state(state, - new_state->crtc); + crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc); /* we should have a crtc state if the plane is attached to a crtc */ if (WARN_ON(!crtc_state)) return 0; @@ -105,11 +104,10 @@ int tilcdc_plane_init(struct drm_device *dev, struct tilcdc_drm_private *priv = dev->dev_private; int ret; - ret = drm_plane_init(dev, plane, 1, - &tilcdc_plane_funcs, - priv->pixelformats, - priv->num_pixelformats, - true); + ret = drm_universal_plane_init(dev, plane, 1, &tilcdc_plane_funcs, + priv->pixelformats, + priv->num_pixelformats, + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { dev_err(dev->dev, "Failed to initialize plane: %d\n", ret); return ret; |
