Commit 47bfd6c0 authored by Jyri Sarha's avatar Jyri Sarha

drm/tilcdc: Get rid of legacy dpms mechanism

Get rid of legacy dpms mechanism. This simplifies the code quite a
bit. The old start() and stop() functions become tilcdc_crtc_enable()
and *_disable(). The functions are added with all the necessary
mechanisms from the old dpms function and they are used directly as
the crtc helper enable() and disable() callbacks.
Signed-off-by: default avatarJyri Sarha <jsarha@ti.com>
parent 514d1a1f
...@@ -30,7 +30,7 @@ struct tilcdc_crtc { ...@@ -30,7 +30,7 @@ struct tilcdc_crtc {
struct drm_plane primary; struct drm_plane primary;
const struct tilcdc_panel_info *info; const struct tilcdc_panel_info *info;
struct drm_pending_vblank_event *event; struct drm_pending_vblank_event *event;
int dpms; bool enabled;
wait_queue_head_t frame_done_wq; wait_queue_head_t frame_done_wq;
bool frame_done; bool frame_done;
spinlock_t irq_lock; spinlock_t irq_lock;
...@@ -137,9 +137,15 @@ static void reset(struct drm_crtc *crtc) ...@@ -137,9 +137,15 @@ static void reset(struct drm_crtc *crtc)
tilcdc_clear(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); tilcdc_clear(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET);
} }
static void start(struct drm_crtc *crtc) static void tilcdc_crtc_enable(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
if (tilcdc_crtc->enabled)
return;
pm_runtime_get_sync(dev->dev);
reset(crtc); reset(crtc);
...@@ -150,14 +156,19 @@ static void start(struct drm_crtc *crtc) ...@@ -150,14 +156,19 @@ static void start(struct drm_crtc *crtc)
tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
drm_crtc_vblank_on(crtc); drm_crtc_vblank_on(crtc);
tilcdc_crtc->enabled = true;
} }
static void stop(struct drm_crtc *crtc) void tilcdc_crtc_disable(struct drm_crtc *crtc)
{ {
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct tilcdc_drm_private *priv = dev->dev_private; struct tilcdc_drm_private *priv = dev->dev_private;
if (!tilcdc_crtc->enabled)
return;
tilcdc_crtc->frame_done = false; tilcdc_crtc->frame_done = false;
tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
...@@ -177,13 +188,37 @@ static void stop(struct drm_crtc *crtc) ...@@ -177,13 +188,37 @@ static void stop(struct drm_crtc *crtc)
drm_crtc_vblank_off(crtc); drm_crtc_vblank_off(crtc);
tilcdc_crtc_disable_irqs(dev); tilcdc_crtc_disable_irqs(dev);
pm_runtime_put_sync(dev->dev);
if (tilcdc_crtc->next_fb) {
drm_flip_work_queue(&tilcdc_crtc->unref_work,
tilcdc_crtc->next_fb);
tilcdc_crtc->next_fb = NULL;
}
if (tilcdc_crtc->curr_fb) {
drm_flip_work_queue(&tilcdc_crtc->unref_work,
tilcdc_crtc->curr_fb);
tilcdc_crtc->curr_fb = NULL;
}
drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq);
tilcdc_crtc->last_vblank = ktime_set(0, 0);
tilcdc_crtc->enabled = false;
}
static bool tilcdc_crtc_is_on(struct drm_crtc *crtc)
{
return crtc->state && crtc->state->enable && crtc->state->active;
} }
static void tilcdc_crtc_destroy(struct drm_crtc *crtc) static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
{ {
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); tilcdc_crtc_disable(crtc);
of_node_put(crtc->port); of_node_put(crtc->port);
drm_crtc_cleanup(crtc); drm_crtc_cleanup(crtc);
...@@ -237,52 +272,6 @@ int tilcdc_crtc_page_flip(struct drm_crtc *crtc, ...@@ -237,52 +272,6 @@ int tilcdc_crtc_page_flip(struct drm_crtc *crtc,
return 0; return 0;
} }
void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct tilcdc_drm_private *priv = dev->dev_private;
/* we really only care about on or off: */
if (mode != DRM_MODE_DPMS_ON)
mode = DRM_MODE_DPMS_OFF;
if (tilcdc_crtc->dpms == mode)
return;
tilcdc_crtc->dpms = mode;
if (mode == DRM_MODE_DPMS_ON) {
pm_runtime_get_sync(dev->dev);
start(crtc);
} else {
stop(crtc);
pm_runtime_put_sync(dev->dev);
if (tilcdc_crtc->next_fb) {
drm_flip_work_queue(&tilcdc_crtc->unref_work,
tilcdc_crtc->next_fb);
tilcdc_crtc->next_fb = NULL;
}
if (tilcdc_crtc->curr_fb) {
drm_flip_work_queue(&tilcdc_crtc->unref_work,
tilcdc_crtc->curr_fb);
tilcdc_crtc->curr_fb = NULL;
}
drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq);
tilcdc_crtc->last_vblank = ktime_set(0, 0);
}
}
int tilcdc_crtc_current_dpms_state(struct drm_crtc *crtc)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
return tilcdc_crtc->dpms;
}
static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc, static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode, const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
...@@ -312,16 +301,6 @@ static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc, ...@@ -312,16 +301,6 @@ static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc,
return true; return true;
} }
static void tilcdc_crtc_disable(struct drm_crtc *crtc)
{
tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
}
static void tilcdc_crtc_enable(struct drm_crtc *crtc)
{
tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
}
static void tilcdc_crtc_mode_set_nofb(struct drm_crtc *crtc) static void tilcdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
{ {
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
...@@ -655,18 +634,15 @@ void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc, ...@@ -655,18 +634,15 @@ void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc,
void tilcdc_crtc_update_clk(struct drm_crtc *crtc) void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
{ {
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct tilcdc_drm_private *priv = dev->dev_private; struct tilcdc_drm_private *priv = dev->dev_private;
int dpms = tilcdc_crtc->dpms;
unsigned long lcd_clk; unsigned long lcd_clk;
const unsigned clkdiv = 2; /* using a fixed divider of 2 */ const unsigned clkdiv = 2; /* using a fixed divider of 2 */
int ret; int ret;
pm_runtime_get_sync(dev->dev); pm_runtime_get_sync(dev->dev);
if (dpms == DRM_MODE_DPMS_ON) tilcdc_crtc_disable(crtc);
tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
/* mode.clock is in KHz, set_rate wants parameter in Hz */ /* mode.clock is in KHz, set_rate wants parameter in Hz */
ret = clk_set_rate(priv->clk, crtc->mode.clock * 1000 * clkdiv); ret = clk_set_rate(priv->clk, crtc->mode.clock * 1000 * clkdiv);
...@@ -690,8 +666,8 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc) ...@@ -690,8 +666,8 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
LCDC_V2_DMA_CLK_EN | LCDC_V2_LIDD_CLK_EN | LCDC_V2_DMA_CLK_EN | LCDC_V2_LIDD_CLK_EN |
LCDC_V2_CORE_CLK_EN); LCDC_V2_CORE_CLK_EN);
if (dpms == DRM_MODE_DPMS_ON) if (tilcdc_crtc_is_on(crtc))
tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_ON); tilcdc_crtc_enable(crtc);
out: out:
pm_runtime_put_sync(dev->dev); pm_runtime_put_sync(dev->dev);
...@@ -802,7 +778,6 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) ...@@ -802,7 +778,6 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
if (ret < 0) if (ret < 0)
goto fail; goto fail;
tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF;
init_waitqueue_head(&tilcdc_crtc->frame_done_wq); init_waitqueue_head(&tilcdc_crtc->frame_done_wq);
drm_flip_work_init(&tilcdc_crtc->unref_work, drm_flip_work_init(&tilcdc_crtc->unref_work,
......
...@@ -113,12 +113,18 @@ static int tilcdc_commit(struct drm_device *dev, ...@@ -113,12 +113,18 @@ static int tilcdc_commit(struct drm_device *dev,
* current layout. * current layout.
*/ */
/* Keep HW on while we commit the state. */
pm_runtime_get_sync(dev->dev);
drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_modeset_disables(dev, state);
drm_atomic_helper_commit_planes(dev, state, false); drm_atomic_helper_commit_planes(dev, state, false);
drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state);
/* Now HW should remain on if need becase the crtc is enabled */
pm_runtime_put_sync(dev->dev);
drm_atomic_helper_wait_for_vblanks(dev, state); drm_atomic_helper_wait_for_vblanks(dev, state);
drm_atomic_helper_cleanup_planes(dev, state); drm_atomic_helper_cleanup_planes(dev, state);
...@@ -183,7 +189,7 @@ static int tilcdc_unload(struct drm_device *dev) ...@@ -183,7 +189,7 @@ static int tilcdc_unload(struct drm_device *dev)
{ {
struct tilcdc_drm_private *priv = dev->dev_private; struct tilcdc_drm_private *priv = dev->dev_private;
tilcdc_crtc_dpms(priv->crtc, DRM_MODE_DPMS_OFF); tilcdc_crtc_disable(priv->crtc);
tilcdc_remove_external_encoders(dev); tilcdc_remove_external_encoders(dev);
......
...@@ -170,8 +170,7 @@ void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc, ...@@ -170,8 +170,7 @@ void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc,
bool simulate_vesa_sync); bool simulate_vesa_sync);
int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode); int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode);
int tilcdc_crtc_max_width(struct drm_crtc *crtc); int tilcdc_crtc_max_width(struct drm_crtc *crtc);
void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode); void tilcdc_crtc_disable(struct drm_crtc *crtc);
int tilcdc_crtc_current_dpms_state(struct drm_crtc *crtc);
int tilcdc_crtc_page_flip(struct drm_crtc *crtc, int tilcdc_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event, struct drm_pending_vblank_event *event,
......
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