diff options
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 39 | ||||
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_panel.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_plane.c | 46 | 
3 files changed, 49 insertions, 37 deletions
| diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 30213708fc99..29890d704cb4 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -203,18 +203,19 @@ static void tilcdc_crtc_set_clk(struct drm_crtc *crtc)  	struct drm_device *dev = crtc->dev;  	struct tilcdc_drm_private *priv = dev->dev_private;  	struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); -	unsigned long clk_rate, real_rate, req_rate; +	unsigned long clk_rate, real_pclk_rate, pclk_rate;  	unsigned int clkdiv;  	int ret;  	clkdiv = 2; /* first try using a standard divider of 2 */  	/* mode.clock is in KHz, set_rate wants parameter in Hz */ -	req_rate = crtc->mode.clock * 1000; +	pclk_rate = crtc->mode.clock * 1000; -	ret = clk_set_rate(priv->clk, req_rate * clkdiv); +	ret = clk_set_rate(priv->clk, pclk_rate * clkdiv);  	clk_rate = clk_get_rate(priv->clk); -	if (ret < 0 || tilcdc_pclk_diff(req_rate, clk_rate) > 5) { +	real_pclk_rate = clk_rate / clkdiv; +	if (ret < 0 || tilcdc_pclk_diff(pclk_rate, real_pclk_rate) > 5) {  		/*  		 * If we fail to set the clock rate (some architectures don't  		 * use the common clock framework yet and may not implement @@ -229,7 +230,7 @@ static void tilcdc_crtc_set_clk(struct drm_crtc *crtc)  			return;  		} -		clkdiv = DIV_ROUND_CLOSEST(clk_rate, req_rate); +		clkdiv = DIV_ROUND_CLOSEST(clk_rate, pclk_rate);  		/*  		 * Emit a warning if the real clock rate resulting from the @@ -238,12 +239,12 @@ static void tilcdc_crtc_set_clk(struct drm_crtc *crtc)  		 * 5% is an arbitrary value - LCDs are usually quite tolerant  		 * about pixel clock rates.  		 */ -		real_rate = clkdiv * req_rate; +		real_pclk_rate = clk_rate / clkdiv; -		if (tilcdc_pclk_diff(clk_rate, real_rate) > 5) { +		if (tilcdc_pclk_diff(pclk_rate, real_pclk_rate) > 5) {  			dev_warn(dev->dev, -				 "effective pixel clock rate (%luHz) differs from the calculated rate (%luHz)\n", -				 clk_rate, real_rate); +				 "effective pixel clock rate (%luHz) differs from the requested rate (%luHz)\n", +				 real_pclk_rate, pclk_rate);  		}  	} @@ -393,7 +394,7 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)  			return;  		}  	} -	reg |= info->fdd < 12; +	reg |= info->fdd << 12;  	tilcdc_write(dev, LCDC_RASTER_CTRL_REG, reg);  	if (info->invert_pxl_clk) @@ -515,6 +516,15 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)  	drm_crtc_vblank_off(crtc); +	spin_lock_irq(&crtc->dev->event_lock); + +	if (crtc->state->event) { +		drm_crtc_send_vblank_event(crtc, crtc->state->event); +		crtc->state->event = NULL; +	} + +	spin_unlock_irq(&crtc->dev->event_lock); +  	tilcdc_crtc_disable_irqs(dev);  	pm_runtime_put_sync(dev->dev); @@ -904,13 +914,12 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)  	tilcdc_clear_irqstatus(dev, stat);  	if (stat & LCDC_END_OF_FRAME0) { -		unsigned long flags;  		bool skip_event = false;  		ktime_t now;  		now = ktime_get(); -		spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); +		spin_lock(&tilcdc_crtc->irq_lock);  		tilcdc_crtc->last_vblank = now; @@ -920,21 +929,21 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)  			skip_event = true;  		} -		spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); +		spin_unlock(&tilcdc_crtc->irq_lock);  		drm_crtc_handle_vblank(crtc);  		if (!skip_event) {  			struct drm_pending_vblank_event *event; -			spin_lock_irqsave(&dev->event_lock, flags); +			spin_lock(&dev->event_lock);  			event = tilcdc_crtc->event;  			tilcdc_crtc->event = NULL;  			if (event)  				drm_crtc_send_vblank_event(crtc, event); -			spin_unlock_irqrestore(&dev->event_lock, flags); +			spin_unlock(&dev->event_lock);  		}  		if (tilcdc_crtc->frame_intact) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 00efc30b47d8..42357808eaf2 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -399,7 +399,6 @@ static struct platform_driver panel_driver = {  	.probe = panel_probe,  	.remove = panel_remove,  	.driver = { -		.owner = THIS_MODULE,  		.name = "tilcdc-panel",  		.of_match_table = panel_of_match,  	}, diff --git a/drivers/gpu/drm/tilcdc/tilcdc_plane.c b/drivers/gpu/drm/tilcdc/tilcdc_plane.c index 2f681a713815..74a5c8832229 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_plane.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_plane.c @@ -21,48 +21,51 @@ static const struct drm_plane_funcs tilcdc_plane_funcs = {  };  static int tilcdc_plane_atomic_check(struct drm_plane *plane, -				     struct drm_plane_state *state) +				     struct drm_atomic_state *state)  { +	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, +									   plane);  	struct drm_crtc_state *crtc_state; -	struct drm_plane_state *old_state = plane->state; +	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, +									   plane);  	unsigned int pitch; -	if (!state->crtc) +	if (!new_state->crtc)  		return 0; -	if (WARN_ON(!state->fb)) +	if (WARN_ON(!new_state->fb))  		return -EINVAL; -	if (state->crtc_x || state->crtc_y) { +	if (new_state->crtc_x || new_state->crtc_y) {  		dev_err(plane->dev->dev, "%s: crtc position must be zero.",  			__func__);  		return -EINVAL;  	} -	crtc_state = drm_atomic_get_existing_crtc_state(state->state, -							state->crtc); +	crtc_state = drm_atomic_get_existing_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; -	if (crtc_state->mode.hdisplay != state->crtc_w || -	    crtc_state->mode.vdisplay != state->crtc_h) { +	if (crtc_state->mode.hdisplay != new_state->crtc_w || +	    crtc_state->mode.vdisplay != new_state->crtc_h) {  		dev_err(plane->dev->dev,  			"%s: Size must match mode (%dx%d == %dx%d)", __func__,  			crtc_state->mode.hdisplay, crtc_state->mode.vdisplay, -			state->crtc_w, state->crtc_h); +			new_state->crtc_w, new_state->crtc_h);  		return -EINVAL;  	}  	pitch = crtc_state->mode.hdisplay * -		state->fb->format->cpp[0]; -	if (state->fb->pitches[0] != pitch) { +		new_state->fb->format->cpp[0]; +	if (new_state->fb->pitches[0] != pitch) {  		dev_err(plane->dev->dev,  			"Invalid pitch: fb and crtc widths must be the same");  		return -EINVAL;  	} -	if (old_state->fb && state->fb->format != old_state->fb->format) { +	if (old_state->fb && new_state->fb->format != old_state->fb->format) {  		dev_dbg(plane->dev->dev,  			"%s(): pixel format change requires mode_change\n",  			__func__); @@ -73,20 +76,21 @@ static int tilcdc_plane_atomic_check(struct drm_plane *plane,  }  static void tilcdc_plane_atomic_update(struct drm_plane *plane, -				       struct drm_plane_state *old_state) +				       struct drm_atomic_state *state)  { -	struct drm_plane_state *state = plane->state; +	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, +									   plane); -	if (!state->crtc) +	if (!new_state->crtc)  		return; -	if (WARN_ON(!state->fb || !state->crtc->state)) +	if (WARN_ON(!new_state->fb || !new_state->crtc->state))  		return; -	if (tilcdc_crtc_update_fb(state->crtc, -				  state->fb, -				  state->crtc->state->event) == 0) { -		state->crtc->state->event = NULL; +	if (tilcdc_crtc_update_fb(new_state->crtc, +				  new_state->fb, +				  new_state->crtc->state->event) == 0) { +		new_state->crtc->state->event = NULL;  	}  } | 
