|
@@ -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) {
|