Ejemplo n.º 1
0
void mmdvfs_notify_scenario_enter(MTK_SMI_BWC_SCEN scen)
{
#if !MMDVFS_ENABLE
	return;
#endif

	MMDVFSMSG("enter %d\n", scen);

	if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_WQHD) {
	#if MMDVFS_ENABLE_WQHD
		if (scen == SMI_BWC_SCEN_VP) {
			mmdvfs_start_gpu_monitor(&g_mmdvfs_mgr->gpu_monitor);
		}
	#endif /* MMDVFS_ENABLE_WQHD */
	} else {	/* FHD */
		switch (scen) {
			case SMI_BWC_SCEN_ICFP:
				mmdvfs_set_step(scen, MMDVFS_VOLTAGE_HIGH);
				break;

			case SMI_BWC_SCEN_VR:
			case SMI_BWC_SCEN_VR_SLOW:		
				mmdvfs_set_step(scen, mmdvfs_query(scen, NULL));
				/* workaround for ICFP...its mmdvfs_set() will come after leaving ICFP */
				mmdvfs_set_step(SMI_BWC_SCEN_ICFP, mmdvfs_get_default_step());
				break;
				
			default:
				break;
		}
	}	
}
Ejemplo n.º 2
0
int mmdvfs_set_step(MTK_SMI_BWC_SCEN scenario, mmdvfs_voltage_enum step)
{
	int i, scen_index;
	mmdvfs_voltage_enum final_step = mmdvfs_get_default_step();

#if !MMDVFS_ENABLE
	return 0;
#endif

#if defined(SMI_D1)
	/* D1 FHD always HPM. do not have to trigger vcore dvfs. */
	if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_FHD)
		return 0;

#endif

	MMDVFSMSG("MMDVFS set voltage scen %d step %d\n", scenario, step);

	if ((scenario >= MMDVFS_SCEN_COUNT) || (scenario < SMI_BWC_SCEN_NORMAL)) {
		MMDVFSERR("invalid scenario\n");
		return -1;
	}

	/* dump information */
	mmdvfs_dump_info();

	/* go through all scenarios to decide the final step */
	scen_index = (int)scenario;

	spin_lock(&g_mmdvfs_mgr->scen_lock);

	g_mmdvfs_scenario_voltage[scen_index] = step;

	/* one high = final high */
	for (i = 0; i < MMDVFS_SCEN_COUNT; i++) {
		if (g_mmdvfs_scenario_voltage[i] == MMDVFS_VOLTAGE_HIGH) {
			final_step = MMDVFS_VOLTAGE_HIGH;
			break;
		}
	}

	g_mmdvfs_current_step = final_step;

	spin_unlock(&g_mmdvfs_mgr->scen_lock);

	MMDVFSMSG("MMDVFS set voltage scen %d step %d final %d\n", scenario,
	step, final_step);

#if MMDVFS_ENABLE
	/* call vcore dvfs API */
	if (final_step == MMDVFS_VOLTAGE_HIGH)
		vcorefs_request_dvfs_opp(KIR_MM, OPPI_PERF);
	else
		vcorefs_request_dvfs_opp(KIR_MM, OPPI_UNREQ);

