Пример #1
0
int mdp_hw_init(struct mdp_info *mdp)
{
	int ret;

	ret = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp,
				  MDP_DMA_P_DONE, mdp_dma_to_mddi);
	if (ret)
		return ret;

	mdp_writel(mdp, 0, MDP_INTR_ENABLE);
	mdp_writel(mdp, 0, MDP_DMA_P_HIST_INTR_ENABLE);

	/* XXX: why set this? QCT says it should be > mdp_pclk,
	 * but they never set the clkrate of pclk */
	mdp_set_core_clk(4);
	pr_info("%s: mdp_clk=%lu\n", __func__, clk_get_rate(mdp->clk));

	/* TODO: Configure the VG/RGB pipes fetch data */

	/* this should work for any mdp_clk freq.
	 * TODO: use different value for mdp_clk freqs >= 90Mhz */
	mdp_writel(mdp, 0x27, MDP_DMA_P_FETCH_CFG); /* 8 bytes-burst x 8 req */

	mdp_writel(mdp, 0x3, MDP_EBI2_PORTMAP_MODE);

	/* 3 pending requests */
	mdp_writel(mdp, 0x02222, MDP_MAX_RD_PENDING_CMD_CONFIG);

	/* no overlay processing, sw controls everything */
	mdp_writel(mdp, 0, MDP_LAYERMIXER_IN_CFG);
	mdp_writel(mdp, 1 << 3, MDP_OVERLAYPROC0_CFG);
	mdp_writel(mdp, 1 << 3, MDP_OVERLAYPROC1_CFG);

	/* XXX: HACK! hardcode to do mddi on primary */
	mdp_writel(mdp, 0x2, MDP_DISP_INTF_SEL);
	return 0;
}
Пример #2
0
static int mdp_lcdc_probe(struct platform_device *pdev)
{
	struct msm_lcdc_platform_data *pdata = pdev->dev.platform_data;
	struct mdp_lcdc_info *lcdc;
	int ret = 0;
#ifdef CONFIG_ZTE_UART_USE_RGB_LCD_LVDS
	printk("enter mdp_lcdc_probe \n");
#endif
	if (!pdata) {
		pr_err("%s: no LCDC platform data found\n", __func__);
		return -EINVAL;
	}

	lcdc = kzalloc(sizeof(struct mdp_lcdc_info), GFP_KERNEL);
	if (!lcdc)
		return -ENOMEM;

	/* We don't actually own the clocks, the mdp does. */
	lcdc->mdp_clk = clk_get(mdp_dev->dev.parent, "mdp_clk");
	if (IS_ERR(lcdc->mdp_clk)) {
		pr_err("%s: failed to get mdp_clk\n", __func__);
		ret = PTR_ERR(lcdc->mdp_clk);
		goto err_get_mdp_clk;
	}

	lcdc->pclk = clk_get(mdp_dev->dev.parent, "lcdc_pclk_clk");
	if (IS_ERR(lcdc->pclk)) {
		pr_err("%s: failed to get lcdc_pclk\n", __func__);
		ret = PTR_ERR(lcdc->pclk);
		goto err_get_pclk;
	}

	lcdc->pad_pclk = clk_get(mdp_dev->dev.parent, "lcdc_pad_pclk_clk");
	if (IS_ERR(lcdc->pad_pclk)) {
		pr_err("%s: failed to get lcdc_pad_pclk\n", __func__);
		ret = PTR_ERR(lcdc->pad_pclk);
		goto err_get_pad_pclk;
	}

	init_waitqueue_head(&lcdc->vsync_waitq);
	lcdc->pdata = pdata;
	lcdc->frame_start_cb.func = lcdc_frame_start;

	platform_set_drvdata(pdev, lcdc);

	mdp_out_if_register(mdp_dev, MSM_LCDC_INTERFACE, lcdc, MDP_DMA_P_DONE,
			    lcdc_dma_start);

	precompute_timing_parms(lcdc);

	lcdc->fb_start = pdata->fb_resource->start;
	lcdc->mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);

	lcdc->fb_panel_data.suspend = lcdc_suspend;
	lcdc->fb_panel_data.resume = lcdc_resume;
	lcdc->fb_panel_data.wait_vsync = lcdc_wait_vsync;
	lcdc->fb_panel_data.request_vsync = lcdc_request_vsync;
	lcdc->fb_panel_data.clear_vsync = lcdc_clear_vsync;
	lcdc->fb_panel_data.blank = lcdc_blank;
	lcdc->fb_panel_data.unblank = lcdc_unblank;
	lcdc->fb_panel_data.fb_data = pdata->fb_data;
	lcdc->fb_panel_data.interface_type = MSM_LCDC_INTERFACE;

	ret = lcdc_hw_init(lcdc);
	if (ret) {
		pr_err("%s: Cannot initialize the mdp_lcdc\n", __func__);
		goto err_hw_init;
	}

	lcdc->fb_pdev.name = "msm_panel";
	lcdc->fb_pdev.id = pdata->fb_id;
	lcdc->fb_pdev.resource = pdata->fb_resource;
	lcdc->fb_pdev.num_resources = 1;
	lcdc->fb_pdev.dev.platform_data = &lcdc->fb_panel_data;

	if (pdata->panel_ops->init)
		pdata->panel_ops->init(pdata->panel_ops);

	ret = platform_device_register(&lcdc->fb_pdev);
	if (ret) {
		pr_err("%s: Cannot register msm_panel pdev\n", __func__);
		goto err_plat_dev_reg;
	}

	pr_info("%s: initialized\n", __func__);

	return 0;

