aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tilcdc
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-10-17 10:13:47 +1000
committerDave Airlie <airlied@redhat.com>2017-10-17 10:13:47 +1000
commitf8d4710458a7e22fa4df2e8b1358c17b985ef86c (patch)
tree0c309a8c8380cfa3bc4b3030644372401ad497b8 /drivers/gpu/drm/tilcdc
parentMerge tag 'drm-misc-next-2017-10-16' of git://anongit.freedesktop.org/drm/drm-misc into drm-next (diff)
parentdrm/tilcdc: Remove redundant OF_DETACHED flag setting (diff)
downloadlinux-dev-f8d4710458a7e22fa4df2e8b1358c17b985ef86c.tar.xz
linux-dev-f8d4710458a7e22fa4df2e8b1358c17b985ef86c.zip
Merge tag 'tilcdc-4.15' of https://github.com/jsarha/linux into drm-next
tilcdc changes for v4.15 * tag 'tilcdc-4.15' of https://github.com/jsarha/linux: drm/tilcdc: Remove redundant OF_DETACHED flag setting drm/tilcdc: Precalculate total frametime in tilcdc_crtc_set_mode() drm/tilcdc: Use tilcdc_crtc_shutdown() in tilcdc_crtc_destroy() drm/tilcdc: Remove WARN_ON(!drm_modeset_is_locked(&crtc->mutex)) checks drm/tilcdc: Turn raster off in crtc reset, if it was on in the HW drm/tilcdc: switch to drm_*{get,put} helpers drm/tilcdc: tilcdc_tfp410: make of_device_ids const. drm/tilcdc: tilcdc_panel: make of_device_ids const.
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c51
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_panel.c2
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c1
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_tfp410.c4
4 files changed, 44 insertions, 14 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index d2589f310437..6ef4d1a1e3a9 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -24,6 +24,7 @@
#include <linux/completion.h>
#include <linux/dma-mapping.h>
#include <linux/of_graph.h>
+#include <linux/math64.h>
#include "tilcdc_drv.h"
#include "tilcdc_regs.h"
@@ -48,6 +49,7 @@ struct tilcdc_crtc {
unsigned int lcd_fck_rate;
ktime_t last_vblank;
+ unsigned int hvtotal_us;
struct drm_framebuffer *curr_fb;
struct drm_framebuffer *next_fb;
@@ -292,6 +294,12 @@ static void tilcdc_crtc_set_clk(struct drm_crtc *crtc)
LCDC_V2_CORE_CLK_EN);
}
+uint tilcdc_mode_hvtotal(const struct drm_display_mode *mode)
+{
+ return (uint) div_u64(1000llu * mode->htotal * mode->vtotal,
+ mode->clock);
+}
+
static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
@@ -459,6 +467,9 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
drm_framebuffer_get(fb);
crtc->hwmode = crtc->state->adjusted_mode;
+
+ tilcdc_crtc->hvtotal_us =
+ tilcdc_mode_hvtotal(&crtc->hwmode);
}
static void tilcdc_crtc_enable(struct drm_crtc *crtc)
@@ -467,7 +478,6 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
unsigned long flags;
- WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
mutex_lock(&tilcdc_crtc->enable_lock);
if (tilcdc_crtc->enabled || tilcdc_crtc->shutdown) {
mutex_unlock(&tilcdc_crtc->enable_lock);
@@ -564,7 +574,6 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)
static void tilcdc_crtc_disable(struct drm_crtc *crtc)
{
- WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
tilcdc_crtc_off(crtc, false);
}
@@ -608,9 +617,7 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct tilcdc_drm_private *priv = crtc->dev->dev_private;
- drm_modeset_lock(&crtc->mutex, NULL);
- tilcdc_crtc_disable(crtc);
- drm_modeset_unlock(&crtc->mutex);
+ tilcdc_crtc_shutdown(crtc);
flush_workqueue(priv->wq);
@@ -626,8 +633,6 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
- WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
-
if (tilcdc_crtc->event) {
dev_err(dev->dev, "already pending page flip!\n");
return -EBUSY;
@@ -648,7 +653,7 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
next_vblank = ktime_add_us(tilcdc_crtc->last_vblank,
- 1000000 / crtc->hwmode.vrefresh);
+ tilcdc_crtc->hvtotal_us);
tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get()));
if (tdiff < TILCDC_VBLANK_SAFETY_THRESHOLD_US)
@@ -728,11 +733,39 @@ static void tilcdc_crtc_disable_vblank(struct drm_crtc *crtc)
{
}
+static void tilcdc_crtc_reset(struct drm_crtc *crtc)
+{
+ struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ int ret;
+
+ drm_atomic_helper_crtc_reset(crtc);
+
+ /* Turn the raster off if it for some reason is on. */
+ pm_runtime_get_sync(dev->dev);
+ if (tilcdc_read(dev, LCDC_RASTER_CTRL_REG) & LCDC_RASTER_ENABLE) {
+ /* Enable DMA Frame Done Interrupt */
+ tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_FRAME_DONE);
+ tilcdc_clear_irqstatus(dev, 0xffffffff);
+
+ tilcdc_crtc->frame_done = false;
+ tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+
+ ret = wait_event_timeout(tilcdc_crtc->frame_done_wq,
+ tilcdc_crtc->frame_done,
+ msecs_to_jiffies(500));
+ if (ret == 0)
+ dev_err(dev->dev, "%s: timeout waiting for framedone\n",
+ __func__);
+ }
+ pm_runtime_put_sync(dev->dev);
+}
+
static const struct drm_crtc_funcs tilcdc_crtc_funcs = {
.destroy = tilcdc_crtc_destroy,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
- .reset = drm_atomic_helper_crtc_reset,
+ .reset = tilcdc_crtc_reset,
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
.enable_vblank = tilcdc_crtc_enable_vblank,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index 1813a3623ce6..8eebb5f826a6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -418,7 +418,7 @@ static int panel_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id panel_of_match[] = {
+static const struct of_device_id panel_of_match[] = {
{ .compatible = "ti,tilcdc,panel", },
{ },
};
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
index 623a9140493c..482299a6f3b0 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
@@ -163,7 +163,6 @@ static struct device_node * __init tilcdc_get_overlay(struct kfree_table *kft)
return NULL;
}
- of_node_set_flag(overlay, OF_DETACHED);
ret = of_resolve_phandles(overlay);
if (ret) {
pr_err("%s: Failed to resolve phandles: %d\n", __func__, ret);
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
index 1e2dfb1b1d6b..7e3643462a08 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
@@ -289,8 +289,6 @@ static const struct tilcdc_module_ops tfp410_module_ops = {
* Device:
*/
-static struct of_device_id tfp410_of_match[];
-
static int tfp410_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
@@ -375,7 +373,7 @@ static int tfp410_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id tfp410_of_match[] = {
+static const struct of_device_id tfp410_of_match[] = {
{ .compatible = "ti,tilcdc,tfp410", },
{ },
};