#endif

	return 0;
}
Ejemplo n.º 3
0
static mmdvfs_voltage_enum mmdvfs_query(MTK_SMI_BWC_SCEN scenario, MTK_MMDVFS_CMD *cmd)
{
	mmdvfs_voltage_enum step = mmdvfs_get_default_step();
	unsigned int venc_size;
	MTK_MMDVFS_CMD cmd_default;

	venc_size = g_mmdvfs_info->video_record_size[0] * g_mmdvfs_info->video_record_size[1];

	/* use default info */
	if (cmd == NULL) {
		memset(&cmd_default, 0, sizeof(MTK_MMDVFS_CMD));
		cmd_default.camera_mode = MMDVFS_CAMERA_MODE_FLAG_DEFAULT;
		cmd = &cmd_default;
	}

	/* collect the final information */
	if (cmd->sensor_size == 0) {
		cmd->sensor_size = g_mmdvfs_cmd.sensor_size;
	}

	if (cmd->sensor_fps == 0) {
		cmd->sensor_fps = g_mmdvfs_cmd.sensor_fps;
	}

	if (cmd->camera_mode == MMDVFS_CAMERA_MODE_FLAG_DEFAULT) {
		cmd->camera_mode = g_mmdvfs_cmd.camera_mode;
	}	

	/* HIGH level scenarios */
	switch (scenario) {
		case SMI_BWC_SCEN_VR:
			if (cmd->sensor_size >= MMDVFS_PIXEL_NUM_SENSOR_FULL) {
				/* VR4K high */
				step = MMDVFS_VOLTAGE_HIGH;
			} else if (cmd->camera_mode &
					   (MMDVFS_CAMERA_MODE_FLAG_PIP | MMDVFS_CAMERA_MODE_FLAG_VFB | MMDVFS_CAMERA_MODE_FLAG_EIS_2_0)) {
				/* PIP or VFB or EIS keeps high for ISP clock */
				step = MMDVFS_VOLTAGE_HIGH;
			}		
			break;
			
		case SMI_BWC_SCEN_VR_SLOW:
			/* >= 120 fps SLOW MOTION high */
			if (cmd->sensor_fps >= 120) {
				step = MMDVFS_VOLTAGE_HIGH;
			}
			break;

		case SMI_BWC_SCEN_ICFP:
			step = MMDVFS_VOLTAGE_HIGH;
			break;

		default:
			break;
	}

	return step;
}
Ejemplo n.º 4
0
void mmdvfs_init(MTK_SMI_BWC_MM_INFO *info)
{
#if !MMDVFS_ENABLE
	return;
#endif

	spin_lock_init(&g_mmdvfs_mgr->scen_lock);
	/* set current step as the default step */
	g_mmdvfs_current_step = mmdvfs_get_default_step();

	g_mmdvfs_info = info;
}
Ejemplo n.º 5
0
static mmdvfs_voltage_enum mmdvfs_query(MTK_SMI_BWC_SCEN scenario,
MTK_MMDVFS_CMD *cmd)
{
	mmdvfs_voltage_enum step = mmdvfs_get_default_step();
	unsigned int venc_size;
	MTK_MMDVFS_CMD cmd_default;

	venc_size = g_mmdvfs_info->video_record_size[0]
	* g_mmdvfs_info->video_record_size[1];

	/* use default info */
	if (cmd == NULL) {
		memset(&cmd_default, 0, sizeof(MTK_MMDVFS_CMD));
		cmd_default.camera_mode = MMDVFS_CAMERA_MODE_FLAG_DEFAULT;
		cmd = &cmd_default;
	}

	/* collect the final information */
	if (cmd->sensor_size == 0)
		cmd->sensor_size = g_mmdvfs_cmd.sensor_size;

	if (cmd->sensor_fps == 0)
		cmd->sensor_fps = g_mmdvfs_cmd.sensor_fps;

	if (cmd->camera_mode == MMDVFS_CAMERA_MODE_FLAG_DEFAULT)
		cmd->camera_mode = g_mmdvfs_cmd.camera_mode;

	/* HIGH level scenarios */
	switch (scenario) {
#if defined(SMI_D2)         /* D2 ISP >= 6M HIGH */
	case SMI_BWC_SCEN_VR_SLOW:
	case SMI_BWC_SCEN_VR:
	if (cmd->sensor_size >= MMDVFS_PIXEL_NUM_SENSOR_6M)
		step = MMDVFS_VOLTAGE_HIGH;

	break;
#endif
	/* force HPM for engineering mode */
	case SMI_BWC_SCEN_FORCE_MMDVFS:
		step = MMDVFS_VOLTAGE_HIGH;
		break;
	default:
		break;
	}

	return step;
}
Ejemplo n.º 6
0
void mmdvfs_notify_scenario_exit(MTK_SMI_BWC_SCEN scen)
{
#if !MMDVFS_ENABLE
	return;
#endif

	MMDVFSMSG("leave %d\n", scen);

	if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_WQHD) {
	#if MMDVFS_ENABLE_WQHD	
		if (scen == SMI_BWC_SCEN_VP) {
			mmdvfs_stop_gpu_monitor(&g_mmdvfs_mgr->gpu_monitor);
		}
	#endif /* MMDVFS_ENABLE_WQHD */
	}

	/* reset scenario voltage to default when it exits */
	mmdvfs_set_step(scen, mmdvfs_get_default_step());
}
Ejemplo n.º 7
0
void mmdvfs_notify_scenario_exit(MTK_SMI_BWC_SCEN scen)
{
#if !MMDVFS_ENABLE
	return;
#endif

	MMDVFSMSG("leave %d\n", scen);

#if !defined(SMI_D3)        /* d3 does not need this workaround because the MMCLK is always the highest */
	/*
	 * keep HPM for 4 seconds after exiting camera scenarios to get rid of
	 * cam framework will let us go to normal scenario for a short time
	 * (ex: STOP PREVIEW --> NORMAL --> START PREVIEW)
	 * where the LPM mode (low MMCLK) may cause ISP failures
	 */
	if ((scen == SMI_BWC_SCEN_VR) || (scen == SMI_BWC_SCEN_VR_SLOW)
	|| (scen == SMI_BWC_SCEN_ICFP)) {
		mmdvfs_start_cam_monitor();
	}
#endif              /* !defined(SMI_D3) */

	/* reset scenario voltage to default when it exits */
	mmdvfs_set_step(scen, mmdvfs_get_default_step());
}
Ejemplo n.º 8
0
static void mmdvfs_cam_work_handler(struct work_struct *work)
{
	MMDVFSMSG("CAM handler %d\n", jiffies_to_msecs(jiffies));
	mmdvfs_set_step(MMDVFS_CAM_MON_SCEN, mmdvfs_get_default_step());
}
Ejemplo n.º 9
0
int mmdvfs_set_step(MTK_SMI_BWC_SCEN scenario, mmdvfs_voltage_enum step)
{
	int i, scen_index;
	mmdvfs_voltage_enum final_step = mmdvfs_get_default_step();

#if !MMDVFS_ENABLE
	return 0;
#endif

#if !MMDVFS_ENABLE_WQHD
	/* do nothing if disable MMDVFS in WQHD */
	if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_WQHD) {
		return 0;
	}
