diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index a7621859f8f4..4a70f2da76ae 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -1028,6 +1028,11 @@ static int mdss_fb_probe(struct platform_device *pdev) if (!pdata) return -EPROBE_DEFER; + if (!mdp_instance) { + pr_err("mdss mdp resource not initialized yet\n"); + return -ENODEV; + } + /* * alloc framebuffer info + par data */ @@ -3280,8 +3285,10 @@ void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo, var->right_margin = pinfo->lcdc.h_front_porch; var->left_margin = pinfo->lcdc.h_back_porch; var->hsync_len = pinfo->lcdc.h_pulse_width; - var->pixclock = KHZ2PICOS((unsigned long int)pinfo->clk_rate/1000); + if (pinfo->clk_rate) + var->pixclock = KHZ2PICOS((unsigned long int) + pinfo->clk_rate/1000); if (pinfo->physical_width) var->width = pinfo->physical_width; if (pinfo->physical_height) diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 1d70f8217515..1219b82cdc03 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -1457,4 +1457,20 @@ void mdss_mdp_wb_free(struct mdss_mdp_writeback *wb); void mdss_mdp_ctl_dsc_setup(struct mdss_mdp_ctl *ctl, struct mdss_panel_info *pinfo); +#ifdef CONFIG_FB_MSM_MDP_NONE +struct mdss_data_type *mdss_mdp_get_mdata(void) +{ + return NULL; +} + +int mdss_mdp_copy_layer_pp_info(struct mdp_input_layer *layer) +{ + return -EFAULT; +} + +void mdss_mdp_free_layer_pp_info(struct mdp_input_layer *layer) +{ +} + +#endif /* CONFIG_FB_MSM_MDP_NONE */ #endif /* MDSS_MDP_H */ diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 1d71225c6d9b..27cc16d9c3cf 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -1002,11 +1002,12 @@ struct mdss_panel_timing *mdss_panel_get_timing_by_name( const char *name); #else static inline int mdss_panel_debugfs_init( - struct mdss_panel_info *panel_info) { return 0; }; + struct mdss_panel_info *panel_info, + char const *panel_name) { return 0; }; static inline void mdss_panel_debugfs_cleanup( - struct mdss_panel_info *panel_info) { }; + struct mdss_panel_info *panel_info) { }; static inline void mdss_panel_debugfsinfo_to_panelinfo( - struct mdss_panel_info *panel_info) { }; + struct mdss_panel_info *panel_info) { }; static inline void mdss_panel_info_from_timing(struct mdss_panel_timing *pt, struct mdss_panel_info *pinfo) { }; static inline struct mdss_panel_timing *mdss_panel_get_timing_by_name( diff --git a/drivers/video/fbdev/msm/mdss_qpic.c b/drivers/video/fbdev/msm/mdss_qpic.c index 00b1dd88dc1b..0f62f2537def 100644 --- a/drivers/video/fbdev/msm/mdss_qpic.c +++ b/drivers/video/fbdev/msm/mdss_qpic.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -32,7 +32,6 @@ #include #include -#include #include "mdss_fb.h" #include "mdss_qpic.h" @@ -71,7 +70,12 @@ static struct platform_driver mdss_qpic_driver = { int qpic_on(struct msm_fb_data_type *mfd) { int ret; + + if (qpic_res->qpic_a_clk) + clk_prepare_enable(qpic_res->qpic_a_clk); + ret = mdss_qpic_panel_on(qpic_res->panel_data, &qpic_res->panel_io); + qpic_res->qpic_is_on = true; return ret; } @@ -81,6 +85,12 @@ int qpic_off(struct msm_fb_data_type *mfd) ret = mdss_qpic_panel_off(qpic_res->panel_data, &qpic_res->panel_io); if (use_irq) qpic_interrupt_en(false); + + if (qpic_res->qpic_a_clk) + clk_disable_unprepare(qpic_res->qpic_a_clk); + + qpic_res->qpic_is_on = false; + return ret; } @@ -110,6 +120,11 @@ static void mdss_qpic_pan_display(struct msm_fb_data_type *mfd) return; } + if (!qpic_res->qpic_is_on) { + pr_err("%s: Failed since panel is not ON\n"); + return; + } + fbi = mfd->fbi; bpp = fbi->var.bits_per_pixel / 8; @@ -210,6 +225,9 @@ int qpic_register_panel(struct mdss_panel_data *pdata) struct platform_device *mdss_fb_dev = NULL; int rc; + if (!qpic_res) + return -ENODEV; + mdss_fb_dev = platform_device_alloc("mdss_fb", pdata->panel_info.pdest); if (!mdss_fb_dev) { pr_err("unable to allocate mdss_fb device\n"); @@ -448,7 +466,7 @@ static int qpic_wait_for_fifo(void) data &= 0x3F; if (data == 0) return ret; - INIT_COMPLETION(qpic_res->fifo_eof_comp); + reinit_completion(&qpic_res->fifo_eof_comp); QPIC_OUTP(QPIC_REG_QPIC_LCDC_IRQ_EN, (1 << 4)); ret = wait_for_completion_timeout(&qpic_res->fifo_eof_comp, msecs_to_jiffies(QPIC_MAX_VSYNC_WAIT_TIME)); @@ -487,7 +505,7 @@ static int qpic_wait_for_eof(void) data = QPIC_INP(QPIC_REG_QPIC_LCDC_IRQ_STTS); if (data & (1 << 2)) return ret; - INIT_COMPLETION(qpic_res->fifo_eof_comp); + reinit_completion(&qpic_res->fifo_eof_comp); QPIC_OUTP(QPIC_REG_QPIC_LCDC_IRQ_EN, (1 << 2)); ret = wait_for_completion_timeout(&qpic_res->fifo_eof_comp, msecs_to_jiffies(QPIC_MAX_VSYNC_WAIT_TIME)); @@ -738,6 +756,10 @@ static int mdss_qpic_probe(struct platform_device *pdev) goto probe_done; } + qpic_res->qpic_a_clk = clk_get(&pdev->dev, "core_a_clk"); + if (IS_ERR(qpic_res->qpic_a_clk)) + pr_err("%s: Can't find core_a_clk", __func__); + qpic_res->irq = res->start; qpic_res->res_init = true; diff --git a/drivers/video/fbdev/msm/mdss_qpic.h b/drivers/video/fbdev/msm/mdss_qpic.h index f8ae6b194d81..c0e3f9aa7ef7 100644 --- a/drivers/video/fbdev/msm/mdss_qpic.h +++ b/drivers/video/fbdev/msm/mdss_qpic.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -15,7 +15,6 @@ #define MDSS_QPIC_H #include -#include #include #include @@ -86,6 +85,8 @@ struct qpic_data_type { struct qpic_panel_io_desc panel_io; u32 bus_handle; struct completion fifo_eof_comp; + u32 qpic_is_on; + struct clk *qpic_a_clk; }; u32 qpic_send_frame( diff --git a/drivers/video/fbdev/msm/mdss_qpic_panel.c b/drivers/video/fbdev/msm/mdss_qpic_panel.c index d888befd9cd7..a1e2b52aaefc 100644 --- a/drivers/video/fbdev/msm/mdss_qpic_panel.c +++ b/drivers/video/fbdev/msm/mdss_qpic_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -224,15 +224,18 @@ static int mdss_panel_parse_dt(struct platform_device *pdev, __func__, __LINE__); return -EINVAL; } - panel_data->panel_info.xres = (!rc ? res[0] : 240); - panel_data->panel_info.yres = (!rc ? res[1] : 320); + + pr_debug("panel res %d %d\n", res[0], res[1]); + panel_data->panel_info.xres = (!rc ? res[0] : 320); + panel_data->panel_info.yres = (!rc ? res[1] : 480); rc = of_property_read_u32(np, "qcom,mdss-pan-bpp", &tmp); if (rc) { pr_err("%s:%d, panel bpp not specified\n", __func__, __LINE__); return -EINVAL; } - panel_data->panel_info.bpp = (!rc ? tmp : 24); + pr_debug("panel bpp %d\n", tmp); + panel_data->panel_info.bpp = (!rc ? tmp : 18); of_property_read_u32(np, "qcom,refresh_rate", &panel_refresh_rate); panel_data->panel_info.type = EBI2_PANEL; @@ -273,10 +276,6 @@ static int mdss_qpic_panel_probe(struct platform_device *pdev) qpic_panel_off = ili9341_off; } - if (qpic_panel_on == ili9341_on) { - vendor_pdata.panel_info.xres = 240; - vendor_pdata.panel_info.yres = 320; - } rc = qpic_register_panel(&vendor_pdata); if (rc) diff --git a/drivers/video/fbdev/msm/mdss_smmu.h b/drivers/video/fbdev/msm/mdss_smmu.h index a7b95f5742b6..788bbff66a89 100644 --- a/drivers/video/fbdev/msm/mdss_smmu.h +++ b/drivers/video/fbdev/msm/mdss_smmu.h @@ -170,7 +170,7 @@ static inline struct dma_buf_attachment *mdss_smmu_dma_buf_attach( struct dma_buf *dma_buf, struct device *dev, int domain) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - if (!mdata->smmu_ops.smmu_dma_buf_attach) + if (!mdata || !mdata->smmu_ops.smmu_dma_buf_attach) return NULL; return mdata->smmu_ops.smmu_dma_buf_attach(dma_buf, dev, domain); @@ -203,7 +203,7 @@ static inline int mdss_smmu_dma_alloc_coherent(struct device *dev, size_t size, gfp_t gfp, int domain) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - if (!mdata->smmu_ops.smmu_dma_alloc_coherent) + if (!mdata || !mdata->smmu_ops.smmu_dma_alloc_coherent) return -ENOSYS; return mdata->smmu_ops.smmu_dma_alloc_coherent(dev, size, diff --git a/drivers/video/fbdev/msm/qpic_panel_ili_qvga.c b/drivers/video/fbdev/msm/qpic_panel_ili_qvga.c index db2cc7b43cbe..9b4960b66a71 100644 --- a/drivers/video/fbdev/msm/qpic_panel_ili_qvga.c +++ b/drivers/video/fbdev/msm/qpic_panel_ili_qvga.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013 - 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -24,8 +24,6 @@ #include #include -#include - #include "mdss.h" #include "mdss_qpic.h" #include "mdss_qpic_panel.h" @@ -45,7 +43,7 @@ static int panel_io_init(struct qpic_panel_io_desc *panel_io) } if (panel_io->avdd_vreg) { rc = regulator_set_voltage(panel_io->avdd_vreg, - 2700000, 2700000); + 2704000, 2704000); if (rc) { pr_err("vdd_vreg->set_voltage failed, rc=%d\n", rc); return -EINVAL; @@ -77,6 +75,9 @@ static void panel_io_off(struct qpic_panel_io_desc *qpic_panel_io) void ili9341_off(struct qpic_panel_io_desc *qpic_panel_io) { + qpic_send_pkt(OP_SET_DISPLAY_OFF, NULL, 0); + /* wait for 20 ms after display off */ + msleep(20); panel_io_off(qpic_panel_io); }