summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-07-03 18:58:22 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-07-03 18:58:22 +0000
commit188fc8cc03e0a42b09f888f17b7ab9decd3a2116 (patch)
tree4fc8f288f1b00311c4633b4506e986b91b19676e /sys/dev/pci/drm
parent586d750798150b1bd0db0465ddefe1305923ea91 (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.c86
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;