Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc10332b authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms: clean up pll struct



- add a new flag for fixed post div
- pull the pll flags into the struct

Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent a348c84d
Loading
Loading
Loading
Loading
+17 −18
Original line number Diff line number Diff line
@@ -426,7 +426,11 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
	uint32_t adjusted_clock;
	uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
	struct radeon_pll *pll;
	int pll_flags = 0;

	if (radeon_crtc->crtc_id == 0)
		pll = &rdev->clock.p1pll;
	else
		pll = &rdev->clock.p2pll;

	memset(&args, 0, sizeof(args));

@@ -434,20 +438,20 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
		if ((rdev->family == CHIP_RS600) ||
		    (rdev->family == CHIP_RS690) ||
		    (rdev->family == CHIP_RS740))
			pll_flags |= (RADEON_PLL_USE_FRAC_FB_DIV |
			pll->flags |= (RADEON_PLL_USE_FRAC_FB_DIV |
				       RADEON_PLL_PREFER_CLOSEST_LOWER);

		if (ASIC_IS_DCE32(rdev) && mode->clock > 200000)	/* range limits??? */
			pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
			pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
		else
			pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
			pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
	} else {
		pll_flags |= RADEON_PLL_LEGACY;
		pll->flags |= RADEON_PLL_LEGACY;

		if (mode->clock > 200000)	/* range limits??? */
			pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
			pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
		else
			pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
			pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;

	}

@@ -456,10 +460,10 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
			if (!ASIC_IS_AVIVO(rdev)) {
				if (encoder->encoder_type !=
				    DRM_MODE_ENCODER_DAC)
					pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
					pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
				if (encoder->encoder_type ==
					DRM_MODE_ENCODER_LVDS)
					pll_flags |= RADEON_PLL_USE_REF_DIV;
					pll->flags |= RADEON_PLL_USE_REF_DIV;
			}
			radeon_encoder = to_radeon_encoder(encoder);
			break;
@@ -494,23 +498,18 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
			adjusted_clock = mode->clock;
	}

	if (radeon_crtc->crtc_id == 0)
		pll = &rdev->clock.p1pll;
	else
		pll = &rdev->clock.p2pll;

	if (ASIC_IS_AVIVO(rdev)) {
		if (radeon_new_pll)
			radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
						 &fb_div, &frac_fb_div,
						 &ref_div, &post_div, pll_flags);
						 &ref_div, &post_div);
		else
			radeon_compute_pll(pll, adjusted_clock, &pll_clock,
					   &fb_div, &frac_fb_div,
					   &ref_div, &post_div, pll_flags);
					   &ref_div, &post_div);
	} else
		radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
				   &ref_div, &post_div, pll_flags);
				   &ref_div, &post_div);

	index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+19 −16
