diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-07-03 18:58:22 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-07-03 18:58:22 +0000 |
commit | 188fc8cc03e0a42b09f888f17b7ab9decd3a2116 (patch) | |
tree | 4fc8f288f1b00311c4633b4506e986b91b19676e /sys/dev/pci/drm | |
parent | 586d750798150b1bd0db0465ddefe1305923ea91 (diff) |
Get clocks from Open Firmware on macppc and sparc64.
ok jsg@
Diffstat (limited to 'sys/dev/pci/drm')
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_clocks.c | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/sys/dev/pci/drm/radeon/radeon_clocks.c b/sys/dev/pci/drm/radeon/radeon_clocks.c index 5a6e3ab15da..3d8d6044e00 100644 --- a/sys/dev/pci/drm/radeon/radeon_clocks.c +++ b/sys/dev/pci/drm/radeon/radeon_clocks.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_clocks.c,v 1.1 2013/08/12 04:11:53 jsg Exp $ */ +/* $OpenBSD: radeon_clocks.c,v 1.2 2014/07/03 18:58:21 kettenis Exp $ */ /* * Copyright 2008 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -32,6 +32,10 @@ #include "radeon.h" #include "atom.h" +#if defined(__macppc__) || defined(__sparc64__) +#include <dev/ofw/openfirm.h> +#endif + uint32_t radeon_legacy_get_engine_clock(struct radeon_device *); uint32_t radeon_legacy_get_memory_clock(struct radeon_device *); void radeon_legacy_set_engine_clock(struct radeon_device *, uint32_t); @@ -96,6 +100,8 @@ uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) return mclk; } +#ifdef __linux__ + #ifdef CONFIG_OF /* * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device @@ -177,6 +183,84 @@ static bool radeon_read_clocks_OF(struct drm_device *dev) } #endif /* CONFIG_OF */ +#else + +#if defined(__macppc__) || defined(__sparc64__) +/* + * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device + * tree. Hopefully, ATI OF driver is kind enough to fill these + */ +static bool radeon_read_clocks_OF(struct drm_device *dev) +{ + struct radeon_device *rdev = dev->dev_private; + int node = PCITAG_NODE(rdev->pa_tag); + uint32_t 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 (OF_getprop(node, "ATY,RefCLK", &val, sizeof(val)) != sizeof(val) || !val) + 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; + } + /* not sure what the max should be in all cases */ + rdev->clock.max_pixel_clock = 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; + + if (OF_getprop(node, "ATY,SCLK", &val, sizeof(val)) == sizeof(val) && val) + rdev->clock.default_sclk = (val) / 10; + else + rdev->clock.default_sclk = + radeon_legacy_get_engine_clock(rdev); + + if (OF_getprop(node, "ATY,MCLK", &val, sizeof(val)) == sizeof(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 radeon_read_clocks_OF(struct drm_device *dev) +{ + return false; +} +#endif /* CONFIG_OF */ + +#endif + void radeon_get_clock_info(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; |