예제 #1
0
u32 vcd_init_device_context(struct vcd_drv_ctxt *drv_ctxt,
		u32 ev_code)
{
	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
	u32 rc;
	struct ddl_init_config ddl_init;

	VCD_MSG_LOW("vcd_init_device_context:");

	dev_ctxt->pending_cmd = VCD_CMD_NONE;

	rc = vcd_power_event(dev_ctxt, NULL, VCD_EVT_PWR_DEV_INIT_BEGIN);
	VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_INIT_BEGIN failed");

	VCD_MSG_HIGH("Device powered ON and clocked");
	rc = vcd_sched_create(&dev_ctxt->sched_clnt_list);
	if (VCD_FAILED(rc)) {
		VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_sched_create", rc);

		(void)vcd_power_event(dev_ctxt, NULL,
					  VCD_EVT_PWR_DEV_INIT_FAIL);

		return rc;
	}

	VCD_MSG_HIGH("Created scheduler instance.");

	ddl_init.core_virtual_base_addr = dev_ctxt->device_base_addr;
	ddl_init.interrupt_clr = dev_ctxt->config.interrupt_clr;
	ddl_init.ddl_callback = vcd_ddl_callback;

	rc = ddl_device_init(&ddl_init, NULL);

	if (VCD_FAILED(rc)) {
		VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_device_init", rc);
		vcd_sched_destroy(&dev_ctxt->sched_clnt_list);
		(void)vcd_power_event(dev_ctxt, NULL,
					  VCD_EVT_PWR_DEV_INIT_FAIL);
	} else {
		vcd_device_timer_start(dev_ctxt);
		vcd_do_device_state_transition(drv_ctxt,
						   VCD_DEVICE_STATE_INITING,
						   ev_code);
	}
    #if 0// FEATURE_PANTECH_MMP_QCOM_CR, QC_Case#01099598, bump clock to turbo mode for clip which's macroblock count per second goes beyond 1080p 30fps  
	dev_ctxt->turbo_mode_set = 0;
    #endif

	return rc;
}
u32 vcd_init_device_context(struct vcd_drv_ctxt *drv_ctxt,
		u32 ev_code)
{
	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
	u32 rc;
	struct ddl_init_config ddl_init;

	VCD_MSG_LOW("vcd_init_device_context:");

	dev_ctxt->pending_cmd = VCD_CMD_NONE;

	rc = vcd_power_event(dev_ctxt, NULL, VCD_EVT_PWR_DEV_INIT_BEGIN);
	VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_INIT_BEGIN failed");

	VCD_MSG_HIGH("Device powered ON and clocked");
	rc = vcd_sched_create(&dev_ctxt->sched_clnt_list);
	if (VCD_FAILED(rc)) {
		VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_sched_create", rc);

		(void)vcd_power_event(dev_ctxt, NULL,
					  VCD_EVT_PWR_DEV_INIT_FAIL);

		return rc;
	}

	VCD_MSG_HIGH("Created scheduler instance.");

	ddl_init.core_virtual_base_addr = dev_ctxt->device_base_addr;
	ddl_init.interrupt_clr = dev_ctxt->config.interrupt_clr;
	ddl_init.ddl_callback = vcd_ddl_callback;

	rc = ddl_device_init(&ddl_init, NULL);

	if (VCD_FAILED(rc)) {
		VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_device_init", rc);
		vcd_sched_destroy(&dev_ctxt->sched_clnt_list);
		(void)vcd_power_event(dev_ctxt, NULL,
					  VCD_EVT_PWR_DEV_INIT_FAIL);
	} else {
		vcd_device_timer_start(dev_ctxt);
		vcd_do_device_state_transition(drv_ctxt,
						   VCD_DEVICE_STATE_INITING,
						   ev_code);
	}
	dev_ctxt->turbo_mode_set = 0;

	return rc;
}
void vcd_handle_device_init_failed(struct vcd_drv_ctxt_type_t *p_drv_ctxt,
                                   u32 status)
{
    struct vcd_clnt_ctxt_type_t *p_client;
    struct vcd_clnt_ctxt_type_t *p_tmp_client;

    VCD_MSG_ERROR("Device init failed. status = %d", status);

    p_client = p_drv_ctxt->dev_ctxt.p_cctxt_list_head;
    while (p_client) {
        p_client->callback(VCD_EVT_RESP_OPEN,
                           status, NULL, 0, 0, p_client->p_client_data);

        p_tmp_client = p_client;
        p_client = p_client->p_next;

        vcd_destroy_client_context(p_tmp_client);
    }
    if (ddl_device_release(NULL))
        VCD_MSG_ERROR("Failed: ddl_device_release");

    (void)sched_destroy(p_drv_ctxt->dev_ctxt.sched_hdl);
    p_drv_ctxt->dev_ctxt.sched_hdl = NULL;

    if (vcd_power_event(&p_drv_ctxt->dev_ctxt,
                        NULL, VCD_EVT_PWR_DEV_INIT_FAIL))
        VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_FAIL failed");

    vcd_do_device_state_transition(p_drv_ctxt,
                                   VCD_DEVICE_STATE_NOT_INIT,
                                   DEVICE_STATE_EVENT_NUMBER(pf_dev_cb));
}
예제 #4
0
void vcd_handle_device_init_failed(struct vcd_drv_ctxt *drv_ctxt,
		u32 status)
{
	struct vcd_clnt_ctxt *client;
	struct vcd_clnt_ctxt *tmp_client;

	VCD_MSG_ERROR("Device init failed. status = %d", status);

	client = drv_ctxt->dev_ctxt.cctxt_list_head;
	while (client) {
		client->callback(VCD_EVT_RESP_OPEN,
				   status, NULL, 0, 0, client->client_data);

		tmp_client = client;
		client = client->next;

		vcd_destroy_client_context(tmp_client);
	}
	if (ddl_device_release(NULL))
		VCD_MSG_ERROR("Failed: ddl_device_release");

	vcd_sched_destroy(&drv_ctxt->dev_ctxt.sched_clnt_list);
	if (vcd_power_event(&drv_ctxt->dev_ctxt,
		NULL, VCD_EVT_PWR_DEV_INIT_FAIL))
		VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_FAIL failed");

	vcd_do_device_state_transition(drv_ctxt,
		VCD_DEVICE_STATE_NOT_INIT,
		DEVICE_STATE_EVENT_NUMBER(dev_cb));
}
예제 #5
0
u32 vcd_reset_device_context(struct vcd_drv_ctxt *drv_ctxt,
	u32 ev_code)
{
	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
	u32 rc = VCD_S_SUCCESS;

	VCD_MSG_LOW("vcd_reset_device_context:");
	vcd_reset_device_channels(dev_ctxt);
	rc = vcd_power_event(&drv_ctxt->dev_ctxt, NULL,
						 VCD_EVT_PWR_DEV_TERM_BEGIN);
	VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_TERM_BEGIN failed");
	if (ddl_reset_hw(0))
		VCD_MSG_HIGH("HW Reset done");
	else
		VCD_MSG_FATAL("HW Reset failed");

	(void)vcd_power_event(dev_ctxt, NULL, VCD_EVT_PWR_DEV_TERM_END);

	return VCD_S_SUCCESS;
}
예제 #6
0
static u32 vcd_stop_in_run(struct vcd_clnt_ctxt *cctxt)
{
	u32 rc = VCD_S_SUCCESS;
	VCD_MSG_LOW("vcd_stop_in_run:");
	rc = vcd_stop_cmn(cctxt);
	if (!VCD_FAILED(rc) &&
		(cctxt->status.mask & VCD_FIRST_IP_RCVD)) {
		rc = vcd_power_event(cctxt->dev_ctxt,
				     cctxt, VCD_EVT_PWR_CLNT_LAST_FRAME);
	}
	return rc;
}
예제 #7
0
static u32 vcd_stop_in_run(struct vcd_clnt_ctxt_type_t *p_cctxt)
{
	u32 rc = VCD_S_SUCCESS;

	VCD_MSG_LOW("vcd_stop_in_run:");

	rc = vcd_stop_cmn(p_cctxt);

	if (!VCD_FAILED(rc) && p_cctxt->status.b_first_ip_frame_recvd) {
		rc = vcd_power_event(p_cctxt->p_dev_ctxt,
				     p_cctxt, VCD_EVT_PWR_CLNT_LAST_FRAME);
	}

	return rc;
}
예제 #8
0
static u32 vcd_stop_in_eos(struct vcd_clnt_ctxt *cctxt)
{
	u32 rc = VCD_S_SUCCESS;
	VCD_MSG_LOW("vcd_stop_in_eos:");
	if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) {
		rc = vcd_stop_cmn(cctxt);
		if (!VCD_FAILED(rc)) {
			rc = vcd_power_event(cctxt->dev_ctxt,
				cctxt, VCD_EVT_PWR_CLNT_LAST_FRAME);
			cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF;
		}
	} else
		cctxt->status.mask |= VCD_STOP_PENDING;
	return rc;
}
static u32 vcd_pause_in_run(struct vcd_clnt_ctxt_type_t *p_cctxt)
{
    u32 rc = VCD_S_SUCCESS;

    VCD_MSG_LOW("vcd_pause_in_run:");

    if (p_cctxt->b_sched_clnt_valid) {
        rc = vcd_map_sched_status(sched_suspend_resume_client
                                  (p_cctxt->p_dev_ctxt->sched_hdl,
                                   p_cctxt->sched_clnt_hdl, FALSE));
    }

    VCD_FAILED_RETURN(rc, "Failed: sched_suspend_resume_client");

    if (p_cctxt->status.n_frame_submitted > 0) {
        vcd_do_client_state_transition(p_cctxt,
                                       VCD_CLIENT_STATE_PAUSING,
                                       CLIENT_STATE_EVENT_NUMBER
                                       (pf_pause));

    } else {
        VCD_MSG_HIGH("No client frames are currently being processed");

        vcd_do_client_state_transition(p_cctxt,
                                       VCD_CLIENT_STATE_PAUSED,
                                       CLIENT_STATE_EVENT_NUMBER
                                       (pf_pause));

        p_cctxt->callback(VCD_EVT_RESP_PAUSE,
                          VCD_S_SUCCESS,
                          NULL, 0, p_cctxt, p_cctxt->p_client_data);

        rc = vcd_power_event(p_cctxt->p_dev_ctxt, p_cctxt,
                             VCD_EVT_PWR_CLNT_PAUSE);

        if (VCD_FAILED(rc))
            VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_PAUSE_END failed");

    }

    return VCD_S_SUCCESS;
}
static u32 vcd_resume_in_paused(struct vcd_clnt_ctxt_type_t *p_cctxt)
{
    struct vcd_dev_ctxt_type *p_dev_ctxt = p_cctxt->p_dev_ctxt;
    u32 rc = VCD_S_SUCCESS;

    VCD_MSG_LOW("vcd_resume_in_paused:");

    if (p_cctxt->b_sched_clnt_valid) {

        rc = vcd_power_event(p_cctxt->p_dev_ctxt,
                             p_cctxt, VCD_EVT_PWR_CLNT_RESUME);

        if (VCD_FAILED(rc)) {
            VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_RESUME failed");
        } else {

            rc = vcd_map_sched_status(sched_suspend_resume_client
                                      (p_cctxt->p_dev_ctxt->
                                       sched_hdl,
                                       p_cctxt->sched_clnt_hdl,
                                       TRUE));
            if (VCD_FAILED(rc)) {
                VCD_MSG_ERROR
                ("rc = 0x%x. Failed: "
                 "sched_suspend_resume_client",
                 rc);
            }

        }
        if (!VCD_FAILED(rc))
            vcd_try_submit_frame(p_dev_ctxt);
    }

    if (!VCD_FAILED(rc)) {
        vcd_do_client_state_transition(p_cctxt,
                                       VCD_CLIENT_STATE_RUN,
                                       CLIENT_STATE_EVENT_NUMBER
                                       (pf_resume));
    }

    return rc;
}
예제 #11
0
//LGE_S NEXTi dongkyu31.lee
//static u32 vcd_pause_in_run(struct vcd_clnt_ctxt *cctxt)
static u32 vcd_pause_cmn(struct vcd_clnt_ctxt *cctxt)
{
	u32 rc = VCD_S_SUCCESS;

	//VCD_MSG_LOW("vcd_pause_in_run:");
	VCD_MSG_LOW("vcd_pause_cmn:");

	if (cctxt->sched_clnt_hdl) {
		rc = vcd_sched_suspend_resume_clnt(cctxt, false);
		VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt");
	}

	if (cctxt->status.frame_submitted > 0) {
		vcd_do_client_state_transition(cctxt,
					       VCD_CLIENT_STATE_PAUSING,
					       CLIENT_STATE_EVENT_NUMBER
					       (pause));

	} else {
		VCD_MSG_HIGH("No client frames are currently being processed");

		vcd_do_client_state_transition(cctxt,
					       VCD_CLIENT_STATE_PAUSED,
					       CLIENT_STATE_EVENT_NUMBER
					       (pause));

		cctxt->callback(VCD_EVT_RESP_PAUSE,
				  VCD_S_SUCCESS,
				  NULL, 0, cctxt, cctxt->client_data);

		rc = vcd_power_event(cctxt->dev_ctxt, cctxt,
				     VCD_EVT_PWR_CLNT_PAUSE);

		if (VCD_FAILED(rc))
			VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_PAUSE_END failed");

	}

	return VCD_S_SUCCESS;
}
예제 #12
0
static u32 vcd_resume_in_paused(struct vcd_clnt_ctxt *cctxt)
{
	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
	u32 rc = VCD_S_SUCCESS;

	VCD_MSG_LOW("vcd_resume_in_paused:");


	if (cctxt->sched_clnt_hdl) {
		rc = vcd_power_event(cctxt->dev_ctxt,
				     cctxt, VCD_EVT_PWR_CLNT_RESUME);

		if (VCD_FAILED(rc)) {
			VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_RESUME failed");
		} else {
			rc = vcd_sched_suspend_resume_clnt(cctxt, true);
			if (VCD_FAILED(rc)) {
				VCD_MSG_ERROR
				    ("rc = 0x%x. Failed: "
				     "vcd_sched_suspend_resume_clnt",
				     rc);
			}

		}
		if (!VCD_FAILED(rc)) {
			vcd_do_client_state_transition(cctxt,
						       VCD_CLIENT_STATE_RUN,
						       CLIENT_STATE_EVENT_NUMBER
						       (resume));
			vcd_try_submit_frame(dev_ctxt);
		}
	} else {
		vcd_do_client_state_transition(cctxt,
					       VCD_CLIENT_STATE_RUN,
					       CLIENT_STATE_EVENT_NUMBER
					       (resume));
	}

	return rc;
}
예제 #13
0
static void vcd_clnt_cb_in_pausing
    (struct vcd_clnt_ctxt *cctxt,
     u32 event,
     u32 status,
     void *payload, size_t sz, u32 *ddl_handle, void *const client_data)
{
	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
	u32 rc = VCD_S_SUCCESS;
	u32 frm_trans_end = false;

	VCD_MSG_LOW("vcd_clnt_cb_in_pausing:");

	if (cctxt->ddl_handle != ddl_handle) {
		VCD_MSG_ERROR("ddl_handle mismatch");

		return;
	}

	switch (event) {
	case VCD_EVT_RESP_INPUT_DONE:
		{
			rc = vcd_handle_input_done(cctxt, payload, event,
						   status);

			break;
		}

	case VCD_EVT_RESP_OUTPUT_DONE:
		{
			rc = vcd_handle_frame_done(cctxt, payload, event,
						   status);
			break;
		}
	case VCD_EVT_RESP_OUTPUT_REQ:
		{
			rc = vcd_handle_output_required(cctxt, payload,
				status);
			break;
		}
	case VCD_EVT_IND_OUTPUT_RECONFIG:
		{
			rc = vcd_handle_ind_output_reconfig(cctxt,
				payload, status);
			if (!VCD_FAILED(rc)) {
				frm_trans_end = true;
				payload = NULL;
			}
			break;
		}
	case VCD_EVT_IND_HWERRFATAL:
		{
			vcd_handle_ind_hw_err_fatal(cctxt,
				VCD_EVT_RESP_PAUSE,	status);
			rc = VCD_ERR_FAIL;
			break;
		}
	default:
		{
			VCD_MSG_ERROR
			    ("Unexpected callback event=%d status=%d from DDL",
			     event, status);

			dev_ctxt->command_continue = false;

			break;
		}

	}

	if (!VCD_FAILED(rc)) {

		if (payload &&
			((struct ddl_frame_data_tag *)\
			payload)->frm_trans_end) {

			vcd_mark_frame_channel(cctxt->dev_ctxt);
			frm_trans_end = true;
		}
		if (frm_trans_end && !cctxt->status.frame_submitted) {
			VCD_MSG_HIGH
			    ("All pending frames recvd from DDL");

			cctxt->callback(VCD_EVT_RESP_PAUSE,
					  VCD_S_SUCCESS,
					  NULL,
					  0,
					  cctxt,
					  cctxt->client_data);

			vcd_do_client_state_transition(cctxt,
					VCD_CLIENT_STATE_PAUSED,
					CLIENT_STATE_EVENT_NUMBER
						       (clnt_cb));

			rc = vcd_power_event(cctxt->dev_ctxt,
					     cctxt,
					     VCD_EVT_PWR_CLNT_PAUSE);

			if (VCD_FAILED(rc)) {
				VCD_MSG_ERROR
				    ("VCD_EVT_PWR_CLNT_PAUSE_END"
				     "failed");
			}
		}
	}
}
예제 #14
0
static void vcd_dev_cb_in_initing
	(struct vcd_drv_ctxt *drv_ctxt,
	 u32 event,
	 u32 status,
	 void *payload, size_t sz, u32 *ddl_handle, void *const client_data)
{
	struct vcd_dev_ctxt *dev_ctxt;
	struct vcd_clnt_ctxt *client;
	struct vcd_clnt_ctxt *tmp_client;
	struct vcd_handle_container container;
	u32 rc = VCD_S_SUCCESS;
	u32 client_inited = false;
	u32 fail_all_open = false;

	VCD_MSG_LOW("vcd_dev_cb_in_initing:");

	if (event != VCD_EVT_RESP_DEVICE_INIT) {
		VCD_MSG_ERROR("vcd_dev_cb_in_initing: Unexpected event %d",
				  (int)event);
		return;
	}

	dev_ctxt = &drv_ctxt->dev_ctxt;

	dev_ctxt->command_continue = false;

	if (VCD_FAILED(status)) {
		vcd_handle_device_init_failed(drv_ctxt, status);

		return;
	}

	vcd_do_device_state_transition(drv_ctxt,
					   VCD_DEVICE_STATE_READY,
					   DEVICE_STATE_EVENT_NUMBER(open));

	if (!dev_ctxt->cctxt_list_head) {
		VCD_MSG_HIGH("All clients are closed");

		dev_ctxt->pending_cmd = VCD_CMD_DEVICE_TERM;

		return;
	}

	if (!dev_ctxt->ddl_cmd_ch_depth
		|| !dev_ctxt->trans_tbl)
		rc = vcd_setup_with_ddl_capabilities(dev_ctxt);


	if (VCD_FAILED(rc)) {
		VCD_MSG_ERROR
			("rc = 0x%x: Failed vcd_setup_with_ddl_capabilities",
			 rc);

		fail_all_open = true;
	}

	client = dev_ctxt->cctxt_list_head;
	while (client) {
		if (!fail_all_open)
			rc = vcd_init_client_context(client);


		if (!VCD_FAILED(rc)) {
			container.handle = (void *)client;
			client->callback(VCD_EVT_RESP_OPEN,
					   VCD_S_SUCCESS,
					   &container,
					   sizeof(container),
					   container.handle,
					   client->client_data);

			client = client->next;

			client_inited = true;
		} else {
			VCD_MSG_ERROR
				("rc = 0x%x, Failed: vcd_init_client_context",
				 rc);

			client->callback(VCD_EVT_RESP_OPEN,
					   rc,
					   NULL, 0, 0, client->client_data);

			tmp_client = client;
			client = client->next;

			vcd_destroy_client_context(tmp_client);
		}
	}

	if (!client_inited || fail_all_open) {
		VCD_MSG_ERROR("All client open requests failed");

		dev_ctxt->pending_cmd = VCD_CMD_DEVICE_TERM;
	} else {
		if (vcd_power_event(dev_ctxt, NULL,
					 VCD_EVT_PWR_DEV_INIT_END)) {
			VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_END failed");
		}
	}
}
예제 #15
0
void vcd_continue(void)
{
	struct vcd_drv_ctxt *drv_ctxt;
	struct vcd_dev_ctxt *dev_ctxt;
	u32 command_continue;
	struct vcd_transc *transc;
	u32 rc;
	VCD_MSG_LOW("vcd_continue:");

	drv_ctxt = vcd_get_drv_context();
	dev_ctxt = &drv_ctxt->dev_ctxt;

	dev_ctxt->command_continue = false;

	if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_INIT) {
		VCD_MSG_HIGH("VCD_CMD_DEVICE_INIT is pending");

		dev_ctxt->pending_cmd = VCD_CMD_NONE;

		(void)vcd_init_device_context(drv_ctxt,
			DEVICE_STATE_EVENT_NUMBER(open));
	} else if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_TERM) {
		VCD_MSG_HIGH("VCD_CMD_DEVICE_TERM is pending");

		dev_ctxt->pending_cmd = VCD_CMD_NONE;

		(void)vcd_deinit_device_context(drv_ctxt,
			DEVICE_STATE_EVENT_NUMBER(close));
	} else if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_RESET) {
		VCD_MSG_HIGH("VCD_CMD_DEVICE_RESET is pending");
		dev_ctxt->pending_cmd = VCD_CMD_NONE;
		(void)vcd_reset_device_context(drv_ctxt,
			DEVICE_STATE_EVENT_NUMBER(dev_cb));
	} else {
		if (dev_ctxt->set_perf_lvl_pending) {
			rc = vcd_power_event(dev_ctxt, NULL,
						 VCD_EVT_PWR_DEV_SET_PERFLVL);

			if (VCD_FAILED(rc)) {
				VCD_MSG_ERROR
					("VCD_EVT_PWR_CLNT_SET_PERFLVL failed");
				VCD_MSG_HIGH
					("Not running at desired perf level."
					 "curr=%d, reqd=%d",
					 dev_ctxt->curr_perf_lvl,
					 dev_ctxt->reqd_perf_lvl);
			} else {
				dev_ctxt->set_perf_lvl_pending = false;
			}
		}

		do {
			command_continue = false;

			if (vcd_get_command_channel_in_loop
				(dev_ctxt, &transc)) {
				if (vcd_submit_command_in_continue(dev_ctxt,
					transc))
					command_continue = true;
				else {
					VCD_MSG_MED
						("No more commands to submit");

					vcd_release_command_channel(dev_ctxt,
						transc);

					vcd_release_interim_command_channels
						(dev_ctxt);
				}
			}
		} while (command_continue);

		do {
			command_continue = false;

			if (vcd_get_frame_channel_in_loop
				(dev_ctxt, &transc)) {
				if (vcd_try_submit_frame_in_continue(dev_ctxt,
					transc)) {
					command_continue = true;
				} else {
					VCD_MSG_MED("No more frames to submit");

					vcd_release_frame_channel(dev_ctxt,
								  transc);

					vcd_release_interim_frame_channels
						(dev_ctxt);
				}
			}

		} while (command_continue);

		if (!vcd_core_is_busy(dev_ctxt)) {
			rc = vcd_power_event(dev_ctxt, NULL,
				VCD_EVT_PWR_CLNT_CMD_END);

			if (VCD_FAILED(rc))
				VCD_MSG_ERROR("Failed:"
					"VCD_EVT_PWR_CLNT_CMD_END");
		}
	}
}
예제 #16
0
static void vcd_clnt_cb_in_pausing
    (struct vcd_clnt_ctxt_type_t *p_cctxt,
     u32 event,
     u32 status,
     void *p_payload, u32 size, u32 *ddl_handle, void *const p_client_data)
{
	struct vcd_dev_ctxt_type *p_dev_ctxt = p_cctxt->p_dev_ctxt;
	u32 rc = VCD_S_SUCCESS;
	u32 b_frm_trans_end = FALSE;

	VCD_MSG_LOW("vcd_clnt_cb_in_pausing:");

	if (p_cctxt->ddl_handle != ddl_handle) {
		VCD_MSG_ERROR("ddl_handle mismatch");

		return;
	}

	switch (event) {
	case VCD_EVT_RESP_INPUT_DONE:
		{
			rc = vcd_handle_input_done(p_cctxt, p_payload, event,
						   status);

			break;
		}

	case VCD_EVT_RESP_OUTPUT_DONE:
		{
			rc = vcd_handle_frame_done(p_cctxt, p_payload, event,
						   status);
			break;
		}
	case VCD_EVT_RESP_OUTPUT_REQ:
		{
			rc = vcd_handle_output_required(p_cctxt, p_payload,
				status);
			break;
		}
	case VCD_EVT_IND_OUTPUT_RECONFIG:
		{
			(void) vcd_handle_ind_output_reconfig(p_cctxt,
				p_payload, status);

			b_frm_trans_end = TRUE;
			p_payload = NULL;

			break;
		}
	case VCD_EVT_IND_HWERRFATAL:
		{
			vcd_handle_ind_hw_err_fatal(p_cctxt,
				VCD_EVT_RESP_PAUSE,	status);
			rc = VCD_ERR_FAIL;
			break;
		}
	default:
		{
			VCD_MSG_ERROR
			    ("Unexpected callback event=%d status=%d from DDL",
			     event, status);

			p_dev_ctxt->b_continue = FALSE;

			break;
		}

	}

	if (!VCD_FAILED(rc)) {

		if (p_payload &&
			((struct ddl_frame_data_type_tag *)\
			p_payload)->b_frm_trans_end) {

			vcd_mark_frame_channel(p_cctxt->p_dev_ctxt);
			b_frm_trans_end = TRUE;
		}
		if (b_frm_trans_end && !p_cctxt->status.n_frame_submitted) {
			VCD_MSG_HIGH
			    ("All pending frames recvd from DDL");

			p_cctxt->callback(VCD_EVT_RESP_PAUSE,
					  VCD_S_SUCCESS,
					  NULL,
					  0,
					  p_cctxt,
					  p_cctxt->p_client_data);

			vcd_do_client_state_transition(p_cctxt,
					VCD_CLIENT_STATE_PAUSED,
					CLIENT_STATE_EVENT_NUMBER
						       (pf_clnt_cb));

			rc = vcd_power_event(p_cctxt->p_dev_ctxt,
					     p_cctxt,
					     VCD_EVT_PWR_CLNT_PAUSE);

			if (VCD_FAILED(rc)) {
				VCD_MSG_ERROR
				    ("VCD_EVT_PWR_CLNT_PAUSE_END"
				     "failed");
			}
		}
	}
}
void vcd_continue(void)
{
    struct vcd_drv_ctxt_type_t *p_drv_ctxt;
    struct vcd_dev_ctxt_type *p_dev_ctxt;
    u32 b_continue;
    struct vcd_transc_type *p_transc;
    u32 rc;
    VCD_MSG_LOW("vcd_continue:");

    p_drv_ctxt = vcd_get_drv_context();
    p_dev_ctxt = &p_drv_ctxt->dev_ctxt;

    p_dev_ctxt->b_continue = FALSE;

    if (p_dev_ctxt->e_pending_cmd == VCD_CMD_DEVICE_INIT) {
        VCD_MSG_HIGH("VCD_CMD_DEVICE_INIT is pending");

        p_dev_ctxt->e_pending_cmd = VCD_CMD_NONE;

        (void)vcd_init_device_context(p_drv_ctxt,
                                      DEVICE_STATE_EVENT_NUMBER(pf_open));
    } else if (p_dev_ctxt->e_pending_cmd == VCD_CMD_DEVICE_TERM) {
        VCD_MSG_HIGH("VCD_CMD_DEVICE_TERM is pending");

        p_dev_ctxt->e_pending_cmd = VCD_CMD_NONE;

        (void)vcd_deinit_device_context(p_drv_ctxt,
                                        DEVICE_STATE_EVENT_NUMBER(pf_close));
    } else if (p_dev_ctxt->e_pending_cmd == VCD_CMD_DEVICE_RESET) {
        VCD_MSG_HIGH("VCD_CMD_DEVICE_RESET is pending");
        p_dev_ctxt->e_pending_cmd = VCD_CMD_NONE;
        (void)vcd_reset_device_context(p_drv_ctxt,
                                       DEVICE_STATE_EVENT_NUMBER(pf_dev_cb));
    } else {
        if (p_dev_ctxt->b_set_perf_lvl_pending) {
            rc = vcd_power_event(p_dev_ctxt, NULL,
                                 VCD_EVT_PWR_DEV_SET_PERFLVL);

            if (VCD_FAILED(rc)) {
                VCD_MSG_ERROR
                ("VCD_EVT_PWR_CLNT_SET_PERFLVL failed");
                VCD_MSG_HIGH
                ("Not running at desired perf level."
                 "curr=%d, reqd=%d",
                 p_dev_ctxt->n_curr_perf_lvl,
                 p_dev_ctxt->n_reqd_perf_lvl);
            } else {
                p_dev_ctxt->b_set_perf_lvl_pending = FALSE;
            }
        }

        do {
            b_continue = FALSE;

            if (vcd_get_command_channel_in_loop
                    (p_dev_ctxt, &p_transc)) {
                if (vcd_submit_command_in_continue(p_dev_ctxt,
                                                   p_transc))
                    b_continue = TRUE;
                else {
                    VCD_MSG_MED
                    ("No more commands to submit");

                    vcd_release_command_channel(p_dev_ctxt,
                                                p_transc);

                    vcd_release_interim_command_channels
                    (p_dev_ctxt);
                }
            }
        } while (b_continue);

        do {
            b_continue = FALSE;

            if (vcd_get_frame_channel_in_loop
                    (p_dev_ctxt, &p_transc)) {
                if (vcd_try_submit_frame_in_continue(p_dev_ctxt,
                                                     p_transc)) {
                    b_continue = TRUE;
                } else {
                    VCD_MSG_MED("No more frames to submit");

                    vcd_release_frame_channel(p_dev_ctxt,
                                              p_transc);

                    vcd_release_interim_frame_channels
                    (p_dev_ctxt);
                }
            }

        } while (b_continue);

        if (!vcd_core_is_busy(p_dev_ctxt)) {
            rc = vcd_power_event(p_dev_ctxt, NULL,
                                 VCD_EVT_PWR_CLNT_CMD_END);

            if (VCD_FAILED(rc))
                VCD_MSG_ERROR("Failed:"
                              "VCD_EVT_PWR_CLNT_CMD_END");
        }
    }
}
static void vcd_dev_cb_in_initing
(struct vcd_drv_ctxt_type_t *p_drv_ctxt,
 u32 event,
 u32 status,
 void *p_payload, u32 size, u32 *ddl_handle, void *const p_client_data)
{
    struct vcd_dev_ctxt_type *p_dev_ctxt;
    struct vcd_clnt_ctxt_type_t *p_client;
    struct vcd_clnt_ctxt_type_t *p_tmp_client;
    struct vcd_handle_container_type container;
    u32 rc = VCD_S_SUCCESS;
    u32 b_client_inited = FALSE;
    u32 b_fail_all_open = FALSE;

    VCD_MSG_LOW("vcd_dev_cb_in_initing:");

    if (event != VCD_EVT_RESP_DEVICE_INIT) {
        VCD_MSG_ERROR("vcd_dev_cb_in_initing: Unexpected event %d",
                      (int)event);
        return;
    }

    p_dev_ctxt = &p_drv_ctxt->dev_ctxt;

    p_dev_ctxt->b_continue = FALSE;

    if (VCD_FAILED(status)) {
        vcd_handle_device_init_failed(p_drv_ctxt, status);

        return;
    }

    vcd_do_device_state_transition(p_drv_ctxt,
                                   VCD_DEVICE_STATE_READY,
                                   DEVICE_STATE_EVENT_NUMBER(pf_open));

    if (!p_dev_ctxt->p_cctxt_list_head) {
        VCD_MSG_HIGH("All clients are closed");

        p_dev_ctxt->e_pending_cmd = VCD_CMD_DEVICE_TERM;

        return;
    }

    if (!p_dev_ctxt->n_ddl_cmd_ch_depth
            || !p_dev_ctxt->a_trans_tbl)
        rc = vcd_setup_with_ddl_capabilities(p_dev_ctxt);


    if (VCD_FAILED(rc)) {
        VCD_MSG_ERROR
        ("rc = 0x%x: Failed vcd_setup_with_ddl_capabilities",
         rc);

        b_fail_all_open = TRUE;
    }

    p_client = p_dev_ctxt->p_cctxt_list_head;
    while (p_client) {
        if (!b_fail_all_open)
            rc = vcd_init_client_context(p_client);


        if (!VCD_FAILED(rc)) {
            container.handle = (void *)p_client;
            p_client->callback(VCD_EVT_RESP_OPEN,
                               VCD_S_SUCCESS,
                               &container,
                               sizeof(container),
                               container.handle,
                               p_client->p_client_data);

            p_client = p_client->p_next;

            b_client_inited = TRUE;
        } else {
            VCD_MSG_ERROR
            ("rc = 0x%x, Failed: vcd_init_client_context",
             rc);

            p_client->callback(VCD_EVT_RESP_OPEN,
                               rc,
                               NULL, 0, 0, p_client->p_client_data);

            p_tmp_client = p_client;
            p_client = p_client->p_next;

            vcd_destroy_client_context(p_tmp_client);
        }
    }

    if (!b_client_inited || b_fail_all_open) {
        VCD_MSG_ERROR("All client open requests failed");

        p_dev_ctxt->e_pending_cmd = VCD_CMD_DEVICE_TERM;
    } else {
        if (vcd_power_event(p_dev_ctxt, NULL,
                            VCD_EVT_PWR_DEV_INIT_END)) {
            VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_END failed");
        }
    }
}