err_plat_dev_reg:
err_hw_init:
	platform_set_drvdata(pdev, NULL);
	clk_put(lcdc->pad_pclk);
err_get_pad_pclk:
	clk_put(lcdc->pclk);
err_get_pclk:
	clk_put(lcdc->mdp_clk);
err_get_mdp_clk:
	kfree(lcdc);
	return ret;
}
Пример #3
0
static int mdp_lcdc_probe(struct platform_device *pdev)
{
	struct msm_lcdc_platform_data *pdata = pdev->dev.platform_data;
	struct mdp_lcdc_info *lcdc;
	int ret = 0;
#ifdef CONFIG_MSM_MDP40
	struct mdp4_overlay_pipe *pipe;
	int ptype;
#endif

	if (!pdata) {
		pr_err("%s: no LCDC platform data found\n", __func__);
		return -EINVAL;
	}

	lcdc = kzalloc(sizeof(struct mdp_lcdc_info), GFP_KERNEL);
	if (!lcdc)
		return -ENOMEM;

	/* We don't actually own the clocks, the mdp does. */
	lcdc->mdp_clk = clk_get(mdp_dev->dev.parent, "mdp_clk");
	if (IS_ERR(lcdc->mdp_clk)) {
		pr_err("%s: failed to get mdp_clk\n", __func__);
		ret = PTR_ERR(lcdc->mdp_clk);
		goto err_get_mdp_clk;
	}

	lcdc->pclk = clk_get(mdp_dev->dev.parent, "lcdc_pclk_clk");
	if (IS_ERR(lcdc->pclk)) {
		pr_err("%s: failed to get lcdc_pclk\n", __func__);
		ret = PTR_ERR(lcdc->pclk);
		goto err_get_pclk;
	}

	lcdc->pad_pclk = clk_get(mdp_dev->dev.parent, "lcdc_pad_pclk_clk");
	if (IS_ERR(lcdc->pad_pclk)) {
		pr_err("%s: failed to get lcdc_pad_pclk\n", __func__);
		ret = PTR_ERR(lcdc->pad_pclk);
		goto err_get_pad_pclk;
	}

	init_waitqueue_head(&lcdc->vsync_waitq);
	lcdc->pdata = pdata;
	lcdc->frame_start_cb.func = lcdc_frame_start;

	platform_set_drvdata(pdev, lcdc);
#ifdef CONFIG_MSM_MDP40
	mdp_out_if_register(mdp_dev, MSM_LCDC_INTERFACE, lcdc, INTR_OVERLAY0_DONE,
			    lcdc_overlay_start);
#else
	mdp_out_if_register(mdp_dev, MSM_LCDC_INTERFACE, lcdc, MDP_DMA_P_DONE,
			    lcdc_dma_start);
#endif
	precompute_timing_parms(lcdc);

	lcdc->fb_start = pdata->fb_resource->start;
	lcdc->mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
	if(lcdc->mdp->mdp_dev.color_format)
		lcdc->color_format = lcdc->mdp->mdp_dev.color_format;
	else
		lcdc->color_format = MSM_MDP_OUT_IF_FMT_RGB565;

#ifdef CONFIG_MSM_MDP40
	if (lcdc_pipe == NULL) {
		ptype = mdp4_overlay_format2type(MDP_RGB_565);
		pipe = mdp4_overlay_pipe_alloc(ptype);
		if (!pipe)
			goto err_mdp4_overlay_pipe_alloc;
		pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
		pipe->mixer_num  = MDP4_MIXER0;
		pipe->src_format = MDP_RGB_565;
		mdp4_overlay_format2pipe(pipe);
		pipe->mdp = lcdc->mdp;

		lcdc_pipe = pipe; /* keep it */
	} else {
		pipe = lcdc_pipe;
	}

	pipe->src_height = pdata->fb_data->yres;
	pipe->src_width = pdata->fb_data->xres;
	pipe->src_h = pdata->fb_data->yres;
	pipe->src_w = pdata->fb_data->xres;
	pipe->src_y = 0;
	pipe->src_x = 0;
	pipe->srcp0_addr = (uint32_t) lcdc->fb_start;
	pipe->srcp0_ystride = pdata->fb_data->xres * 2;

	mdp4_overlay_rgb_setup(pipe);
	mdp4_mixer_stage_up(pipe);
#endif

	lcdc->fb_panel_data.suspend = lcdc_suspend;
	lcdc->fb_panel_data.resume = lcdc_resume;
	lcdc->fb_panel_data.wait_vsync = lcdc_wait_vsync;
	lcdc->fb_panel_data.request_vsync = lcdc_request_vsync;
	lcdc->fb_panel_data.clear_vsync = lcdc_clear_vsync;
	lcdc->fb_panel_data.blank = lcdc_blank;
	lcdc->fb_panel_data.unblank = lcdc_unblank;
	lcdc->fb_panel_data.fb_data = pdata->fb_data;
	lcdc->fb_panel_data.interface_type = MSM_LCDC_INTERFACE;
	lcdc->fb_panel_data.shutdown = lcdc_shutdown;

	ret = lcdc_hw_init(lcdc);
	if (ret) {
		pr_err("%s: Cannot initialize the mdp_lcdc\n", __func__);
		goto err_hw_init;
	}

	lcdc->fb_pdev.name = "msm_panel";
	lcdc->fb_pdev.id = pdata->fb_id;
	lcdc->fb_pdev.resource = pdata->fb_resource;
	lcdc->fb_pdev.num_resources = 1;
	lcdc->fb_pdev.dev.platform_data = &lcdc->fb_panel_data;


	ret = platform_device_register(&lcdc->fb_pdev);
	if (ret) {
		pr_err("%s: Cannot register msm_panel pdev\n", __func__);
		goto err_plat_dev_reg;
	}

	pr_info("%s: initialized\n", __func__);

	return 0;

err_plat_dev_reg:
err_hw_init:
#ifdef CONFIG_MSM_MDP40
err_mdp4_overlay_pipe_alloc:
#endif
	platform_set_drvdata(pdev, NULL);
	clk_put(lcdc->pad_pclk);
err_get_pad_pclk:
	clk_put(lcdc->pclk);
err_get_pclk:
	clk_put(lcdc->mdp_clk);
err_get_mdp_clk:
	kfree(lcdc);
	return ret;
}
Пример #4
0
int mdp_hw_init(struct mdp_info *mdp)
{
	int n;

	n = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp,
				  MDP_DMA_P_DONE, mdp_dma_to_mddi);
	if (n)
		return n;

	mdp_writel(mdp, 0, MDP_INTR_ENABLE);

	/* debug interface write access */
	mdp_writel(mdp, 1, 0x60);
	mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE);

