diff options
Diffstat (limited to 'drivers/gpu/drm/imx')
| -rw-r--r-- | drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 29 | ||||
| -rw-r--r-- | drivers/gpu/drm/imx/ipuv3/imx-tve.c | 17 | ||||
| -rw-r--r-- | drivers/gpu/drm/imx/ipuv3/parallel-display.c | 4 |
3 files changed, 35 insertions, 15 deletions
diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c index ec5fd9a01f1e..465b5a6ad5bb 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c @@ -17,7 +17,9 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_dumb_buffers.h> #include <drm/drm_fbdev_dma.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_managed.h> @@ -141,17 +143,32 @@ static int imx_drm_dumb_create(struct drm_file *file_priv, struct drm_device *drm, struct drm_mode_create_dumb *args) { - u32 width = args->width; + u32 fourcc; + const struct drm_format_info *info; + u64 pitch_align; int ret; - args->width = ALIGN(width, 8); - - ret = drm_gem_dma_dumb_create(file_priv, drm, args); + /* + * Hardware requires the framebuffer width to be aligned to + * multiples of 8. The mode-setting code handles this, but + * the buffer pitch has to be aligned as well. Set the pitch + * alignment accordingly, so that the each scanline fits into + * the allocated buffer. + */ + fourcc = drm_driver_color_mode_format(drm, args->bpp); + if (fourcc == DRM_FORMAT_INVALID) + return -EINVAL; + info = drm_format_info(fourcc); + if (!info) + return -EINVAL; + pitch_align = drm_format_info_min_pitch(info, 0, SZ_8); + if (!pitch_align || pitch_align > U32_MAX) + return -EINVAL; + ret = drm_mode_size_dumb(drm, args, pitch_align, 0); if (ret) return ret; - args->width = width; - return ret; + return drm_gem_dma_dumb_create(file_priv, drm, args); } static const struct drm_driver imx_drm_driver = { diff --git a/drivers/gpu/drm/imx/ipuv3/imx-tve.c b/drivers/gpu/drm/imx/ipuv3/imx-tve.c index c5629e155d25..63f23b821b0b 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-tve.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-tve.c @@ -368,17 +368,20 @@ static unsigned long clk_tve_di_recalc_rate(struct clk_hw *hw, return 0; } -static long clk_tve_di_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_tve_di_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long div; - div = *prate / rate; + div = req->best_parent_rate / req->rate; if (div >= 4) - return *prate / 4; + req->rate = req->best_parent_rate / 4; else if (div >= 2) - return *prate / 2; - return *prate; + req->rate = req->best_parent_rate / 2; + else + req->rate = req->best_parent_rate; + + return 0; } static int clk_tve_di_set_rate(struct clk_hw *hw, unsigned long rate, @@ -409,7 +412,7 @@ static int clk_tve_di_set_rate(struct clk_hw *hw, unsigned long rate, } static const struct clk_ops clk_tve_di_ops = { - .round_rate = clk_tve_di_round_rate, + .determine_rate = clk_tve_di_determine_rate, .set_rate = clk_tve_di_set_rate, .recalc_rate = clk_tve_di_recalc_rate, }; diff --git a/drivers/gpu/drm/imx/ipuv3/parallel-display.c b/drivers/gpu/drm/imx/ipuv3/parallel-display.c index 6d8325c76697..dfdeb926fe9c 100644 --- a/drivers/gpu/drm/imx/ipuv3/parallel-display.c +++ b/drivers/gpu/drm/imx/ipuv3/parallel-display.c @@ -134,10 +134,10 @@ static int imx_pd_bridge_atomic_check(struct drm_bridge *bridge, struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); struct drm_display_info *di = &conn_state->connector->display_info; struct drm_bridge_state *next_bridge_state = NULL; - struct drm_bridge *next_bridge; u32 bus_flags, bus_fmt; - next_bridge = drm_bridge_get_next_bridge(bridge); + struct drm_bridge *next_bridge __free(drm_bridge_put) = drm_bridge_get_next_bridge(bridge); + if (next_bridge) next_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, next_bridge); |