Merge tag 'v3.10-rc1' into stable/for-linus-3.10
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / gpu / drm / radeon / radeon_atombios.c
index 0dd87c0e0fac4198ea6ea970233317ff749216fa..dea6f63c9724af9b493fb5693f9e3f406edcb0fb 100644 (file)
@@ -2028,6 +2028,8 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
        num_modes = power_info->info.ucNumOfPowerModeEntries;
        if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
                num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
+       if (num_modes == 0)
+               return state_index;
        rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL);
        if (!rdev->pm.power_state)
                return state_index;
@@ -2307,7 +2309,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
                rdev->pm.default_power_state_index = state_index;
                rdev->pm.power_state[state_index].default_clock_mode =
                        &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
-               if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) {
+               if ((rdev->family >= CHIP_BARTS) && !(rdev->flags & RADEON_IS_IGP)) {
                        /* NI chips post without MC ucode, so default clocks are strobe mode only */
                        rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
                        rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
@@ -2345,7 +2347,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
                        sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
                        rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
                }
-       } else if (ASIC_IS_DCE6(rdev)) {
+       } else if (rdev->family >= CHIP_TAHITI) {
                sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
                sclk |= clock_info->si.ucEngineClockHigh << 16;
                mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
@@ -2358,7 +2360,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
                        le16_to_cpu(clock_info->si.usVDDC);
                rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
                        le16_to_cpu(clock_info->si.usVDDCI);
-       } else if (ASIC_IS_DCE4(rdev)) {
+       } else if (rdev->family >= CHIP_CEDAR) {
                sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
                sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
                mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
@@ -2432,6 +2434,8 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
        power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
 
        radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
+       if (power_info->pplib.ucNumStates == 0)
+               return state_index;
        rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
                                       power_info->pplib.ucNumStates, GFP_KERNEL);
        if (!rdev->pm.power_state)
@@ -2514,6 +2518,7 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
        int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
         u16 data_offset;
        u8 frev, crev;
+       u8 *power_state_offset;
 
        if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
                                   &frev, &crev, &data_offset))
@@ -2530,15 +2535,17 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
        non_clock_info_array = (struct _NonClockInfoArray *)
                (mode_info->atom_context->bios + data_offset +
                 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
+       if (state_array->ucNumEntries == 0)
+               return state_index;
        rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
                                       state_array->ucNumEntries, GFP_KERNEL);
        if (!rdev->pm.power_state)
                return state_index;
+       power_state_offset = (u8 *)state_array->states;
        for (i = 0; i < state_array->ucNumEntries; i++) {
                mode_index = 0;
-               power_state = (union pplib_power_state *)&state_array->states[i];
-               /* XXX this might be an inagua bug... */
-               non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
+               power_state = (union pplib_power_state *)power_state_offset;
+               non_clock_array_index = power_state->v2.nonClockInfoIndex;
                non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
                        &non_clock_info_array->nonClockInfo[non_clock_array_index];
                rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
@@ -2550,9 +2557,6 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
                if (power_state->v2.ucNumDPMLevels) {
                        for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
                                clock_array_index = power_state->v2.clockInfoIndex[j];
-                               /* XXX this might be an inagua bug... */
-                               if (clock_array_index >= clock_info_array->ucNumEntries)
-                                       continue;
                                clock_info = (union pplib_clock_info *)
                                        &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
                                valid = radeon_atombios_parse_pplib_clock_info(rdev,
@@ -2574,6 +2578,7 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
                                                                   non_clock_info);
                        state_index++;
                }
+               power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
        }
        /* if multiple clock modes, mark the lowest as no display */
        for (i = 0; i < state_index; i++) {
@@ -2620,7 +2625,9 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
                default:
                        break;
                }
-       } else {
+       }
+
+       if (state_index == 0) {
                rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
                if (rdev->pm.power_state) {
                        rdev->pm.power_state[0].clock_info =