#ifndef CONFIG_MSM_MDP22
	/* disable lcdc */
	mdp_writel(mdp, 0, MDP_LCDC_EN);
	/* enable auto clock gating for all blocks by default */
	mdp_writel(mdp, 0xffffffff, MDP_CGC_EN);
	/* reset color/gamma correct parms */
	mdp_writel(mdp, 0, MDP_DMA_P_COLOR_CORRECT_CONFIG);
#endif

	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc);
	mdp_writel(mdp, 1, 0x60);

	for (n = 0; n < ARRAY_SIZE(csc_color_lut); n++)
		mdp_writel(mdp, csc_color_lut[n].val, csc_color_lut[n].reg);

	/* clear up unused fg/main registers */
	/* comp.plane 2&3 ystride */
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120);

	/* unpacked pattern */
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c);

	/* comp.plane 2 & 3 */
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118);

	/* clear unused bg registers */
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);

	for (n = 0; n < ARRAY_SIZE(csc_matrix_config_table); n++)
		mdp_writel(mdp, csc_matrix_config_table[n].val,
			   csc_matrix_config_table[n].reg);

	mdp_ppp_init_scale(mdp);

#ifndef CONFIG_MSM_MDP31
	mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG);
#endif

	return 0;
}
Пример #5
0
static int tvenc_probe(struct platform_device *pdev)
{
	int ret;
	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
	struct tvenc_info *tvenc;
	struct msm_tvenc_platform_data *pdata = pdev->dev.platform_data;

	printk(KERN_INFO "%s()\n", __func__);
	tvenc = kzalloc(sizeof(struct tvenc_info), GFP_KERNEL);
	if (!tvenc)
		return -ENOMEM;

	tvenc->tvenc_clk = clk_get(NULL, "tv_enc_clk");
	if (IS_ERR(tvenc->tvenc_clk)) {
		pr_err("error: can't get tvenc_clk!\n");
		ret = PTR_ERR(tvenc->tvenc_clk);
		goto err_get_tvenc_clk;
	}

	tvenc->tvdac_clk = clk_get(NULL, "tv_dac_clk");
	if (IS_ERR(tvenc->tvdac_clk)) {
		pr_err("error: can't get tvdac_clk!\n");
		ret = PTR_ERR(tvenc->tvdac_clk);
		goto err_get_tvdac_clk;
	}

	init_waitqueue_head(&tvenc->vsync_waitq);
	tvenc->pdata = pdata;
	tvenc->video_relay = pdata->video_relay;
	tvenc->frame_start_cb.func = tvenc_frame_start;

	platform_set_drvdata(pdev, tvenc);
	mdp_out_if_register(mdp_dev, MSM_TV_INTERFACE, tvenc, TV_OUT_DMA3_DONE,
			tvenc_dma_start);

	tvenc->fb_start = pdata->fb_resource->start;
	tvenc->mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);

	tvenc->fb_panel_data.suspend = tvenc_suspend;
	tvenc->fb_panel_data.resume = tvenc_resume;
	tvenc->fb_panel_data.wait_vsync = tvenc_wait_vsync;
	tvenc->fb_panel_data.request_vsync = tvenc_request_vsync;
	tvenc->fb_panel_data.clear_vsync = tvenc_clear_vsync;
	tvenc->fb_panel_data.blank = NULL;
	tvenc->fb_panel_data.unblank = NULL;
	tvenc->fb_panel_data.fb_data = pdata->fb_data;
	tvenc->fb_panel_data.interface_type = MSM_TV_INTERFACE;

	tvenc->fb_pdev.name = "tvfb";
	tvenc->fb_pdev.id = pdata->fb_id;
	tvenc->fb_pdev.resource = pdata->fb_resource;
	tvenc->fb_pdev.num_resources = 1;
	tvenc->fb_pdev.dev.platform_data = &tvenc->fb_panel_data;

	ret = platform_device_register(&tvenc->fb_pdev);
	if (ret) {
		pr_err("%s: Cannot register msm_panel pdev\n", __func__);
		goto err_plat_dev_reg;
	}

	tvenc_base = ioremap(pdev->resource[0].start,
			pdev->resource[0].end - pdev->resource[0].start + 1);
	if (!tvenc_base) {
		pr_err("tvenc_base ioremap failed!\n");
		ret = -ENOMEM;
		goto reg_ioremap_err;
	}
	tvenc_setup_detection(&tvenc->fb_panel_data, 1);

	/* starting address[31..8] of Video frame buffer is CS0 */
	mdp_writel(mdp, (pdata->fb_resource->start) >> 3, MDP_TV_OUT_BUF_ADDR);
	mdp_writel(mdp, 0x4c60674, 0xC0004);	/* flicker filter enabled */
	mdp_writel(mdp, 0x20, 0xC0010);		/* sobel treshold */
	mdp_writel(mdp, 0xeb0010, 0xC0018);	/* Y  Max, Y  min */
	mdp_writel(mdp, 0xf00010, 0xC001C);	/* Cb Max, Cb min */
	mdp_writel(mdp, 0xf00010, 0xC0020);	/* Cb Max, Cb min */
	mdp_writel(mdp, 0x67686970, 0xC000C);	/* add a few chars for CC */
	mdp_writel(mdp, 1, 0xC0000);		/* MDP tv out enable */

	return 0;

reg_ioremap_err:

err_plat_dev_reg:
	clk_put(tvenc->tvenc_clk);
err_get_tvenc_clk:
	clk_put(tvenc->tvdac_clk);
err_get_tvdac_clk:
	kfree(tvenc);

	return ret;
}