drm/radeon/atom: add helper to calcuate mpll params
authorAlex Deucher <alexander.deucher@amd.com>
Wed, 13 Feb 2013 21:38:25 +0000 (16:38 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 27 Jun 2013 23:16:23 +0000 (19:16 -0400)
There's a new table for calculating the memory pll
parameters on SI.  Required for SI DPM support.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_mode.h

index f57e36d6fb4aa7358a114ae60a07b220db5a749c..1fb1d3faed0a24e2c542f4349d845d924e34b450 100644 (file)
@@ -219,6 +219,10 @@ int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
                                   u32 clock,
                                   bool strobe_mode,
                                   struct atom_clock_dividers *dividers);
+int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev,
+                                       u32 clock,
+                                       bool strobe_mode,
+                                       struct atom_mpll_param *mpll_param);
 void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type);
 int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev,
                                          u16 voltage_level, u8 voltage_type,
index 612d9bc1ccb0c880b0ef8edb92c1c8f293f6c8d8..45a6f5d155df445ac7213965bee7a87d87fb55e2 100644 (file)
@@ -2833,6 +2833,57 @@ int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
        return 0;
 }
 
+int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev,
+                                       u32 clock,
+                                       bool strobe_mode,
+                                       struct atom_mpll_param *mpll_param)
+{
+       COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 args;
+       int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam);
+       u8 frev, crev;
+
+       memset(&args, 0, sizeof(args));
+       memset(mpll_param, 0, sizeof(struct atom_mpll_param));
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return -EINVAL;
+
+       switch (frev) {
+       case 2:
+               switch (crev) {
+               case 1:
+                       /* SI */
+                       args.ulClock = cpu_to_le32(clock);      /* 10 khz */
+                       args.ucInputFlag = 0;
+                       if (strobe_mode)
+                               args.ucInputFlag |= MPLL_INPUT_FLAG_STROBE_MODE_EN;
+
+                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+                       mpll_param->clkfrac = le16_to_cpu(args.ulFbDiv.usFbDivFrac);
+                       mpll_param->clkf = le16_to_cpu(args.ulFbDiv.usFbDiv);
+                       mpll_param->post_div = args.ucPostDiv;
+                       mpll_param->dll_speed = args.ucDllSpeed;
+                       mpll_param->bwcntl = args.ucBWCntl;
+                       mpll_param->vco_mode =
+                               (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK) ? 1 : 0;
+                       mpll_param->yclk_sel =
+                               (args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0;
+                       mpll_param->qdr =
+                               (args.ucPllCntlFlag & MPLL_CNTL_FLAG_QDR_ENABLE) ? 1 : 0;
+                       mpll_param->half_rate =
+                               (args.ucPllCntlFlag & MPLL_CNTL_FLAG_AD_HALF_RATE) ? 1 : 0;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
 void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
 {
        DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
index 02bf4a755f34de10ee6bbcea0957a3f93d33bf90..e5ea915993d98ccbb0d26e37060e55f11a5bc41c 100644 (file)
@@ -519,6 +519,30 @@ struct atom_clock_dividers {
        u32 flags;
 };
 
+struct atom_mpll_param {
+       union {
+               struct {
+#ifdef __BIG_ENDIAN
+                       u32 reserved : 8;
+                       u32 clkfrac : 12;
+                       u32 clkf : 12;
+#else
+                       u32 clkf : 12;
+                       u32 clkfrac : 12;
+                       u32 reserved : 8;
+#endif
+               };
+               u32 fb_div;
+       };
+       u32 post_div;
+       u32 bwcntl;
+       u32 dll_speed;
+       u32 vco_mode;
+       u32 yclk_sel;
+       u32 qdr;
+       u32 half_rate;
+};
+
 #define MEM_TYPE_GDDR5  0x50
 #define MEM_TYPE_GDDR4  0x40
 #define MEM_TYPE_GDDR3  0x30