Subversion Repositories Kolibri OS

Rev

Rev 2997 | Rev 5078 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2997 Rev 3764
Line 2026... Line 2026...
2026
				}
2026
				}
2027
			}
2027
			}
2028
			num_modes = power_info->info.ucNumOfPowerModeEntries;
2028
			num_modes = power_info->info.ucNumOfPowerModeEntries;
2029
			if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
2029
			if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
2030
				num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
2030
				num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
-
 
2031
	if (num_modes == 0)
-
 
2032
		return state_index;
2031
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL);
2033
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL);
2032
	if (!rdev->pm.power_state)
2034
	if (!rdev->pm.power_state)
2033
		return state_index;
2035
		return state_index;
2034
			/* last mode is usually default, array is low to high */
2036
			/* last mode is usually default, array is low to high */
2035
			for (i = 0; i < num_modes; i++) {
2037
			for (i = 0; i < num_modes; i++) {
Line 2305... Line 2307...
2305
						rdev->pm.power_state[state_index].type =
2307
						rdev->pm.power_state[state_index].type =
2306
							POWER_STATE_TYPE_DEFAULT;
2308
							POWER_STATE_TYPE_DEFAULT;
2307
						rdev->pm.default_power_state_index = state_index;
2309
						rdev->pm.default_power_state_index = state_index;
2308
						rdev->pm.power_state[state_index].default_clock_mode =
2310
						rdev->pm.power_state[state_index].default_clock_mode =
2309
							&rdev->pm.power_state[state_index].clock_info[mode_index - 1];
2311
							&rdev->pm.power_state[state_index].clock_info[mode_index - 1];
2310
		if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) {
2312
		if ((rdev->family >= CHIP_BARTS) && !(rdev->flags & RADEON_IS_IGP)) {
2311
			/* NI chips post without MC ucode, so default clocks are strobe mode only */
2313
			/* NI chips post without MC ucode, so default clocks are strobe mode only */
2312
			rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
2314
			rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
2313
			rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
2315
			rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
2314
			rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;
2316
			rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;
2315
			rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci;
2317
			rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci;
Line 2343... Line 2345...
2343
		} else {
2345
		} else {
2344
			sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow);
2346
			sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow);
2345
			sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
2347
			sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
2346
			rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2348
			rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2347
		}
2349
		}
2348
	} else if (ASIC_IS_DCE6(rdev)) {
2350
	} else if (rdev->family >= CHIP_TAHITI) {
2349
		sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
2351
		sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
2350
		sclk |= clock_info->si.ucEngineClockHigh << 16;
2352
		sclk |= clock_info->si.ucEngineClockHigh << 16;
2351
		mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
2353
		mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
2352
		mclk |= clock_info->si.ucMemoryClockHigh << 16;
2354
		mclk |= clock_info->si.ucMemoryClockHigh << 16;
2353
		rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2355
		rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
Line 2356... Line 2358...
2356
			VOLTAGE_SW;
2358
			VOLTAGE_SW;
2357
		rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
2359
		rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
2358
			le16_to_cpu(clock_info->si.usVDDC);
2360
			le16_to_cpu(clock_info->si.usVDDC);
2359
		rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
2361
		rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
2360
			le16_to_cpu(clock_info->si.usVDDCI);
2362
			le16_to_cpu(clock_info->si.usVDDCI);
2361
	} else if (ASIC_IS_DCE4(rdev)) {
2363
	} else if (rdev->family >= CHIP_CEDAR) {
2362
		sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
2364
		sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
2363
		sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
2365
		sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
2364
		mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
2366
		mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
2365
		mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
2367
		mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
2366
		rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2368
		rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
Line 2430... Line 2432...
2430
				   &frev, &crev, &data_offset))
2432
				   &frev, &crev, &data_offset))
2431
		return state_index;
2433
		return state_index;
2432
	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2434
	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
Line 2433... Line 2435...
2433
 
2435
 
-
 
2436
	radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
-
 
2437
	if (power_info->pplib.ucNumStates == 0)
2434
	radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
2438
		return state_index;
2435
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2439
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2436
				       power_info->pplib.ucNumStates, GFP_KERNEL);
2440
				       power_info->pplib.ucNumStates, GFP_KERNEL);
2437
	if (!rdev->pm.power_state)
2441
	if (!rdev->pm.power_state)
2438
		return state_index;
2442
		return state_index;
Line 2512... Line 2516...
2512
	bool valid;
2516
	bool valid;
2513
	union power_info *power_info;
2517
	union power_info *power_info;
2514
	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2518
	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2515
        u16 data_offset;
2519
        u16 data_offset;
2516
	u8 frev, crev;
2520
	u8 frev, crev;
-
 
2521
	u8 *power_state_offset;
Line 2517... Line 2522...
2517
 
2522
 
2518
	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2523
	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2519
				   &frev, &crev, &data_offset))
2524
				   &frev, &crev, &data_offset))
2520
		return state_index;
2525
		return state_index;
