Commit 43417823 authored by Tomi Valkeinen's avatar Tomi Valkeinen
Browse files

OMAPDSS: DSS: add new clock calculation code



Add new way to iterate over DSS clock divisors. dss_div_calc() provides
a generic way to go over all the divisors, within given clock range.
dss_div_calc() will call a callback function for each divider set,
making the function reusable for all use cases.

Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent 7c284e6e
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -473,6 +473,45 @@ int dss_calc_clock_rates(struct dss_clock_info *cinfo)
	return 0;
}

bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)
{
	int fckd, fckd_start, fckd_stop;
	unsigned long fck;
	unsigned long fck_hw_max;
	unsigned long fckd_hw_max;
	unsigned long prate;

	if (dss.dpll4_m4_ck == NULL) {
		/*
		 * TODO: dss1_fclk can be changed on OMAP2, but the available
		 * dividers are not continuous. We just use the pre-set rate for
		 * now.
		 */
		fck = clk_get_rate(dss.dss_clk);
		fckd = 1;
		return func(fckd, fck, data);
	}

	fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
	fckd_hw_max = dss.feat->fck_div_max;

	prate = dss_get_dpll4_rate() * dss.feat->dss_fck_multiplier;

	fck_min = fck_min ? fck_min : 1;

	fckd_start = min(prate / fck_min, fckd_hw_max);
	fckd_stop = max(DIV_ROUND_UP(prate, fck_hw_max), 1ul);

	for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
		fck = prate / fckd;

		if (func(fckd, fck, data))
			return true;
	}

	return false;
}

int dss_set_clock_div(struct dss_clock_info *cinfo)
{
	if (dss.dpll4_m4_ck) {
+3 −0
Original line number Diff line number Diff line
@@ -271,6 +271,9 @@ int dss_set_clock_div(struct dss_clock_info *cinfo);
int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
		struct dispc_clock_info *dispc_cinfo);

typedef bool (*dss_div_calc_func)(int fckd, unsigned long fck, void *data);
bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data);

/* SDI */
int sdi_init_platform_driver(void) __init;
void sdi_uninit_platform_driver(void) __exit;