#endif /* MMDVFS_ENABLE_WQHD */

	MMDVFSMSG("MMDVFS set voltage scen %d step %d\n", scenario, step);

	if (scenario >= SMI_BWC_SCEN_CNT || (scenario < SMI_BWC_SCEN_NORMAL))
	{
		MMDVFSERR("invalid scenario\n");
		return -1;
	}

	/* dump information */
	mmdvfs_dump_info();

	/* go through all scenarios to decide the final step */
	scen_index = (int)scenario;

	spin_lock(&g_mmdvfs_mgr->scen_lock);
	
	g_mmdvfs_scenario_voltage[scen_index] = step;

	/* one high = final high */
	for (i = 0; i < SMI_BWC_SCEN_CNT; i++) {
		if (g_mmdvfs_scenario_voltage[i] == MMDVFS_VOLTAGE_HIGH) {
			final_step = MMDVFS_VOLTAGE_HIGH;
			break;
		}
	}

	g_mmdvfs_current_step = final_step;
	
	spin_unlock(&g_mmdvfs_mgr->scen_lock);

	MMDVFSMSG("MMDVFS set voltage scen %d step %d final %d\n", scenario, step, final_step);

#if	MMDVFS_ENABLE
	/* call vcore dvfs API */
    if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_WQHD) {	/* WQHD */
    	// TODO: use final_step and retry vcore dvfs
		MMDVFSMSG("HIGH to %d\n", step);
		if (step == MMDVFS_VOLTAGE_LOW) {
			vcorefs_request_dvfs_opp(KR_MM_SCEN, OPPI_LOW_PWR);
		} else {
			vcorefs_request_dvfs_opp(KR_MM_SCEN, OPPI_UNREQ);	
		}
	} else { /* FHD */
		MMDVFSMSG("FHD %d\n", final_step);	
		if (final_step == MMDVFS_VOLTAGE_HIGH) {
			vcorefs_request_dvfs_opp(KR_MM_SCEN, OPPI_PERF);
		} else {
			vcorefs_request_dvfs_opp(KR_MM_SCEN, OPPI_UNREQ);
		}
	}
#endif

	return 0;
}