xref: /openbmc/linux/drivers/gpu/drm/radeon/radeon_clocks.c (revision 8dd06ef34b6e2f41b29fbf5fc1663780f2524285)
1771fe6b9SJerome Glisse /*
2771fe6b9SJerome Glisse  * Copyright 2008 Advanced Micro Devices, Inc.
3771fe6b9SJerome Glisse  * Copyright 2008 Red Hat Inc.
4771fe6b9SJerome Glisse  * Copyright 2009 Jerome Glisse.
5771fe6b9SJerome Glisse  *
6771fe6b9SJerome Glisse  * Permission is hereby granted, free of charge, to any person obtaining a
7771fe6b9SJerome Glisse  * copy of this software and associated documentation files (the "Software"),
8771fe6b9SJerome Glisse  * to deal in the Software without restriction, including without limitation
9771fe6b9SJerome Glisse  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10771fe6b9SJerome Glisse  * and/or sell copies of the Software, and to permit persons to whom the
11771fe6b9SJerome Glisse  * Software is furnished to do so, subject to the following conditions:
12771fe6b9SJerome Glisse  *
13771fe6b9SJerome Glisse  * The above copyright notice and this permission notice shall be included in
14771fe6b9SJerome Glisse  * all copies or substantial portions of the Software.
15771fe6b9SJerome Glisse  *
16771fe6b9SJerome Glisse  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17771fe6b9SJerome Glisse  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18771fe6b9SJerome Glisse  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19771fe6b9SJerome Glisse  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20771fe6b9SJerome Glisse  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21771fe6b9SJerome Glisse  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22771fe6b9SJerome Glisse  * OTHER DEALINGS IN THE SOFTWARE.
23771fe6b9SJerome Glisse  *
24771fe6b9SJerome Glisse  * Authors: Dave Airlie
25771fe6b9SJerome Glisse  *          Alex Deucher
26771fe6b9SJerome Glisse  *          Jerome Glisse
27771fe6b9SJerome Glisse  */
28f9183127SSam Ravnborg 
29*2ef79416SThomas Zimmermann #include <linux/pci.h>
30*2ef79416SThomas Zimmermann 
31f9183127SSam Ravnborg #include <drm/drm_device.h>
32760285e7SDavid Howells #include <drm/radeon_drm.h>
33f9183127SSam Ravnborg 
34f9183127SSam Ravnborg #include "atom.h"
35771fe6b9SJerome Glisse #include "radeon.h"
36297b1286SBaoyou Xie #include "radeon_asic.h"
37f9183127SSam Ravnborg #include "radeon_reg.h"
38771fe6b9SJerome Glisse 
39771fe6b9SJerome Glisse /* 10 khz */
radeon_legacy_get_engine_clock(struct radeon_device * rdev)407433874eSRafał Miłecki uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
41771fe6b9SJerome Glisse {
42771fe6b9SJerome Glisse 	struct radeon_pll *spll = &rdev->clock.spll;
43771fe6b9SJerome Glisse 	uint32_t fb_div, ref_div, post_div, sclk;
44771fe6b9SJerome Glisse 
45771fe6b9SJerome Glisse 	fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
46771fe6b9SJerome Glisse 	fb_div = (fb_div >> RADEON_SPLL_FB_DIV_SHIFT) & RADEON_SPLL_FB_DIV_MASK;
47771fe6b9SJerome Glisse 	fb_div <<= 1;
48771fe6b9SJerome Glisse 	fb_div *= spll->reference_freq;
49771fe6b9SJerome Glisse 
50771fe6b9SJerome Glisse 	ref_div =
51771fe6b9SJerome Glisse 	    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
524b30b870SDave Airlie 
534b30b870SDave Airlie 	if (ref_div == 0)
544b30b870SDave Airlie 		return 0;
554b30b870SDave Airlie 
56771fe6b9SJerome Glisse 	sclk = fb_div / ref_div;
57771fe6b9SJerome Glisse 
58771fe6b9SJerome Glisse 	post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK;
59771fe6b9SJerome Glisse 	if (post_div == 2)
60771fe6b9SJerome Glisse 		sclk >>= 1;
61771fe6b9SJerome Glisse 	else if (post_div == 3)
62771fe6b9SJerome Glisse 		sclk >>= 2;
63771fe6b9SJerome Glisse 	else if (post_div == 4)
6438678d35SAlex Deucher 		sclk >>= 3;
65771fe6b9SJerome Glisse 
66771fe6b9SJerome Glisse 	return sclk;
67771fe6b9SJerome Glisse }
68771fe6b9SJerome Glisse 
69771fe6b9SJerome Glisse /* 10 khz */
radeon_legacy_get_memory_clock(struct radeon_device * rdev)705ea597f3SRafał Miłecki uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
71771fe6b9SJerome Glisse {
72771fe6b9SJerome Glisse 	struct radeon_pll *mpll = &rdev->clock.mpll;
73771fe6b9SJerome Glisse 	uint32_t fb_div, ref_div, post_div, mclk;
74771fe6b9SJerome Glisse 
75771fe6b9SJerome Glisse 	fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
76771fe6b9SJerome Glisse 	fb_div = (fb_div >> RADEON_MPLL_FB_DIV_SHIFT) & RADEON_MPLL_FB_DIV_MASK;
77771fe6b9SJerome Glisse 	fb_div <<= 1;
78771fe6b9SJerome Glisse 	fb_div *= mpll->reference_freq;
79771fe6b9SJerome Glisse 
80771fe6b9SJerome Glisse 	ref_div =
81771fe6b9SJerome Glisse 	    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
824b30b870SDave Airlie 
834b30b870SDave Airlie 	if (ref_div == 0)
844b30b870SDave Airlie 		return 0;
854b30b870SDave Airlie 
86771fe6b9SJerome Glisse 	mclk = fb_div / ref_div;
87771fe6b9SJerome Glisse 
88771fe6b9SJerome Glisse 	post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7;
89771fe6b9SJerome Glisse 	if (post_div == 2)
90771fe6b9SJerome Glisse 		mclk >>= 1;
91771fe6b9SJerome Glisse 	else if (post_div == 3)
92771fe6b9SJerome Glisse 		mclk >>= 2;
93771fe6b9SJerome Glisse 	else if (post_div == 4)
9438678d35SAlex Deucher 		mclk >>= 3;
95771fe6b9SJerome Glisse 
96771fe6b9SJerome Glisse 	return mclk;
97771fe6b9SJerome Glisse }
98771fe6b9SJerome Glisse 
997b044f40SBenjamin Herrenschmidt #ifdef CONFIG_OF
1007b044f40SBenjamin Herrenschmidt /*
1017b044f40SBenjamin Herrenschmidt  * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device
1027b044f40SBenjamin Herrenschmidt  * tree. Hopefully, ATI OF driver is kind enough to fill these
1037b044f40SBenjamin Herrenschmidt  */
radeon_read_clocks_OF(struct drm_device * dev)104ee276291SRalf Baechle static bool radeon_read_clocks_OF(struct drm_device *dev)
1057b044f40SBenjamin Herrenschmidt {
1067b044f40SBenjamin Herrenschmidt 	struct radeon_device *rdev = dev->dev_private;
1077b044f40SBenjamin Herrenschmidt 	struct device_node *dp = rdev->pdev->dev.of_node;
1087b044f40SBenjamin Herrenschmidt 	const u32 *val;
1097b044f40SBenjamin Herrenschmidt 	struct radeon_pll *p1pll = &rdev->clock.p1pll;
1107b044f40SBenjamin Herrenschmidt 	struct radeon_pll *p2pll = &rdev->clock.p2pll;
1117b044f40SBenjamin Herrenschmidt 	struct radeon_pll *spll = &rdev->clock.spll;
1127b044f40SBenjamin Herrenschmidt 	struct radeon_pll *mpll = &rdev->clock.mpll;
1137b044f40SBenjamin Herrenschmidt 
1147b044f40SBenjamin Herrenschmidt 	if (dp == NULL)
1157b044f40SBenjamin Herrenschmidt 		return false;
1167b044f40SBenjamin Herrenschmidt 	val = of_get_property(dp, "ATY,RefCLK", NULL);
1177b044f40SBenjamin Herrenschmidt 	if (!val || !*val) {
1187ca85295SJoe Perches 		pr_warn("radeonfb: No ATY,RefCLK property !\n");
1197b044f40SBenjamin Herrenschmidt 		return false;
1207b044f40SBenjamin Herrenschmidt 	}
1217b044f40SBenjamin Herrenschmidt 	p1pll->reference_freq = p2pll->reference_freq = (*val) / 10;
1227b044f40SBenjamin Herrenschmidt 	p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
1237b044f40SBenjamin Herrenschmidt 	if (p1pll->reference_div < 2)
1247b044f40SBenjamin Herrenschmidt 		p1pll->reference_div = 12;
1257b044f40SBenjamin Herrenschmidt 	p2pll->reference_div = p1pll->reference_div;
1267b044f40SBenjamin Herrenschmidt 
1277b044f40SBenjamin Herrenschmidt 	/* These aren't in the device-tree */
1287b044f40SBenjamin Herrenschmidt 	if (rdev->family >= CHIP_R420) {
1297b044f40SBenjamin Herrenschmidt 		p1pll->pll_in_min = 100;
1307b044f40SBenjamin Herrenschmidt 		p1pll->pll_in_max = 1350;
1317b044f40SBenjamin Herrenschmidt 		p1pll->pll_out_min = 20000;
1327b044f40SBenjamin Herrenschmidt 		p1pll->pll_out_max = 50000;
1337b044f40SBenjamin Herrenschmidt 		p2pll->pll_in_min = 100;
1347b044f40SBenjamin Herrenschmidt 		p2pll->pll_in_max = 1350;
1357b044f40SBenjamin Herrenschmidt 		p2pll->pll_out_min = 20000;
1367b044f40SBenjamin Herrenschmidt 		p2pll->pll_out_max = 50000;
1377b044f40SBenjamin Herrenschmidt 	} else {
1387b044f40SBenjamin Herrenschmidt 		p1pll->pll_in_min = 40;
1397b044f40SBenjamin Herrenschmidt 		p1pll->pll_in_max = 500;
1407b044f40SBenjamin Herrenschmidt 		p1pll->pll_out_min = 12500;
1417b044f40SBenjamin Herrenschmidt 		p1pll->pll_out_max = 35000;
1427b044f40SBenjamin Herrenschmidt 		p2pll->pll_in_min = 40;
1437b044f40SBenjamin Herrenschmidt 		p2pll->pll_in_max = 500;
1447b044f40SBenjamin Herrenschmidt 		p2pll->pll_out_min = 12500;
1457b044f40SBenjamin Herrenschmidt 		p2pll->pll_out_max = 35000;
1467b044f40SBenjamin Herrenschmidt 	}
147b20f9befSAlex Deucher 	/* not sure what the max should be in all cases */
148b20f9befSAlex Deucher 	rdev->clock.max_pixel_clock = 35000;
1497b044f40SBenjamin Herrenschmidt 
1507b044f40SBenjamin Herrenschmidt 	spll->reference_freq = mpll->reference_freq = p1pll->reference_freq;
1517b044f40SBenjamin Herrenschmidt 	spll->reference_div = mpll->reference_div =
1527b044f40SBenjamin Herrenschmidt 		RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
1537b044f40SBenjamin Herrenschmidt 			    RADEON_M_SPLL_REF_DIV_MASK;
1547b044f40SBenjamin Herrenschmidt 
1557b044f40SBenjamin Herrenschmidt 	val = of_get_property(dp, "ATY,SCLK", NULL);
1567b044f40SBenjamin Herrenschmidt 	if (val && *val)
1577b044f40SBenjamin Herrenschmidt 		rdev->clock.default_sclk = (*val) / 10;
1587b044f40SBenjamin Herrenschmidt 	else
1597b044f40SBenjamin Herrenschmidt 		rdev->clock.default_sclk =
1607b044f40SBenjamin Herrenschmidt 			radeon_legacy_get_engine_clock(rdev);
1617b044f40SBenjamin Herrenschmidt 
1627b044f40SBenjamin Herrenschmidt 	val = of_get_property(dp, "ATY,MCLK", NULL);
1637b044f40SBenjamin Herrenschmidt 	if (val && *val)
1647b044f40SBenjamin Herrenschmidt 		rdev->clock.default_mclk = (*val) / 10;
1657b044f40SBenjamin Herrenschmidt 	else
1667b044f40SBenjamin Herrenschmidt 		rdev->clock.default_mclk =
1677b044f40SBenjamin Herrenschmidt 			radeon_legacy_get_memory_clock(rdev);
1687b044f40SBenjamin Herrenschmidt 
1697b044f40SBenjamin Herrenschmidt 	DRM_INFO("Using device-tree clock info\n");
1707b044f40SBenjamin Herrenschmidt 
1717b044f40SBenjamin Herrenschmidt 	return true;
1727b044f40SBenjamin Herrenschmidt }
1737b044f40SBenjamin Herrenschmidt #else
radeon_read_clocks_OF(struct drm_device * dev)174ee276291SRalf Baechle static bool radeon_read_clocks_OF(struct drm_device *dev)
1757b044f40SBenjamin Herrenschmidt {
1767b044f40SBenjamin Herrenschmidt 	return false;
1777b044f40SBenjamin Herrenschmidt }
1787b044f40SBenjamin Herrenschmidt #endif /* CONFIG_OF */
1797b044f40SBenjamin Herrenschmidt 
radeon_get_clock_info(struct drm_device * dev)180771fe6b9SJerome Glisse void radeon_get_clock_info(struct drm_device *dev)
181771fe6b9SJerome Glisse {
182771fe6b9SJerome Glisse 	struct radeon_device *rdev = dev->dev_private;
183771fe6b9SJerome Glisse 	struct radeon_pll *p1pll = &rdev->clock.p1pll;
184771fe6b9SJerome Glisse 	struct radeon_pll *p2pll = &rdev->clock.p2pll;
185bcc1c2a1SAlex Deucher 	struct radeon_pll *dcpll = &rdev->clock.dcpll;
186771fe6b9SJerome Glisse 	struct radeon_pll *spll = &rdev->clock.spll;
187771fe6b9SJerome Glisse 	struct radeon_pll *mpll = &rdev->clock.mpll;
188771fe6b9SJerome Glisse 	int ret;
189771fe6b9SJerome Glisse 
190771fe6b9SJerome Glisse 	if (rdev->is_atom_bios)
191771fe6b9SJerome Glisse 		ret = radeon_atom_get_clock_info(dev);
192771fe6b9SJerome Glisse 	else
193771fe6b9SJerome Glisse 		ret = radeon_combios_get_clock_info(dev);
1947b044f40SBenjamin Herrenschmidt 	if (!ret)
1957b044f40SBenjamin Herrenschmidt 		ret = radeon_read_clocks_OF(dev);
196771fe6b9SJerome Glisse 
197771fe6b9SJerome Glisse 	if (ret) {
1982a008d0cSAlex Deucher 		if (p1pll->reference_div < 2) {
1992a008d0cSAlex Deucher 			if (!ASIC_IS_AVIVO(rdev)) {
2002a008d0cSAlex Deucher 				u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV);
2012a008d0cSAlex Deucher 				if (ASIC_IS_R300(rdev))
2022a008d0cSAlex Deucher 					p1pll->reference_div =
2032a008d0cSAlex Deucher 						(tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
2042a008d0cSAlex Deucher 				else
2052a008d0cSAlex Deucher 					p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
206771fe6b9SJerome Glisse 				if (p1pll->reference_div < 2)
207771fe6b9SJerome Glisse 					p1pll->reference_div = 12;
2082a008d0cSAlex Deucher 			} else
2092a008d0cSAlex Deucher 				p1pll->reference_div = 12;
2102a008d0cSAlex Deucher 		}
211771fe6b9SJerome Glisse 		if (p2pll->reference_div < 2)
212771fe6b9SJerome Glisse 			p2pll->reference_div = 12;
2133ce0a23dSJerome Glisse 		if (rdev->family < CHIP_RS600) {
214771fe6b9SJerome Glisse 			if (spll->reference_div < 2)
215771fe6b9SJerome Glisse 				spll->reference_div =
216771fe6b9SJerome Glisse 					RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
217771fe6b9SJerome Glisse 					RADEON_M_SPLL_REF_DIV_MASK;
2183ce0a23dSJerome Glisse 		}
219771fe6b9SJerome Glisse 		if (mpll->reference_div < 2)
220771fe6b9SJerome Glisse 			mpll->reference_div = spll->reference_div;
221771fe6b9SJerome Glisse 	} else {
222771fe6b9SJerome Glisse 		if (ASIC_IS_AVIVO(rdev)) {
223771fe6b9SJerome Glisse 			/* TODO FALLBACK */
224771fe6b9SJerome Glisse 		} else {
225771fe6b9SJerome Glisse 			DRM_INFO("Using generic clock info\n");
226771fe6b9SJerome Glisse 
2279adceaa5SDave Airlie 			/* may need to be per card */
2289adceaa5SDave Airlie 			rdev->clock.max_pixel_clock = 35000;
2299adceaa5SDave Airlie 
230771fe6b9SJerome Glisse 			if (rdev->flags & RADEON_IS_IGP) {
231771fe6b9SJerome Glisse 				p1pll->reference_freq = 1432;
232771fe6b9SJerome Glisse 				p2pll->reference_freq = 1432;
233771fe6b9SJerome Glisse 				spll->reference_freq = 1432;
234771fe6b9SJerome Glisse 				mpll->reference_freq = 1432;
235771fe6b9SJerome Glisse 			} else {
236771fe6b9SJerome Glisse 				p1pll->reference_freq = 2700;
237771fe6b9SJerome Glisse 				p2pll->reference_freq = 2700;
238771fe6b9SJerome Glisse 				spll->reference_freq = 2700;
239771fe6b9SJerome Glisse 				mpll->reference_freq = 2700;
240771fe6b9SJerome Glisse 			}
241771fe6b9SJerome Glisse 			p1pll->reference_div =
242771fe6b9SJerome Glisse 			    RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
243771fe6b9SJerome Glisse 			if (p1pll->reference_div < 2)
244771fe6b9SJerome Glisse 				p1pll->reference_div = 12;
245771fe6b9SJerome Glisse 			p2pll->reference_div = p1pll->reference_div;
246771fe6b9SJerome Glisse 
247771fe6b9SJerome Glisse 			if (rdev->family >= CHIP_R420) {
248771fe6b9SJerome Glisse 				p1pll->pll_in_min = 100;
249771fe6b9SJerome Glisse 				p1pll->pll_in_max = 1350;
250771fe6b9SJerome Glisse 				p1pll->pll_out_min = 20000;
251771fe6b9SJerome Glisse 				p1pll->pll_out_max = 50000;
252771fe6b9SJerome Glisse 				p2pll->pll_in_min = 100;
253771fe6b9SJerome Glisse 				p2pll->pll_in_max = 1350;
254771fe6b9SJerome Glisse 				p2pll->pll_out_min = 20000;
255771fe6b9SJerome Glisse 				p2pll->pll_out_max = 50000;
256771fe6b9SJerome Glisse 			} else {
257771fe6b9SJerome Glisse 				p1pll->pll_in_min = 40;
258771fe6b9SJerome Glisse 				p1pll->pll_in_max = 500;
259771fe6b9SJerome Glisse 				p1pll->pll_out_min = 12500;
260771fe6b9SJerome Glisse 				p1pll->pll_out_max = 35000;
261771fe6b9SJerome Glisse 				p2pll->pll_in_min = 40;
262771fe6b9SJerome Glisse 				p2pll->pll_in_max = 500;
263771fe6b9SJerome Glisse 				p2pll->pll_out_min = 12500;
264771fe6b9SJerome Glisse 				p2pll->pll_out_max = 35000;
265771fe6b9SJerome Glisse 			}
266771fe6b9SJerome Glisse 
267771fe6b9SJerome Glisse 			spll->reference_div =
268771fe6b9SJerome Glisse 			    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
269771fe6b9SJerome Glisse 			    RADEON_M_SPLL_REF_DIV_MASK;
270771fe6b9SJerome Glisse 			mpll->reference_div = spll->reference_div;
271771fe6b9SJerome Glisse 			rdev->clock.default_sclk =
272771fe6b9SJerome Glisse 			    radeon_legacy_get_engine_clock(rdev);
273771fe6b9SJerome Glisse 			rdev->clock.default_mclk =
274771fe6b9SJerome Glisse 			    radeon_legacy_get_memory_clock(rdev);
275771fe6b9SJerome Glisse 		}
276771fe6b9SJerome Glisse 	}
277771fe6b9SJerome Glisse 
278771fe6b9SJerome Glisse 	/* pixel clocks */
279771fe6b9SJerome Glisse 	if (ASIC_IS_AVIVO(rdev)) {
280771fe6b9SJerome Glisse 		p1pll->min_post_div = 2;
281771fe6b9SJerome Glisse 		p1pll->max_post_div = 0x7f;
282771fe6b9SJerome Glisse 		p1pll->min_frac_feedback_div = 0;
283771fe6b9SJerome Glisse 		p1pll->max_frac_feedback_div = 9;
284771fe6b9SJerome Glisse 		p2pll->min_post_div = 2;
285771fe6b9SJerome Glisse 		p2pll->max_post_div = 0x7f;
286771fe6b9SJerome Glisse 		p2pll->min_frac_feedback_div = 0;
287771fe6b9SJerome Glisse 		p2pll->max_frac_feedback_div = 9;
288771fe6b9SJerome Glisse 	} else {
289771fe6b9SJerome Glisse 		p1pll->min_post_div = 1;
290771fe6b9SJerome Glisse 		p1pll->max_post_div = 16;
291771fe6b9SJerome Glisse 		p1pll->min_frac_feedback_div = 0;
292771fe6b9SJerome Glisse 		p1pll->max_frac_feedback_div = 0;
293771fe6b9SJerome Glisse 		p2pll->min_post_div = 1;
294771fe6b9SJerome Glisse 		p2pll->max_post_div = 12;
295771fe6b9SJerome Glisse 		p2pll->min_frac_feedback_div = 0;
296771fe6b9SJerome Glisse 		p2pll->max_frac_feedback_div = 0;
297771fe6b9SJerome Glisse 	}
298771fe6b9SJerome Glisse 
299bcc1c2a1SAlex Deucher 	/* dcpll is DCE4 only */
300bcc1c2a1SAlex Deucher 	dcpll->min_post_div = 2;
301bcc1c2a1SAlex Deucher 	dcpll->max_post_div = 0x7f;
302bcc1c2a1SAlex Deucher 	dcpll->min_frac_feedback_div = 0;
303bcc1c2a1SAlex Deucher 	dcpll->max_frac_feedback_div = 9;
304bcc1c2a1SAlex Deucher 	dcpll->min_ref_div = 2;
305bcc1c2a1SAlex Deucher 	dcpll->max_ref_div = 0x3ff;
306bcc1c2a1SAlex Deucher 	dcpll->min_feedback_div = 4;
307bcc1c2a1SAlex Deucher 	dcpll->max_feedback_div = 0xfff;
308bcc1c2a1SAlex Deucher 	dcpll->best_vco = 0;
309bcc1c2a1SAlex Deucher 
310771fe6b9SJerome Glisse 	p1pll->min_ref_div = 2;
311771fe6b9SJerome Glisse 	p1pll->max_ref_div = 0x3ff;
312771fe6b9SJerome Glisse 	p1pll->min_feedback_div = 4;
313771fe6b9SJerome Glisse 	p1pll->max_feedback_div = 0x7ff;
314771fe6b9SJerome Glisse 	p1pll->best_vco = 0;
315771fe6b9SJerome Glisse 
316771fe6b9SJerome Glisse 	p2pll->min_ref_div = 2;
317771fe6b9SJerome Glisse 	p2pll->max_ref_div = 0x3ff;
318771fe6b9SJerome Glisse 	p2pll->min_feedback_div = 4;
319771fe6b9SJerome Glisse 	p2pll->max_feedback_div = 0x7ff;
320771fe6b9SJerome Glisse 	p2pll->best_vco = 0;
321771fe6b9SJerome Glisse 
322771fe6b9SJerome Glisse 	/* system clock */
323771fe6b9SJerome Glisse 	spll->min_post_div = 1;
324771fe6b9SJerome Glisse 	spll->max_post_div = 1;
325771fe6b9SJerome Glisse 	spll->min_ref_div = 2;
326771fe6b9SJerome Glisse 	spll->max_ref_div = 0xff;
327771fe6b9SJerome Glisse 	spll->min_feedback_div = 4;
328771fe6b9SJerome Glisse 	spll->max_feedback_div = 0xff;
329771fe6b9SJerome Glisse 	spll->best_vco = 0;
330771fe6b9SJerome Glisse 
331771fe6b9SJerome Glisse 	/* memory clock */
332771fe6b9SJerome Glisse 	mpll->min_post_div = 1;
333771fe6b9SJerome Glisse 	mpll->max_post_div = 1;
334771fe6b9SJerome Glisse 	mpll->min_ref_div = 2;
335771fe6b9SJerome Glisse 	mpll->max_ref_div = 0xff;
336771fe6b9SJerome Glisse 	mpll->min_feedback_div = 4;
337771fe6b9SJerome Glisse 	mpll->max_feedback_div = 0xff;
338771fe6b9SJerome Glisse 	mpll->best_vco = 0;
339771fe6b9SJerome Glisse 
3408807286eSAlex Deucher 	if (!rdev->clock.default_sclk)
3418807286eSAlex Deucher 		rdev->clock.default_sclk = radeon_get_engine_clock(rdev);
342798bcf73SAlex Deucher 	if ((!rdev->clock.default_mclk) && rdev->asic->pm.get_memory_clock)
3438807286eSAlex Deucher 		rdev->clock.default_mclk = radeon_get_memory_clock(rdev);
3448807286eSAlex Deucher 
3458807286eSAlex Deucher 	rdev->pm.current_sclk = rdev->clock.default_sclk;
3468807286eSAlex Deucher 	rdev->pm.current_mclk = rdev->clock.default_mclk;
3478807286eSAlex Deucher 
348771fe6b9SJerome Glisse }
349771fe6b9SJerome Glisse 
350771fe6b9SJerome Glisse /* 10 khz */
calc_eng_mem_clock(struct radeon_device * rdev,uint32_t req_clock,int * fb_div,int * post_div)351771fe6b9SJerome Glisse static uint32_t calc_eng_mem_clock(struct radeon_device *rdev,
352771fe6b9SJerome Glisse 				   uint32_t req_clock,
353771fe6b9SJerome Glisse 				   int *fb_div, int *post_div)
354771fe6b9SJerome Glisse {
355771fe6b9SJerome Glisse 	struct radeon_pll *spll = &rdev->clock.spll;
356771fe6b9SJerome Glisse 	int ref_div = spll->reference_div;
357771fe6b9SJerome Glisse 
358771fe6b9SJerome Glisse 	if (!ref_div)
359771fe6b9SJerome Glisse 		ref_div =
360771fe6b9SJerome Glisse 		    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
361771fe6b9SJerome Glisse 		    RADEON_M_SPLL_REF_DIV_MASK;
362771fe6b9SJerome Glisse 
363771fe6b9SJerome Glisse 	if (req_clock < 15000) {
364771fe6b9SJerome Glisse 		*post_div = 8;
365771fe6b9SJerome Glisse 		req_clock *= 8;
366771fe6b9SJerome Glisse 	} else if (req_clock < 30000) {
367771fe6b9SJerome Glisse 		*post_div = 4;
368771fe6b9SJerome Glisse 		req_clock *= 4;
369771fe6b9SJerome Glisse 	} else if (req_clock < 60000) {
370771fe6b9SJerome Glisse 		*post_div = 2;
371771fe6b9SJerome Glisse 		req_clock *= 2;
372771fe6b9SJerome Glisse 	} else
373771fe6b9SJerome Glisse 		*post_div = 1;
374771fe6b9SJerome Glisse 
375771fe6b9SJerome Glisse 	req_clock *= ref_div;
376771fe6b9SJerome Glisse 	req_clock += spll->reference_freq;
377771fe6b9SJerome Glisse 	req_clock /= (2 * spll->reference_freq);
378771fe6b9SJerome Glisse 
379771fe6b9SJerome Glisse 	*fb_div = req_clock & 0xff;
380771fe6b9SJerome Glisse 
381771fe6b9SJerome Glisse 	req_clock = (req_clock & 0xffff) << 1;
382771fe6b9SJerome Glisse 	req_clock *= spll->reference_freq;
383771fe6b9SJerome Glisse 	req_clock /= ref_div;
384771fe6b9SJerome Glisse 	req_clock /= *post_div;
385771fe6b9SJerome Glisse 
386771fe6b9SJerome Glisse 	return req_clock;
387771fe6b9SJerome Glisse }
388771fe6b9SJerome Glisse 
389771fe6b9SJerome Glisse /* 10 khz */
radeon_legacy_set_engine_clock(struct radeon_device * rdev,uint32_t eng_clock)390771fe6b9SJerome Glisse void radeon_legacy_set_engine_clock(struct radeon_device *rdev,
391771fe6b9SJerome Glisse 				    uint32_t eng_clock)
392771fe6b9SJerome Glisse {
393771fe6b9SJerome Glisse 	uint32_t tmp;
394771fe6b9SJerome Glisse 	int fb_div, post_div;
395771fe6b9SJerome Glisse 
396771fe6b9SJerome Glisse 	/* XXX: wait for idle */
397771fe6b9SJerome Glisse 
398771fe6b9SJerome Glisse 	eng_clock = calc_eng_mem_clock(rdev, eng_clock, &fb_div, &post_div);
399771fe6b9SJerome Glisse 
400771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
401771fe6b9SJerome Glisse 	tmp &= ~RADEON_DONT_USE_XTALIN;
402771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
403771fe6b9SJerome Glisse 
404771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_SCLK_CNTL);
405771fe6b9SJerome Glisse 	tmp &= ~RADEON_SCLK_SRC_SEL_MASK;
406771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_SCLK_CNTL, tmp);
407771fe6b9SJerome Glisse 
408771fe6b9SJerome Glisse 	udelay(10);
409771fe6b9SJerome Glisse 
410771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
411771fe6b9SJerome Glisse 	tmp |= RADEON_SPLL_SLEEP;
412771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
413771fe6b9SJerome Glisse 
414771fe6b9SJerome Glisse 	udelay(2);
415771fe6b9SJerome Glisse 
416771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
417771fe6b9SJerome Glisse 	tmp |= RADEON_SPLL_RESET;
418771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
419771fe6b9SJerome Glisse 
420771fe6b9SJerome Glisse 	udelay(200);
421771fe6b9SJerome Glisse 
422771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
423771fe6b9SJerome Glisse 	tmp &= ~(RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT);
424771fe6b9SJerome Glisse 	tmp |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT;
425771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_M_SPLL_REF_FB_DIV, tmp);
426771fe6b9SJerome Glisse 
427771fe6b9SJerome Glisse 	/* XXX: verify on different asics */
428771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
429771fe6b9SJerome Glisse 	tmp &= ~RADEON_SPLL_PVG_MASK;
430771fe6b9SJerome Glisse 	if ((eng_clock * post_div) >= 90000)
431771fe6b9SJerome Glisse 		tmp |= (0x7 << RADEON_SPLL_PVG_SHIFT);
432771fe6b9SJerome Glisse 	else
433771fe6b9SJerome Glisse 		tmp |= (0x4 << RADEON_SPLL_PVG_SHIFT);
434771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
435771fe6b9SJerome Glisse 
436771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
437771fe6b9SJerome Glisse 	tmp &= ~RADEON_SPLL_SLEEP;
438771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
439771fe6b9SJerome Glisse 
440771fe6b9SJerome Glisse 	udelay(2);
441771fe6b9SJerome Glisse 
442771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
443771fe6b9SJerome Glisse 	tmp &= ~RADEON_SPLL_RESET;
444771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
445771fe6b9SJerome Glisse 
446771fe6b9SJerome Glisse 	udelay(200);
447771fe6b9SJerome Glisse 
448771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_SCLK_CNTL);
449771fe6b9SJerome Glisse 	tmp &= ~RADEON_SCLK_SRC_SEL_MASK;
450771fe6b9SJerome Glisse 	switch (post_div) {
451771fe6b9SJerome Glisse 	case 1:
452771fe6b9SJerome Glisse 	default:
453771fe6b9SJerome Glisse 		tmp |= 1;
454771fe6b9SJerome Glisse 		break;
455771fe6b9SJerome Glisse 	case 2:
456771fe6b9SJerome Glisse 		tmp |= 2;
457771fe6b9SJerome Glisse 		break;
458771fe6b9SJerome Glisse 	case 4:
459771fe6b9SJerome Glisse 		tmp |= 3;
460771fe6b9SJerome Glisse 		break;
461771fe6b9SJerome Glisse 	case 8:
462771fe6b9SJerome Glisse 		tmp |= 4;
463771fe6b9SJerome Glisse 		break;
464771fe6b9SJerome Glisse 	}
465771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_SCLK_CNTL, tmp);
466771fe6b9SJerome Glisse 
467771fe6b9SJerome Glisse 	udelay(20);
468771fe6b9SJerome Glisse 
469771fe6b9SJerome Glisse 	tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
470771fe6b9SJerome Glisse 	tmp |= RADEON_DONT_USE_XTALIN;
471771fe6b9SJerome Glisse 	WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
472771fe6b9SJerome Glisse 
473771fe6b9SJerome Glisse 	udelay(10);
474771fe6b9SJerome Glisse }
475771fe6b9SJerome Glisse 
radeon_legacy_set_clock_gating(struct radeon_device * rdev,int enable)476771fe6b9SJerome Glisse void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
477771fe6b9SJerome Glisse {
478771fe6b9SJerome Glisse 	uint32_t tmp;
479771fe6b9SJerome Glisse 
480771fe6b9SJerome Glisse 	if (enable) {
481771fe6b9SJerome Glisse 		if (rdev->flags & RADEON_SINGLE_CRTC) {
482771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
483771fe6b9SJerome Glisse 			if ((RREG32(RADEON_CONFIG_CNTL) &
484771fe6b9SJerome Glisse 			     RADEON_CFG_ATI_REV_ID_MASK) >
485771fe6b9SJerome Glisse 			    RADEON_CFG_ATI_REV_A13) {
486771fe6b9SJerome Glisse 				tmp &=
487771fe6b9SJerome Glisse 				    ~(RADEON_SCLK_FORCE_CP |
488771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_RB);
489771fe6b9SJerome Glisse 			}
490771fe6b9SJerome Glisse 			tmp &=
491771fe6b9SJerome Glisse 			    ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
492771fe6b9SJerome Glisse 			      RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE |
493771fe6b9SJerome Glisse 			      RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE |
494771fe6b9SJerome Glisse 			      RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM |
495771fe6b9SJerome Glisse 			      RADEON_SCLK_FORCE_TDM);
496771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
497771fe6b9SJerome Glisse 		} else if (ASIC_IS_R300(rdev)) {
498771fe6b9SJerome Glisse 			if ((rdev->family == CHIP_RS400) ||
499771fe6b9SJerome Glisse 			    (rdev->family == CHIP_RS480)) {
500771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_SCLK_CNTL);
501771fe6b9SJerome Glisse 				tmp &=
502771fe6b9SJerome Glisse 				    ~(RADEON_SCLK_FORCE_DISP2 |
503771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_CP |
504771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_HDP |
505771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_DISP1 |
506771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_TOP |
507771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP
508771fe6b9SJerome Glisse 				      | RADEON_SCLK_FORCE_IDCT |
509771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR
510771fe6b9SJerome Glisse 				      | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX
511771fe6b9SJerome Glisse 				      | R300_SCLK_FORCE_US |
512771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_TV_SCLK |
513771fe6b9SJerome Glisse 				      R300_SCLK_FORCE_SU |
514771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_OV0);
515771fe6b9SJerome Glisse 				tmp |= RADEON_DYN_STOP_LAT_MASK;
516771fe6b9SJerome Glisse 				tmp |=
517771fe6b9SJerome Glisse 				    RADEON_SCLK_FORCE_TOP |
518771fe6b9SJerome Glisse 				    RADEON_SCLK_FORCE_VIP;
519771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_SCLK_CNTL, tmp);
520771fe6b9SJerome Glisse 
521771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
522771fe6b9SJerome Glisse 				tmp &= ~RADEON_SCLK_MORE_FORCEON;
523771fe6b9SJerome Glisse 				tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
524771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
525771fe6b9SJerome Glisse 
526771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
527771fe6b9SJerome Glisse 				tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
528771fe6b9SJerome Glisse 					RADEON_PIXCLK_DAC_ALWAYS_ONb);
529771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
530771fe6b9SJerome Glisse 
531771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
532771fe6b9SJerome Glisse 				tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
533771fe6b9SJerome Glisse 					RADEON_PIX2CLK_DAC_ALWAYS_ONb |
534771fe6b9SJerome Glisse 					RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
535771fe6b9SJerome Glisse 					R300_DVOCLK_ALWAYS_ONb |
536771fe6b9SJerome Glisse 					RADEON_PIXCLK_BLEND_ALWAYS_ONb |
537771fe6b9SJerome Glisse 					RADEON_PIXCLK_GV_ALWAYS_ONb |
538771fe6b9SJerome Glisse 					R300_PIXCLK_DVO_ALWAYS_ONb |
539771fe6b9SJerome Glisse 					RADEON_PIXCLK_LVDS_ALWAYS_ONb |
540771fe6b9SJerome Glisse 					RADEON_PIXCLK_TMDS_ALWAYS_ONb |
541771fe6b9SJerome Glisse 					R300_PIXCLK_TRANS_ALWAYS_ONb |
542771fe6b9SJerome Glisse 					R300_PIXCLK_TVO_ALWAYS_ONb |
543771fe6b9SJerome Glisse 					R300_P2G2CLK_ALWAYS_ONb |
544aa96e341SRoel Kluin 					R300_P2G2CLK_DAC_ALWAYS_ONb);
545771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
546771fe6b9SJerome Glisse 			} else if (rdev->family >= CHIP_RV350) {
547771fe6b9SJerome Glisse 				tmp = RREG32_PLL(R300_SCLK_CNTL2);
548771fe6b9SJerome Glisse 				tmp &= ~(R300_SCLK_FORCE_TCL |
549771fe6b9SJerome Glisse 					 R300_SCLK_FORCE_GA |
550771fe6b9SJerome Glisse 					 R300_SCLK_FORCE_CBA);
551771fe6b9SJerome Glisse 				tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT |
552771fe6b9SJerome Glisse 					R300_SCLK_GA_MAX_DYN_STOP_LAT |
553771fe6b9SJerome Glisse 					R300_SCLK_CBA_MAX_DYN_STOP_LAT);
554771fe6b9SJerome Glisse 				WREG32_PLL(R300_SCLK_CNTL2, tmp);
555771fe6b9SJerome Glisse 
556771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_SCLK_CNTL);
557771fe6b9SJerome Glisse 				tmp &=
558771fe6b9SJerome Glisse 				    ~(RADEON_SCLK_FORCE_DISP2 |
559771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_CP |
560771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_HDP |
561771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_DISP1 |
562771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_TOP |
563771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP
564771fe6b9SJerome Glisse 				      | RADEON_SCLK_FORCE_IDCT |
565771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR
566771fe6b9SJerome Glisse 				      | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX
567771fe6b9SJerome Glisse 				      | R300_SCLK_FORCE_US |
568771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_TV_SCLK |
569771fe6b9SJerome Glisse 				      R300_SCLK_FORCE_SU |
570771fe6b9SJerome Glisse 				      RADEON_SCLK_FORCE_OV0);
571771fe6b9SJerome Glisse 				tmp |= RADEON_DYN_STOP_LAT_MASK;
572771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_SCLK_CNTL, tmp);
573771fe6b9SJerome Glisse 
574771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
575771fe6b9SJerome Glisse 				tmp &= ~RADEON_SCLK_MORE_FORCEON;
576771fe6b9SJerome Glisse 				tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
577771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
578771fe6b9SJerome Glisse 
579771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
580771fe6b9SJerome Glisse 				tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
581771fe6b9SJerome Glisse 					RADEON_PIXCLK_DAC_ALWAYS_ONb);
582771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
583771fe6b9SJerome Glisse 
584771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
585771fe6b9SJerome Glisse 				tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
586771fe6b9SJerome Glisse 					RADEON_PIX2CLK_DAC_ALWAYS_ONb |
587771fe6b9SJerome Glisse 					RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
588771fe6b9SJerome Glisse 					R300_DVOCLK_ALWAYS_ONb |
589771fe6b9SJerome Glisse 					RADEON_PIXCLK_BLEND_ALWAYS_ONb |
590771fe6b9SJerome Glisse 					RADEON_PIXCLK_GV_ALWAYS_ONb |
591771fe6b9SJerome Glisse 					R300_PIXCLK_DVO_ALWAYS_ONb |
592771fe6b9SJerome Glisse 					RADEON_PIXCLK_LVDS_ALWAYS_ONb |
593771fe6b9SJerome Glisse 					RADEON_PIXCLK_TMDS_ALWAYS_ONb |
594771fe6b9SJerome Glisse 					R300_PIXCLK_TRANS_ALWAYS_ONb |
595771fe6b9SJerome Glisse 					R300_PIXCLK_TVO_ALWAYS_ONb |
596771fe6b9SJerome Glisse 					R300_P2G2CLK_ALWAYS_ONb |
597aa96e341SRoel Kluin 					R300_P2G2CLK_DAC_ALWAYS_ONb);
598771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
599771fe6b9SJerome Glisse 
600771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_MCLK_MISC);
601771fe6b9SJerome Glisse 				tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
602771fe6b9SJerome Glisse 					RADEON_IO_MCLK_DYN_ENABLE);
603771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_MCLK_MISC, tmp);
604771fe6b9SJerome Glisse 
605771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_MCLK_CNTL);
606771fe6b9SJerome Glisse 				tmp |= (RADEON_FORCEON_MCLKA |
607771fe6b9SJerome Glisse 					RADEON_FORCEON_MCLKB);
608771fe6b9SJerome Glisse 
609771fe6b9SJerome Glisse 				tmp &= ~(RADEON_FORCEON_YCLKA |
610771fe6b9SJerome Glisse 					 RADEON_FORCEON_YCLKB |
611771fe6b9SJerome Glisse 					 RADEON_FORCEON_MC);
612771fe6b9SJerome Glisse 
613771fe6b9SJerome Glisse 				/* Some releases of vbios have set DISABLE_MC_MCLKA
614771fe6b9SJerome Glisse 				   and DISABLE_MC_MCLKB bits in the vbios table.  Setting these
615771fe6b9SJerome Glisse 				   bits will cause H/W hang when reading video memory with dynamic clocking
616771fe6b9SJerome Glisse 				   enabled. */
617771fe6b9SJerome Glisse 				if ((tmp & R300_DISABLE_MC_MCLKA) &&
618771fe6b9SJerome Glisse 				    (tmp & R300_DISABLE_MC_MCLKB)) {
619771fe6b9SJerome Glisse 					/* If both bits are set, then check the active channels */
620771fe6b9SJerome Glisse 					tmp = RREG32_PLL(RADEON_MCLK_CNTL);
621771fe6b9SJerome Glisse 					if (rdev->mc.vram_width == 64) {
622771fe6b9SJerome Glisse 						if (RREG32(RADEON_MEM_CNTL) &
623771fe6b9SJerome Glisse 						    R300_MEM_USE_CD_CH_ONLY)
624771fe6b9SJerome Glisse 							tmp &=
625771fe6b9SJerome Glisse 							    ~R300_DISABLE_MC_MCLKB;
626771fe6b9SJerome Glisse 						else
627771fe6b9SJerome Glisse 							tmp &=
628771fe6b9SJerome Glisse 							    ~R300_DISABLE_MC_MCLKA;
629771fe6b9SJerome Glisse 					} else {
630771fe6b9SJerome Glisse 						tmp &= ~(R300_DISABLE_MC_MCLKA |
631771fe6b9SJerome Glisse 							 R300_DISABLE_MC_MCLKB);
632771fe6b9SJerome Glisse 					}
633771fe6b9SJerome Glisse 				}
634771fe6b9SJerome Glisse 
635771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_MCLK_CNTL, tmp);
636771fe6b9SJerome Glisse 			} else {
637771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_SCLK_CNTL);
638771fe6b9SJerome Glisse 				tmp &= ~(R300_SCLK_FORCE_VAP);
639771fe6b9SJerome Glisse 				tmp |= RADEON_SCLK_FORCE_CP;
640771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_SCLK_CNTL, tmp);
6414de833c3SArnd Bergmann 				mdelay(15);
642771fe6b9SJerome Glisse 
643771fe6b9SJerome Glisse 				tmp = RREG32_PLL(R300_SCLK_CNTL2);
644771fe6b9SJerome Glisse 				tmp &= ~(R300_SCLK_FORCE_TCL |
645771fe6b9SJerome Glisse 					 R300_SCLK_FORCE_GA |
646771fe6b9SJerome Glisse 					 R300_SCLK_FORCE_CBA);
647771fe6b9SJerome Glisse 				WREG32_PLL(R300_SCLK_CNTL2, tmp);
648771fe6b9SJerome Glisse 			}
649771fe6b9SJerome Glisse 		} else {
650771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_CLK_PWRMGT_CNTL);
651771fe6b9SJerome Glisse 
652771fe6b9SJerome Glisse 			tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK |
653771fe6b9SJerome Glisse 				 RADEON_DISP_DYN_STOP_LAT_MASK |
654771fe6b9SJerome Glisse 				 RADEON_DYN_STOP_MODE_MASK);
655771fe6b9SJerome Glisse 
656771fe6b9SJerome Glisse 			tmp |= (RADEON_ENGIN_DYNCLK_MODE |
657771fe6b9SJerome Glisse 				(0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
658771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp);
6594de833c3SArnd Bergmann 			mdelay(15);
660771fe6b9SJerome Glisse 
661771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
662771fe6b9SJerome Glisse 			tmp |= RADEON_SCLK_DYN_START_CNTL;
663771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
6644de833c3SArnd Bergmann 			mdelay(15);
665771fe6b9SJerome Glisse 
666771fe6b9SJerome Glisse 			/* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
667771fe6b9SJerome Glisse 			   to lockup randomly, leave them as set by BIOS.
668771fe6b9SJerome Glisse 			 */
669771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
670771fe6b9SJerome Glisse 			/*tmp &= RADEON_SCLK_SRC_SEL_MASK; */
671771fe6b9SJerome Glisse 			tmp &= ~RADEON_SCLK_FORCEON_MASK;
672771fe6b9SJerome Glisse 
673771fe6b9SJerome Glisse 			/*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300 */
674771fe6b9SJerome Glisse 			if (((rdev->family == CHIP_RV250) &&
675771fe6b9SJerome Glisse 			     ((RREG32(RADEON_CONFIG_CNTL) &
676771fe6b9SJerome Glisse 			       RADEON_CFG_ATI_REV_ID_MASK) <
677771fe6b9SJerome Glisse 			      RADEON_CFG_ATI_REV_A13))
678771fe6b9SJerome Glisse 			    || ((rdev->family == CHIP_RV100)
679771fe6b9SJerome Glisse 				&&
680771fe6b9SJerome Glisse 				((RREG32(RADEON_CONFIG_CNTL) &
681771fe6b9SJerome Glisse 				  RADEON_CFG_ATI_REV_ID_MASK) <=
682771fe6b9SJerome Glisse 				 RADEON_CFG_ATI_REV_A13))) {
683771fe6b9SJerome Glisse 				tmp |= RADEON_SCLK_FORCE_CP;
684771fe6b9SJerome Glisse 				tmp |= RADEON_SCLK_FORCE_VIP;
685771fe6b9SJerome Glisse 			}
686771fe6b9SJerome Glisse 
687771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
688771fe6b9SJerome Glisse 
689771fe6b9SJerome Glisse 			if ((rdev->family == CHIP_RV200) ||
690771fe6b9SJerome Glisse 			    (rdev->family == CHIP_RV250) ||
691771fe6b9SJerome Glisse 			    (rdev->family == CHIP_RV280)) {
692771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
693771fe6b9SJerome Glisse 				tmp &= ~RADEON_SCLK_MORE_FORCEON;
694771fe6b9SJerome Glisse 
695771fe6b9SJerome Glisse 				/* RV200::A11 A12 RV250::A11 A12 */
696771fe6b9SJerome Glisse 				if (((rdev->family == CHIP_RV200) ||
697771fe6b9SJerome Glisse 				     (rdev->family == CHIP_RV250)) &&
698771fe6b9SJerome Glisse 				    ((RREG32(RADEON_CONFIG_CNTL) &
699771fe6b9SJerome Glisse 				      RADEON_CFG_ATI_REV_ID_MASK) <
700771fe6b9SJerome Glisse 				     RADEON_CFG_ATI_REV_A13)) {
701771fe6b9SJerome Glisse 					tmp |= RADEON_SCLK_MORE_FORCEON;
702771fe6b9SJerome Glisse 				}
703771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
7044de833c3SArnd Bergmann 				mdelay(15);
705771fe6b9SJerome Glisse 			}
706771fe6b9SJerome Glisse 
707771fe6b9SJerome Glisse 			/* RV200::A11 A12, RV250::A11 A12 */
708771fe6b9SJerome Glisse 			if (((rdev->family == CHIP_RV200) ||
709771fe6b9SJerome Glisse 			     (rdev->family == CHIP_RV250)) &&
710771fe6b9SJerome Glisse 			    ((RREG32(RADEON_CONFIG_CNTL) &
711771fe6b9SJerome Glisse 			      RADEON_CFG_ATI_REV_ID_MASK) <
712771fe6b9SJerome Glisse 			     RADEON_CFG_ATI_REV_A13)) {
713771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL);
714771fe6b9SJerome Glisse 				tmp |= RADEON_TCL_BYPASS_DISABLE;
715771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
716771fe6b9SJerome Glisse 			}
7174de833c3SArnd Bergmann 			mdelay(15);
718771fe6b9SJerome Glisse 
719771fe6b9SJerome Glisse 			/*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */
720771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
721771fe6b9SJerome Glisse 			tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
722771fe6b9SJerome Glisse 				RADEON_PIX2CLK_DAC_ALWAYS_ONb |
723771fe6b9SJerome Glisse 				RADEON_PIXCLK_BLEND_ALWAYS_ONb |
724771fe6b9SJerome Glisse 				RADEON_PIXCLK_GV_ALWAYS_ONb |
725771fe6b9SJerome Glisse 				RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
726771fe6b9SJerome Glisse 				RADEON_PIXCLK_LVDS_ALWAYS_ONb |
727771fe6b9SJerome Glisse 				RADEON_PIXCLK_TMDS_ALWAYS_ONb);
728771fe6b9SJerome Glisse 
729771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
7304de833c3SArnd Bergmann 			mdelay(15);
731771fe6b9SJerome Glisse 
732771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
733771fe6b9SJerome Glisse 			tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
734771fe6b9SJerome Glisse 				RADEON_PIXCLK_DAC_ALWAYS_ONb);
735771fe6b9SJerome Glisse 
736771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
7374de833c3SArnd Bergmann 			mdelay(15);
738771fe6b9SJerome Glisse 		}
739771fe6b9SJerome Glisse 	} else {
740771fe6b9SJerome Glisse 		/* Turn everything OFF (ForceON to everything) */
741771fe6b9SJerome Glisse 		if (rdev->flags & RADEON_SINGLE_CRTC) {
742771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
743771fe6b9SJerome Glisse 			tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP |
744771fe6b9SJerome Glisse 				RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP
745771fe6b9SJerome Glisse 				| RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE |
746771fe6b9SJerome Glisse 				RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP |
747771fe6b9SJerome Glisse 				RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB |
748771fe6b9SJerome Glisse 				RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM |
749771fe6b9SJerome Glisse 				RADEON_SCLK_FORCE_RB);
750771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
751771fe6b9SJerome Glisse 		} else if ((rdev->family == CHIP_RS400) ||
752771fe6b9SJerome Glisse 			   (rdev->family == CHIP_RS480)) {
753771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
754771fe6b9SJerome Glisse 			tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
755771fe6b9SJerome Glisse 				RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1
756771fe6b9SJerome Glisse 				| RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
757771fe6b9SJerome Glisse 				R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
758771fe6b9SJerome Glisse 				RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
759771fe6b9SJerome Glisse 				R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
760771fe6b9SJerome Glisse 				R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
761771fe6b9SJerome Glisse 				R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
762771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
763771fe6b9SJerome Glisse 
764771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
765771fe6b9SJerome Glisse 			tmp |= RADEON_SCLK_MORE_FORCEON;
766771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
767771fe6b9SJerome Glisse 
768771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
769771fe6b9SJerome Glisse 			tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
770771fe6b9SJerome Glisse 				 RADEON_PIXCLK_DAC_ALWAYS_ONb |
771771fe6b9SJerome Glisse 				 R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
772771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
773771fe6b9SJerome Glisse 
774771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
775771fe6b9SJerome Glisse 			tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
776771fe6b9SJerome Glisse 				 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
777771fe6b9SJerome Glisse 				 RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
778771fe6b9SJerome Glisse 				 R300_DVOCLK_ALWAYS_ONb |
779771fe6b9SJerome Glisse 				 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
780771fe6b9SJerome Glisse 				 RADEON_PIXCLK_GV_ALWAYS_ONb |
781771fe6b9SJerome Glisse 				 R300_PIXCLK_DVO_ALWAYS_ONb |
782771fe6b9SJerome Glisse 				 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
783771fe6b9SJerome Glisse 				 RADEON_PIXCLK_TMDS_ALWAYS_ONb |
784771fe6b9SJerome Glisse 				 R300_PIXCLK_TRANS_ALWAYS_ONb |
785771fe6b9SJerome Glisse 				 R300_PIXCLK_TVO_ALWAYS_ONb |
786771fe6b9SJerome Glisse 				 R300_P2G2CLK_ALWAYS_ONb |
787aa96e341SRoel Kluin 				 R300_P2G2CLK_DAC_ALWAYS_ONb |
788771fe6b9SJerome Glisse 				 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
789771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
790771fe6b9SJerome Glisse 		} else if (rdev->family >= CHIP_RV350) {
791771fe6b9SJerome Glisse 			/* for RV350/M10, no delays are required. */
792771fe6b9SJerome Glisse 			tmp = RREG32_PLL(R300_SCLK_CNTL2);
793771fe6b9SJerome Glisse 			tmp |= (R300_SCLK_FORCE_TCL |
794771fe6b9SJerome Glisse 				R300_SCLK_FORCE_GA | R300_SCLK_FORCE_CBA);
795771fe6b9SJerome Glisse 			WREG32_PLL(R300_SCLK_CNTL2, tmp);
796771fe6b9SJerome Glisse 
797771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
798771fe6b9SJerome Glisse 			tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
799771fe6b9SJerome Glisse 				RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1
800771fe6b9SJerome Glisse 				| RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
801771fe6b9SJerome Glisse 				R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
802771fe6b9SJerome Glisse 				RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
803771fe6b9SJerome Glisse 				R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
804771fe6b9SJerome Glisse 				R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
805771fe6b9SJerome Glisse 				R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
806771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
807771fe6b9SJerome Glisse 
808771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
809771fe6b9SJerome Glisse 			tmp |= RADEON_SCLK_MORE_FORCEON;
810771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
811771fe6b9SJerome Glisse 
812771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_MCLK_CNTL);
813771fe6b9SJerome Glisse 			tmp |= (RADEON_FORCEON_MCLKA |
814771fe6b9SJerome Glisse 				RADEON_FORCEON_MCLKB |
815771fe6b9SJerome Glisse 				RADEON_FORCEON_YCLKA |
816771fe6b9SJerome Glisse 				RADEON_FORCEON_YCLKB | RADEON_FORCEON_MC);
817771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_MCLK_CNTL, tmp);
818771fe6b9SJerome Glisse 
819771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
820771fe6b9SJerome Glisse 			tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
821771fe6b9SJerome Glisse 				 RADEON_PIXCLK_DAC_ALWAYS_ONb |
822771fe6b9SJerome Glisse 				 R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
823771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
824771fe6b9SJerome Glisse 
825771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
826771fe6b9SJerome Glisse 			tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
827771fe6b9SJerome Glisse 				 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
828771fe6b9SJerome Glisse 				 RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
829771fe6b9SJerome Glisse 				 R300_DVOCLK_ALWAYS_ONb |
830771fe6b9SJerome Glisse 				 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
831771fe6b9SJerome Glisse 				 RADEON_PIXCLK_GV_ALWAYS_ONb |
832771fe6b9SJerome Glisse 				 R300_PIXCLK_DVO_ALWAYS_ONb |
833771fe6b9SJerome Glisse 				 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
834771fe6b9SJerome Glisse 				 RADEON_PIXCLK_TMDS_ALWAYS_ONb |
835771fe6b9SJerome Glisse 				 R300_PIXCLK_TRANS_ALWAYS_ONb |
836771fe6b9SJerome Glisse 				 R300_PIXCLK_TVO_ALWAYS_ONb |
837771fe6b9SJerome Glisse 				 R300_P2G2CLK_ALWAYS_ONb |
838aa96e341SRoel Kluin 				 R300_P2G2CLK_DAC_ALWAYS_ONb |
839771fe6b9SJerome Glisse 				 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
840771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
841771fe6b9SJerome Glisse 		} else {
842771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
843771fe6b9SJerome Glisse 			tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2);
844771fe6b9SJerome Glisse 			tmp |= RADEON_SCLK_FORCE_SE;
845771fe6b9SJerome Glisse 
846771fe6b9SJerome Glisse 			if (rdev->flags & RADEON_SINGLE_CRTC) {
847771fe6b9SJerome Glisse 				tmp |= (RADEON_SCLK_FORCE_RB |
848771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_TDM |
849771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_TAM |
850771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_PB |
851771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_RE |
852771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_VIP |
853771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_IDCT |
854771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_TOP |
855771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_DISP1 |
856771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_DISP2 |
857771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_HDP);
858771fe6b9SJerome Glisse 			} else if ((rdev->family == CHIP_R300) ||
859771fe6b9SJerome Glisse 				   (rdev->family == CHIP_R350)) {
860771fe6b9SJerome Glisse 				tmp |= (RADEON_SCLK_FORCE_HDP |
861771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_DISP1 |
862771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_DISP2 |
863771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_TOP |
864771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_IDCT |
865771fe6b9SJerome Glisse 					RADEON_SCLK_FORCE_VIP);
866771fe6b9SJerome Glisse 			}
867771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
868771fe6b9SJerome Glisse 
8694de833c3SArnd Bergmann 			mdelay(16);
870771fe6b9SJerome Glisse 
871771fe6b9SJerome Glisse 			if ((rdev->family == CHIP_R300) ||
872771fe6b9SJerome Glisse 			    (rdev->family == CHIP_R350)) {
873771fe6b9SJerome Glisse 				tmp = RREG32_PLL(R300_SCLK_CNTL2);
874771fe6b9SJerome Glisse 				tmp |= (R300_SCLK_FORCE_TCL |
875771fe6b9SJerome Glisse 					R300_SCLK_FORCE_GA |
876771fe6b9SJerome Glisse 					R300_SCLK_FORCE_CBA);
877771fe6b9SJerome Glisse 				WREG32_PLL(R300_SCLK_CNTL2, tmp);
8784de833c3SArnd Bergmann 				mdelay(16);
879771fe6b9SJerome Glisse 			}
880771fe6b9SJerome Glisse 
881771fe6b9SJerome Glisse 			if (rdev->flags & RADEON_IS_IGP) {
882771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_MCLK_CNTL);
883771fe6b9SJerome Glisse 				tmp &= ~(RADEON_FORCEON_MCLKA |
884771fe6b9SJerome Glisse 					 RADEON_FORCEON_YCLKA);
885771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_MCLK_CNTL, tmp);
8864de833c3SArnd Bergmann 				mdelay(16);
887771fe6b9SJerome Glisse 			}
888771fe6b9SJerome Glisse 
889771fe6b9SJerome Glisse 			if ((rdev->family == CHIP_RV200) ||
890771fe6b9SJerome Glisse 			    (rdev->family == CHIP_RV250) ||
891771fe6b9SJerome Glisse 			    (rdev->family == CHIP_RV280)) {
892771fe6b9SJerome Glisse 				tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
893771fe6b9SJerome Glisse 				tmp |= RADEON_SCLK_MORE_FORCEON;
894771fe6b9SJerome Glisse 				WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
8954de833c3SArnd Bergmann 				mdelay(16);
896771fe6b9SJerome Glisse 			}
897771fe6b9SJerome Glisse 
898771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
899771fe6b9SJerome Glisse 			tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
900771fe6b9SJerome Glisse 				 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
901771fe6b9SJerome Glisse 				 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
902771fe6b9SJerome Glisse 				 RADEON_PIXCLK_GV_ALWAYS_ONb |
903771fe6b9SJerome Glisse 				 RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
904771fe6b9SJerome Glisse 				 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
905771fe6b9SJerome Glisse 				 RADEON_PIXCLK_TMDS_ALWAYS_ONb);
906771fe6b9SJerome Glisse 
907771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
9084de833c3SArnd Bergmann 			mdelay(16);
909771fe6b9SJerome Glisse 
910771fe6b9SJerome Glisse 			tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
911771fe6b9SJerome Glisse 			tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
912771fe6b9SJerome Glisse 				 RADEON_PIXCLK_DAC_ALWAYS_ONb);
913771fe6b9SJerome Glisse 			WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
914771fe6b9SJerome Glisse 		}
915771fe6b9SJerome Glisse 	}
916771fe6b9SJerome Glisse }
917771fe6b9SJerome Glisse 
918