drm/radeon/kms: rework spread spectrum handling

This patch reworks spread spectrum handling to enable it
properly on lvds and DP/eDP links.  It also fixes several
bugs in the old spread spectrum code.

- Use the ss recommended reference divider if available
when calculating the pll
- Use the proper ss command tables on pre-DCE3 asics
- Avoid reading past the end of the ss info tables
- Enable ss on evergreen asics (lvds, dp, tmds)
- Enable ss on DP/eDP links

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 29f5517..d25cf09 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -324,21 +324,24 @@
 struct radeon_atom_ss {
 	uint16_t percentage;
 	uint8_t type;
-	uint8_t step;
+	uint16_t step;
 	uint8_t delay;
 	uint8_t range;
 	uint8_t refdiv;
+	/* asic_ss */
+	uint16_t rate;
+	uint16_t amount;
 };
 
 struct radeon_encoder_atom_dig {
 	bool linkb;
 	/* atom dig */
 	bool coherent_mode;
-	int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */
-	/* atom lvds */
-	uint32_t lvds_misc;
+	int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB, etc. */
+	/* atom lvds/edp */
+	uint32_t lcd_misc;
 	uint16_t panel_pwr_delay;
-	struct radeon_atom_ss *ss;
+	uint32_t lcd_ss_id;
 	/* panel mode */
 	struct drm_display_mode native_mode;
 };
@@ -480,6 +483,13 @@
 
 extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);
 
+extern bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev,
+					     struct radeon_atom_ss *ss,
+					     int id);
+extern bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
+					     struct radeon_atom_ss *ss,
+					     int id, u32 clock);
+
 extern void radeon_compute_pll(struct radeon_pll *pll,
 			       uint64_t freq,
 			       uint32_t *dot_clock_p,