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

Commit 7b044f40 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Dave Airlie
Browse files

drm/radeon: Add probing of clocks from device-tree



When we find no ROM we understand and a device-tree is present, see
if we can retreive clock info from there.

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent b494d5d4
Loading
Loading
Loading
Loading
+81 −0
Original line number Diff line number Diff line
@@ -91,6 +91,85 @@ uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
	return mclk;
}

#ifdef CONFIG_OF
/*
 * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device
 * tree. Hopefully, ATI OF driver is kind enough to fill these
 */
static bool __devinit radeon_read_clocks_OF(struct drm_device *dev)
{
	struct radeon_device *rdev = dev->dev_private;
	struct device_node *dp = rdev->pdev->dev.of_node;
	const u32 *val;
	struct radeon_pll *p1pll = &rdev->clock.p1pll;
	struct radeon_pll *p2pll = &rdev->clock.p2pll;
	struct radeon_pll *spll = &rdev->clock.spll;
	struct radeon_pll *mpll = &rdev->clock.mpll;

	if (dp == NULL)
		return false;
	val = of_get_property(dp, "ATY,RefCLK", NULL);
	if (!val || !*val) {
		printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n");
		return false;
	}
	p1pll->reference_freq = p2pll->reference_freq = (*val) / 10;
	p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
	if (p1pll->reference_div < 2)
		p1pll->reference_div = 12;
	p2pll->reference_div = p1pll->reference_div;	

	/* These aren't in the device-tree */
	if (rdev->family >= CHIP_R420) {
		p1pll->pll_in_min = 100;
		p1pll->pll_in_max = 1350;
		p1pll->pll_out_min = 20000;
		p1pll->pll_out_max = 50000;
		p2pll->pll_in_min = 100;
		p2pll->pll_in_max = 1350;
		p2pll->pll_out_min = 20000;
		p2pll->pll_out_max = 50000;
	} else {
		p1pll->pll_in_min = 40;
		p1pll->pll_in_max = 500;
		p1pll->pll_out_min = 12500;
		p1pll->pll_out_max = 35000;
		p2pll->pll_in_min = 40;
		p2pll->pll_in_max = 500;
		p2pll->pll_out_min = 12500;
		p2pll->pll_out_max = 35000;
	}

	spll->reference_freq = mpll->reference_freq = p1pll->reference_freq;
	spll->reference_div = mpll->reference_div =
		RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
			    RADEON_M_SPLL_REF_DIV_MASK;

	val = of_get_property(dp, "ATY,SCLK", NULL);
	if (val && *val)
		rdev->clock.default_sclk = (*val) / 10;
	else
		rdev->clock.default_sclk =
			radeon_legacy_get_engine_clock(rdev);
			
	val = of_get_property(dp, "ATY,MCLK", NULL);
	if (val && *val)
		rdev->clock.default_mclk = (*val) / 10;
	else
		rdev->clock.default_mclk =
			radeon_legacy_get_memory_clock(rdev);

	DRM_INFO("Using device-tree clock info\n");
	
	return true;
}
#else
static bool __devinit radeon_read_clocks_OF(struct drm_device *dev)
{
	return false;
}
#endif /* CONFIG_OF */

void radeon_get_clock_info(struct drm_device *dev)
{
	struct radeon_device *rdev = dev->dev_private;
@@ -105,6 +184,8 @@ void radeon_get_clock_info(struct drm_device *dev)
		ret = radeon_atom_get_clock_info(dev);
	else
		ret = radeon_combios_get_clock_info(dev);
	if (!ret)
		ret = radeon_read_clocks_OF(dev);

	if (ret) {
		if (p1pll->reference_div < 2) {