static int mdp3_ctrl_intf_init(struct msm_fb_data_type *mfd, struct mdp3_intf *intf) { int rc; struct mdp3_intf_cfg cfg; struct mdp3_video_intf_cfg *video = &cfg.video; struct mdss_panel_info *p = mfd->panel_info; int h_back_porch = p->lcdc.h_back_porch; int h_front_porch = p->lcdc.h_front_porch; int w = p->xres; int v_back_porch = p->lcdc.v_back_porch; int v_front_porch = p->lcdc.v_front_porch; int h = p->yres; int h_sync_skew = p->lcdc.hsync_skew; int h_pulse_width = p->lcdc.h_pulse_width; int v_pulse_width = p->lcdc.v_pulse_width; int hsync_period = h_front_porch + h_back_porch + w + h_pulse_width; int vsync_period = v_front_porch + v_back_porch + h + v_pulse_width; vsync_period *= hsync_period; cfg.type = mdp3_ctrl_get_intf_type(mfd); if (cfg.type == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO || cfg.type == MDP3_DMA_OUTPUT_SEL_LCDC) { video->hsync_period = hsync_period; video->hsync_pulse_width = h_pulse_width; video->vsync_period = vsync_period; video->vsync_pulse_width = v_pulse_width * hsync_period; video->display_start_x = h_back_porch + h_pulse_width; video->display_end_x = hsync_period - h_front_porch - 1; video->display_start_y = (v_back_porch + v_pulse_width) * hsync_period; video->display_end_y = vsync_period - v_front_porch * hsync_period - 1; video->active_start_x = video->display_start_x; video->active_end_x = video->display_end_x; video->active_h_enable = true; video->active_start_y = video->display_start_y; video->active_end_y = video->display_end_y; video->active_v_enable = true; video->hsync_skew = h_sync_skew; video->hsync_polarity = 1; video->vsync_polarity = 1; video->de_polarity = 1; } else if (cfg.type == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { cfg.dsi_cmd.primary_dsi_cmd_id = 0; cfg.dsi_cmd.secondary_dsi_cmd_id = 1; cfg.dsi_cmd.dsi_cmd_tg_intf_sel = 0; } else return -EINVAL; rc = mdp3_intf_init(intf, &cfg); return rc; }
static int mdp3_update_panel_info(struct msm_fb_data_type *mfd, int mode) { int ret = 0; struct mdp3_session_data *mdp3_session; struct mdss_panel_data *panel; u32 intf_type = 0; if (!mfd || !mfd->mdp.private1) return -EINVAL; mdp3_session = mfd->mdp.private1; panel = mdp3_session->panel; if (!panel->event_handler) return 0; ret = panel->event_handler(panel, MDSS_EVENT_DSI_DYNAMIC_SWITCH, (void *)(unsigned long)mode); if (ret) pr_err("Dynamic switch to %s mode failed!\n", mode ? "command" : "video"); if (mode == 1) mfd->panel.type = MIPI_CMD_PANEL; else mfd->panel.type = MIPI_VIDEO_PANEL; if (mfd->panel.type != MIPI_VIDEO_PANEL) mdp3_session->wait_for_dma_done = mdp3_wait_for_dma_done; intf_type = mdp3_ctrl_get_intf_type(mfd); mdp3_session->intf->cfg.type = intf_type; mdp3_session->intf->available = 1; mdp3_session->intf->in_use = 1; mdp3_res->intf[intf_type].in_use = 1; mdp3_intf_init(mdp3_session->intf); mdp3_session->dma->output_config.out_sel = intf_type; mdp3_session->status = mdp3_session->intf->active; return 0; }
int mdp3_ctrl_init(struct msm_fb_data_type *mfd) { struct device *dev = mfd->fbi->dev; struct msm_mdp_interface *mdp3_interface = &mfd->mdp; struct mdp3_session_data *mdp3_session = NULL; u32 intf_type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO; int rc; int splash_mismatch = 0; pr_info("mdp3_ctrl_init\n"); rc = mdp3_parse_dt_splash(mfd); if (rc) splash_mismatch = 1; mdp3_interface->on_fnc = mdp3_ctrl_on; mdp3_interface->off_fnc = mdp3_ctrl_off; mdp3_interface->do_histogram = NULL; mdp3_interface->cursor_update = NULL; mdp3_interface->dma_fnc = mdp3_ctrl_pan_display; mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler; mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff; mdp3_interface->lut_update = mdp3_ctrl_lut_update; mdp3_interface->configure_panel = mdp3_update_panel_info; mdp3_session = kzalloc(sizeof(struct mdp3_session_data), GFP_KERNEL); if (!mdp3_session) { pr_err("fail to allocate mdp3 private data structure"); return -ENOMEM; } mutex_init(&mdp3_session->lock); INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off); INIT_WORK(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done); atomic_set(&mdp3_session->vsync_countdown, 0); mutex_init(&mdp3_session->histo_lock); mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL); if (!mdp3_session->dma) { rc = -ENODEV; goto init_done; } rc = mdp3_dma_init(mdp3_session->dma); if (rc) { pr_err("fail to init dma\n"); goto init_done; } intf_type = mdp3_ctrl_get_intf_type(mfd); mdp3_session->intf = mdp3_get_display_intf(intf_type); if (!mdp3_session->intf) { rc = -ENODEV; goto init_done; } rc = mdp3_intf_init(mdp3_session->intf); if (rc) { pr_err("fail to init interface\n"); goto init_done; } mdp3_session->dma->output_config.out_sel = intf_type; mdp3_session->mfd = mfd; mdp3_session->panel = dev_get_platdata(&mfd->pdev->dev); mdp3_session->status = mdp3_session->intf->active; mdp3_session->overlay.id = MSMFB_NEW_REQUEST; mdp3_bufq_init(&mdp3_session->bufq_in); mdp3_bufq_init(&mdp3_session->bufq_out); mdp3_session->histo_status = 0; mdp3_session->lut_sel = 0; BLOCKING_INIT_NOTIFIER_HEAD(&mdp3_session->notifier_head); init_timer(&mdp3_session->vsync_timer); mdp3_session->vsync_timer.function = mdp3_vsync_timer_func; mdp3_session->vsync_timer.data = (u32)mdp3_session; mdp3_session->vsync_period = 1000 / mfd->panel_info->mipi.frame_rate; mfd->mdp.private1 = mdp3_session; init_completion(&mdp3_session->dma_completion); if (intf_type != MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) mdp3_session->wait_for_dma_done = mdp3_wait_for_dma_done; rc = sysfs_create_group(&dev->kobj, &vsync_fs_attr_group); if (rc) { pr_err("vsync sysfs group creation failed, ret=%d\n", rc); goto init_done; } mdp3_session->vsync_event_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "vsync_event"); if (!mdp3_session->vsync_event_sd) { pr_err("vsync_event sysfs lookup failed\n"); rc = -ENODEV; goto init_done; } rc = mdp3_create_sysfs_link(dev); if (rc) pr_warn("problem creating link to mdp sysfs\n"); kobject_uevent(&dev->kobj, KOBJ_ADD); pr_debug("vsync kobject_uevent(KOBJ_ADD)\n"); if (mdp3_get_cont_spash_en()) { mdp3_session->clk_on = 1; mdp3_session->in_splash_screen = 1; mdp3_ctrl_notifier_register(mdp3_session, &mdp3_session->mfd->mdp_sync_pt_data.notifier); } if (splash_mismatch) { pr_err("splash memory mismatch, stop splash\n"); mdp3_ctrl_off(mfd); } mdp3_session->vsync_before_commit = true; init_done: if (IS_ERR_VALUE(rc)) kfree(mdp3_session); return rc; }