xref: /dflybsd-src/sys/dev/drm/radeon/radeon_clocks.c (revision a85cb24f18e3804e75ab8bcda7692564d0563317)
1926deccbSFrançois Tigeot /*
2926deccbSFrançois Tigeot  * Copyright 2008 Advanced Micro Devices, Inc.
3926deccbSFrançois Tigeot  * Copyright 2008 Red Hat Inc.
4926deccbSFrançois Tigeot  * Copyright 2009 Jerome Glisse.
5926deccbSFrançois Tigeot  *
6926deccbSFrançois Tigeot  * Permission is hereby granted, free of charge, to any person obtaining a
7926deccbSFrançois Tigeot  * copy of this software and associated documentation files (the "Software"),
8926deccbSFrançois Tigeot  * to deal in the Software without restriction, including without limitation
9926deccbSFrançois Tigeot  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10926deccbSFrançois Tigeot  * and/or sell copies of the Software, and to permit persons to whom the
11926deccbSFrançois Tigeot  * Software is furnished to do so, subject to the following conditions:
12926deccbSFrançois Tigeot  *
13926deccbSFrançois Tigeot  * The above copyright notice and this permission notice shall be included in
14926deccbSFrançois Tigeot  * all copies or substantial portions of the Software.
15926deccbSFrançois Tigeot  *
16926deccbSFrançois Tigeot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17926deccbSFrançois Tigeot  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18926deccbSFrançois Tigeot  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19926deccbSFrançois Tigeot  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20926deccbSFrançois Tigeot  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21926deccbSFrançois Tigeot  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22926deccbSFrançois Tigeot  * OTHER DEALINGS IN THE SOFTWARE.
23926deccbSFrançois Tigeot  *
24926deccbSFrançois Tigeot  * Authors: Dave Airlie
25926deccbSFrançois Tigeot  *          Alex Deucher
26926deccbSFrançois Tigeot  *          Jerome Glisse
27926deccbSFrançois Tigeot  */
28926deccbSFrançois Tigeot #include <drm/drmP.h>
2983b4b9b9SFrançois Tigeot #include <drm/radeon_drm.h>
30926deccbSFrançois Tigeot #include "radeon_reg.h"
31926deccbSFrançois Tigeot #include "radeon.h"
32926deccbSFrançois Tigeot #include "radeon_asic.h"
33926deccbSFrançois Tigeot #include "atom.h"
34926deccbSFrançois Tigeot 
35926deccbSFrançois Tigeot /* 10 khz */
radeon_legacy_get_engine_clock(struct radeon_device * rdev)36926deccbSFrançois Tigeot uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
37926deccbSFrançois Tigeot {
38926deccbSFrançois Tigeot 	struct radeon_pll *spll = &rdev->clock.spll;
39926deccbSFrançois Tigeot 	uint32_t fb_div, ref_div, post_div, sclk;
40926deccbSFrançois Tigeot 
41926deccbSFrançois Tigeot 	fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
42926deccbSFrançois Tigeot 	fb_div = (fb_div >> RADEON_SPLL_FB_DIV_SHIFT) & RADEON_SPLL_FB_DIV_MASK;
43926deccbSFrançois Tigeot 	fb_div <<= 1;
44926deccbSFrançois Tigeot 	fb_div *= spll->reference_freq;
45926deccbSFrançois Tigeot 
46926deccbSFrançois Tigeot 	ref_div =
47926deccbSFrançois Tigeot 	    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
48926deccbSFrançois Tigeot 
49926deccbSFrançois Tigeot 	if (ref_div == 0)
50926deccbSFrançois Tigeot 		return 0;
51926deccbSFrançois Tigeot 
52926deccbSFrançois Tigeot 	sclk = fb_div / ref_div;
53926deccbSFrançois Tigeot 
54926deccbSFrançois Tigeot 	post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK;
55926deccbSFrançois Tigeot 	if (post_div == 2)
56926deccbSFrançois Tigeot 		sclk >>= 1;
57926deccbSFrançois Tigeot 	else if (post_div == 3)
58926deccbSFrançois Tigeot 		sclk >>= 2;
59926deccbSFrançois Tigeot 	else if (post_div == 4)
60926deccbSFrançois Tigeot 		sclk >>= 3;
61926deccbSFrançois Tigeot 
62926deccbSFrançois Tigeot 	return sclk;
63926deccbSFrançois Tigeot }
64926deccbSFrançois Tigeot 
65926deccbSFrançois Tigeot /* 10 khz */
radeon_legacy_get_memory_clock(struct radeon_device * rdev)66926deccbSFrançois Tigeot uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
67926deccbSFrançois Tigeot {
68926deccbSFrançois Tigeot 	struct radeon_pll *mpll = &rdev->clock.mpll;
69926deccbSFrançois Tigeot 	uint32_t fb_div, ref_div, post_div, mclk;
70926deccbSFrançois Tigeot 
71926deccbSFrançois Tigeot 	fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
72926deccbSFrançois Tigeot 	fb_div = (fb_div >> RADEON_MPLL_FB_DIV_SHIFT) & RADEON_MPLL_FB_DIV_MASK;
73926deccbSFrançois Tigeot 	fb_div <<= 1;
74926deccbSFrançois Tigeot 	fb_div *= mpll->reference_freq;
75926deccbSFrançois Tigeot 
76926deccbSFrançois Tigeot 	ref_div =
77926deccbSFrançois Tigeot 	    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
78926deccbSFrançois Tigeot 
79926deccbSFrançois Tigeot 	if (ref_div == 0)
80926deccbSFrançois Tigeot 		return 0;
81926deccbSFrançois Tigeot 
82926deccbSFrançois Tigeot 	mclk = fb_div / ref_div;
83926deccbSFrançois Tigeot 
84926deccbSFrançois Tigeot 	post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7;
85926deccbSFrançois Tigeot 	if (post_div == 2)
86926deccbSFrançois Tigeot 		mclk >>= 1;
87926deccbSFrançois Tigeot 	else if (post_div == 3)
88926deccbSFrançois Tigeot 		mclk >>= 2;
89926deccbSFrançois Tigeot 	else if (post_div == 4)
90926deccbSFrançois Tigeot 		mclk >>= 3;
91926deccbSFrançois Tigeot 
92926deccbSFrançois Tigeot 	return mclk;
93926deccbSFrançois Tigeot }
94926deccbSFrançois Tigeot 
95926deccbSFrançois Tigeot #ifdef CONFIG_OF
96926deccbSFrançois Tigeot /*
97926deccbSFrançois Tigeot  * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device
98926deccbSFrançois Tigeot  * tree. Hopefully, ATI OF driver is kind enough to fill these
99926deccbSFrançois Tigeot  */
radeon_read_clocks_OF(struct drm_device * dev)100926deccbSFrançois Tigeot static bool radeon_read_clocks_OF(struct drm_device *dev)
101926deccbSFrançois Tigeot {
102926deccbSFrançois Tigeot 	struct radeon_device *rdev = dev->dev_private;
103926deccbSFrançois Tigeot 	struct device_node *dp = rdev->pdev->dev.of_node;
104926deccbSFrançois Tigeot 	const u32 *val;
105926deccbSFrançois Tigeot 	struct radeon_pll *p1pll = &rdev->clock.p1pll;
106926deccbSFrançois Tigeot 	struct radeon_pll *p2pll = &rdev->clock.p2pll;
107926deccbSFrançois Tigeot 	struct radeon_pll *spll = &rdev->clock.spll;
108926deccbSFrançois Tigeot 	struct radeon_pll *mpll = &rdev->clock.mpll;
109926deccbSFrançois Tigeot 
110926deccbSFrançois Tigeot 	if (dp == NULL)
111926deccbSFrançois Tigeot 		return false;
112926deccbSFrançois Tigeot 	val = of_get_property(dp, "ATY,RefCLK", NULL);
113926deccbSFrançois Tigeot 	if (!val || !*val) {
114*a85cb24fSFrançois Tigeot 		pr_warn("radeonfb: No ATY,RefCLK property !\n");
115926deccbSFrançois Tigeot 		return false;
116926deccbSFrançois Tigeot 	}
117926deccbSFrançois Tigeot 	p1pll->reference_freq = p2pll->reference_freq = (*val) / 10;
118926deccbSFrançois Tigeot 	p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
119926deccbSFrançois Tigeot 	if (p1pll->reference_div < 2)
120926deccbSFrançois Tigeot 		p1pll->reference_div = 12;
121926deccbSFrançois Tigeot 	p2pll->reference_div = p1pll->reference_div;
122926deccbSFrançois Tigeot 
123926deccbSFrançois Tigeot 	/* These aren't in the device-tree */
124926deccbSFrançois Tigeot 	if (rdev->family >= CHIP_R420) {
125926deccbSFrançois Tigeot 		p1pll->pll_in_min = 100;
126926deccbSFrançois Tigeot 		p1pll->pll_in_max = 1350;
127926deccbSFrançois Tigeot 		p1pll->pll_out_min = 20000;
128926deccbSFrançois Tigeot 		p1pll->pll_out_max = 50000;
129926deccbSFrançois Tigeot 		p2pll->pll_in_min = 100;
130926deccbSFrançois Tigeot 		p2pll->pll_in_max = 1350;
131926deccbSFrançois Tigeot 		p2pll->pll_out_min = 20000;
132926deccbSFrançois Tigeot 		p2pll->pll_out_max = 50000;
133926deccbSFrançois Tigeot 	} else {
134926deccbSFrançois Tigeot 		p1pll->pll_in_min = 40;
135926deccbSFrançois Tigeot 		p1pll->pll_in_max = 500;
136926deccbSFrançois Tigeot 		p1pll->pll_out_min = 12500;
137926deccbSFrançois Tigeot 		p1pll->pll_out_max = 35000;
138926deccbSFrançois Tigeot 		p2pll->pll_in_min = 40;
139926deccbSFrançois Tigeot 		p2pll->pll_in_max = 500;
140926deccbSFrançois Tigeot 		p2pll->pll_out_min = 12500;
141926deccbSFrançois Tigeot 		p2pll->pll_out_max = 35000;
142926deccbSFrançois Tigeot 	}
143926deccbSFrançois Tigeot 	/* not sure what the max should be in all cases */
144926deccbSFrançois Tigeot 	rdev->clock.max_pixel_clock = 35000;
145926deccbSFrançois Tigeot 
146926deccbSFrançois Tigeot 	spll->reference_freq = mpll->reference_freq = p1pll->reference_freq;
147926deccbSFrançois Tigeot 	spll->reference_div = mpll->reference_div =
148926deccbSFrançois Tigeot 		RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
149926deccbSFrançois Tigeot 			    RADEON_M_SPLL_REF_DIV_MASK;
150926deccbSFrançois Tigeot 
151926deccbSFrançois Tigeot 	val = of_get_property(dp, "ATY,SCLK", NULL);
152926deccbSFrançois Tigeot 	if (val && *val)
153926deccbSFrançois Tigeot 		rdev->clock.default_sclk = (*val) / 10;
154926deccbSFrançois Tigeot 	else
155926deccbSFrançois Tigeot 		rdev->clock.default_sclk =
156926deccbSFrançois Tigeot 			radeon_legacy_get_engine_clock(rdev);
157926deccbSFrançois Tigeot 
158926deccbSFrançois Tigeot 	val = of_get_property(dp, "ATY,MCLK", NULL);
159926deccbSFrançois Tigeot 	if (val && *val)
160926deccbSFrançois Tigeot 		rdev->clock.default_mclk = (*val) / 10;
161926deccbSFrançois Tigeot 	else
162926deccbSFrançois Tigeot 		rdev->clock.default_mclk =
163926deccbSFrançois Tigeot 			radeon_legacy_get_memory_clock(rdev);
164926deccbSFrançois Tigeot 
165926deccbSFrançois Tigeot 	DRM_INFO("Using device-tree clock info\n");
166926deccbSFrançois Tigeot 
167926deccbSFrançois Tigeot 	return true;
168926deccbSFrançois Tigeot }
169926deccbSFrançois Tigeot #else
radeon_read_clocks_OF(struct drm_device * dev)170926deccbSFrançois Tigeot static bool radeon_read_clocks_OF(struct drm_device *dev)
171926deccbSFrançois Tigeot {
172926deccbSFrançois Tigeot 	return false;
173926deccbSFrançois Tigeot }
174926deccbSFrançois Tigeot #endif /* CONFIG_OF */
175926deccbSFrançois Tigeot 
radeon_get_clock_info(struct drm_device * dev)176926deccbSFrançois Tigeot void radeon_get_clock_info(struct drm_device *dev)
177926deccbSFrançois Tigeot {
178926deccbSFrançois Tigeot 	struct radeon_device *rdev = dev->dev_private;
179926deccbSFrançois Tigeot 	struct radeon_pll *p1pll = &rdev->clock.p1pll;
180926deccbSFrançois Tigeot 	struct radeon_pll *p2pll = &rdev->clock.p2pll;
181926deccbSFrançois Tigeot 	struct radeon_pll *dcpll = &rdev->clock.dcpll;
182926deccbSFrançois Tigeot 	struct radeon_pll *spll = &rdev->clock.spll;
183926deccbSFrançois Tigeot 	struct radeon_pll *mpll = &rdev->clock.mpll;
184926deccbSFrançois Tigeot 	int ret;
185926deccbSFrançois Tigeot 
186926deccbSFrançois Tigeot 	if (rdev->is_atom_bios)
187926deccbSFrançois Tigeot 		ret = radeon_atom_get_clock_info(dev);
188926deccbSFrançois Tigeot 	else
189926deccbSFrançois Tigeot 		ret = radeon_combios_get_clock_info(dev);
190926deccbSFrançois Tigeot 	if (!ret)
191926deccbSFrançois Tigeot 		ret = radeon_read_clocks_OF(dev);
192926deccbSFrançois Tigeot 
193926deccbSFrançois Tigeot 	if (ret) {
194926deccbSFrançois Tigeot 		if (p1pll->reference_div < 2) {
195926deccbSFrançois Tigeot 			if (!ASIC_IS_AVIVO(rdev)) {
196926deccbSFrançois Tigeot 				u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV);
197926deccbSFrançois Tigeot 				if (ASIC_IS_R300(rdev))
198926deccbSFrançois Tigeot 					p1pll->reference_div =
199926deccbSFrançois Tigeot 						(tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
200926deccbSFrançois Tigeot 				else
201926deccbSFrançois Tigeot 					p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
202926deccbSFrançois Tigeot 				if (p1pll->reference_div < 2)
203926deccbSFrançois Tigeot 					p1pll->reference_div = 12;
204926deccbSFrançois Tigeot 			} else
205926deccbSFrançois Tigeot 				p1pll->reference_div = 12;
206926deccbSFrançois Tigeot 		}
207926deccbSFrançois Tigeot 		if (p2pll->reference_div < 2)
208926deccbSFrançois Tigeot 			p2pll->reference_div = 12;
209926deccbSFrançois Tigeot 		if (rdev->family < CHIP_RS600) {
210926deccbSFrançois Tigeot 			if (spll->reference_div < 2)
211926deccbSFrançois Tigeot 				spll->reference_div =
212926deccbSFrançois Tigeot 					RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
213926deccbSFrançois Tigeot 					RADEON_M_SPLL_REF_DIV_MASK;
214926deccbSFrançois Tigeot 		}
215926deccbSFrançois Tigeot 		if (mpll->reference_div < 2)
216926deccbSFrançois Tigeot 			mpll->reference_div = spll->reference_div;
217926deccbSFrançois Tigeot 	} else {
218926deccbSFrançois Tigeot 		if (ASIC_IS_AVIVO(rdev)) {
219926deccbSFrançois Tigeot 			/* TODO FALLBACK */
220926deccbSFrançois Tigeot 		} else {
221926deccbSFrançois Tigeot 			DRM_INFO("Using generic clock info\n");
222926deccbSFrançois Tigeot 
223926deccbSFrançois Tigeot 			/* may need to be per card */
224926deccbSFrançois Tigeot 			rdev->clock.max_pixel_clock = 35000;
225926deccbSFrançois Tigeot 
226926deccbSFrançois Tigeot 			if (rdev->flags & RADEON_IS_IGP) {
227926deccbSFrançois Tigeot 				p1pll->reference_freq = 1432;
228926deccbSFrançois Tigeot 				p2pll->reference_freq = 1432;
229926deccbSFrançois Tigeot 				spll->reference_freq = 1432;
230926deccbSFrançois Tigeot 				mpll->reference_freq = 1432;
231926deccbSFrançois Tigeot 			} else {
232926deccbSFrançois Tigeot 				p1pll->reference_freq = 2700;
233926deccbSFrançois Tigeot 				p2pll->reference_freq = 2700;
234926deccbSFrançois Tigeot 				spll->reference_freq = 2700;
235926deccbSFrançois Tigeot 				mpll->reference_freq = 2700;
236926deccbSFrançois Tigeot 			}
237926deccbSFrançois Tigeot 			p1pll->reference_div =
238926deccbSFrançois Tigeot 			    RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
239926deccbSFrançois Tigeot 			if (p1pll->reference_div < 2)
240926deccbSFrançois Tigeot 				p1pll->reference_div = 12;
241926deccbSFrançois Tigeot 			p2pll->reference_div = p1pll->reference_div;
242926deccbSFrançois Tigeot 
243926deccbSFrançois Tigeot 			if (rdev->family >= CHIP_R420) {
244926deccbSFrançois Tigeot 				p1pll->pll_in_min = 100;
245926deccbSFrançois Tigeot 				p1pll->pll_in_max = 1350;
246926deccbSFrançois Tigeot 				p1pll->pll_out_min = 20000;
247926deccbSFrançois Tigeot 				p1pll->pll_out_max = 50000;
248926deccbSFrançois Tigeot 				p2pll->pll_in_min = 100;
249926deccbSFrançois Tigeot 				p2pll->pll_in_max = 1350;
250926deccbSFrançois Tigeot 				p2pll->pll_out_min = 20000;
251926deccbSFrançois Tigeot 				p2pll->pll_out_max = 50000;
252926deccbSFrançois Tigeot 			} else {
253926deccbSFrançois Tigeot 				p1pll->pll_in_min = 40;
254926deccbSFrançois Tigeot 				p1pll->pll_in_max = 500;
255926deccbSFrançois Tigeot 				p1pll->pll_out_min = 12500;
256926deccbSFrançois Tigeot 				p1pll->pll_out_max = 35000;
257926deccbSFrançois Tigeot 				p2pll->pll_in_min = 40;
258926deccbSFrançois Tigeot 				p2pll->pll_in_max = 500;
259926deccbSFrançois Tigeot 				p2pll->pll_out_min = 12500;
260926deccbSFrançois Tigeot 				p2pll->pll_out_max = 35000;
261926deccbSFrançois Tigeot 			}
262926deccbSFrançois Tigeot 
263926deccbSFrançois Tigeot 			spll->reference_div =
264926deccbSFrançois Tigeot 			    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
265926deccbSFrançois Tigeot 			    RADEON_M_SPLL_REF_DIV_MASK;
266926deccbSFrançois Tigeot 			mpll->reference_div = spll->reference_div;
267926deccbSFrançois Tigeot 			rdev->clock.default_sclk =
268926deccbSFrançois Tigeot 			    radeon_legacy_get_engine_clock(rdev);
269926deccbSFrançois Tigeot 			rdev->clock.default_mclk =
270926deccbSFrançois Tigeot 			    radeon_legacy_get_memory_clock(rdev);
271926deccbSFrançois Tigeot 		}
272926deccbSFrançois Tigeot 	}
273926deccbSFrançois Tigeot 
274926deccbSFrançois Tigeot 	/* pixel clocks */
275926deccbSFrançois Tigeot 	if (ASIC_IS_AVIVO(rdev)) {
276926deccbSFrançois Tigeot 		p1pll->min_post_div = 2;
277926deccbSFrançois Tigeot 		p1pll->max_post_div = 0x7f;
278926deccbSFrançois Tigeot 		p1pll->min_frac_feedback_div = 0;
279926deccbSFrançois Tigeot 		p1pll->max_frac_feedback_div = 9;
280926deccbSFrançois Tigeot 		p2pll->min_post_div = 2;
281926deccbSFrançois Tigeot 		p2pll->max_post_div = 0x7f;
282926deccbSFrançois Tigeot 		p2pll->min_frac_feedback_div = 0;
283926deccbSFrançois Tigeot 		p2pll->max_frac_feedback_div = 9;
284926deccbSFrançois Tigeot 	} else {
285926deccbSFrançois Tigeot 		p1pll->min_post_div = 1;
286926deccbSFrançois Tigeot 		p1pll->max_post_div = 16;
287926deccbSFrançois Tigeot 		p1pll->min_frac_feedback_div = 0;
288926deccbSFrançois Tigeot 		p1pll->max_frac_feedback_div = 0;
289926deccbSFrançois Tigeot 		p2pll->min_post_div = 1;
290926deccbSFrançois Tigeot 		p2pll->max_post_div = 12;
291926deccbSFrançois Tigeot 		p2pll->min_frac_feedback_div = 0;
292926deccbSFrançois Tigeot 		p2pll->max_frac_feedback_div = 0;
293926deccbSFrançois Tigeot 	}
294926deccbSFrançois Tigeot 
295926deccbSFrançois Tigeot 	/* dcpll is DCE4 only */
296926deccbSFrançois Tigeot 	dcpll->min_post_div = 2;
297926deccbSFrançois Tigeot 	dcpll->max_post_div = 0x7f;
298926deccbSFrançois Tigeot 	dcpll->min_frac_feedback_div = 0;
299926deccbSFrançois Tigeot 	dcpll->max_frac_feedback_div = 9;
300926deccbSFrançois Tigeot 	dcpll->min_ref_div = 2;
301926deccbSFrançois Tigeot 	dcpll->max_ref_div = 0x3ff;
302926deccbSFrançois Tigeot 	dcpll->min_feedback_div = 4;
303926deccbSFrançois Tigeot 	dcpll->max_feedback_div = 0xfff;
304926deccbSFrançois Tigeot 	dcpll->best_vco = 0;
305926deccbSFrançois Tigeot 
306926deccbSFrançois Tigeot 	p1pll->min_ref_div = 2;
307926deccbSFrançois Tigeot 	p1pll->max_ref_div = 0x3ff;
308926deccbSFrançois Tigeot 	p1pll->min_feedback_div = 4;
309926deccbSFrançois Tigeot 	p1pll->max_feedback_div = 0x7ff;
310926deccbSFrançois Tigeot 	p1pll->best_vco = 0;
311926deccbSFrançois Tigeot 
312926deccbSFrançois Tigeot 	p2pll->min_ref_div = 2;
313926deccbSFrançois Tigeot 	p2pll->max_ref_div = 0x3ff;
314926deccbSFrançois Tigeot 	p2pll->min_feedback_div = 4;
315926deccbSFrançois Tigeot 	p2pll->max_feedback_div = 0x7ff;
316926deccbSFrançois Tigeot 	p2pll->best_vco = 0;
317926deccbSFrançois Tigeot 
318926deccbSFrançois Tigeot 	/* system clock */
319926deccbSFrançois Tigeot 	spll->min_post_div = 1;
320926deccbSFrançois Tigeot 	spll->max_post_div = 1;
321926deccbSFrançois Tigeot 	spll->min_ref_div = 2;
322926deccbSFrançois Tigeot 	spll->max_ref_div = 0xff;
323926deccbSFrançois Tigeot 	spll->min_feedback_div = 4;
324926deccbSFrançois Tigeot 	spll->max_feedback_div = 0xff;
325926deccbSFrançois Tigeot 	spll->best_vco = 0;
326926deccbSFrançois Tigeot 
327926deccbSFrançois Tigeot 	/* memory clock */
328926deccbSFrançois Tigeot 	mpll->min_post_div = 1;
329926deccbSFrançois Tigeot 	mpll->max_post_div = 1;
330926deccbSFrançois Tigeot 	mpll->min_ref_div = 2;
331926deccbSFrançois Tigeot 	mpll->max_ref_div = 0xff;
332926deccbSFrançois Tigeot 	mpll->min_feedback_div = 4;
333926deccbSFrançois Tigeot 	mpll->max_feedback_div = 0xff;
334926deccbSFrançois Tigeot 	mpll->best_vco = 0;
335926deccbSFrançois Tigeot 
336926deccbSFrançois Tigeot 	if (!rdev->clock.default_sclk)
337926deccbSFrançois Tigeot 		rdev->clock.default_sclk = radeon_get_engine_clock(rdev);
338926deccbSFrançois Tigeot 	if ((!rdev->clock.default_mclk) && rdev->asic->pm.get_memory_clock)
339926deccbSFrançois Tigeot 		rdev->clock.default_mclk = radeon_get_memory_clock(rdev);
340926deccbSFrançois Tigeot 
341926deccbSFrançois Tigeot 	rdev->pm.current_sclk = rdev->clock.default_sclk;
342926deccbSFrançois Tigeot 	rdev->pm.current_mclk = rdev->clock.default_mclk;
343926deccbSFrançois Tigeot 
344926deccbSFrançois Tigeot }
345926deccbSFrançois Tigeot 
346926deccbSFrançois Tigeot /* 10 khz */
calc_eng_mem_clock(struct radeon_device * rdev,uint32_t req_clock,int * fb_div,int * post_div)347926deccbSFrançois Tigeot static uint32_t calc_eng_mem_clock(struct radeon_device *rdev,
348926deccbSFrançois Tigeot 				   uint32_t req_clock,
349926deccbSFrançois Tigeot 				   int *fb_div, int *post_div)
350926deccbSFrançois Tigeot {
351926deccbSFrançois Tigeot 	struct radeon_pll *spll = &rdev->clock.spll;
352926deccbSFrançois Tigeot 	int ref_div = spll->reference_div;
353926deccbSFrançois Tigeot 
354926deccbSFrançois Tigeot 	if (!ref_div)
355926deccbSFrançois Tigeot 		ref_div =
356926deccbSFrançois Tigeot 		    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
357926deccbSFrançois Tigeot 		    RADEON_M_SPLL_REF_DIV_MASK;
358926deccbSFrançois Tigeot 
359926deccbSFrançois Tigeot 	if (req_clock < 15000) {
360926deccbSFrançois Tigeot 		*post_div = 8;
361926deccbSFrançois Tigeot 		req_clock *= 8;
362926deccbSFrançois Tigeot 	} else if (req_clock < 30000) {
363926deccbSFrançois Tigeot 		*post_div = 4;
364926deccbSFrançois Tigeot 		req_clock *= 4;
365926deccbSFrançois Tigeot 	} else if (req_clock < 60000) {
366926deccbSFrançois Tigeot 		*post_div = 2;
367926deccbSFrançois Tigeot 		req_clock *= 2;
368926deccbSFrançois Tigeot 	} else
369926deccbSFrançois Tigeot 		*post_div = 1;
370926deccbSFrançois Tigeot 
371926deccbSFrançois Tigeot 	req_clock *= ref_div;
372926deccbSFrançois Tigeot 	req_clock += spll->reference_freq;
373926deccbSFrançois Tigeot 	req_clock /= (2 * spll->reference_freq);
374926deccbSFrançois Tigeot 
375926deccbSFrançois Tigeot 	*fb_div = req_clock & 0xff;
376926deccbSFrançois Tigeot 
377926deccbSFrançois Tigeot 	req_clock = (req_clock & 0xffff) << 1;
378926deccbSFrançois Tigeot 	req_clock *= spll->reference_freq;
379926deccbSFrançois Tigeot 	req_clock /= ref_div;
380926deccbSFrançois Tigeot 	req_clock /= *post_div;
381926deccbSFrançois Tigeot 
382926deccbSFrançois Tigeot 	return req_clock;
383926deccbSFrançois Tigeot }
384926deccbSFrançois Tigeot 
385926deccbSFrançois Tigeot /* 10 khz */
radeon_legacy_set_engine_clock(struct radeon_device * rdev,uint32_t eng_clock)386926deccbSFrançois Tigeot void radeon_legacy_set_engine_clock(struct radeon_device *rdev,
387926deccbSFrançois Tigeot 				    uint32_t eng_clock)
388926deccbSFrançois Tigeot {
389926deccbSFrançois Tigeot 	uint32_t tmp;
390926deccbSFrançois Tigeot 	int fb_div, post_div;
391926deccbSFrançois Tigeot 
392926deccbSFrançois Tigeot 	/* XXX: wait for idle */
393926deccbSFrançois Tigeot 
394926deccbSFrançois Tigeot 	eng_clock = calc_eng_mem_clock(rdev, eng_clock, &fb_div, &post_div);
395926deccbSFrançois Tigeot 
396926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
397926deccbSFrançois Tigeot 	tmp &= ~RADEON_DONT_USE_XTALIN;
398926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
399926deccbSFrançois Tigeot 
400926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_SCLK_CNTL);
401926deccbSFrançois Tigeot 	tmp &= ~RADEON_SCLK_SRC_SEL_MASK;
402926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_SCLK_CNTL, tmp);
403926deccbSFrançois Tigeot 
404c4ef309bSzrj 	udelay(10);
405926deccbSFrançois Tigeot 
406926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
407926deccbSFrançois Tigeot 	tmp |= RADEON_SPLL_SLEEP;
408926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
409926deccbSFrançois Tigeot 
410c4ef309bSzrj 	udelay(2);
411926deccbSFrançois Tigeot 
412926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
413926deccbSFrançois Tigeot 	tmp |= RADEON_SPLL_RESET;
414926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
415926deccbSFrançois Tigeot 
416c4ef309bSzrj 	udelay(200);
417926deccbSFrançois Tigeot 
418926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
419926deccbSFrançois Tigeot 	tmp &= ~(RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT);
420926deccbSFrançois Tigeot 	tmp |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT;
421926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_M_SPLL_REF_FB_DIV, tmp);
422926deccbSFrançois Tigeot 
423926deccbSFrançois Tigeot 	/* XXX: verify on different asics */
424926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
425926deccbSFrançois Tigeot 	tmp &= ~RADEON_SPLL_PVG_MASK;
426926deccbSFrançois Tigeot 	if ((eng_clock * post_div) >= 90000)
427926deccbSFrançois Tigeot 		tmp |= (0x7 << RADEON_SPLL_PVG_SHIFT);
428926deccbSFrançois Tigeot 	else
429926deccbSFrançois Tigeot 		tmp |= (0x4 << RADEON_SPLL_PVG_SHIFT);
430926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
431926deccbSFrançois Tigeot 
432926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
433926deccbSFrançois Tigeot 	tmp &= ~RADEON_SPLL_SLEEP;
434926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
435926deccbSFrançois Tigeot 
436c4ef309bSzrj 	udelay(2);
437926deccbSFrançois Tigeot 
438926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_SPLL_CNTL);
439926deccbSFrançois Tigeot 	tmp &= ~RADEON_SPLL_RESET;
440926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_SPLL_CNTL, tmp);
441926deccbSFrançois Tigeot 
442c4ef309bSzrj 	udelay(200);
443926deccbSFrançois Tigeot 
444926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_SCLK_CNTL);
445926deccbSFrançois Tigeot 	tmp &= ~RADEON_SCLK_SRC_SEL_MASK;
446926deccbSFrançois Tigeot 	switch (post_div) {
447926deccbSFrançois Tigeot 	case 1:
448926deccbSFrançois Tigeot 	default:
449926deccbSFrançois Tigeot 		tmp |= 1;
450926deccbSFrançois Tigeot 		break;
451926deccbSFrançois Tigeot 	case 2:
452926deccbSFrançois Tigeot 		tmp |= 2;
453926deccbSFrançois Tigeot 		break;
454926deccbSFrançois Tigeot 	case 4:
455926deccbSFrançois Tigeot 		tmp |= 3;
456926deccbSFrançois Tigeot 		break;
457926deccbSFrançois Tigeot 	case 8:
458926deccbSFrançois Tigeot 		tmp |= 4;
459926deccbSFrançois Tigeot 		break;
460926deccbSFrançois Tigeot 	}
461926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_SCLK_CNTL, tmp);
462926deccbSFrançois Tigeot 
463c4ef309bSzrj 	udelay(20);
464926deccbSFrançois Tigeot 
465926deccbSFrançois Tigeot 	tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
466926deccbSFrançois Tigeot 	tmp |= RADEON_DONT_USE_XTALIN;
467926deccbSFrançois Tigeot 	WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
468926deccbSFrançois Tigeot 
469c4ef309bSzrj 	udelay(10);
470926deccbSFrançois Tigeot }
471926deccbSFrançois Tigeot 
radeon_legacy_set_clock_gating(struct radeon_device * rdev,int enable)472926deccbSFrançois Tigeot void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
473926deccbSFrançois Tigeot {
474926deccbSFrançois Tigeot 	uint32_t tmp;
475926deccbSFrançois Tigeot 
476926deccbSFrançois Tigeot 	if (enable) {
477926deccbSFrançois Tigeot 		if (rdev->flags & RADEON_SINGLE_CRTC) {
478926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
479926deccbSFrançois Tigeot 			if ((RREG32(RADEON_CONFIG_CNTL) &
480926deccbSFrançois Tigeot 			     RADEON_CFG_ATI_REV_ID_MASK) >
481926deccbSFrançois Tigeot 			    RADEON_CFG_ATI_REV_A13) {
482926deccbSFrançois Tigeot 				tmp &=
483926deccbSFrançois Tigeot 				    ~(RADEON_SCLK_FORCE_CP |
484926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_RB);
485926deccbSFrançois Tigeot 			}
486926deccbSFrançois Tigeot 			tmp &=
487926deccbSFrançois Tigeot 			    ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
488926deccbSFrançois Tigeot 			      RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE |
489926deccbSFrançois Tigeot 			      RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE |
490926deccbSFrançois Tigeot 			      RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM |
491926deccbSFrançois Tigeot 			      RADEON_SCLK_FORCE_TDM);
492926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
493926deccbSFrançois Tigeot 		} else if (ASIC_IS_R300(rdev)) {
494926deccbSFrançois Tigeot 			if ((rdev->family == CHIP_RS400) ||
495926deccbSFrançois Tigeot 			    (rdev->family == CHIP_RS480)) {
496926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_SCLK_CNTL);
497926deccbSFrançois Tigeot 				tmp &=
498926deccbSFrançois Tigeot 				    ~(RADEON_SCLK_FORCE_DISP2 |
499926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_CP |
500926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_HDP |
501926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_DISP1 |
502926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_TOP |
503926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP
504926deccbSFrançois Tigeot 				      | RADEON_SCLK_FORCE_IDCT |
505926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR
506926deccbSFrançois Tigeot 				      | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX
507926deccbSFrançois Tigeot 				      | R300_SCLK_FORCE_US |
508926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_TV_SCLK |
509926deccbSFrançois Tigeot 				      R300_SCLK_FORCE_SU |
510926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_OV0);
511926deccbSFrançois Tigeot 				tmp |= RADEON_DYN_STOP_LAT_MASK;
512926deccbSFrançois Tigeot 				tmp |=
513926deccbSFrançois Tigeot 				    RADEON_SCLK_FORCE_TOP |
514926deccbSFrançois Tigeot 				    RADEON_SCLK_FORCE_VIP;
515926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_SCLK_CNTL, tmp);
516926deccbSFrançois Tigeot 
517926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
518926deccbSFrançois Tigeot 				tmp &= ~RADEON_SCLK_MORE_FORCEON;
519926deccbSFrançois Tigeot 				tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
520926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
521926deccbSFrançois Tigeot 
522926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
523926deccbSFrançois Tigeot 				tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
524926deccbSFrançois Tigeot 					RADEON_PIXCLK_DAC_ALWAYS_ONb);
525926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
526926deccbSFrançois Tigeot 
527926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
528926deccbSFrançois Tigeot 				tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
529926deccbSFrançois Tigeot 					RADEON_PIX2CLK_DAC_ALWAYS_ONb |
530926deccbSFrançois Tigeot 					RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
531926deccbSFrançois Tigeot 					R300_DVOCLK_ALWAYS_ONb |
532926deccbSFrançois Tigeot 					RADEON_PIXCLK_BLEND_ALWAYS_ONb |
533926deccbSFrançois Tigeot 					RADEON_PIXCLK_GV_ALWAYS_ONb |
534926deccbSFrançois Tigeot 					R300_PIXCLK_DVO_ALWAYS_ONb |
535926deccbSFrançois Tigeot 					RADEON_PIXCLK_LVDS_ALWAYS_ONb |
536926deccbSFrançois Tigeot 					RADEON_PIXCLK_TMDS_ALWAYS_ONb |
537926deccbSFrançois Tigeot 					R300_PIXCLK_TRANS_ALWAYS_ONb |
538926deccbSFrançois Tigeot 					R300_PIXCLK_TVO_ALWAYS_ONb |
539926deccbSFrançois Tigeot 					R300_P2G2CLK_ALWAYS_ONb |
540926deccbSFrançois Tigeot 					R300_P2G2CLK_DAC_ALWAYS_ONb);
541926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
542926deccbSFrançois Tigeot 			} else if (rdev->family >= CHIP_RV350) {
543926deccbSFrançois Tigeot 				tmp = RREG32_PLL(R300_SCLK_CNTL2);
544926deccbSFrançois Tigeot 				tmp &= ~(R300_SCLK_FORCE_TCL |
545926deccbSFrançois Tigeot 					 R300_SCLK_FORCE_GA |
546926deccbSFrançois Tigeot 					 R300_SCLK_FORCE_CBA);
547926deccbSFrançois Tigeot 				tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT |
548926deccbSFrançois Tigeot 					R300_SCLK_GA_MAX_DYN_STOP_LAT |
549926deccbSFrançois Tigeot 					R300_SCLK_CBA_MAX_DYN_STOP_LAT);
550926deccbSFrançois Tigeot 				WREG32_PLL(R300_SCLK_CNTL2, tmp);
551926deccbSFrançois Tigeot 
552926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_SCLK_CNTL);
553926deccbSFrançois Tigeot 				tmp &=
554926deccbSFrançois Tigeot 				    ~(RADEON_SCLK_FORCE_DISP2 |
555926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_CP |
556926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_HDP |
557926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_DISP1 |
558926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_TOP |
559926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP
560926deccbSFrançois Tigeot 				      | RADEON_SCLK_FORCE_IDCT |
561926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR
562926deccbSFrançois Tigeot 				      | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX
563926deccbSFrançois Tigeot 				      | R300_SCLK_FORCE_US |
564926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_TV_SCLK |
565926deccbSFrançois Tigeot 				      R300_SCLK_FORCE_SU |
566926deccbSFrançois Tigeot 				      RADEON_SCLK_FORCE_OV0);
567926deccbSFrançois Tigeot 				tmp |= RADEON_DYN_STOP_LAT_MASK;
568926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_SCLK_CNTL, tmp);
569926deccbSFrançois Tigeot 
570926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
571926deccbSFrançois Tigeot 				tmp &= ~RADEON_SCLK_MORE_FORCEON;
572926deccbSFrançois Tigeot 				tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
573926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
574926deccbSFrançois Tigeot 
575926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
576926deccbSFrançois Tigeot 				tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
577926deccbSFrançois Tigeot 					RADEON_PIXCLK_DAC_ALWAYS_ONb);
578926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
579926deccbSFrançois Tigeot 
580926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
581926deccbSFrançois Tigeot 				tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
582926deccbSFrançois Tigeot 					RADEON_PIX2CLK_DAC_ALWAYS_ONb |
583926deccbSFrançois Tigeot 					RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
584926deccbSFrançois Tigeot 					R300_DVOCLK_ALWAYS_ONb |
585926deccbSFrançois Tigeot 					RADEON_PIXCLK_BLEND_ALWAYS_ONb |
586926deccbSFrançois Tigeot 					RADEON_PIXCLK_GV_ALWAYS_ONb |
587926deccbSFrançois Tigeot 					R300_PIXCLK_DVO_ALWAYS_ONb |
588926deccbSFrançois Tigeot 					RADEON_PIXCLK_LVDS_ALWAYS_ONb |
589926deccbSFrançois Tigeot 					RADEON_PIXCLK_TMDS_ALWAYS_ONb |
590926deccbSFrançois Tigeot 					R300_PIXCLK_TRANS_ALWAYS_ONb |
591926deccbSFrançois Tigeot 					R300_PIXCLK_TVO_ALWAYS_ONb |
592926deccbSFrançois Tigeot 					R300_P2G2CLK_ALWAYS_ONb |
593926deccbSFrançois Tigeot 					R300_P2G2CLK_DAC_ALWAYS_ONb);
594926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
595926deccbSFrançois Tigeot 
596926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_MCLK_MISC);
597926deccbSFrançois Tigeot 				tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
598926deccbSFrançois Tigeot 					RADEON_IO_MCLK_DYN_ENABLE);
599926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_MCLK_MISC, tmp);
600926deccbSFrançois Tigeot 
601926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_MCLK_CNTL);
602926deccbSFrançois Tigeot 				tmp |= (RADEON_FORCEON_MCLKA |
603926deccbSFrançois Tigeot 					RADEON_FORCEON_MCLKB);
604926deccbSFrançois Tigeot 
605926deccbSFrançois Tigeot 				tmp &= ~(RADEON_FORCEON_YCLKA |
606926deccbSFrançois Tigeot 					 RADEON_FORCEON_YCLKB |
607926deccbSFrançois Tigeot 					 RADEON_FORCEON_MC);
608926deccbSFrançois Tigeot 
609926deccbSFrançois Tigeot 				/* Some releases of vbios have set DISABLE_MC_MCLKA
610926deccbSFrançois Tigeot 				   and DISABLE_MC_MCLKB bits in the vbios table.  Setting these
611926deccbSFrançois Tigeot 				   bits will cause H/W hang when reading video memory with dynamic clocking
612926deccbSFrançois Tigeot 				   enabled. */
613926deccbSFrançois Tigeot 				if ((tmp & R300_DISABLE_MC_MCLKA) &&
614926deccbSFrançois Tigeot 				    (tmp & R300_DISABLE_MC_MCLKB)) {
615926deccbSFrançois Tigeot 					/* If both bits are set, then check the active channels */
616926deccbSFrançois Tigeot 					tmp = RREG32_PLL(RADEON_MCLK_CNTL);
617926deccbSFrançois Tigeot 					if (rdev->mc.vram_width == 64) {
618926deccbSFrançois Tigeot 						if (RREG32(RADEON_MEM_CNTL) &
619926deccbSFrançois Tigeot 						    R300_MEM_USE_CD_CH_ONLY)
620926deccbSFrançois Tigeot 							tmp &=
621926deccbSFrançois Tigeot 							    ~R300_DISABLE_MC_MCLKB;
622926deccbSFrançois Tigeot 						else
623926deccbSFrançois Tigeot 							tmp &=
624926deccbSFrançois Tigeot 							    ~R300_DISABLE_MC_MCLKA;
625926deccbSFrançois Tigeot 					} else {
626926deccbSFrançois Tigeot 						tmp &= ~(R300_DISABLE_MC_MCLKA |
627926deccbSFrançois Tigeot 							 R300_DISABLE_MC_MCLKB);
628926deccbSFrançois Tigeot 					}
629926deccbSFrançois Tigeot 				}
630926deccbSFrançois Tigeot 
631926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_MCLK_CNTL, tmp);
632926deccbSFrançois Tigeot 			} else {
633926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_SCLK_CNTL);
634926deccbSFrançois Tigeot 				tmp &= ~(R300_SCLK_FORCE_VAP);
635926deccbSFrançois Tigeot 				tmp |= RADEON_SCLK_FORCE_CP;
636926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_SCLK_CNTL, tmp);
637c4ef309bSzrj 				mdelay(15);
638926deccbSFrançois Tigeot 
639926deccbSFrançois Tigeot 				tmp = RREG32_PLL(R300_SCLK_CNTL2);
640926deccbSFrançois Tigeot 				tmp &= ~(R300_SCLK_FORCE_TCL |
641926deccbSFrançois Tigeot 					 R300_SCLK_FORCE_GA |
642926deccbSFrançois Tigeot 					 R300_SCLK_FORCE_CBA);
643926deccbSFrançois Tigeot 				WREG32_PLL(R300_SCLK_CNTL2, tmp);
644926deccbSFrançois Tigeot 			}
645926deccbSFrançois Tigeot 		} else {
646926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_CLK_PWRMGT_CNTL);
647926deccbSFrançois Tigeot 
648926deccbSFrançois Tigeot 			tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK |
649926deccbSFrançois Tigeot 				 RADEON_DISP_DYN_STOP_LAT_MASK |
650926deccbSFrançois Tigeot 				 RADEON_DYN_STOP_MODE_MASK);
651926deccbSFrançois Tigeot 
652926deccbSFrançois Tigeot 			tmp |= (RADEON_ENGIN_DYNCLK_MODE |
653926deccbSFrançois Tigeot 				(0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
654926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp);
655c4ef309bSzrj 			mdelay(15);
656926deccbSFrançois Tigeot 
657926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
658926deccbSFrançois Tigeot 			tmp |= RADEON_SCLK_DYN_START_CNTL;
659926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
660c4ef309bSzrj 			mdelay(15);
661926deccbSFrançois Tigeot 
662926deccbSFrançois Tigeot 			/* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
663926deccbSFrançois Tigeot 			   to lockup randomly, leave them as set by BIOS.
664926deccbSFrançois Tigeot 			 */
665926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
666926deccbSFrançois Tigeot 			/*tmp &= RADEON_SCLK_SRC_SEL_MASK; */
667926deccbSFrançois Tigeot 			tmp &= ~RADEON_SCLK_FORCEON_MASK;
668926deccbSFrançois Tigeot 
669926deccbSFrançois Tigeot 			/*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300 */
670926deccbSFrançois Tigeot 			if (((rdev->family == CHIP_RV250) &&
671926deccbSFrançois Tigeot 			     ((RREG32(RADEON_CONFIG_CNTL) &
672926deccbSFrançois Tigeot 			       RADEON_CFG_ATI_REV_ID_MASK) <
673926deccbSFrançois Tigeot 			      RADEON_CFG_ATI_REV_A13))
674926deccbSFrançois Tigeot 			    || ((rdev->family == CHIP_RV100)
675926deccbSFrançois Tigeot 				&&
676926deccbSFrançois Tigeot 				((RREG32(RADEON_CONFIG_CNTL) &
677926deccbSFrançois Tigeot 				  RADEON_CFG_ATI_REV_ID_MASK) <=
678926deccbSFrançois Tigeot 				 RADEON_CFG_ATI_REV_A13))) {
679926deccbSFrançois Tigeot 				tmp |= RADEON_SCLK_FORCE_CP;
680926deccbSFrançois Tigeot 				tmp |= RADEON_SCLK_FORCE_VIP;
681926deccbSFrançois Tigeot 			}
682926deccbSFrançois Tigeot 
683926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
684926deccbSFrançois Tigeot 
685926deccbSFrançois Tigeot 			if ((rdev->family == CHIP_RV200) ||
686926deccbSFrançois Tigeot 			    (rdev->family == CHIP_RV250) ||
687926deccbSFrançois Tigeot 			    (rdev->family == CHIP_RV280)) {
688926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
689926deccbSFrançois Tigeot 				tmp &= ~RADEON_SCLK_MORE_FORCEON;
690926deccbSFrançois Tigeot 
691926deccbSFrançois Tigeot 				/* RV200::A11 A12 RV250::A11 A12 */
692926deccbSFrançois Tigeot 				if (((rdev->family == CHIP_RV200) ||
693926deccbSFrançois Tigeot 				     (rdev->family == CHIP_RV250)) &&
694926deccbSFrançois Tigeot 				    ((RREG32(RADEON_CONFIG_CNTL) &
695926deccbSFrançois Tigeot 				      RADEON_CFG_ATI_REV_ID_MASK) <
696926deccbSFrançois Tigeot 				     RADEON_CFG_ATI_REV_A13)) {
697926deccbSFrançois Tigeot 					tmp |= RADEON_SCLK_MORE_FORCEON;
698926deccbSFrançois Tigeot 				}
699926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
700c4ef309bSzrj 				mdelay(15);
701926deccbSFrançois Tigeot 			}
702926deccbSFrançois Tigeot 
703926deccbSFrançois Tigeot 			/* RV200::A11 A12, RV250::A11 A12 */
704926deccbSFrançois Tigeot 			if (((rdev->family == CHIP_RV200) ||
705926deccbSFrançois Tigeot 			     (rdev->family == CHIP_RV250)) &&
706926deccbSFrançois Tigeot 			    ((RREG32(RADEON_CONFIG_CNTL) &
707926deccbSFrançois Tigeot 			      RADEON_CFG_ATI_REV_ID_MASK) <
708926deccbSFrançois Tigeot 			     RADEON_CFG_ATI_REV_A13)) {
709926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL);
710926deccbSFrançois Tigeot 				tmp |= RADEON_TCL_BYPASS_DISABLE;
711926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
712926deccbSFrançois Tigeot 			}
713c4ef309bSzrj 			mdelay(15);
714926deccbSFrançois Tigeot 
715926deccbSFrançois Tigeot 			/*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */
716926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
717926deccbSFrançois Tigeot 			tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
718926deccbSFrançois Tigeot 				RADEON_PIX2CLK_DAC_ALWAYS_ONb |
719926deccbSFrançois Tigeot 				RADEON_PIXCLK_BLEND_ALWAYS_ONb |
720926deccbSFrançois Tigeot 				RADEON_PIXCLK_GV_ALWAYS_ONb |
721926deccbSFrançois Tigeot 				RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
722926deccbSFrançois Tigeot 				RADEON_PIXCLK_LVDS_ALWAYS_ONb |
723926deccbSFrançois Tigeot 				RADEON_PIXCLK_TMDS_ALWAYS_ONb);
724926deccbSFrançois Tigeot 
725926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
726c4ef309bSzrj 			mdelay(15);
727926deccbSFrançois Tigeot 
728926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
729926deccbSFrançois Tigeot 			tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
730926deccbSFrançois Tigeot 				RADEON_PIXCLK_DAC_ALWAYS_ONb);
731926deccbSFrançois Tigeot 
732926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
733c4ef309bSzrj 			mdelay(15);
734926deccbSFrançois Tigeot 		}
735926deccbSFrançois Tigeot 	} else {
736926deccbSFrançois Tigeot 		/* Turn everything OFF (ForceON to everything) */
737926deccbSFrançois Tigeot 		if (rdev->flags & RADEON_SINGLE_CRTC) {
738926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
739926deccbSFrançois Tigeot 			tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP |
740926deccbSFrançois Tigeot 				RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP
741926deccbSFrançois Tigeot 				| RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE |
742926deccbSFrançois Tigeot 				RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP |
743926deccbSFrançois Tigeot 				RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB |
744926deccbSFrançois Tigeot 				RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM |
745926deccbSFrançois Tigeot 				RADEON_SCLK_FORCE_RB);
746926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
747926deccbSFrançois Tigeot 		} else if ((rdev->family == CHIP_RS400) ||
748926deccbSFrançois Tigeot 			   (rdev->family == CHIP_RS480)) {
749926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
750926deccbSFrançois Tigeot 			tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
751926deccbSFrançois Tigeot 				RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1
752926deccbSFrançois Tigeot 				| RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
753926deccbSFrançois Tigeot 				R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
754926deccbSFrançois Tigeot 				RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
755926deccbSFrançois Tigeot 				R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
756926deccbSFrançois Tigeot 				R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
757926deccbSFrançois Tigeot 				R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
758926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
759926deccbSFrançois Tigeot 
760926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
761926deccbSFrançois Tigeot 			tmp |= RADEON_SCLK_MORE_FORCEON;
762926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
763926deccbSFrançois Tigeot 
764926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
765926deccbSFrançois Tigeot 			tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
766926deccbSFrançois Tigeot 				 RADEON_PIXCLK_DAC_ALWAYS_ONb |
767926deccbSFrançois Tigeot 				 R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
768926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
769926deccbSFrançois Tigeot 
770926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
771926deccbSFrançois Tigeot 			tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
772926deccbSFrançois Tigeot 				 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
773926deccbSFrançois Tigeot 				 RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
774926deccbSFrançois Tigeot 				 R300_DVOCLK_ALWAYS_ONb |
775926deccbSFrançois Tigeot 				 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
776926deccbSFrançois Tigeot 				 RADEON_PIXCLK_GV_ALWAYS_ONb |
777926deccbSFrançois Tigeot 				 R300_PIXCLK_DVO_ALWAYS_ONb |
778926deccbSFrançois Tigeot 				 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
779926deccbSFrançois Tigeot 				 RADEON_PIXCLK_TMDS_ALWAYS_ONb |
780926deccbSFrançois Tigeot 				 R300_PIXCLK_TRANS_ALWAYS_ONb |
781926deccbSFrançois Tigeot 				 R300_PIXCLK_TVO_ALWAYS_ONb |
782926deccbSFrançois Tigeot 				 R300_P2G2CLK_ALWAYS_ONb |
783926deccbSFrançois Tigeot 				 R300_P2G2CLK_DAC_ALWAYS_ONb |
784926deccbSFrançois Tigeot 				 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
785926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
786926deccbSFrançois Tigeot 		} else if (rdev->family >= CHIP_RV350) {
787926deccbSFrançois Tigeot 			/* for RV350/M10, no delays are required. */
788926deccbSFrançois Tigeot 			tmp = RREG32_PLL(R300_SCLK_CNTL2);
789926deccbSFrançois Tigeot 			tmp |= (R300_SCLK_FORCE_TCL |
790926deccbSFrançois Tigeot 				R300_SCLK_FORCE_GA | R300_SCLK_FORCE_CBA);
791926deccbSFrançois Tigeot 			WREG32_PLL(R300_SCLK_CNTL2, tmp);
792926deccbSFrançois Tigeot 
793926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
794926deccbSFrançois Tigeot 			tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
795926deccbSFrançois Tigeot 				RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1
796926deccbSFrançois Tigeot 				| RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
797926deccbSFrançois Tigeot 				R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
798926deccbSFrançois Tigeot 				RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
799926deccbSFrançois Tigeot 				R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
800926deccbSFrançois Tigeot 				R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
801926deccbSFrançois Tigeot 				R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
802926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
803926deccbSFrançois Tigeot 
804926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
805926deccbSFrançois Tigeot 			tmp |= RADEON_SCLK_MORE_FORCEON;
806926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
807926deccbSFrançois Tigeot 
808926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_MCLK_CNTL);
809926deccbSFrançois Tigeot 			tmp |= (RADEON_FORCEON_MCLKA |
810926deccbSFrançois Tigeot 				RADEON_FORCEON_MCLKB |
811926deccbSFrançois Tigeot 				RADEON_FORCEON_YCLKA |
812926deccbSFrançois Tigeot 				RADEON_FORCEON_YCLKB | RADEON_FORCEON_MC);
813926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_MCLK_CNTL, tmp);
814926deccbSFrançois Tigeot 
815926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
816926deccbSFrançois Tigeot 			tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
817926deccbSFrançois Tigeot 				 RADEON_PIXCLK_DAC_ALWAYS_ONb |
818926deccbSFrançois Tigeot 				 R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
819926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
820926deccbSFrançois Tigeot 
821926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
822926deccbSFrançois Tigeot 			tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
823926deccbSFrançois Tigeot 				 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
824926deccbSFrançois Tigeot 				 RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
825926deccbSFrançois Tigeot 				 R300_DVOCLK_ALWAYS_ONb |
826926deccbSFrançois Tigeot 				 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
827926deccbSFrançois Tigeot 				 RADEON_PIXCLK_GV_ALWAYS_ONb |
828926deccbSFrançois Tigeot 				 R300_PIXCLK_DVO_ALWAYS_ONb |
829926deccbSFrançois Tigeot 				 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
830926deccbSFrançois Tigeot 				 RADEON_PIXCLK_TMDS_ALWAYS_ONb |
831926deccbSFrançois Tigeot 				 R300_PIXCLK_TRANS_ALWAYS_ONb |
832926deccbSFrançois Tigeot 				 R300_PIXCLK_TVO_ALWAYS_ONb |
833926deccbSFrançois Tigeot 				 R300_P2G2CLK_ALWAYS_ONb |
834926deccbSFrançois Tigeot 				 R300_P2G2CLK_DAC_ALWAYS_ONb |
835926deccbSFrançois Tigeot 				 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
836926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
837926deccbSFrançois Tigeot 		} else {
838926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_SCLK_CNTL);
839926deccbSFrançois Tigeot 			tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2);
840926deccbSFrançois Tigeot 			tmp |= RADEON_SCLK_FORCE_SE;
841926deccbSFrançois Tigeot 
842926deccbSFrançois Tigeot 			if (rdev->flags & RADEON_SINGLE_CRTC) {
843926deccbSFrançois Tigeot 				tmp |= (RADEON_SCLK_FORCE_RB |
844926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_TDM |
845926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_TAM |
846926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_PB |
847926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_RE |
848926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_VIP |
849926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_IDCT |
850926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_TOP |
851926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_DISP1 |
852926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_DISP2 |
853926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_HDP);
854926deccbSFrançois Tigeot 			} else if ((rdev->family == CHIP_R300) ||
855926deccbSFrançois Tigeot 				   (rdev->family == CHIP_R350)) {
856926deccbSFrançois Tigeot 				tmp |= (RADEON_SCLK_FORCE_HDP |
857926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_DISP1 |
858926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_DISP2 |
859926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_TOP |
860926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_IDCT |
861926deccbSFrançois Tigeot 					RADEON_SCLK_FORCE_VIP);
862926deccbSFrançois Tigeot 			}
863926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_SCLK_CNTL, tmp);
864926deccbSFrançois Tigeot 
865c4ef309bSzrj 			mdelay(16);
866926deccbSFrançois Tigeot 
867926deccbSFrançois Tigeot 			if ((rdev->family == CHIP_R300) ||
868926deccbSFrançois Tigeot 			    (rdev->family == CHIP_R350)) {
869926deccbSFrançois Tigeot 				tmp = RREG32_PLL(R300_SCLK_CNTL2);
870926deccbSFrançois Tigeot 				tmp |= (R300_SCLK_FORCE_TCL |
871926deccbSFrançois Tigeot 					R300_SCLK_FORCE_GA |
872926deccbSFrançois Tigeot 					R300_SCLK_FORCE_CBA);
873926deccbSFrançois Tigeot 				WREG32_PLL(R300_SCLK_CNTL2, tmp);
874c4ef309bSzrj 				mdelay(16);
875926deccbSFrançois Tigeot 			}
876926deccbSFrançois Tigeot 
877926deccbSFrançois Tigeot 			if (rdev->flags & RADEON_IS_IGP) {
878926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_MCLK_CNTL);
879926deccbSFrançois Tigeot 				tmp &= ~(RADEON_FORCEON_MCLKA |
880926deccbSFrançois Tigeot 					 RADEON_FORCEON_YCLKA);
881926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_MCLK_CNTL, tmp);
882c4ef309bSzrj 				mdelay(16);
883926deccbSFrançois Tigeot 			}
884926deccbSFrançois Tigeot 
885926deccbSFrançois Tigeot 			if ((rdev->family == CHIP_RV200) ||
886926deccbSFrançois Tigeot 			    (rdev->family == CHIP_RV250) ||
887926deccbSFrançois Tigeot 			    (rdev->family == CHIP_RV280)) {
888926deccbSFrançois Tigeot 				tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
889926deccbSFrançois Tigeot 				tmp |= RADEON_SCLK_MORE_FORCEON;
890926deccbSFrançois Tigeot 				WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
891c4ef309bSzrj 				mdelay(16);
892926deccbSFrançois Tigeot 			}
893926deccbSFrançois Tigeot 
894926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
895926deccbSFrançois Tigeot 			tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
896926deccbSFrançois Tigeot 				 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
897926deccbSFrançois Tigeot 				 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
898926deccbSFrançois Tigeot 				 RADEON_PIXCLK_GV_ALWAYS_ONb |
899926deccbSFrançois Tigeot 				 RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
900926deccbSFrançois Tigeot 				 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
901926deccbSFrançois Tigeot 				 RADEON_PIXCLK_TMDS_ALWAYS_ONb);
902926deccbSFrançois Tigeot 
903926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
904c4ef309bSzrj 			mdelay(16);
905926deccbSFrançois Tigeot 
906926deccbSFrançois Tigeot 			tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
907926deccbSFrançois Tigeot 			tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
908926deccbSFrançois Tigeot 				 RADEON_PIXCLK_DAC_ALWAYS_ONb);
909926deccbSFrançois Tigeot 			WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
910926deccbSFrançois Tigeot 		}
911926deccbSFrançois Tigeot 	}
912926deccbSFrançois Tigeot }
913926deccbSFrançois Tigeot 
914