예제 #1
0
파일: mali_pp.c 프로젝트: ChangYX/Linux3188
void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual)
{
	u32 num_frame_registers;
	u32 relative_address;
	u32 start_index;
	u32 nr_of_regs;
	u32 *frame_registers = mali_pp_job_get_frame_registers(job);
	u32 *wb0_registers = mali_pp_job_get_wb0_registers(job);
	u32 *wb1_registers = mali_pp_job_get_wb1_registers(job);
	u32 *wb2_registers = mali_pp_job_get_wb2_registers(job);
	core->counter_src0_used = mali_pp_job_get_perf_counter_src0(job);
	core->counter_src1_used = mali_pp_job_get_perf_counter_src1(job);

	MALI_DEBUG_ASSERT_POINTER(core);

	/* Write frame registers */
	num_frame_registers = (_MALI_PRODUCT_ID_MALI200 == mali_kernel_core_get_product_id()) ? MALI_PP_MALI200_NUM_FRAME_REGISTERS : MALI_PP_MALI400_NUM_FRAME_REGISTERS;

	/*
	 * There are two frame registers which are different for each sub job:
	 * 1. The Renderer List Address Register (MALI200_REG_ADDR_FRAME)
	 * 2. The FS Stack Address Register (MALI200_REG_ADDR_STACK)
	 */
	mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_FRAME / sizeof(u32)]);

	/* For virtual jobs, the stack address shouldn't be broadcast but written individually */
	if (!mali_pp_job_is_virtual(job) || restart_virtual)
	{
		mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_STACK / sizeof(u32)]);
	}

	/* Write registers between MALI200_REG_ADDR_FRAME and MALI200_REG_ADDR_STACK */
	relative_address = MALI200_REG_ADDR_RSW;
	start_index = MALI200_REG_ADDR_RSW / sizeof(u32);
	nr_of_regs = (MALI200_REG_ADDR_STACK - MALI200_REG_ADDR_RSW) / sizeof(u32);

	mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
	        relative_address, &frame_registers[start_index],
	        nr_of_regs, &mali_frame_registers_reset_values[start_index]);

	/* MALI200_REG_ADDR_STACK_SIZE */
	relative_address = MALI200_REG_ADDR_STACK_SIZE;
	start_index = MALI200_REG_ADDR_STACK_SIZE / sizeof(u32);

	mali_hw_core_register_write_relaxed_conditional(&core->hw_core,
	        relative_address, frame_registers[start_index],
	        mali_frame_registers_reset_values[start_index]);

	/* Skip 2 reserved registers */

	/* Write remaining registers */
	relative_address = MALI200_REG_ADDR_ORIGIN_OFFSET_X;
	start_index = MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
	nr_of_regs = num_frame_registers - MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);

	mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
	        relative_address, &frame_registers[start_index],
	        nr_of_regs, &mali_frame_registers_reset_values[start_index]);

	/* Write WBx registers */
	if (wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
	{
		mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
	}

	if (wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
	{
		mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
	}

	if (wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
	{
		mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
	}

	if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
	{
		mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
		mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
	}
	if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
	{
		mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
		mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
	}

	MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description));

	/* Adding barrier to make sure all rester writes are finished */
	_mali_osk_write_mem_barrier();

	/* This is the command that starts the core. */
	mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);

	/* Adding barrier to make sure previous rester writes is finished */
	_mali_osk_write_mem_barrier();
}
예제 #2
0
void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job)
{
	u32 relative_address;
	u32 start_index;
	u32 nr_of_regs;
	u32 *frame_registers = mali_pp_job_get_frame_registers(job);
	u32 *wb0_registers = mali_pp_job_get_wb0_registers(job);
	u32 *wb1_registers = mali_pp_job_get_wb1_registers(job);
	u32 *wb2_registers = mali_pp_job_get_wb2_registers(job);
	u32 counter_src0 = mali_pp_job_get_perf_counter_src0(job, sub_job);
	u32 counter_src1 = mali_pp_job_get_perf_counter_src1(job, sub_job);

	MALI_DEBUG_ASSERT_POINTER(core);

	/* Write registers between MALI200_REG_ADDR_FRAME and MALI200_REG_ADDR_STACK */
	relative_address = MALI200_REG_ADDR_RSW;
	start_index = MALI200_REG_ADDR_RSW / sizeof(u32);
	nr_of_regs = (MALI200_REG_ADDR_STACK - MALI200_REG_ADDR_RSW) / sizeof(u32);

	mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
	        relative_address, &frame_registers[start_index],
	        nr_of_regs, &mali_frame_registers_reset_values[start_index]);

	/* MALI200_REG_ADDR_STACK_SIZE */
	relative_address = MALI200_REG_ADDR_STACK_SIZE;
	start_index = MALI200_REG_ADDR_STACK_SIZE / sizeof(u32);

	mali_hw_core_register_write_relaxed_conditional(&core->hw_core,
	        relative_address, frame_registers[start_index],
	        mali_frame_registers_reset_values[start_index]);

	/* Skip 2 reserved registers */

	/* Write remaining registers */
	relative_address = MALI200_REG_ADDR_ORIGIN_OFFSET_X;
	start_index = MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
	nr_of_regs = MALI_PP_MALI400_NUM_FRAME_REGISTERS - MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);

	mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
	        relative_address, &frame_registers[start_index],
	        nr_of_regs, &mali_frame_registers_reset_values[start_index]);

	/* Write WBx registers */
	if (wb0_registers[0]) { /* M200_WB0_REG_SOURCE_SELECT register */
		mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
	}

	if (wb1_registers[0]) { /* M200_WB1_REG_SOURCE_SELECT register */
		mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
	}

	if (wb2_registers[0]) { /* M200_WB2_REG_SOURCE_SELECT register */
		mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
	}

	if (MALI_HW_CORE_NO_COUNTER != counter_src0) {
		mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, counter_src0);
		mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
	}
	if (MALI_HW_CORE_NO_COUNTER != counter_src1) {
		mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, counter_src1);
		mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
	}

#ifdef CONFIG_MALI400_HEATMAPS_ENABLED
	if(job->uargs.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_HEATMAP_ENABLE) {
		mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERFMON_CONTR, ((job->uargs.tilesx & 0x3FF) << 16) | 1);
		mali_hw_core_register_write_relaxed(&core->hw_core,  MALI200_REG_ADDR_MGMT_PERFMON_BASE, job->uargs.heatmap_mem & 0xFFFFFFF8);
	}
#endif /* CONFIG_MALI400_HEATMAPS_ENABLED */

	MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description));

	/* Adding barrier to make sure all rester writes are finished */
	_mali_osk_write_mem_barrier();

	/* This is the command that starts the core. */
	mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);

	/* Adding barrier to make sure previous rester writes is finished */
	_mali_osk_write_mem_barrier();
}