Original line number Diff line number Diff line
@@ -411,11 +411,12 @@ void radeon_compute_pll(struct radeon_pll *pll,
			uint32_t *fb_div_p,
			uint32_t *frac_fb_div_p,
			uint32_t *ref_div_p,
			uint32_t *post_div_p,
			int flags)
			uint32_t *post_div_p)
{
	uint32_t min_ref_div = pll->min_ref_div;
	uint32_t max_ref_div = pll->max_ref_div;
	uint32_t min_post_div = pll->min_post_div;
	uint32_t max_post_div = pll->max_post_div;
	uint32_t min_fractional_feed_div = 0;
	uint32_t max_fractional_feed_div = 0;
	uint32_t best_vco = pll->best_vco;
@@ -431,7 +432,7 @@ void radeon_compute_pll(struct radeon_pll *pll,
	DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
	freq = freq * 1000;

	if (flags & RADEON_PLL_USE_REF_DIV)
	if (pll->flags & RADEON_PLL_USE_REF_DIV)
		min_ref_div = max_ref_div = pll->reference_div;
	else {
		while (min_ref_div < max_ref_div-1) {
@@ -446,19 +447,22 @@ void radeon_compute_pll(struct radeon_pll *pll,
		}
	}

	if (flags & RADEON_PLL_USE_FRAC_FB_DIV) {
	if (pll->flags & RADEON_PLL_USE_POST_DIV)
		min_post_div = max_post_div = pll->post_div;

	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
		min_fractional_feed_div = pll->min_frac_feedback_div;
		max_fractional_feed_div = pll->max_frac_feedback_div;
	}

	for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) {
	for (post_div = min_post_div; post_div <= max_post_div; ++post_div) {
		uint32_t ref_div;

		if ((flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
		if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
			continue;

		/* legacy radeons only have a few post_divs */
		if (flags & RADEON_PLL_LEGACY) {
		if (pll->flags & RADEON_PLL_LEGACY) {
			if ((post_div == 5) ||
			    (post_div == 7) ||
			    (post_div == 9) ||
@@ -505,7 +509,7 @@ void radeon_compute_pll(struct radeon_pll *pll,
					tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div;
					current_freq = radeon_div(tmp, ref_div * post_div);

					if (flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
					if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
						error = freq - current_freq;
						error = error < 0 ? 0xffffffff : error;
					} else
@@ -532,12 +536,12 @@ void radeon_compute_pll(struct radeon_pll *pll,
							best_freq = current_freq;
							best_error = error;
							best_vco_diff = vco_diff;
						} else if (((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
							   ((flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
							   ((flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
							   ((flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
							   ((flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
							   ((flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
						} else if (((pll->flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
							   ((pll->flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
							   ((pll->flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
							   ((pll->flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
							   ((pll->flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
							   ((pll->flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
							best_post_div = post_div;
							best_ref_div = ref_div;
							best_feedback_div = feedback_div;
@@ -573,8 +577,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
			      uint32_t *fb_div_p,
			      uint32_t *frac_fb_div_p,
			      uint32_t *ref_div_p,
			      uint32_t *post_div_p,
			      int flags)
			      uint32_t *post_div_p)
{
	fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq;
	fixed20_12 pll_out_max, pll_out_min;
+7 −7
Original line number Diff line number Diff line
@@ -692,7 +692,6 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
	uint32_t post_divider = 0;
	uint32_t freq = 0;
	uint8_t pll_gain;
	int pll_flags = RADEON_PLL_LEGACY;
	bool use_bios_divs = false;
	/* PLL registers */
	uint32_t pll_ref_div = 0;
@@ -726,10 +725,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
	else
		pll = &rdev->clock.p1pll;

	pll->flags = RADEON_PLL_LEGACY;

	if (mode->clock > 200000) /* range limits??? */
		pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
		pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
	else
		pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
		pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;

	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
		if (encoder->crtc == crtc) {
@@ -741,7 +742,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
			}

			if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
				pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
				pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
			if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
				if (!rdev->is_atom_bios) {
					struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
@@ -756,7 +757,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
						}
					}
				}
				pll_flags |= RADEON_PLL_USE_REF_DIV;
				pll->flags |= RADEON_PLL_USE_REF_DIV;
			}
		}
	}
@@ -766,8 +767,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
	if (!use_bios_divs) {
		radeon_compute_pll(pll, mode->clock,
				   &freq, &feedback_div, &frac_fb_div,
				   &reference_div, &post_divider,
				   pll_flags);
				   &reference_div, &post_divider);

		for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
			if (post_div->divider == post_divider)
+19 −8
Original line number Diff line number Diff line
@@ -125,16 +125,24 @@ struct radeon_tmds_pll {
#define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9)
#define RADEON_PLL_USE_FRAC_FB_DIV      (1 << 10)
#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
#define RADEON_PLL_USE_POST_DIV         (1 << 12)

struct radeon_pll {
	uint16_t reference_freq;
	uint16_t reference_div;
	/* reference frequency */
	uint32_t reference_freq;

	/* fixed dividers */
	uint32_t reference_div;
	uint32_t post_div;

	/* pll in/out limits */
	uint32_t pll_in_min;
	uint32_t pll_in_max;
	uint32_t pll_out_min;
	uint32_t pll_out_max;
	uint16_t xclk;
	uint32_t best_vco;

	/* divider limits */
	uint32_t min_ref_div;
	uint32_t max_ref_div;
	uint32_t min_post_div;
@@ -143,7 +151,12 @@ struct radeon_pll {
	uint32_t max_feedback_div;
	uint32_t min_frac_feedback_div;
	uint32_t max_frac_feedback_div;
	uint32_t best_vco;

	/* flags for the current clock */
	uint32_t flags;

	/* pll id */
	uint32_t id;
};

struct radeon_i2c_chan {
@@ -417,8 +430,7 @@ extern void radeon_compute_pll(struct radeon_pll *pll,
			       uint32_t *fb_div_p,
			       uint32_t *frac_fb_div_p,
			       uint32_t *ref_div_p,
			       uint32_t *post_div_p,
			       int flags);
			       uint32_t *post_div_p);

extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
				     uint64_t freq,
@@ -426,8 +438,7 @@ extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
				     uint32_t *fb_div_p,
				     uint32_t *frac_fb_div_p,
				     uint32_t *ref_div_p,
				     uint32_t *post_div_p,
				     int flags);
				     uint32_t *post_div_p);

extern void radeon_setup_encoder_clones(struct drm_device *dev);