Line 2528... Line 2533...
2528
		(mode_info->atom_context->bios + data_offset +
2533
		(mode_info->atom_context->bios + data_offset +
2529
		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
2534
		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
2530
	non_clock_info_array = (struct _NonClockInfoArray *)
2535
	non_clock_info_array = (struct _NonClockInfoArray *)
2531
		(mode_info->atom_context->bios + data_offset +
2536
		(mode_info->atom_context->bios + data_offset +
2532
		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
2537
		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
-
 
2538
	if (state_array->ucNumEntries == 0)
-
 
2539
		return state_index;
2533
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2540
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2534
				       state_array->ucNumEntries, GFP_KERNEL);
2541
				       state_array->ucNumEntries, GFP_KERNEL);
2535
	if (!rdev->pm.power_state)
2542
	if (!rdev->pm.power_state)
2536
		return state_index;
2543
		return state_index;
-
 
2544
	power_state_offset = (u8 *)state_array->states;
2537
	for (i = 0; i < state_array->ucNumEntries; i++) {
2545
	for (i = 0; i < state_array->ucNumEntries; i++) {
2538
		mode_index = 0;
2546
		mode_index = 0;
2539
		power_state = (union pplib_power_state *)&state_array->states[i];
2547
		power_state = (union pplib_power_state *)power_state_offset;
2540
		/* XXX this might be an inagua bug... */
-
 
2541
		non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
2548
		non_clock_array_index = power_state->v2.nonClockInfoIndex;
2542
		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2549
		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2543
			&non_clock_info_array->nonClockInfo[non_clock_array_index];
2550
			&non_clock_info_array->nonClockInfo[non_clock_array_index];
2544
		rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
2551
		rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
2545
							     (power_state->v2.ucNumDPMLevels ?
2552
							     (power_state->v2.ucNumDPMLevels ?
2546
							      power_state->v2.ucNumDPMLevels : 1),
2553
							      power_state->v2.ucNumDPMLevels : 1),
Line 2548... Line 2555...
2548
		if (!rdev->pm.power_state[i].clock_info)
2555
		if (!rdev->pm.power_state[i].clock_info)
2549
			return state_index;
2556
			return state_index;
2550
		if (power_state->v2.ucNumDPMLevels) {
2557
		if (power_state->v2.ucNumDPMLevels) {
2551
		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
2558
		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
2552
			clock_array_index = power_state->v2.clockInfoIndex[j];
2559
			clock_array_index = power_state->v2.clockInfoIndex[j];
2553
			/* XXX this might be an inagua bug... */
-
 
2554
			if (clock_array_index >= clock_info_array->ucNumEntries)
-
 
2555
				continue;
-
 
2556
			clock_info = (union pplib_clock_info *)
2560
			clock_info = (union pplib_clock_info *)
2557
					&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
2561
					&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
2558
			valid = radeon_atombios_parse_pplib_clock_info(rdev,
2562
			valid = radeon_atombios_parse_pplib_clock_info(rdev,
2559
								       state_index, mode_index,
2563
								       state_index, mode_index,
2560
								       clock_info);
2564
								       clock_info);
Line 2572... Line 2576...
2572
		if (mode_index) {
2576
		if (mode_index) {
2573
			radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
2577
			radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
2574
								   non_clock_info);
2578
								   non_clock_info);
2575
					state_index++;
2579
					state_index++;
2576
				}
2580
				}
-
 
2581
		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
2577
			}
2582
			}
2578
			/* if multiple clock modes, mark the lowest as no display */
2583
			/* if multiple clock modes, mark the lowest as no display */
2579
			for (i = 0; i < state_index; i++) {
2584
			for (i = 0; i < state_index; i++) {
2580
				if (rdev->pm.power_state[i].num_clock_modes > 1)
2585
				if (rdev->pm.power_state[i].num_clock_modes > 1)
2581
					rdev->pm.power_state[i].clock_info[0].flags |=
2586
					rdev->pm.power_state[i].clock_info[0].flags |=
Line 2618... Line 2623...
2618
			state_index = radeon_atombios_parse_power_table_6(rdev);
2623
			state_index = radeon_atombios_parse_power_table_6(rdev);
2619
			break;
2624
			break;
2620
		default:
2625
		default:
2621
			break;
2626
			break;
2622
		}
2627
		}
2623
	} else {
2628
	}
-
 
2629
 
-
 
2630
	if (state_index == 0) {
2624
		rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
2631
		rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
2625
		if (rdev->pm.power_state) {
2632
		if (rdev->pm.power_state) {
2626
			rdev->pm.power_state[0].clock_info =
2633
			rdev->pm.power_state[0].clock_info =
2627
				kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2634
				kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2628
			if (rdev->pm.power_state[0].clock_info) {
2635
			if (rdev->pm.power_state[0].clock_info) {
Line 2652... Line 2659...
2652
			rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
2659
			rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
2653
	else
2660
	else
2654
		rdev->pm.current_vddc = 0;
2661
		rdev->pm.current_vddc = 0;
2655
}
2662
}
Line -... Line 2663...
-
 
2663
 
-
 
2664
union get_clock_dividers {
-
 
2665
	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1;
-
 
2666
	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2;
-
 
2667
	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;
-
 
2668
	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;
-
 
2669
	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;
-
 
2670
};
-
 
2671
 
-
 
2672
int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
-
 
2673
				   u8 clock_type,
-
 
2674
				   u32 clock,
-
 
2675
				   bool strobe_mode,
-
 
2676
				   struct atom_clock_dividers *dividers)
-
 
2677
{
-
 
2678
	union get_clock_dividers args;
-
 
2679
	int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL);
-
 
2680
	u8 frev, crev;
-
 
2681
 
-
 
2682
	memset(&args, 0, sizeof(args));
-
 
2683
	memset(dividers, 0, sizeof(struct atom_clock_dividers));
-
 
2684
 
-
 
2685
	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
-
 
2686
		return -EINVAL;
-
 
2687
 
-
 
2688
	switch (crev) {
-
 
2689
	case 1:
-
 
2690
		/* r4xx, r5xx */
-
 
2691
		args.v1.ucAction = clock_type;
-
 
2692
		args.v1.ulClock = cpu_to_le32(clock);	/* 10 khz */
-
 
2693
 
-
 
2694
		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
 
2695
 
-
 
2696
		dividers->post_div = args.v1.ucPostDiv;
-
 
2697
		dividers->fb_div = args.v1.ucFbDiv;
-
 
2698
		dividers->enable_post_div = true;
-
 
2699
		break;
-
 
2700
	case 2:
-
 
2701
	case 3:
-
 
2702
		/* r6xx, r7xx, evergreen, ni */
-
 
2703
		if (rdev->family <= CHIP_RV770) {
-
 
2704
			args.v2.ucAction = clock_type;
-
 
2705
			args.v2.ulClock = cpu_to_le32(clock);	/* 10 khz */
-
 
2706
 
-
 
2707
			atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
 
2708
 
-
 
2709
			dividers->post_div = args.v2.ucPostDiv;
-
 
2710
			dividers->fb_div = le16_to_cpu(args.v2.usFbDiv);
-
 
2711
			dividers->ref_div = args.v2.ucAction;
-
 
2712
			if (rdev->family == CHIP_RV770) {
-
 
2713
				dividers->enable_post_div = (le32_to_cpu(args.v2.ulClock) & (1 << 24)) ?
-
 
2714
					true : false;
-
 
2715
				dividers->vco_mode = (le32_to_cpu(args.v2.ulClock) & (1 << 25)) ? 1 : 0;
-
 
2716
			} else
-
 
2717
				dividers->enable_post_div = (dividers->fb_div & 1) ? true : false;
-
 
2718
		} else {
-
 
2719
			if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {
-
 
2720
				args.v3.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
-
 
2721
 
-
 
2722
				atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
 
2723
 
-
 
2724
				dividers->post_div = args.v3.ucPostDiv;
-
 
2725
				dividers->enable_post_div = (args.v3.ucCntlFlag &
-
 
2726
							     ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
-
 
2727
				dividers->enable_dithen = (args.v3.ucCntlFlag &
-
 
2728
							   ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
-
 
2729
				dividers->fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
-
 
2730
				dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);
-
 
2731
				dividers->ref_div = args.v3.ucRefDiv;
-
 
2732
				dividers->vco_mode = (args.v3.ucCntlFlag &
-
 
2733
						      ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
-
 
2734
			} else {
-
 
2735
				args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
-
 
2736
				if (strobe_mode)
-
 
2737
					args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
-
 
2738
 
-
 
2739
				atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
 
2740
 
-
 
2741
				dividers->post_div = args.v5.ucPostDiv;
-
 
2742
				dividers->enable_post_div = (args.v5.ucCntlFlag &
-
 
2743
							     ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
-
 
2744
				dividers->enable_dithen = (args.v5.ucCntlFlag &
-
 
2745
							   ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
-
 
2746
				dividers->whole_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDiv);
-
 
2747
				dividers->frac_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDivFrac);
-
 
2748
				dividers->ref_div = args.v5.ucRefDiv;
-
 
2749
				dividers->vco_mode = (args.v5.ucCntlFlag &
-
 
2750
						      ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
-
 
2751
			}
-
 
2752
		}
-
 
2753
		break;
-
 
2754
	case 4:
-
 
2755
		/* fusion */
-
 
2756
		args.v4.ulClock = cpu_to_le32(clock);	/* 10 khz */
-
 
2757
 
-
 
2758
		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
 
2759
 
-
 
2760
		dividers->post_div = args.v4.ucPostDiv;
-
 
2761
		dividers->real_clock = le32_to_cpu(args.v4.ulClock);
-
 
2762
		break;
-
 
2763
	default:
-
 
2764
		return -EINVAL;
-
 
2765
	}
-
 
2766
	return 0;
-
 
2767
}
2656
 
2768
 
2657
void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
2769
void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
2658
{
2770
{
2659
	DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
2771
	DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;