diff options
Diffstat (limited to 'drivers/video/tegra/dc/dc.c')
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index c42df4c1957e..063d12e4714d 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -49,6 +49,7 @@ #include <mach/latency_allowance.h> #include "dc_reg.h" +#include "dc_config.h" #include "dc_priv.h" #include "nvsd.h" @@ -93,25 +94,14 @@ struct tegra_dc *tegra_dcs[TEGRA_MAX_DC]; DEFINE_MUTEX(tegra_dc_lock); DEFINE_MUTEX(shared_lock); -static const struct { - bool h; - bool v; -} can_filter[] = { - /* Window A has no filtering */ - { false, false }, - /* Window B has both H and V filtering */ - { true, true }, - /* Window C has only H filtering */ - { false, true }, -}; -static inline bool win_use_v_filter(const struct tegra_dc_win *win) +static inline bool win_use_v_filter(struct tegra_dc *dc, const struct tegra_dc_win *win) { - return can_filter[win->idx].v && + return tegra_dc_feature_has_filter(dc, win->idx, HAS_V_FILTER) && win->h.full != dfixed_const(win->out_h); } -static inline bool win_use_h_filter(const struct tegra_dc_win *win) +static inline bool win_use_h_filter(struct tegra_dc *dc, const struct tegra_dc_win *win) { - return can_filter[win->idx].h && + return tegra_dc_feature_has_filter(dc, win->idx, HAS_H_FILTER) && win->w.full != dfixed_const(win->out_w); } @@ -902,7 +892,7 @@ static void tegra_dc_set_latency_allowance(struct tegra_dc *dc, /* tegra_dc_get_bandwidth() treats V filter windows as double * bandwidth, but LA has a seperate client for V filter */ - if (w->idx == 1 && win_use_v_filter(w)) + if (w->idx == 1 && win_use_v_filter(dc, w)) bw /= 2; /* our bandwidth is in kbytes/sec, but LA takes MBps. @@ -1020,7 +1010,7 @@ static unsigned long tegra_dc_calc_win_bandwidth(struct tegra_dc *dc, * is of the luma plane's size only. */ bpp = tegra_dc_is_yuv_planar(w->fmt) ? 2 * tegra_dc_fmt_bpp(w->fmt) : tegra_dc_fmt_bpp(w->fmt); - ret = dc->mode.pclk / 1000UL * bpp / 8 * (win_use_v_filter(w) ? 2 : 1) + ret = dc->mode.pclk / 1000UL * bpp / 8 * (win_use_v_filter(dc, w) ? 2 : 1) * dfixed_trunc(w->w) / w->out_w * (WIN_IS_TILED(w) ? tiled_windows_bw_multiplier : 1); /* @@ -1205,8 +1195,8 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n) unsigned Bpp = tegra_dc_fmt_bpp(win->fmt) / 8; /* Bytes per pixel of bandwidth, used for dda_inc calculation */ unsigned Bpp_bw = Bpp * (yuvp ? 2 : 1); - const bool filter_h = win_use_h_filter(win); - const bool filter_v = win_use_v_filter(win); + const bool filter_h = win_use_h_filter(dc, win); + const bool filter_v = win_use_v_filter(dc, win); if (win->z != dc->blend.z[win->idx]) { dc->blend.z[win->idx] = win->z; @@ -1239,19 +1229,22 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n) tegra_dc_writel(dc, V_SIZE(win->out_h) | H_SIZE(win->out_w), DC_WIN_SIZE); - tegra_dc_writel(dc, - V_PRESCALED_SIZE(dfixed_trunc(win->h)) | - H_PRESCALED_SIZE(dfixed_trunc(win->w) * Bpp), - DC_WIN_PRESCALED_SIZE); - - h_dda = compute_dda_inc(win->w, win->out_w, false, Bpp_bw); - v_dda = compute_dda_inc(win->h, win->out_h, true, Bpp_bw); - tegra_dc_writel(dc, V_DDA_INC(v_dda) | H_DDA_INC(h_dda), - DC_WIN_DDA_INCREMENT); - h_dda = compute_initial_dda(win->x); - v_dda = compute_initial_dda(win->y); - tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA); - tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA); + + if (tegra_dc_feature_has_scaling(dc, win->idx)) { + tegra_dc_writel(dc, + V_PRESCALED_SIZE(dfixed_trunc(win->h)) | + H_PRESCALED_SIZE(dfixed_trunc(win->w) * Bpp), + DC_WIN_PRESCALED_SIZE); + + h_dda = compute_dda_inc(win->w, win->out_w, false, Bpp_bw); + v_dda = compute_dda_inc(win->h, win->out_h, true, Bpp_bw); + tegra_dc_writel(dc, V_DDA_INC(v_dda) | H_DDA_INC(h_dda), + DC_WIN_DDA_INCREMENT); + h_dda = compute_initial_dda(win->x); + v_dda = compute_initial_dda(win->y); + tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA); + tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA); + } tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE); tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE); @@ -1289,16 +1282,18 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n) tegra_dc_writel(dc, dfixed_trunc(v_offset), DC_WINBUF_ADDR_V_OFFSET); - if (WIN_IS_TILED(win)) - tegra_dc_writel(dc, - DC_WIN_BUFFER_ADDR_MODE_TILE | - DC_WIN_BUFFER_ADDR_MODE_TILE_UV, - DC_WIN_BUFFER_ADDR_MODE); - else - tegra_dc_writel(dc, - DC_WIN_BUFFER_ADDR_MODE_LINEAR | - DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV, - DC_WIN_BUFFER_ADDR_MODE); + if (tegra_dc_feature_has_tiling(dc, win->idx)) { + if (WIN_IS_TILED(win)) + tegra_dc_writel(dc, + DC_WIN_BUFFER_ADDR_MODE_TILE | + DC_WIN_BUFFER_ADDR_MODE_TILE_UV, + DC_WIN_BUFFER_ADDR_MODE); + else + tegra_dc_writel(dc, + DC_WIN_BUFFER_ADDR_MODE_LINEAR | + DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV, + DC_WIN_BUFFER_ADDR_MODE); + } val = WIN_ENABLE; if (yuv) @@ -2093,7 +2088,7 @@ u32 tegra_dc_read_checksum_latched(struct tegra_dc *dc) { int crc = 0; - if(!dc) { + if (!dc) { dev_err(&dc->ndev->dev, "Failed to get dc.\n"); goto crc_error; } @@ -3030,6 +3025,8 @@ static int tegra_dc_probe(struct nvhost_device *ndev) switch_dev_register(&dc->modeset_switch); #endif + tegra_dc_feature_register(dc); + if (dc->pdata->default_out) tegra_dc_set_out(dc, dc->pdata->default_out); else |