/* * Calculate peak EMC bandwidth for each enabled window = * pixel_clock * win_bpp * (use_v_filter ? 2 : 1)) * H_scale_factor * * (windows_tiling ? 2 : 1) * * note: * (*) We use 2 tap V filter on T2x/T3x, so need double BW if use V filter * (*) Tiling mode on T30 and DDR3 requires double BW * * return: * bandwidth in kBps */ static unsigned long tegra_dc_calc_win_bandwidth(struct tegra_dc *dc, struct tegra_dc_win *w) { unsigned long ret; int tiled_windows_bw_multiplier; unsigned long bpp; if (!WIN_IS_ENABLED(w)) return 0; if (dfixed_trunc(w->w) == 0 || dfixed_trunc(w->h) == 0 || w->out_w == 0 || w->out_h == 0) return 0; tiled_windows_bw_multiplier = tegra_mc_get_tiled_memory_bandwidth_multiplier(); /* all of tegra's YUV formats(420 and 422) fetch 2 bytes per pixel, * but the size reported by tegra_dc_fmt_bpp for the planar version * 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 * #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC) (win_use_v_filter(dc, w) ? 2 : 1) * #endif dfixed_trunc(w->w) / w->out_w * (WIN_IS_TILED(w) ? tiled_windows_bw_multiplier : 1); return ret; }
/* * Calculate peak EMC bandwidth for each enabled window = * pixel_clock * win_bpp * (use_v_filter ? 2 : 1)) * H_scale_factor * * (windows_tiling ? 2 : 1) * * note: * (*) We use 2 tap V filter on T2x/T3x, so need double BW if use V filter * (*) Tiling mode on T30 and DDR3 requires double BW * * return: * bandwidth in kBps */ static unsigned long tegra_dc_calc_win_bandwidth(struct tegra_dc *dc, struct tegra_dc_win *w) { unsigned in_w; unsigned in_h; unsigned bpp; unsigned long f_w; unsigned long f_h; unsigned long bw; int tiled_windows_bw_multiplier; /* ignore windows that are off or invalid */ if (!WIN_IS_ENABLED(w) || dfixed_trunc(w->w) == 0 || dfixed_trunc(w->h) == 0 || w->out_w == 0 || w->out_h == 0) return 0; if (w->flags & TEGRA_WIN_FLAG_SCAN_COLUMN) { /* rotated : prescaled size is swapped */ in_w = dfixed_trunc(w->h); in_h = dfixed_trunc(w->w); } else { /* normal */ in_w = dfixed_trunc(w->w); in_h = dfixed_trunc(w->h); } tiled_windows_bw_multiplier = tegra_mc_get_tiled_memory_bandwidth_multiplier(); /* all of tegra's YUV formats(420 and 422) fetch 2 bytes per pixel, * but the size reported by tegra_dc_fmt_bpp for the planar version * 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); bw = dc->mode.pclk / 1000UL * bpp / 8; if (WIN_IS_TILED(w)) bw *= tiled_windows_bw_multiplier; #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC) if (win_use_v_filter(dc, w, false)) bw *= 2; #endif /* calculate H & V scaling factor. treat upscaling as 1.00 */ f_w = max(in_w * 100 / w->out_w, 100u); f_h = max(in_h * 100 / w->out_h, 100u); bw *= f_w; bw /= 100; if (win_use_v_filter(dc, w, w->flags & TEGRA_WIN_FLAG_SCAN_COLUMN)) { bw *= f_h; bw /= 100; } return bw; }
/* * Calculate peak EMC bandwidth for each enabled window = * pixel_clock * win_bpp * (use_v_filter ? 2 : 1)) * H_scale_factor * * (windows_tiling ? 2 : 1) * * note: * (*) We use 2 tap V filter on T2x/T3x, so need double BW if use V filter * (*) Tiling mode on T30 and DDR3 requires double BW * * return: * bandwidth in kBps */ static unsigned long tegra_dc_calc_win_bandwidth(struct tegra_dc *dc, struct tegra_dc_win *w) { unsigned long ret; int tiled_windows_bw_multiplier; unsigned long bpp; unsigned in_w; if (!WIN_IS_ENABLED(w)) return 0; if (dfixed_trunc(w->w) == 0 || dfixed_trunc(w->h) == 0 || w->out_w == 0 || w->out_h == 0) return 0; if (w->flags & TEGRA_WIN_FLAG_SCAN_COLUMN) /* rotated: PRESCALE_SIZE swapped, but WIN_SIZE is unchanged */ in_w = dfixed_trunc(w->h); else in_w = dfixed_trunc(w->w); /* normal output, not rotated */ tiled_windows_bw_multiplier = tegra_mc_get_tiled_memory_bandwidth_multiplier(); /* all of tegra's YUV formats(420 and 422) fetch 2 bytes per pixel, * but the size reported by tegra_dc_fmt_bpp for the planar version * 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 * #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC) (win_use_v_filter(dc, w) ? 2 : 1) * #endif in_w / w->out_w * (WIN_IS_TILED(w) ? tiled_windows_bw_multiplier : 1); #ifdef CONFIG_ARCH_TEGRA_2x_SOC /* * Assuming 60% efficiency: i.e. if we calculate we need 70MBps, we * will request 117MBps from EMC. */ ret = ret + (17 * ret / 25); #endif return ret; }
/* * Calculate peak EMC bandwidth for each enabled window = * pixel_clock * win_bpp * (use_v_filter ? 2 : 1)) * H_scale_factor * * (windows_tiling ? 2 : 1) * * note: * (*) We use 2 tap V filter, so need double BW if use V filter * (*) Tiling mode on T30 and DDR3 requires double BW * * return: * bandwidth in kBps */ static unsigned long tegra_dc_calc_win_bandwidth(struct tegra_dc *dc, struct tegra_dc_win *w) { unsigned long ret; int tiled_windows_bw_multiplier; unsigned long bpp; if (!WIN_IS_ENABLED(w)) return 0; if (dfixed_trunc(w->w) == 0 || dfixed_trunc(w->h) == 0 || w->out_w == 0 || w->out_h == 0) return 0; tiled_windows_bw_multiplier = tegra_mc_get_tiled_memory_bandwidth_multiplier(); /* all of tegra's YUV formats(420 and 422) fetch 2 bytes per pixel, * but the size reported by tegra_dc_fmt_bpp for the planar version * 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(dc, w) ? 2 : 1) * dfixed_trunc(w->w) / w->out_w * (WIN_IS_TILED(w) ? tiled_windows_bw_multiplier : 1); #ifdef CONFIG_ARCH_TEGRA_2x_SOC /* * Assuming 60% efficiency: i.e. if we calculate we need 70MBps, we * will request 117MBps from EMC. */ ret = ret + (17 * ret / 25); #endif return ret; }