/* Estimate the pixel gain of PRISM enhancement and soft-clipping algorithm*/ static u32 nvsd_softclip(fixed20_12 pixel, fixed20_12 k, fixed20_12 th) { fixed20_12 num, f; if (pixel.full >= th.full) { num.full = pixel.full - th.full; f.full = dfixed_const(1) - dfixed_div(num, th); } else { f.full = dfixed_const(1); } num.full = dfixed_mul(pixel, f); f.full = dfixed_mul(num, k); num.full = pixel.full + f.full; return min_t(u32, num.full, dfixed_const(255)); }
int nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk, int *N, int *fN, int *M, int *P) { fixed20_12 fb_div, a, b; *P = pll->vco1.maxfreq / clk; if (*P > pll->max_p) *P = pll->max_p; if (*P < pll->min_p) *P = pll->min_p; /* *M = ceil(refclk / pll->vco.max_inputfreq); */ a.full = dfixed_const(pll->refclk); b.full = dfixed_const(pll->vco1.max_inputfreq); a.full = dfixed_div(a, b); a.full = dfixed_ceil(a); *M = dfixed_trunc(a); /* fb_div = (vco * *M) / refclk; */ fb_div.full = dfixed_const(clk * *P); fb_div.full = dfixed_mul(fb_div, a); a.full = dfixed_const(pll->refclk); fb_div.full = dfixed_div(fb_div, a); /* *N = floor(fb_div); */ a.full = dfixed_floor(fb_div); *N = dfixed_trunc(fb_div); /* *fN = (fmod(fb_div, 1.0) * 8192) - 4096; */ b.full = dfixed_const(8192); a.full = dfixed_mul(a, b); fb_div.full = dfixed_mul(fb_div, b); fb_div.full = fb_div.full - a.full; *fN = dfixed_trunc(fb_div) - 4096; *fN &= 0xffff; return clk; }
static int nvsd_set_brightness(struct tegra_dc *dc) { u32 bin_width; int i, j; int val; int pix; int bin_idx; int incr; int base; u32 histo[32]; u32 histo_total = 0; /* count of pixels */ fixed20_12 nonhisto_gain; /* gain of pixels not in histogram */ fixed20_12 est_achieved_gain; /* final gain of pixels */ fixed20_12 histo_gain = dfixed_init(0); /* gain of pixels */ fixed20_12 k, threshold; /* k is the fractional part of HW_K */ fixed20_12 den, num, out; fixed20_12 pix_avg, pix_avg_softclip; /* Collet the inputs of the algorithm */ for (i = 0; i < DC_DISP_SD_HISTOGRAM_NUM; i++) { val = tegra_dc_readl(dc, DC_DISP_SD_HISTOGRAM(i)); for (j = 0; j < 4; j++) histo[i * 4 + j] = SD_HISTOGRAM_BIN(val, (j * 8)); } val = tegra_dc_readl(dc, DC_DISP_SD_HW_K_VALUES); k.full = dfixed_const(SD_HW_K_R(val)); den.full = dfixed_const(1024); k.full = dfixed_div(k, den); val = tegra_dc_readl(dc, DC_DISP_SD_SOFT_CLIPPING); threshold.full = dfixed_const(SD_SOFT_CLIPPING_THRESHOLD(val)); val = tegra_dc_readl(dc, DC_DISP_SD_CONTROL); bin_width = SD_BIN_WIDTH_VAL(val); incr = 1 << bin_width; base = 256 - 32 * incr; for (pix = base, bin_idx = 0; pix < 256; pix += incr, bin_idx++) { num.full = dfixed_const(pix + pix + incr); den.full = dfixed_const(2); pix_avg.full = dfixed_div(num, den); pix_avg_softclip.full = nvsd_softclip(pix_avg, k, threshold); num.full = dfixed_const(histo[bin_idx]); den.full = dfixed_const(256); out.full = dfixed_div(num, den); num.full = dfixed_mul(out, pix_avg_softclip); out.full = dfixed_div(num, pix_avg); histo_gain.full += out.full; histo_total += histo[bin_idx]; } out.full = dfixed_const(256 - histo_total); den.full = dfixed_const(1) + k.full; num.full = dfixed_mul(out, den); den.full = dfixed_const(256); nonhisto_gain.full = dfixed_div(num, den); den.full = nonhisto_gain.full + histo_gain.full; num.full = dfixed_const(1); out.full = dfixed_div(num, den); num.full = dfixed_const(255); est_achieved_gain.full = dfixed_mul(num, out); val = dfixed_trunc(est_achieved_gain); return nvsd_backlght_interplate(val, 128); }