* Re: [PATCH] tmio: call tmiofb_set_par in tmiofb_probe
From: Dmitry Eremin-Solenikov @ 2013-10-19 12:41 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1382003443-5044-1-git-send-email-dbaryshkov@gmail.com>
On Sat, Oct 19, 2013 at 2:48 PM, Jean-Christophe PLAGNIOL-VILLARD
<plagnioj@jcrosoft.com> wrote:
> On 13:50 Thu 17 Oct , Dmitry Eremin-Solenikov wrote:
>> Call tmiofb_set_par() to initlaize fixed variable before registering
>> framebuffer. This is necessary for current kexecboot.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---
>> drivers/video/tmiofb.c | 6 +++++-
>> 1 file changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
>> index deb8733..69fd0f7 100644
>> --- a/drivers/video/tmiofb.c
>> +++ b/drivers/video/tmiofb.c
>> @@ -774,6 +774,10 @@ static int tmiofb_probe(struct platform_device *dev)
>> if (retval)
>> goto err_hw_init;
>>
>> + retval = tmiofb_set_par(info);
>> + if (retval)
>> + goto err_set_par;
>> +
>
> sorry no fix kexecboot
So calling set_par in _probe() is deprecated/fromn upon? Why?
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [Patch v2][ 05/37] fbdev: Add the lacking FB_SYNC_* for matching the DISPLAY_FLAGS_*
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-10-19 11:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382022155-21954-6-git-send-email-denis@eukrea.com>
On 17:02 Thu 17 Oct , Denis Carikli wrote:
> Without that fix, drivers using the fb_videomode_from_videomode
> function will not be able to get certain information because
> some DISPLAY_FLAGS_* have no corresponding FB_SYNC_*.
>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: linux-fbdev@vger.kernel.org
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Stephen Warren <swarren@wwwdotorg.org>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Cc: devicetree@vger.kernel.org
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: Eric Bénard <eric@eukrea.com>
> Signed-off-by: Denis Carikli <denis@eukrea.com>
> ---
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Best Regards,
J.
> drivers/video/fbmon.c | 4 ++++
> include/uapi/linux/fb.h | 2 ++
> 2 files changed, 6 insertions(+)
>
> diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
> index 6103fa6..29a9ed0 100644
> --- a/drivers/video/fbmon.c
> +++ b/drivers/video/fbmon.c
> @@ -1402,6 +1402,10 @@ int fb_videomode_from_videomode(const struct videomode *vm,
> fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
> if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
> fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
> + if (vm->flags & DISPLAY_FLAGS_DE_HIGH)
> + fbmode->sync |= FB_SYNC_DE_HIGH_ACT;
> + if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
> + fbmode->sync |= FB_SYNC_PIXDAT_HIGH_ACT;
> if (vm->flags & DISPLAY_FLAGS_INTERLACED)
> fbmode->vmode |= FB_VMODE_INTERLACED;
> if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
> diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
> index fb795c3..30487df 100644
> --- a/include/uapi/linux/fb.h
> +++ b/include/uapi/linux/fb.h
> @@ -215,6 +215,8 @@ struct fb_bitfield {
> /* vtotal = 144d/288n/576i => PAL */
> /* vtotal = 121d/242n/484i => NTSC */
> #define FB_SYNC_ON_GREEN 32 /* sync on green */
> +#define FB_SYNC_DE_HIGH_ACT 64 /* data enable high active */
> +#define FB_SYNC_PIXDAT_HIGH_ACT 64 /* data enable high active */
>
> #define FB_VMODE_NONINTERLACED 0 /* non interlaced */
> #define FB_VMODE_INTERLACED 1 /* interlaced */
> --
> 1.7.9.5
>
^ permalink raw reply
* Re: [Patch v2][ 07/37] video: mx3fb: Introduce regulator support.
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-10-19 11:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382022155-21954-8-git-send-email-denis@eukrea.com>
On 17:02 Thu 17 Oct , Denis Carikli wrote:
> This commit is based on the following commit by Fabio Estevam:
> 4344429 video: mxsfb: Introduce regulator support
>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: linux-fbdev@vger.kernel.org
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: Eric Bénard <eric@eukrea.com>
> Signed-off-by: Denis Carikli <denis@eukrea.com>
> ---
> drivers/video/mx3fb.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
> index 804f874..37704da 100644
> --- a/drivers/video/mx3fb.c
> +++ b/drivers/video/mx3fb.c
> @@ -27,6 +27,7 @@
> #include <linux/clk.h>
> #include <linux/mutex.h>
> #include <linux/dma/ipu-dma.h>
> +#include <linux/regulator/consumer.h>
>
> #include <linux/platform_data/dma-imx.h>
> #include <linux/platform_data/video-mx3fb.h>
> @@ -267,6 +268,7 @@ struct mx3fb_info {
> struct dma_async_tx_descriptor *txd;
> dma_cookie_t cookie;
> struct scatterlist sg[2];
> + struct regulator *reg_lcd;
>
> struct fb_var_screeninfo cur_var; /* current var info */
> };
> @@ -1001,6 +1003,7 @@ static void __blank(int blank, struct fb_info *fbi)
> struct mx3fb_info *mx3_fbi = fbi->par;
> struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
> int was_blank = mx3_fbi->blank;
> + int ret;
>
> mx3_fbi->blank = blank;
>
> @@ -1019,6 +1022,15 @@ static void __blank(int blank, struct fb_info *fbi)
> case FB_BLANK_HSYNC_SUSPEND:
> case FB_BLANK_NORMAL:
> sdc_set_brightness(mx3fb, 0);
> + if (mx3_fbi->reg_lcd) {
> + if (regulator_is_enabled(mx3_fbi->reg_lcd)) {
do we realy need ot check if enabled?
this should be handled by the regulator API
same as clock I can disable not enabled clock
Best Regards,
J.
> + ret = regulator_disable(mx3_fbi->reg_lcd);
> + if (ret)
> + dev_warn(fbi->device,
> + "lcd regulator disable failed "
> + "with error: %d\n", ret);
> + }
> + }
> memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
> /* Give LCD time to update - enough for 50 and 60 Hz */
> msleep(25);
> @@ -1026,7 +1038,17 @@ static void __blank(int blank, struct fb_info *fbi)
> break;
> case FB_BLANK_UNBLANK:
> sdc_enable_channel(mx3_fbi);
> + if (mx3_fbi->reg_lcd) {
> + if (!regulator_is_enabled(mx3_fbi->reg_lcd)) {
> + ret = regulator_enable(mx3_fbi->reg_lcd);
> + if (ret)
> + dev_warn(fbi->device,
> + "lcd regulator enable failed "
> + "with error: %d\n", ret);
> + }
> + }
> sdc_set_brightness(mx3fb, mx3fb->backlight_level);
> +
> break;
> }
> }
> @@ -1202,6 +1224,7 @@ static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
> {
> struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
> struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
> + int ret;
>
> console_lock();
> fb_set_suspend(mx3fb->fbi, 1);
> @@ -1210,7 +1233,15 @@ static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
> if (mx3_fbi->blank = FB_BLANK_UNBLANK) {
> sdc_disable_channel(mx3_fbi);
> sdc_set_brightness(mx3fb, 0);
> -
> + if (mx3_fbi->reg_lcd) {
> + if (regulator_is_enabled(mx3_fbi->reg_lcd)) {
> + ret = regulator_disable(mx3_fbi->reg_lcd);
> + if (ret)
> + dev_warn(&pdev->dev,
> + "lcd regulator disable failed "
> + "with error: %d\n", ret);
> + }
> + }
> }
> return 0;
> }
> @@ -1222,10 +1253,20 @@ static int mx3fb_resume(struct platform_device *pdev)
> {
> struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
> struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
> + int ret;
>
> if (mx3_fbi->blank = FB_BLANK_UNBLANK) {
> sdc_enable_channel(mx3_fbi);
> sdc_set_brightness(mx3fb, mx3fb->backlight_level);
> + if (mx3_fbi->reg_lcd) {
> + if (!regulator_is_enabled(mx3_fbi->reg_lcd)) {
> + ret = regulator_enable(mx3_fbi->reg_lcd);
> + if (ret)
> + dev_warn(&pdev->dev,
> + "lcd regulator enable failed "
> + "with error: %d\n", ret);
> + }
> + }
> }
>
> console_lock();
> @@ -1438,6 +1479,10 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
> if (ret < 0)
> goto erfb;
>
> + mx3fbi->reg_lcd = devm_regulator_get(dev, "lcd");
> + if (IS_ERR(mx3fbi->reg_lcd))
> + mx3fbi->reg_lcd = NULL;
> +
> return 0;
>
> erfb:
> --
> 1.7.9.5
>
^ permalink raw reply
* Re: [Patch v2][ 08/37] video: mx3fb: Add device tree suport.
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-10-19 11:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382022155-21954-9-git-send-email-denis@eukrea.com>
On 17:02 Thu 17 Oct , Denis Carikli wrote:
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: linux-fbdev@vger.kernel.org
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Stephen Warren <swarren@wwwdotorg.org>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Cc: devicetree@vger.kernel.org
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: Eric Bénard <eric@eukrea.com>
> Signed-off-by: Denis Carikli <denis@eukrea.com>
> ---
> .../devicetree/bindings/video/fsl,mx3-fb.txt | 52 ++++++++
> drivers/video/Kconfig | 2 +
> drivers/video/mx3fb.c | 133 +++++++++++++++++---
> 3 files changed, 171 insertions(+), 16 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/video/fsl,mx3-fb.txt
>
> diff --git a/Documentation/devicetree/bindings/video/fsl,mx3-fb.txt b/Documentation/devicetree/bindings/video/fsl,mx3-fb.txt
> new file mode 100644
> index 0000000..ae0b343
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/fsl,mx3-fb.txt
> @@ -0,0 +1,52 @@
> +Freescale mx3 Framebuffer
> +
> +This framebuffer driver supports the imx31 and imx35 devices.
> +
> +Required properties:
> +- compatible : Must be "fsl,mx3-fb".
> +- reg : Should contain 1 register ranges(address and length).
> +- dmas : Phandle to the ipu dma node as described in
> + Documentation/devicetree/bindings/dma/dma.txt
> +- dma-names : Must be "tx".
> +- clocks : Phandle to the ipu source clock.
> +- display: Phandle to a display node as described in
> + Documentation/devicetree/bindings/video/display-timing.txt
> + Additional, the display node has to define properties:
> + - bits-per-pixel: lcd panel bit-depth.
> +
> +Optional properties:
> +- ipu-disp-format: could be "rgb666", "rgb565", or "rgb888".
> + If not specified defaults to "rgb666".
> +
> +Example:
> +
> + lcdc: mx3fb@53fc00b4 {
> + compatible = "fsl,mx3-fb";
> + reg = <0x53fc00b4 0x0b>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_lcdc_1>;
> + clocks = <&clks 55>;
> + dmas = <&ipu 14>;
> + dma-names = "tx";
> + };
> +
> + ...
> +
> + cmo_qvga: display {
> + model = "CMO-QVGA";
> + bits-per-pixel = <16>;
> + native-mode = <&qvga_timings>;
> + display-timings {
> + qvga_timings: 320x240 {
> + clock-frequency = <6500000>;
> + hactive = <320>;
> + vactive = <240>;
> + hback-porch = <30>;
> + hfront-porch = <38>;
> + vback-porch = <20>;
> + vfront-porch = <3>;
> + hsync-len = <15>;
> + vsync-len = <4>;
> + };
> + };
> + };
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 14317b7..2a638df 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -2359,6 +2359,8 @@ config FB_MX3
> select FB_CFB_FILLRECT
> select FB_CFB_COPYAREA
> select FB_CFB_IMAGEBLIT
> + select VIDEOMODE_HELPERS
> + select FB_MODE_HELPERS
> default y
> help
> This is a framebuffer device for the i.MX31 LCD Controller. So
> diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
> index 37704da..8683dda 100644
> --- a/drivers/video/mx3fb.c
> +++ b/drivers/video/mx3fb.c
> @@ -32,6 +32,8 @@
> #include <linux/platform_data/dma-imx.h>
> #include <linux/platform_data/video-mx3fb.h>
>
> +#include <video/of_display_timing.h>
> +
> #include <asm/io.h>
> #include <asm/uaccess.h>
>
> @@ -759,11 +761,13 @@ static int __set_par(struct fb_info *fbi, bool lock)
> sig_cfg.Hsync_pol = true;
> if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
> sig_cfg.Vsync_pol = true;
> - if (fbi->var.sync & FB_SYNC_CLK_INVERT)
> + if ((fbi->var.sync & FB_SYNC_CLK_INVERT) ||
> + (fbi->var.sync & FB_SYNC_PIXDAT_HIGH_ACT))
> sig_cfg.clk_pol = true;
> if (fbi->var.sync & FB_SYNC_DATA_INVERT)
> sig_cfg.data_pol = true;
> - if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH)
> + if ((fbi->var.sync & FB_SYNC_OE_ACT_HIGH) ||
> + (fbi->var.sync & FB_SYNC_DE_HIGH_ACT))
> sig_cfg.enable_pol = true;
> if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
> sig_cfg.clkidle_en = true;
> @@ -1392,21 +1396,63 @@ static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops)
> return fbi;
> }
>
> +static int match_dt_disp_data(const char *property)
> +{
> + if (!strcmp("rgb666", property))
> + return IPU_DISP_DATA_MAPPING_RGB666;
> + else if (!strcmp("rgb565", property))
> + return IPU_DISP_DATA_MAPPING_RGB565;
> + else if (!strcmp("rgb888", property))
> + return IPU_DISP_DATA_MAPPING_RGB888;
> + else
> + return -EINVAL;
> +}
mode parsing to be a geneirc API
otherwise looks good
Best Regards,
J.
^ permalink raw reply
* Re: [Patch v2][ 10/37] video: imxfb: Also add pwmr for the device tree.
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-10-19 10:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382022155-21954-11-git-send-email-denis@eukrea.com>
On 17:02 Thu 17 Oct , Denis Carikli wrote:
> pwmr has to be set to get the imxfb backlight work,
> though pwmr was only configurable trough the platform data.
>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Stephen Warren <swarren@wwwdotorg.org>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Cc: devicetree@vger.kernel.org
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: linux-fbdev@vger.kernel.org
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: Eric Bénard <eric@eukrea.com>
> Signed-off-by: Denis Carikli <denis@eukrea.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Best Regards,
J.
^ permalink raw reply
* Re: [PATCH] fbdev: fix error return code in metronomefb_probe()
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-10-19 10:52 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <CAPgLHd-FgU-512ivq_eRPqefqb8-7qGY8aoOATiFNZYn-P_4rg@mail.gmail.com>
On 14:25 Sat 12 Oct , Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>
> Fix to return a negative error code from the error handling
> case instead of 0, as done elsewhere in this function.
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Tomi can you take it as a fix
Best Regards,
J.
>
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> ---
> drivers/video/metronomefb.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
> index f30150d..0b36160 100644
> --- a/drivers/video/metronomefb.c
> +++ b/drivers/video/metronomefb.c
> @@ -690,7 +690,8 @@ static int metronomefb_probe(struct platform_device *dev)
> goto err_csum_table;
> }
>
> - if (board->setup_irq(info))
> + retval = board->setup_irq(info);
> + if (retval)
> goto err_csum_table;
>
> retval = metronome_init_regs(par);
>
^ permalink raw reply
* Re: [PATCH] tmio: call tmiofb_set_par in tmiofb_probe
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-10-19 10:48 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1382003443-5044-1-git-send-email-dbaryshkov@gmail.com>
On 13:50 Thu 17 Oct , Dmitry Eremin-Solenikov wrote:
> Call tmiofb_set_par() to initlaize fixed variable before registering
> framebuffer. This is necessary for current kexecboot.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
> drivers/video/tmiofb.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
> index deb8733..69fd0f7 100644
> --- a/drivers/video/tmiofb.c
> +++ b/drivers/video/tmiofb.c
> @@ -774,6 +774,10 @@ static int tmiofb_probe(struct platform_device *dev)
> if (retval)
> goto err_hw_init;
>
> + retval = tmiofb_set_par(info);
> + if (retval)
> + goto err_set_par;
> +
sorry no fix kexecboot
Best Regards,
J.
> fb_videomode_to_modelist(data->modes, data->num_modes,
> &info->modelist);
>
> @@ -787,7 +791,7 @@ static int tmiofb_probe(struct platform_device *dev)
> return 0;
>
> err_register_framebuffer:
> -/*err_set_par:*/
> +err_set_par:
> tmiofb_hw_stop(dev);
> err_hw_init:
> if (cell->disable)
> --
> 1.8.4.rc3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 02/11] video: imxfb: Introduce regulator support.
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-10-19 10:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382108672-23269-2-git-send-email-denis@eukrea.com>
On 17:04 Fri 18 Oct , Denis Carikli wrote:
> This commit is based on the following commit by Fabio Estevam:
> 4344429 video: mxsfb: Introduce regulator support
>
> Cc: Fabio Estevam <fabio.estevam@freescale.com>
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: linux-fbdev@vger.kernel.org
> Cc: Eric Bénard <eric@eukrea.com>
> Signed-off-by: Denis Carikli <denis@eukrea.com>
> ---
> drivers/video/imxfb.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
> index 44ee678..4dd7678 100644
> --- a/drivers/video/imxfb.c
> +++ b/drivers/video/imxfb.c
> @@ -28,6 +28,7 @@
> #include <linux/cpufreq.h>
> #include <linux/clk.h>
> #include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> #include <linux/dma-mapping.h>
> #include <linux/io.h>
> #include <linux/math64.h>
> @@ -145,6 +146,7 @@ struct imxfb_info {
> struct clk *clk_ipg;
> struct clk *clk_ahb;
> struct clk *clk_per;
> + struct regulator *reg_lcd;
> enum imxfb_type devtype;
> bool enabled;
>
> @@ -563,12 +565,23 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
>
> static void imxfb_enable_controller(struct imxfb_info *fbi)
> {
> + int ret;
>
> if (fbi->enabled)
> return;
>
> pr_debug("Enabling LCD controller\n");
>
> + if (fbi->reg_lcd) {
> + ret = regulator_enable(fbi->reg_lcd);
> + if (ret) {
> + dev_err(&fbi->pdev->dev,
> + "lcd regulator enable failed with error: %d\n",
> + ret);
> + return;
> + }
> + }
> +
> writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
>
> /* panning offset 0 (0 pixel offset) */
> @@ -597,6 +610,8 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
>
> static void imxfb_disable_controller(struct imxfb_info *fbi)
> {
> + int ret;
> +
> if (!fbi->enabled)
> return;
>
> @@ -613,6 +628,14 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
> fbi->enabled = false;
>
> writel(0, fbi->regs + LCDC_RMCR);
> +
> + if (fbi->reg_lcd) {
> + ret = regulator_disable(fbi->reg_lcd);
> + if (ret)
> + dev_err(&fbi->pdev->dev,
> + "lcd regulator disable failed with error: %d\n",
> + ret);
> + }
> }
>
> static int imxfb_blank(int blank, struct fb_info *info)
> @@ -1020,6 +1043,10 @@ static int imxfb_probe(struct platform_device *pdev)
> goto failed_register;
> }
>
> + fbi->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
put a warning at list
otherwise looks ok
Best Regards,
J.
> + if (IS_ERR(fbi->reg_lcd))
> + fbi->reg_lcd = NULL;
> +
> imxfb_enable_controller(fbi);
> fbi->pdev = pdev;
> #ifdef PWMR_BACKLIGHT_AVAILABLE
> --
> 1.7.9.5
>
^ permalink raw reply
* Re: [PATCH v3] efifb: prevent null-deref when iterating dmi_list
From: David Herrmann @ 2013-10-19 10:40 UTC (permalink / raw)
To: linux-fbdev@vger.kernel.org
Cc: James Bates, linux-kernel, Tomi Valkeinen,
Jean-Christophe Plagniol-Villard, David Herrmann
In-Reply-To: <1380732219-5458-1-git-send-email-dh.herrmann@gmail.com>
ping
On Wed, Oct 2, 2013 at 6:43 PM, David Herrmann <dh.herrmann@gmail.com> wrote:
> From: James Bates <james.h.bates@gmail.com>
>
> The dmi_list array is initialized using gnu designated initializers, and
> therefore may contain fewer explicitly defined entries as there are
> elements in it. This is because the enum above with M_xyz constants
> contains more items than the designated initializer. Those elements not
> explicitly initialized are implicitly set to 0.
>
> Now efifb_setup() loops through all these array elements, and performs
> a strcmp on each item. For non explicitly initialized elements this will
> be a null pointer:
>
> This patch swaps the check order in the if statement, thus checks first
> whether dmi_list[i].base is null.
>
> Signed-off-by: James Bates <james.h.bates@gmail.com>
> Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
> ---
> v3: fixes the "Author" field and James' email address
>
> drivers/video/efifb.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
> index 7f9ff75..fcb9500 100644
> --- a/drivers/video/efifb.c
> +++ b/drivers/video/efifb.c
> @@ -108,8 +108,8 @@ static int efifb_setup(char *options)
> if (!*this_opt) continue;
>
> for (i = 0; i < M_UNKNOWN; i++) {
> - if (!strcmp(this_opt, efifb_dmi_list[i].optname) &&
> - efifb_dmi_list[i].base != 0) {
> + if (efifb_dmi_list[i].base != 0 &&
> + !strcmp(this_opt, efifb_dmi_list[i].optname)) {
> screen_info.lfb_base = efifb_dmi_list[i].base;
> screen_info.lfb_linelength = efifb_dmi_list[i].stride;
> screen_info.lfb_width = efifb_dmi_list[i].width;
> --
> 1.8.4
>
^ permalink raw reply
* Re: [PATCH v2] pwm-backlight: allow for non-increasing brightness levels
From: Mike Dunn @ 2013-10-18 19:53 UTC (permalink / raw)
To: Thierry Reding
Cc: Richard Purdie, Jingoo Han, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Grant Likely, Rob Herring,
linux-pwm-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Robert Jarzmik, Marek Vasut
In-Reply-To: <20131018074623.GA22291-AwZRO8vwLAwmlAP/+Wk3EA@public.gmane.org>
On 10/18/2013 12:46 AM, Thierry Reding wrote:
> On Sun, Sep 22, 2013 at 09:59:56AM -0700, Mike Dunn wrote:
>> Currently the driver assumes that the values specified in the
>> brightness-levels device tree property increase as they are parsed from
>> left to right. But boards that invert the signal between the PWM output
>> and the backlight will need to specify decreasing brightness-levels.
>> This patch removes the assumption that the last element of the array is
>> the maximum value, and instead searches the array for the maximum value
>> and uses that in the duty cycle calculation.
>>
>> Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
>> ---
>> Changelog:
>> v2:
>> - commit message reworded; correct line wrap used
>> - 'max_level' variable renamed to 'scale'
>> - loop counter variable type changed to unsigned int
>> - value held in scale changed from array index to actual maximum level
>> - blank lines added around loop for readability
>>
>> drivers/video/backlight/pwm_bl.c | 12 ++++++++++--
>> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> Hey Mike,
>
> I've pushed a slightly different version of this patch which gets rid of
> the intermediate max variable and uses the new scale field exclusively
> to pass the same information around. Could you look at the patch from my
> for-next branch in the PWM tree and see whether that still works for the
> specific hardware that you need this for?
Yes looks good.
I also tested the current HEAD of for-next on the Palm Treo 680, including the
enable-gpios DT node property. I will have to do more work and investigation
before I will be able to try the power-supply property, though.
Thanks,
Mike
^ permalink raw reply
* [PATCHv3][ 03/11] video: imxfb: Also add pwmr for the device tree.
From: Denis Carikli @ 2013-10-18 15:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382109422-24454-1-git-send-email-denis@eukrea.com>
pwmr has to be set to get the imxfb backlight work,
though pwmr was only configurable trough the platform data.
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: devicetree@vger.kernel.org
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
.../devicetree/bindings/video/fsl,imx-fb.txt | 3 +++
drivers/video/imxfb.c | 2 ++
2 files changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/video/fsl,imx-fb.txt b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
index 46da08d..ac457ae 100644
--- a/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
+++ b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
@@ -17,6 +17,9 @@ Required nodes:
Optional properties:
- fsl,dmacr: DMA Control Register value. This is optional. By default, the
register is not modified as recommended by the datasheet.
+- fsl,pwmr: LCDC PWM Contrast Control Register value. That property is
+ optional, but defining it is necessary to get the backlight working. If that
+ property is ommited, the register is zeroed.
- fsl,lscr1: LCDC Sharp Configuration Register value.
Example:
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 4dd7678..9da29b3 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -833,6 +833,8 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)
of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr);
+ of_property_read_u32(np, "fsl,pwmr", &fbi->pwmr);
+
/* These two function pointers could be used by some specific
* platforms. */
fbi->lcd_power = NULL;
--
1.7.9.5
^ permalink raw reply related
* [PATCHv3][ 02/11] video: imxfb: Introduce regulator support.
From: Denis Carikli @ 2013-10-18 15:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382109422-24454-1-git-send-email-denis@eukrea.com>
This commit is based on the following commit by Fabio Estevam:
4344429 video: mxsfb: Introduce regulator support
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
drivers/video/imxfb.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 44ee678..4dd7678 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -28,6 +28,7 @@
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/math64.h>
@@ -145,6 +146,7 @@ struct imxfb_info {
struct clk *clk_ipg;
struct clk *clk_ahb;
struct clk *clk_per;
+ struct regulator *reg_lcd;
enum imxfb_type devtype;
bool enabled;
@@ -563,12 +565,23 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
static void imxfb_enable_controller(struct imxfb_info *fbi)
{
+ int ret;
if (fbi->enabled)
return;
pr_debug("Enabling LCD controller\n");
+ if (fbi->reg_lcd) {
+ ret = regulator_enable(fbi->reg_lcd);
+ if (ret) {
+ dev_err(&fbi->pdev->dev,
+ "lcd regulator enable failed with error: %d\n",
+ ret);
+ return;
+ }
+ }
+
writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
/* panning offset 0 (0 pixel offset) */
@@ -597,6 +610,8 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
static void imxfb_disable_controller(struct imxfb_info *fbi)
{
+ int ret;
+
if (!fbi->enabled)
return;
@@ -613,6 +628,14 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
fbi->enabled = false;
writel(0, fbi->regs + LCDC_RMCR);
+
+ if (fbi->reg_lcd) {
+ ret = regulator_disable(fbi->reg_lcd);
+ if (ret)
+ dev_err(&fbi->pdev->dev,
+ "lcd regulator disable failed with error: %d\n",
+ ret);
+ }
}
static int imxfb_blank(int blank, struct fb_info *info)
@@ -1020,6 +1043,10 @@ static int imxfb_probe(struct platform_device *pdev)
goto failed_register;
}
+ fbi->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
+ if (IS_ERR(fbi->reg_lcd))
+ fbi->reg_lcd = NULL;
+
imxfb_enable_controller(fbi);
fbi->pdev = pdev;
#ifdef PWMR_BACKLIGHT_AVAILABLE
--
1.7.9.5
^ permalink raw reply related
* [PATCH 02/11] video: imxfb: Introduce regulator support.
From: Denis Carikli @ 2013-10-18 15:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382108672-23269-1-git-send-email-denis@eukrea.com>
This commit is based on the following commit by Fabio Estevam:
4344429 video: mxsfb: Introduce regulator support
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
drivers/video/imxfb.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 44ee678..4dd7678 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -28,6 +28,7 @@
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/math64.h>
@@ -145,6 +146,7 @@ struct imxfb_info {
struct clk *clk_ipg;
struct clk *clk_ahb;
struct clk *clk_per;
+ struct regulator *reg_lcd;
enum imxfb_type devtype;
bool enabled;
@@ -563,12 +565,23 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
static void imxfb_enable_controller(struct imxfb_info *fbi)
{
+ int ret;
if (fbi->enabled)
return;
pr_debug("Enabling LCD controller\n");
+ if (fbi->reg_lcd) {
+ ret = regulator_enable(fbi->reg_lcd);
+ if (ret) {
+ dev_err(&fbi->pdev->dev,
+ "lcd regulator enable failed with error: %d\n",
+ ret);
+ return;
+ }
+ }
+
writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
/* panning offset 0 (0 pixel offset) */
@@ -597,6 +610,8 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
static void imxfb_disable_controller(struct imxfb_info *fbi)
{
+ int ret;
+
if (!fbi->enabled)
return;
@@ -613,6 +628,14 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
fbi->enabled = false;
writel(0, fbi->regs + LCDC_RMCR);
+
+ if (fbi->reg_lcd) {
+ ret = regulator_disable(fbi->reg_lcd);
+ if (ret)
+ dev_err(&fbi->pdev->dev,
+ "lcd regulator disable failed with error: %d\n",
+ ret);
+ }
}
static int imxfb_blank(int blank, struct fb_info *info)
@@ -1020,6 +1043,10 @@ static int imxfb_probe(struct platform_device *pdev)
goto failed_register;
}
+ fbi->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
+ if (IS_ERR(fbi->reg_lcd))
+ fbi->reg_lcd = NULL;
+
imxfb_enable_controller(fbi);
fbi->pdev = pdev;
#ifdef PWMR_BACKLIGHT_AVAILABLE
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH/RFC v3 00/19] Common Display Framework
From: Andrzej Hajda @ 2013-10-18 11:55 UTC (permalink / raw)
To: Tomi Valkeinen, Laurent Pinchart
Cc: linux-fbdev, dri-devel, Jesse Barnes, Benjamin Gaignard, Tom Gall,
Kyungmin Park, linux-media, Stephen Warren, Mark Zhang,
Alexandre Courbot, Ragesh Radhakrishnan, Thomas Petazzoni,
Sunil Joshi, Maxime Ripard, Vikas Sajjan, Marcus Lorentzon
In-Reply-To: <525FDE54.2070909@ti.com>
On 10/17/2013 02:55 PM, Tomi Valkeinen wrote:
> On 17/10/13 15:26, Andrzej Hajda wrote:
>
>> I am not sure what exactly the encoder performs, if this is only image
>> transport from dispc to panel CDF pipeline in both cases should look like:
>> dispc ----> panel
>> The only difference is that panels will be connected via different Linux bus
>> adapters, but it will be irrelevant to CDF itself. In this case I would say
>> this is DSI-master rather than encoder, or at least that the only
>> function of the
>> encoder is DSI.
> Yes, as I said, it's up to the driver writer how he wants to use CDF. If
> he doesn't see the point of representing the SoC's DSI encoder as a
> separate CDF entity, nobody forces him to do that.
Having it as an entity would cause the 'problem' of two APIs as you
described below :)
One API via control bus, another one via CDF.
>
> On OMAP, we have single DISPC with multiple parallel outputs, and a
> bunch of encoder IPs (MIPI DPI, DSI, DBI, etc). Each encoder IP can be
> connected to some of the DISPC's output. In this case, even if the DSI
> encoder does nothing special, I see it much better to represent the DSI
> encoder as a CDF entity so that the links between DISPC, DSI, and the
> DSI peripherals are all there.
>
>> If display_timings on input and output differs, I suppose it should be
>> modeled
>> as display_entity, as this is an additional functionality(not covered by
>> DSI standard AFAIK).
> Well, DSI standard is about the DSI output. Not about the encoder's
> input, or the internal operation of the encoder.
>
>>>> Of course there are some settings which are not panel dependent and those
>>>> should reside in DSI node.
>>> Exactly. And when the two panels require different non-panel-dependent
>>> settings, how do you represent them in the DT data?
>> non-panel-dependent setting cannot depend on panel, by definition :)
> With "non-panel-dependent" setting I meant something that is a property
> of the DSI master device, but still needs to be configured differently
> for each panel.
>
> Say, pin configuration. When using panel A, the first pin of the DSI
> block could be clock+. With panel B, the first pin could be clock-. This
> configuration is about DSI master, but it is different for each panel.
>
> If we have separate endpoint in the DSI master for each panel, this data
> can be there. If we don't have the endpoint, as is the case with
> separate control bus, where is that data?
I am open to propositions. For me it seems somehow similar to clock mapping
in DT (clock-names are mapped to provider clocks), so I think it could
be put in panel node and it will be parsed by DSI-master.
>
>>>> Could you describe such scenario?
>>> If we have two independent APIs, ctrl and video, that affect the same
>>> underlying hardware, the DSI bus, we could have a scenario like this:
>>>
>>> thread 1:
>>>
>>> ctrl->op_foo();
>>> ctrl->op_bar();
>>>
>>> thread 2:
>>>
>>> video->op_baz();
>>>
>>> Even if all those ops do locking properly internally, the fact that
>>> op_baz() can be called in between op_foo() and op_bar() may cause problems.
>>>
>>> To avoid that issue with two APIs we'd need something like:
>>>
>>> thread 1:
>>>
>>> ctrl->lock();
>>> ctrl->op_foo();
>>> ctrl->op_bar();
>>> ctrl->unlock();
>>>
>>> thread 2:
>>>
>>> video->lock();
>>> video->op_baz();
>>> video->unlock();
>> I should mention I was asking for real hw/drivers configuration.
>> I do not know what do you mean with video->op_baz() ?
>> DSI-master is not modeled in CDF, and only CDF provides video
>> operations.
> It was just an example of the additional complexity with regarding
> locking when using two APIs.
>
> The point is that if the panel driver has two pointers (i.e. API), one
> for the control bus, one for the video bus, and ops on both buses affect
> the same hardware, the locking is not easy.
>
> If, on the other hand, the panel driver only has one API to use, it's
> simple to require the caller to handle any locking.
I guess you are describing scenario with DSI-master having its own entity.
In such case its video ops are accessible at least to all pipeline
neightbourgs and
to pipeline controler, so I do not see how the client side locking would
work anyway.
Additionally multiple panels connected to one DSI also makes it harder.
Thus I do not see that 'client lock' apporach would work anyway, even
using video-source approach.
Andrzej
^ permalink raw reply
* Re: [PATCH] set data enable logic level to low
From: Tomi Valkeinen @ 2013-10-18 8:01 UTC (permalink / raw)
To: Roel Kluin
Cc: Jean-Christophe Plagniol-Villard, linux-omap, linux-fbdev,
linux-kernel
In-Reply-To: <1381704273-31540-1-git-send-email-roel.kluin@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 982 bytes --]
On 14/10/13 01:44, Roel Kluin wrote:
> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
> ---
> drivers/video/omap2/dss/display.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
> index fafe7c9..669a81f 100644
> --- a/drivers/video/omap2/dss/display.c
> +++ b/drivers/video/omap2/dss/display.c
> @@ -266,7 +266,7 @@ void videomode_to_omap_video_timings(const struct videomode *vm,
> OMAPDSS_SIG_ACTIVE_LOW;
> ovt->de_level = vm->flags & DISPLAY_FLAGS_DE_HIGH ?
> OMAPDSS_SIG_ACTIVE_HIGH :
> - OMAPDSS_SIG_ACTIVE_HIGH;
> + OMAPDSS_SIG_ACTIVE_LOW;
> ovt->data_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ?
> OMAPDSS_DRIVE_SIG_RISING_EDGE :
> OMAPDSS_DRIVE_SIG_FALLING_EDGE;
>
Thanks. Next time, please write a patch description and prefix patch
subject with appropriate string. In this case "OMAPDSS: ..." would be fine.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
^ permalink raw reply
* Re: [PATCH v2] pwm-backlight: allow for non-increasing brightness levels
From: Thierry Reding @ 2013-10-18 7:46 UTC (permalink / raw)
To: Mike Dunn
Cc: Richard Purdie, Jingoo Han, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Grant Likely, Rob Herring, linux-pwm, linux-fbdev,
linux-kernel, devicetree, Robert Jarzmik, Marek Vasut
In-Reply-To: <1379869196-19377-1-git-send-email-mikedunn@newsguy.com>
[-- Attachment #1: Type: text/plain, Size: 1384 bytes --]
On Sun, Sep 22, 2013 at 09:59:56AM -0700, Mike Dunn wrote:
> Currently the driver assumes that the values specified in the
> brightness-levels device tree property increase as they are parsed from
> left to right. But boards that invert the signal between the PWM output
> and the backlight will need to specify decreasing brightness-levels.
> This patch removes the assumption that the last element of the array is
> the maximum value, and instead searches the array for the maximum value
> and uses that in the duty cycle calculation.
>
> Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
> ---
> Changelog:
> v2:
> - commit message reworded; correct line wrap used
> - 'max_level' variable renamed to 'scale'
> - loop counter variable type changed to unsigned int
> - value held in scale changed from array index to actual maximum level
> - blank lines added around loop for readability
>
> drivers/video/backlight/pwm_bl.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
Hey Mike,
I've pushed a slightly different version of this patch which gets rid of
the intermediate max variable and uses the new scale field exclusively
to pass the same information around. Could you look at the patch from my
for-next branch in the PWM tree and see whether that still works for the
specific hardware that you need this for?
Thierry
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: How to set fops in "struct platform_pwm_backlight_data"?
From: Mark Zhang @ 2013-10-18 4:48 UTC (permalink / raw)
To: Thierry Reding
Cc: rpurdie, jg1.han, Jean-Christophe PLAGNIOL-VILLARD,
tomi.valkeinen, linux-pwm, linux-fbdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20131017071445.GA2502@ulmo.nvidia.com>
On 10/17/2013 03:14 PM, Thierry Reding wrote:
> On Thu, Oct 17, 2013 at 02:49:57PM +0800, Mark Zhang wrote:
>> Hi,
>>
>> This is the first time I send mail to linux-pwm, I didn't read through
>> the mails in this list, so if somebody already asked this question, I'm
>> sorry about that.
>>
>> I wanna set some fops in "struct platform_pwm_backlight_data". But the
>> currrent probe function in pwm_bl.c says:
>>
>> -------
>> if (!data) {
>> ret = pwm_backlight_parse_dt(&pdev->dev, &defdata);
>> if (ret < 0) {
>> dev_err(&pdev->dev, "failed to find platform data\n");
>> return ret;
>> }
>>
>> data = &defdata;
>> }
>> -------
>>
>> This looks like if we set the platform data for pwm backlight device,
>> "pwm_backlight_parse_dt" will never have a chance to be called, which
>> means the stuffs I defined in backlight DT node will be ignored.
>>
>> If I don't set the platform data for pwm backlight device, according to
>> the pwm_backlight_probe, I will never have a chance to set some fops
>> which I need(like "notify", "check_fb"...).
>>
>> So, what I suppose to do now? Maybe there is a way to set function
>> pointers in DT?
>
> Perhaps you could describe in more detail what you need the functions
> for.
>
Okay, I just want to set the "notify" function pointer in "struct
platform_pwm_backlight_data", because I want to tune the brightness
value before the pwm-bl sets the brightness to hardware. I don't know
how to do that, unless we define the platform data explicitly.
Mark
> Generally you're not supposed to mix DT and platform data. Without more
> info that's about all I can say.
>
> Thierry
>
^ permalink raw reply
* [Patch v2][ 10/37] video: imxfb: Also add pwmr for the device tree.
From: Denis Carikli @ 2013-10-17 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382022155-21954-1-git-send-email-denis@eukrea.com>
pwmr has to be set to get the imxfb backlight work,
though pwmr was only configurable trough the platform data.
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: devicetree@vger.kernel.org
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
.../devicetree/bindings/video/fsl,imx-fb.txt | 3 +++
drivers/video/imxfb.c | 2 ++
2 files changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/video/fsl,imx-fb.txt b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
index 46da08d..ac457ae 100644
--- a/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
+++ b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
@@ -17,6 +17,9 @@ Required nodes:
Optional properties:
- fsl,dmacr: DMA Control Register value. This is optional. By default, the
register is not modified as recommended by the datasheet.
+- fsl,pwmr: LCDC PWM Contrast Control Register value. That property is
+ optional, but defining it is necessary to get the backlight working. If that
+ property is ommited, the register is zeroed.
- fsl,lscr1: LCDC Sharp Configuration Register value.
Example:
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 4dd7678..9da29b3 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -833,6 +833,8 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)
of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr);
+ of_property_read_u32(np, "fsl,pwmr", &fbi->pwmr);
+
/* These two function pointers could be used by some specific
* platforms. */
fbi->lcd_power = NULL;
--
1.7.9.5
^ permalink raw reply related
* [Patch v2][ 09/37] video: imxfb: Introduce regulator support.
From: Denis Carikli @ 2013-10-17 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382022155-21954-1-git-send-email-denis@eukrea.com>
This commit is based on the following commit by Fabio Estevam:
4344429 video: mxsfb: Introduce regulator support
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
drivers/video/imxfb.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 44ee678..4dd7678 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -28,6 +28,7 @@
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/math64.h>
@@ -145,6 +146,7 @@ struct imxfb_info {
struct clk *clk_ipg;
struct clk *clk_ahb;
struct clk *clk_per;
+ struct regulator *reg_lcd;
enum imxfb_type devtype;
bool enabled;
@@ -563,12 +565,23 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
static void imxfb_enable_controller(struct imxfb_info *fbi)
{
+ int ret;
if (fbi->enabled)
return;
pr_debug("Enabling LCD controller\n");
+ if (fbi->reg_lcd) {
+ ret = regulator_enable(fbi->reg_lcd);
+ if (ret) {
+ dev_err(&fbi->pdev->dev,
+ "lcd regulator enable failed with error: %d\n",
+ ret);
+ return;
+ }
+ }
+
writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
/* panning offset 0 (0 pixel offset) */
@@ -597,6 +610,8 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
static void imxfb_disable_controller(struct imxfb_info *fbi)
{
+ int ret;
+
if (!fbi->enabled)
return;
@@ -613,6 +628,14 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
fbi->enabled = false;
writel(0, fbi->regs + LCDC_RMCR);
+
+ if (fbi->reg_lcd) {
+ ret = regulator_disable(fbi->reg_lcd);
+ if (ret)
+ dev_err(&fbi->pdev->dev,
+ "lcd regulator disable failed with error: %d\n",
+ ret);
+ }
}
static int imxfb_blank(int blank, struct fb_info *info)
@@ -1020,6 +1043,10 @@ static int imxfb_probe(struct platform_device *pdev)
goto failed_register;
}
+ fbi->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
+ if (IS_ERR(fbi->reg_lcd))
+ fbi->reg_lcd = NULL;
+
imxfb_enable_controller(fbi);
fbi->pdev = pdev;
#ifdef PWMR_BACKLIGHT_AVAILABLE
--
1.7.9.5
^ permalink raw reply related
* [Patch v2][ 08/37] video: mx3fb: Add device tree suport.
From: Denis Carikli @ 2013-10-17 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382022155-21954-1-git-send-email-denis@eukrea.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: devicetree@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
.../devicetree/bindings/video/fsl,mx3-fb.txt | 52 ++++++++
drivers/video/Kconfig | 2 +
drivers/video/mx3fb.c | 133 +++++++++++++++++---
3 files changed, 171 insertions(+), 16 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/fsl,mx3-fb.txt
diff --git a/Documentation/devicetree/bindings/video/fsl,mx3-fb.txt b/Documentation/devicetree/bindings/video/fsl,mx3-fb.txt
new file mode 100644
index 0000000..ae0b343
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fsl,mx3-fb.txt
@@ -0,0 +1,52 @@
+Freescale mx3 Framebuffer
+
+This framebuffer driver supports the imx31 and imx35 devices.
+
+Required properties:
+- compatible : Must be "fsl,mx3-fb".
+- reg : Should contain 1 register ranges(address and length).
+- dmas : Phandle to the ipu dma node as described in
+ Documentation/devicetree/bindings/dma/dma.txt
+- dma-names : Must be "tx".
+- clocks : Phandle to the ipu source clock.
+- display: Phandle to a display node as described in
+ Documentation/devicetree/bindings/video/display-timing.txt
+ Additional, the display node has to define properties:
+ - bits-per-pixel: lcd panel bit-depth.
+
+Optional properties:
+- ipu-disp-format: could be "rgb666", "rgb565", or "rgb888".
+ If not specified defaults to "rgb666".
+
+Example:
+
+ lcdc: mx3fb@53fc00b4 {
+ compatible = "fsl,mx3-fb";
+ reg = <0x53fc00b4 0x0b>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdc_1>;
+ clocks = <&clks 55>;
+ dmas = <&ipu 14>;
+ dma-names = "tx";
+ };
+
+ ...
+
+ cmo_qvga: display {
+ model = "CMO-QVGA";
+ bits-per-pixel = <16>;
+ native-mode = <&qvga_timings>;
+ display-timings {
+ qvga_timings: 320x240 {
+ clock-frequency = <6500000>;
+ hactive = <320>;
+ vactive = <240>;
+ hback-porch = <30>;
+ hfront-porch = <38>;
+ vback-porch = <20>;
+ vfront-porch = <3>;
+ hsync-len = <15>;
+ vsync-len = <4>;
+ };
+ };
+ };
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 14317b7..2a638df 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2359,6 +2359,8 @@ config FB_MX3
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VIDEOMODE_HELPERS
+ select FB_MODE_HELPERS
default y
help
This is a framebuffer device for the i.MX31 LCD Controller. So
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index 37704da..8683dda 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -32,6 +32,8 @@
#include <linux/platform_data/dma-imx.h>
#include <linux/platform_data/video-mx3fb.h>
+#include <video/of_display_timing.h>
+
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -759,11 +761,13 @@ static int __set_par(struct fb_info *fbi, bool lock)
sig_cfg.Hsync_pol = true;
if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
sig_cfg.Vsync_pol = true;
- if (fbi->var.sync & FB_SYNC_CLK_INVERT)
+ if ((fbi->var.sync & FB_SYNC_CLK_INVERT) ||
+ (fbi->var.sync & FB_SYNC_PIXDAT_HIGH_ACT))
sig_cfg.clk_pol = true;
if (fbi->var.sync & FB_SYNC_DATA_INVERT)
sig_cfg.data_pol = true;
- if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH)
+ if ((fbi->var.sync & FB_SYNC_OE_ACT_HIGH) ||
+ (fbi->var.sync & FB_SYNC_DE_HIGH_ACT))
sig_cfg.enable_pol = true;
if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
sig_cfg.clkidle_en = true;
@@ -1392,21 +1396,63 @@ static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops)
return fbi;
}
+static int match_dt_disp_data(const char *property)
+{
+ if (!strcmp("rgb666", property))
+ return IPU_DISP_DATA_MAPPING_RGB666;
+ else if (!strcmp("rgb565", property))
+ return IPU_DISP_DATA_MAPPING_RGB565;
+ else if (!strcmp("rgb888", property))
+ return IPU_DISP_DATA_MAPPING_RGB888;
+ else
+ return -EINVAL;
+}
+
static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
{
struct device *dev = mx3fb->dev;
struct mx3fb_platform_data *mx3fb_pdata = dev_get_platdata(dev);
- const char *name = mx3fb_pdata->name;
+ struct device_node *np = dev->of_node;
+ const char *name;
+ const char *ipu_disp_format;
unsigned int irq;
struct fb_info *fbi;
struct mx3fb_info *mx3fbi;
const struct fb_videomode *mode;
int ret, num_modes;
+ struct fb_videomode of_mode;
+ enum disp_data_mapping disp_data_fmt = IPU_DISP_DATA_MAPPING_RGB666;
+ struct device_node *display_np, *timings_np;
+
+ if (np) {
+ of_property_read_string(np, "ipu-disp-format",
+ &ipu_disp_format);
+ if (!ipu_disp_format) {
+ dev_err(dev, "Can't get ipu display data mapping.\n");
+ return -EINVAL;
+ }
+
+ mx3fb->disp_data_fmt = match_dt_disp_data(ipu_disp_format);
+ if (mx3fb->disp_data_fmt = -EINVAL) {
+ dev_err(dev, "Illegal display data format \"%s\"\n",
+ ipu_disp_format);
+ return -EINVAL;
+ }
- if (mx3fb_pdata->disp_data_fmt >= ARRAY_SIZE(di_mappings)) {
- dev_err(dev, "Illegal display data format %d\n",
+ display_np = of_parse_phandle(np, "display", 0);
+ if (!display_np) {
+ dev_err(dev, "failed to find display phandle\n");
+ return -ENOENT;
+ }
+
+ of_property_read_string(display_np, "model", &name);
+ } else {
+ name = mx3fb_pdata->name;
+ if (mx3fb_pdata->disp_data_fmt >= ARRAY_SIZE(di_mappings)) {
+ dev_err(dev, "Illegal display data format %d\n",
mx3fb_pdata->disp_data_fmt);
- return -EINVAL;
+ return -EINVAL;
+ }
}
ichan->client = mx3fb;
@@ -1427,12 +1473,39 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
goto emode;
}
- if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) {
- mode = mx3fb_pdata->mode;
- num_modes = mx3fb_pdata->num_modes;
+ if (np) {
+ of_property_read_string(np, "ipu-disp-format",
+ &ipu_disp_format);
+ if (!ipu_disp_format) {
+ dev_err(dev, "Can't get ipu display data mapping.\n");
+ return -EINVAL;
+ }
+
+ disp_data_fmt = match_dt_disp_data(ipu_disp_format);
+
+ if (disp_data_fmt = -EINVAL) {
+ dev_err(dev, "Illegal display data format \"%s\" for "
+ "the node %s\n", ipu_disp_format, np->name);
+ return -EINVAL;
+ }
+
+ ret = of_get_fb_videomode(display_np, &of_mode,
+ OF_USE_NATIVE_MODE);
+ if (!ret) {
+ mode = &of_mode;
+ num_modes = 1;
+ } else {
+ mode = mx3fb_modedb;
+ num_modes = ARRAY_SIZE(mx3fb_modedb);
+ }
} else {
- mode = mx3fb_modedb;
- num_modes = ARRAY_SIZE(mx3fb_modedb);
+ if (mx3fb_pdata->mode || !mx3fb_pdata->num_modes) {
+ mode = mx3fb_pdata->mode;
+ num_modes = mx3fb_pdata->num_modes;
+ } else {
+ mode = mx3fb_modedb;
+ num_modes = ARRAY_SIZE(mx3fb_modedb);
+ }
}
if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode,
@@ -1462,7 +1535,10 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
mx3fbi->mx3fb = mx3fb;
mx3fbi->blank = FB_BLANK_NORMAL;
- mx3fb->disp_data_fmt = mx3fb_pdata->disp_data_fmt;
+ if (!np)
+ mx3fb->disp_data_fmt = mx3fb_pdata->disp_data_fmt;
+ else
+ mx3fb->disp_data_fmt = disp_data_fmt;
init_completion(&mx3fbi->flip_cmpl);
disable_irq(ichan->eof_irq);
@@ -1494,13 +1570,26 @@ emode:
return ret;
}
+static int imx_dma_is_dt_ipu(struct dma_chan *chan)
+{
+ /* Example: 53fc0000.ipu */
+ if (chan && chan->device && chan->device->dev) {
+ char *name = dev_name(chan->device->dev);
+ name = strchr(name, '.');
+ if (name)
+ return !strcmp(name, ".ipu");
+ }
+
+ return 0;
+}
+
static bool chan_filter(struct dma_chan *chan, void *arg)
{
struct dma_chan_request *rq = arg;
struct device *dev;
struct mx3fb_platform_data *mx3fb_pdata;
- if (!imx_dma_is_ipu(chan))
+ if (!imx_dma_is_ipu(chan) && !imx_dma_is_dt_ipu(chan))
return false;
if (!rq)
@@ -1509,8 +1598,12 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
dev = rq->mx3fb->dev;
mx3fb_pdata = dev_get_platdata(dev);
- return rq->id = chan->chan_id &&
- mx3fb_pdata->dma_dev = chan->device->dev;
+ /* When using the devicetree, mx3fb_pdata is NULL */
+ if (imx_dma_is_dt_ipu(chan))
+ return rq->id = chan->chan_id;
+ else
+ return rq->id = chan->chan_id &&
+ mx3fb_pdata->dma_dev = chan->device->dev;
}
static void release_fbi(struct fb_info *fbi)
@@ -1567,7 +1660,8 @@ static int mx3fb_probe(struct platform_device *pdev)
dma_cap_set(DMA_SLAVE, mask);
dma_cap_set(DMA_PRIVATE, mask);
rq.id = IDMAC_SDC_0;
- chan = dma_request_channel(mask, chan_filter, &rq);
+ chan = dma_request_slave_channel_compat(mask, chan_filter, &rq, dev,
+ "tx");
if (!chan) {
ret = -EBUSY;
goto ersdc0;
@@ -1610,9 +1704,16 @@ static int mx3fb_remove(struct platform_device *dev)
return 0;
}
+static struct of_device_id mx3fb_of_dev_id[] = {
+ { .compatible = "fsl,mx3-fb", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mx3fb_of_dev_id);
+
static struct platform_driver mx3fb_driver = {
.driver = {
.name = MX3FB_NAME,
+ .of_match_table = mx3fb_of_dev_id,
.owner = THIS_MODULE,
},
.probe = mx3fb_probe,
--
1.7.9.5
^ permalink raw reply related
* [Patch v2][ 07/37] video: mx3fb: Introduce regulator support.
From: Denis Carikli @ 2013-10-17 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382022155-21954-1-git-send-email-denis@eukrea.com>
This commit is based on the following commit by Fabio Estevam:
4344429 video: mxsfb: Introduce regulator support
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
drivers/video/mx3fb.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index 804f874..37704da 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -27,6 +27,7 @@
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/dma/ipu-dma.h>
+#include <linux/regulator/consumer.h>
#include <linux/platform_data/dma-imx.h>
#include <linux/platform_data/video-mx3fb.h>
@@ -267,6 +268,7 @@ struct mx3fb_info {
struct dma_async_tx_descriptor *txd;
dma_cookie_t cookie;
struct scatterlist sg[2];
+ struct regulator *reg_lcd;
struct fb_var_screeninfo cur_var; /* current var info */
};
@@ -1001,6 +1003,7 @@ static void __blank(int blank, struct fb_info *fbi)
struct mx3fb_info *mx3_fbi = fbi->par;
struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
int was_blank = mx3_fbi->blank;
+ int ret;
mx3_fbi->blank = blank;
@@ -1019,6 +1022,15 @@ static void __blank(int blank, struct fb_info *fbi)
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_NORMAL:
sdc_set_brightness(mx3fb, 0);
+ if (mx3_fbi->reg_lcd) {
+ if (regulator_is_enabled(mx3_fbi->reg_lcd)) {
+ ret = regulator_disable(mx3_fbi->reg_lcd);
+ if (ret)
+ dev_warn(fbi->device,
+ "lcd regulator disable failed "
+ "with error: %d\n", ret);
+ }
+ }
memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
/* Give LCD time to update - enough for 50 and 60 Hz */
msleep(25);
@@ -1026,7 +1038,17 @@ static void __blank(int blank, struct fb_info *fbi)
break;
case FB_BLANK_UNBLANK:
sdc_enable_channel(mx3_fbi);
+ if (mx3_fbi->reg_lcd) {
+ if (!regulator_is_enabled(mx3_fbi->reg_lcd)) {
+ ret = regulator_enable(mx3_fbi->reg_lcd);
+ if (ret)
+ dev_warn(fbi->device,
+ "lcd regulator enable failed "
+ "with error: %d\n", ret);
+ }
+ }
sdc_set_brightness(mx3fb, mx3fb->backlight_level);
+
break;
}
}
@@ -1202,6 +1224,7 @@ static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
{
struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
+ int ret;
console_lock();
fb_set_suspend(mx3fb->fbi, 1);
@@ -1210,7 +1233,15 @@ static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
if (mx3_fbi->blank = FB_BLANK_UNBLANK) {
sdc_disable_channel(mx3_fbi);
sdc_set_brightness(mx3fb, 0);
-
+ if (mx3_fbi->reg_lcd) {
+ if (regulator_is_enabled(mx3_fbi->reg_lcd)) {
+ ret = regulator_disable(mx3_fbi->reg_lcd);
+ if (ret)
+ dev_warn(&pdev->dev,
+ "lcd regulator disable failed "
+ "with error: %d\n", ret);
+ }
+ }
}
return 0;
}
@@ -1222,10 +1253,20 @@ static int mx3fb_resume(struct platform_device *pdev)
{
struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
+ int ret;
if (mx3_fbi->blank = FB_BLANK_UNBLANK) {
sdc_enable_channel(mx3_fbi);
sdc_set_brightness(mx3fb, mx3fb->backlight_level);
+ if (mx3_fbi->reg_lcd) {
+ if (!regulator_is_enabled(mx3_fbi->reg_lcd)) {
+ ret = regulator_enable(mx3_fbi->reg_lcd);
+ if (ret)
+ dev_warn(&pdev->dev,
+ "lcd regulator enable failed "
+ "with error: %d\n", ret);
+ }
+ }
}
console_lock();
@@ -1438,6 +1479,10 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
if (ret < 0)
goto erfb;
+ mx3fbi->reg_lcd = devm_regulator_get(dev, "lcd");
+ if (IS_ERR(mx3fbi->reg_lcd))
+ mx3fbi->reg_lcd = NULL;
+
return 0;
erfb:
--
1.7.9.5
^ permalink raw reply related
* [Patch v2][ 05/37] fbdev: Add the lacking FB_SYNC_* for matching the DISPLAY_FLAGS_*
From: Denis Carikli @ 2013-10-17 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382022155-21954-1-git-send-email-denis@eukrea.com>
Without that fix, drivers using the fb_videomode_from_videomode
function will not be able to get certain information because
some DISPLAY_FLAGS_* have no corresponding FB_SYNC_*.
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: devicetree@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
drivers/video/fbmon.c | 4 ++++
include/uapi/linux/fb.h | 2 ++
2 files changed, 6 insertions(+)
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 6103fa6..29a9ed0 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -1402,6 +1402,10 @@ int fb_videomode_from_videomode(const struct videomode *vm,
fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (vm->flags & DISPLAY_FLAGS_DE_HIGH)
+ fbmode->sync |= FB_SYNC_DE_HIGH_ACT;
+ if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
+ fbmode->sync |= FB_SYNC_PIXDAT_HIGH_ACT;
if (vm->flags & DISPLAY_FLAGS_INTERLACED)
fbmode->vmode |= FB_VMODE_INTERLACED;
if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
index fb795c3..30487df 100644
--- a/include/uapi/linux/fb.h
+++ b/include/uapi/linux/fb.h
@@ -215,6 +215,8 @@ struct fb_bitfield {
/* vtotal = 144d/288n/576i => PAL */
/* vtotal = 121d/242n/484i => NTSC */
#define FB_SYNC_ON_GREEN 32 /* sync on green */
+#define FB_SYNC_DE_HIGH_ACT 64 /* data enable high active */
+#define FB_SYNC_PIXDAT_HIGH_ACT 64 /* data enable high active */
#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
#define FB_VMODE_INTERLACED 1 /* interlaced */
--
1.7.9.5
^ permalink raw reply related
* Backlight enabled by default
From: Thierry Reding @ 2013-10-17 14:41 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Jingoo Han, 'Tomi Valkeinen', 'Richard Purdie',
'Jean-Christophe Plagniol-Villard', linux-fbdev,
linux-kernel, 'Laurent Pinchart'
[-- Attachment #1: Type: text/plain, Size: 2126 bytes --]
While working on integrating backlight functionality with the DRM sub-
system, I came across an oddity of sorts. The backlight subsystem seems
to have an implicit policy of enabling the backlight device when it's
registered. Pretty much every driver seems to do something like this in
.probe():
bl->props.brightness = default_brightness;
bl->props.fb_blank = FB_BLANK_UNBLANK;
backlight_update_status(bl);
There are variations of this theme, but the tendency is certainly to
enable the backlight once it has been registered. Some don't even set
the .fb_blank field, so it will usually stay initialized to zero, which
happens to be FB_BLANK_UNBLANK, so the result will be the same.
I understand that this is actually useful when using something such as
fbdev where the backlight isn't necessarily bound to a display device,
but when used in conjunction with a higher-level API such as DRM, then
this default behaviour becomes somewhat annoying.
The problem is that backlight devices are usually instantiated
separately from the display driver, so with the current default the
backlight will be enabled at some random point in time during boot.
However, DRM for example provides for a display to control very
precisely when the backlight should be enabled, which in turn makes it
easy to light it up right after the display has initialized. If the
backlight is turned on right after it has been probed this could mean
that the display hasn't been initialized yet and therefore there's no
meaningful content yet, and worse, the display might show garbage during
initialization of the display controller.
So I wonder if perhaps a better default would be to not enable the
backlight on boot. If so, this will actually cause a regression of some
sort on non-DRM systems because suddenly the backlight is no longer
enabled by default on boot.
Does anyone have any comments or ideas?
My first reaction was to add a property to the DT so that the driver
could skip enabling the backlight, but I don't think that will be
accepted because it encodes software policy in DT rather than purely
a description of hardware.
Thierry
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH v2] omapdss: Add new panel driver for Topolly td028ttec1 LCD.
From: Marek Belisko @ 2013-10-17 14:14 UTC (permalink / raw)
To: tomi.valkeinen
Cc: plagnioj, linux-kernel, linux-omap, linux-fbdev, Marek Belisko,
H. Nikolaus Schaller
Signed-off-by: Marek Belisko <marek@goldelico.com>
Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
changes from v1:
- reworked to be spi driver instead platform with custom spi bitbang
this configuration was tested with spi_gpio bitbang driver on gta04 board
and works fine (thanks Tomi and Lars-Peter for comments)
- address previous comments
drivers/video/omap2/displays-new/Kconfig | 6 +
drivers/video/omap2/displays-new/Makefile | 1 +
.../omap2/displays-new/panel-tpo-td028ttec1.c | 486 +++++++++++++++++++++
include/video/omap-panel-data.h | 13 +
4 files changed, 506 insertions(+)
create mode 100644 drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
index 6c90885..1054249 100644
--- a/drivers/video/omap2/displays-new/Kconfig
+++ b/drivers/video/omap2/displays-new/Kconfig
@@ -56,6 +56,12 @@ config DISPLAY_PANEL_SHARP_LS037V7DW01
help
LCD Panel used in TI's SDP3430 and EVM boards
+config DISPLAY_PANEL_TPO_TD028TTEC1
+ tristate "TPO TD028TTEC1 LCD Panel"
+ depends on SPI
+ help
+ LCD panel used in Openmoko.
+
config DISPLAY_PANEL_TPO_TD043MTEA1
tristate "TPO TD043MTEA1 LCD Panel"
depends on SPI
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
index 5aeb11b..0323a8a 100644
--- a/drivers/video/omap2/displays-new/Makefile
+++ b/drivers/video/omap2/displays-new/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o
obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
+obj-$(CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
diff --git a/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
new file mode 100644
index 0000000..5a44d30
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
@@ -0,0 +1,486 @@
+/*
+ * Toppoly TD028TTEC1 panel support
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Neo 1973 code (jbt6k74.c):
+ * Copyright (C) 2006-2007 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ *
+ * Ported and adapted from Neo 1973 U-Boot by:
+ * H. Nikolaus Schaller <hns@goldelico.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
+struct panel_drv_data {
+ struct omap_dss_device dssdev;
+ struct omap_dss_device *in;
+
+ int data_lines;
+
+ struct omap_video_timings videomode;
+
+ struct spi_device *spi_dev;
+
+ u16 tx_buf[4];
+};
+
+static struct omap_video_timings td028ttec1_panel_timings = {
+ .x_res = 480,
+ .y_res = 640,
+ .pixel_clock = 22153,
+ .hfp = 24,
+ .hsw = 8,
+ .hbp = 8,
+ .vfp = 4,
+ .vsw = 2,
+ .vbp = 2,
+
+ .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+ .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+
+ .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
+ .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
+ .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
+};
+
+#define JBT_COMMAND 0x000
+#define JBT_DATA 0x100
+
+int jbt_reg_write_nodata(struct panel_drv_data *ddata, u8 reg)
+{
+ int rc;
+
+ ddata->tx_buf[0] = JBT_COMMAND | reg;
+ rc = spi_write(ddata->spi_dev, (u8 *)ddata->tx_buf,
+ 1*sizeof(u16));
+ if (rc != 0)
+ dev_err(&ddata->spi_dev->dev,
+ "jbt_reg_write_nodata spi_write ret %d\n", rc);
+
+ return rc;
+}
+
+int jbt_reg_write(struct panel_drv_data *ddata, u8 reg, u8 data)
+{
+ int rc;
+
+ ddata->tx_buf[0] = JBT_COMMAND | reg;
+ ddata->tx_buf[1] = JBT_DATA | data;
+ rc = spi_write(ddata->spi_dev, (u8 *)ddata->tx_buf,
+ 2*sizeof(u16));
+ if (rc != 0)
+ dev_err(&ddata->spi_dev->dev,
+ "jbt_reg_write spi_write ret %d\n", rc);
+
+ return rc;
+}
+
+int jbt_reg_write16(struct panel_drv_data *ddata, u8 reg, u16 data)
+{
+ int rc;
+
+ ddata->tx_buf[0] = JBT_COMMAND | reg;
+ ddata->tx_buf[1] = JBT_DATA | (data >> 8);
+ ddata->tx_buf[2] = JBT_DATA | (data & 0xff);
+
+ rc = spi_write(ddata->spi_dev, (u8 *)ddata->tx_buf,
+ 3*sizeof(u16));
+
+ if (rc != 0)
+ dev_err(&ddata->spi_dev->dev,
+ "jbt_reg_write16 spi_write ret %d\n", rc);
+
+ return rc;
+}
+
+enum jbt_register {
+ JBT_REG_SLEEP_IN = 0x10,
+ JBT_REG_SLEEP_OUT = 0x11,
+
+ JBT_REG_DISPLAY_OFF = 0x28,
+ JBT_REG_DISPLAY_ON = 0x29,
+
+ JBT_REG_RGB_FORMAT = 0x3a,
+ JBT_REG_QUAD_RATE = 0x3b,
+
+ JBT_REG_POWER_ON_OFF = 0xb0,
+ JBT_REG_BOOSTER_OP = 0xb1,
+ JBT_REG_BOOSTER_MODE = 0xb2,
+ JBT_REG_BOOSTER_FREQ = 0xb3,
+ JBT_REG_OPAMP_SYSCLK = 0xb4,
+ JBT_REG_VSC_VOLTAGE = 0xb5,
+ JBT_REG_VCOM_VOLTAGE = 0xb6,
+ JBT_REG_EXT_DISPL = 0xb7,
+ JBT_REG_OUTPUT_CONTROL = 0xb8,
+ JBT_REG_DCCLK_DCEV = 0xb9,
+ JBT_REG_DISPLAY_MODE1 = 0xba,
+ JBT_REG_DISPLAY_MODE2 = 0xbb,
+ JBT_REG_DISPLAY_MODE = 0xbc,
+ JBT_REG_ASW_SLEW = 0xbd,
+ JBT_REG_DUMMY_DISPLAY = 0xbe,
+ JBT_REG_DRIVE_SYSTEM = 0xbf,
+
+ JBT_REG_SLEEP_OUT_FR_A = 0xc0,
+ JBT_REG_SLEEP_OUT_FR_B = 0xc1,
+ JBT_REG_SLEEP_OUT_FR_C = 0xc2,
+ JBT_REG_SLEEP_IN_LCCNT_D = 0xc3,
+ JBT_REG_SLEEP_IN_LCCNT_E = 0xc4,
+ JBT_REG_SLEEP_IN_LCCNT_F = 0xc5,
+ JBT_REG_SLEEP_IN_LCCNT_G = 0xc6,
+
+ JBT_REG_GAMMA1_FINE_1 = 0xc7,
+ JBT_REG_GAMMA1_FINE_2 = 0xc8,
+ JBT_REG_GAMMA1_INCLINATION = 0xc9,
+ JBT_REG_GAMMA1_BLUE_OFFSET = 0xca,
+
+ JBT_REG_BLANK_CONTROL = 0xcf,
+ JBT_REG_BLANK_TH_TV = 0xd0,
+ JBT_REG_CKV_ON_OFF = 0xd1,
+ JBT_REG_CKV_1_2 = 0xd2,
+ JBT_REG_OEV_TIMING = 0xd3,
+ JBT_REG_ASW_TIMING_1 = 0xd4,
+ JBT_REG_ASW_TIMING_2 = 0xd5,
+
+ JBT_REG_HCLOCK_VGA = 0xec,
+ JBT_REG_HCLOCK_QVGA = 0xed,
+};
+
+#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
+
+static int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ if (omapdss_device_is_connected(dssdev))
+ return 0;
+
+ r = in->ops.dpi->connect(in, dssdev);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (!omapdss_device_is_connected(dssdev))
+ return;
+
+ in->ops.dpi->disconnect(in, dssdev);
+}
+
+static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ if (!omapdss_device_is_connected(dssdev))
+ return -ENODEV;
+
+ if (omapdss_device_is_enabled(dssdev))
+ return 0;
+
+ in->ops.dpi->set_data_lines(in, ddata->data_lines);
+ in->ops.dpi->set_timings(in, &ddata->videomode);
+
+ r = in->ops.dpi->enable(in);
+ if (r)
+ return r;
+
+ dev_dbg(dssdev->dev, "td028ttec1_panel_enable() - state %d\n",
+ dssdev->state);
+
+ /*
+ * according to data sheet: wait 50ms (Tpos of LCM). However, 50ms
+ * seems unreliable with later LCM batches, increasing to 90ms
+ */
+ msleep(90);
+
+ /* three times command zero */
+ r |= jbt_reg_write_nodata(ddata, 0x00);
+ msleep(1000);
+ r |= jbt_reg_write_nodata(ddata, 0x00);
+ msleep(1000);
+ r |= jbt_reg_write_nodata(ddata, 0x00);
+ msleep(1000);
+
+ if (r) {
+ dev_warn(dssdev->dev, "transfer error\n");
+ goto transfer_err;
+ }
+
+ /* deep standby out */
+ r |= jbt_reg_write(ddata, JBT_REG_POWER_ON_OFF, 0x17);
+
+ /* RGB I/F on, RAM write off, QVGA through, SIGCON enable */
+ r |= jbt_reg_write(ddata, JBT_REG_DISPLAY_MODE, 0x80);
+
+ /* Quad mode off */
+ r |= jbt_reg_write(ddata, JBT_REG_QUAD_RATE, 0x00);
+
+ /* AVDD on, XVDD on */
+ r |= jbt_reg_write(ddata, JBT_REG_POWER_ON_OFF, 0x16);
+
+ /* Output control */
+ r |= jbt_reg_write16(ddata, JBT_REG_OUTPUT_CONTROL, 0xfff9);
+
+ /* Sleep mode off */
+ r |= jbt_reg_write_nodata(ddata, JBT_REG_SLEEP_OUT);
+
+ /* at this point we have like 50% grey */
+
+ /* initialize register set */
+ r |= jbt_reg_write(ddata, JBT_REG_DISPLAY_MODE1, 0x01);
+ r |= jbt_reg_write(ddata, JBT_REG_DISPLAY_MODE2, 0x00);
+ r |= jbt_reg_write(ddata, JBT_REG_RGB_FORMAT, 0x60);
+ r |= jbt_reg_write(ddata, JBT_REG_DRIVE_SYSTEM, 0x10);
+ r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_OP, 0x56);
+ r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_MODE, 0x33);
+ r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
+ r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
+ r |= jbt_reg_write(ddata, JBT_REG_OPAMP_SYSCLK, 0x02);
+ r |= jbt_reg_write(ddata, JBT_REG_VSC_VOLTAGE, 0x2b);
+ r |= jbt_reg_write(ddata, JBT_REG_VCOM_VOLTAGE, 0x40);
+ r |= jbt_reg_write(ddata, JBT_REG_EXT_DISPL, 0x03);
+ r |= jbt_reg_write(ddata, JBT_REG_DCCLK_DCEV, 0x04);
+ /*
+ * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement
+ * to avoid red / blue flicker
+ */
+ r |= jbt_reg_write(ddata, JBT_REG_ASW_SLEW, 0x04);
+ r |= jbt_reg_write(ddata, JBT_REG_DUMMY_DISPLAY, 0x00);
+
+ r |= jbt_reg_write(ddata, JBT_REG_SLEEP_OUT_FR_A, 0x11);
+ r |= jbt_reg_write(ddata, JBT_REG_SLEEP_OUT_FR_B, 0x11);
+ r |= jbt_reg_write(ddata, JBT_REG_SLEEP_OUT_FR_C, 0x11);
+ r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040);
+ r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0);
+ r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020);
+ r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0);
+
+ r |= jbt_reg_write16(ddata, JBT_REG_GAMMA1_FINE_1, 0x5533);
+ r |= jbt_reg_write(ddata, JBT_REG_GAMMA1_FINE_2, 0x00);
+ r |= jbt_reg_write(ddata, JBT_REG_GAMMA1_INCLINATION, 0x00);
+ r |= jbt_reg_write(ddata, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
+
+ r |= jbt_reg_write16(ddata, JBT_REG_HCLOCK_VGA, 0x1f0);
+ r |= jbt_reg_write(ddata, JBT_REG_BLANK_CONTROL, 0x02);
+ r |= jbt_reg_write16(ddata, JBT_REG_BLANK_TH_TV, 0x0804);
+
+ r |= jbt_reg_write(ddata, JBT_REG_CKV_ON_OFF, 0x01);
+ r |= jbt_reg_write16(ddata, JBT_REG_CKV_1_2, 0x0000);
+
+ r |= jbt_reg_write16(ddata, JBT_REG_OEV_TIMING, 0x0d0e);
+ r |= jbt_reg_write16(ddata, JBT_REG_ASW_TIMING_1, 0x11a4);
+ r |= jbt_reg_write(ddata, JBT_REG_ASW_TIMING_2, 0x0e);
+
+ r |= jbt_reg_write_nodata(ddata, JBT_REG_DISPLAY_ON);
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+transfer_err:
+
+ return r ? -EIO : 0;
+}
+
+static void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (!omapdss_device_is_enabled(dssdev))
+ return;
+
+ dev_dbg(dssdev->dev, "td028ttec1_panel_disable()\n");
+
+ in->ops.dpi->disable(in);
+
+ jbt_reg_write_nodata(ddata, JBT_REG_DISPLAY_OFF);
+ jbt_reg_write16(ddata, JBT_REG_OUTPUT_CONTROL, 0x8002);
+ jbt_reg_write_nodata(ddata, JBT_REG_SLEEP_IN);
+ jbt_reg_write(ddata, JBT_REG_POWER_ON_OFF, 0x00);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static void td028ttec1_panel_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ ddata->videomode = *timings;
+ dssdev->panel.timings = *timings;
+
+ in->ops.dpi->set_timings(in, timings);
+}
+
+static void td028ttec1_panel_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ *timings = ddata->videomode;
+}
+
+static int td028ttec1_panel_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.dpi->check_timings(in, timings);
+}
+
+static struct omap_dss_driver td028ttec1_ops = {
+ .connect = td028ttec1_panel_connect,
+ .disconnect = td028ttec1_panel_disconnect,
+
+ .enable = td028ttec1_panel_enable,
+ .disable = td028ttec1_panel_disable,
+
+ .set_timings = td028ttec1_panel_set_timings,
+ .get_timings = td028ttec1_panel_get_timings,
+ .check_timings = td028ttec1_panel_check_timings,
+};
+
+static int td028ttec1_panel_probe_pdata(struct spi_device *spi)
+{
+ const struct panel_tpo_td028ttec1_platform_data *pdata;
+ struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
+ struct omap_dss_device *dssdev, *in;
+
+ pdata = dev_get_platdata(&spi->dev);
+
+ in = omap_dss_find_output(pdata->source);
+ if (in = NULL) {
+ dev_err(&spi->dev, "failed to find video source '%s'\n",
+ pdata->source);
+ return -EPROBE_DEFER;
+ }
+
+ ddata->in = in;
+
+ ddata->data_lines = pdata->data_lines;
+
+ dssdev = &ddata->dssdev;
+ dssdev->name = pdata->name;
+
+ return 0;
+}
+
+static int td028ttec1_panel_probe(struct spi_device *spi)
+{
+ struct panel_drv_data *ddata;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ dev_dbg(&spi->dev, "%s\n", __func__);
+
+ spi->bits_per_word = 9;
+ spi->mode = SPI_MODE_3;
+
+ r = spi_setup(spi);
+ if (r < 0) {
+ dev_err(&spi->dev, "spi_setup failed: %d\n", r);
+ return r;
+ }
+
+ ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
+ if (ddata = NULL)
+ return -ENOMEM;
+
+ dev_set_drvdata(&spi->dev, ddata);
+
+ ddata->spi_dev = spi;
+
+ if (dev_get_platdata(&spi->dev)) {
+ r = td028ttec1_panel_probe_pdata(spi);
+ if (r)
+ return r;
+ } else {
+ return -ENODEV;
+ }
+
+ ddata->videomode = td028ttec1_panel_timings;
+
+ dssdev = &ddata->dssdev;
+ dssdev->dev = &spi->dev;
+ dssdev->driver = &td028ttec1_ops;
+ dssdev->type = OMAP_DISPLAY_TYPE_DPI;
+ dssdev->owner = THIS_MODULE;
+ dssdev->panel.timings = ddata->videomode;
+ dssdev->phy.dpi.data_lines = ddata->data_lines;
+
+ r = omapdss_register_display(dssdev);
+ if (r) {
+ dev_err(&spi->dev, "Failed to register panel\n");
+ goto err_reg;
+ }
+
+ return 0;
+
+err_reg:
+ omap_dss_put_device(ddata->in);
+ return r;
+}
+
+static int td028ttec1_panel_remove(struct spi_device *spi)
+{
+ struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
+ struct omap_dss_device *dssdev = &ddata->dssdev;
+ struct omap_dss_device *in = ddata->in;
+
+ dev_dbg(&ddata->spi_dev->dev, "%s\n", __func__);
+
+ omapdss_unregister_display(dssdev);
+
+ td028ttec1_panel_disable(dssdev);
+ td028ttec1_panel_disconnect(dssdev);
+
+ omap_dss_put_device(in);
+
+ return 0;
+}
+
+static struct spi_driver td028ttec1_spi_driver = {
+ .probe = td028ttec1_panel_probe,
+ .remove = td028ttec1_panel_remove,
+
+ .driver = {
+ .name = "panel-tpo-td028ttec1",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_spi_driver(td028ttec1_spi_driver);
+
+MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
+MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver");
+MODULE_LICENSE("GPL");
diff --git a/include/video/omap-panel-data.h b/include/video/omap-panel-data.h
index f7ac8d9..69279c0 100644
--- a/include/video/omap-panel-data.h
+++ b/include/video/omap-panel-data.h
@@ -238,4 +238,17 @@ struct panel_nec_nl8048hl11_platform_data {
int qvga_gpio;
};
+/**
+ * panel-tpo-td028ttec1 platform data
+ * @name: name for display entity
+ * @source: name of the display entity used as a video source
+ * @data_lines: number of DPI datalines
+ */
+struct panel_tpo_td028ttec1_platform_data {
+ const char *name;
+ const char *source;
+
+ int data_lines;
+};
+
#endif /* __OMAP_PANEL_DATA_H */
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH/RFC v3 00/19] Common Display Framework
From: Tomi Valkeinen @ 2013-10-17 12:55 UTC (permalink / raw)
To: Andrzej Hajda, Laurent Pinchart
Cc: linux-fbdev, dri-devel, Jesse Barnes, Benjamin Gaignard, Tom Gall,
Kyungmin Park, linux-media, Stephen Warren, Mark Zhang,
Alexandre Courbot, Ragesh Radhakrishnan, Thomas Petazzoni,
Sunil Joshi, Maxime Ripard, Vikas Sajjan, Marcus Lorentzon
In-Reply-To: <525FD760.20506@samsung.com>
[-- Attachment #1: Type: text/plain, Size: 4219 bytes --]
On 17/10/13 15:26, Andrzej Hajda wrote:
> I am not sure what exactly the encoder performs, if this is only image
> transport from dispc to panel CDF pipeline in both cases should look like:
> dispc ----> panel
> The only difference is that panels will be connected via different Linux bus
> adapters, but it will be irrelevant to CDF itself. In this case I would say
> this is DSI-master rather than encoder, or at least that the only
> function of the
> encoder is DSI.
Yes, as I said, it's up to the driver writer how he wants to use CDF. If
he doesn't see the point of representing the SoC's DSI encoder as a
separate CDF entity, nobody forces him to do that.
On OMAP, we have single DISPC with multiple parallel outputs, and a
bunch of encoder IPs (MIPI DPI, DSI, DBI, etc). Each encoder IP can be
connected to some of the DISPC's output. In this case, even if the DSI
encoder does nothing special, I see it much better to represent the DSI
encoder as a CDF entity so that the links between DISPC, DSI, and the
DSI peripherals are all there.
> If display_timings on input and output differs, I suppose it should be
> modeled
> as display_entity, as this is an additional functionality(not covered by
> DSI standard AFAIK).
Well, DSI standard is about the DSI output. Not about the encoder's
input, or the internal operation of the encoder.
>>> Of course there are some settings which are not panel dependent and those
>>> should reside in DSI node.
>> Exactly. And when the two panels require different non-panel-dependent
>> settings, how do you represent them in the DT data?
>
> non-panel-dependent setting cannot depend on panel, by definition :)
With "non-panel-dependent" setting I meant something that is a property
of the DSI master device, but still needs to be configured differently
for each panel.
Say, pin configuration. When using panel A, the first pin of the DSI
block could be clock+. With panel B, the first pin could be clock-. This
configuration is about DSI master, but it is different for each panel.
If we have separate endpoint in the DSI master for each panel, this data
can be there. If we don't have the endpoint, as is the case with
separate control bus, where is that data?
>>> Could you describe such scenario?
>> If we have two independent APIs, ctrl and video, that affect the same
>> underlying hardware, the DSI bus, we could have a scenario like this:
>>
>> thread 1:
>>
>> ctrl->op_foo();
>> ctrl->op_bar();
>>
>> thread 2:
>>
>> video->op_baz();
>>
>> Even if all those ops do locking properly internally, the fact that
>> op_baz() can be called in between op_foo() and op_bar() may cause problems.
>>
>> To avoid that issue with two APIs we'd need something like:
>>
>> thread 1:
>>
>> ctrl->lock();
>> ctrl->op_foo();
>> ctrl->op_bar();
>> ctrl->unlock();
>>
>> thread 2:
>>
>> video->lock();
>> video->op_baz();
>> video->unlock();
> I should mention I was asking for real hw/drivers configuration.
> I do not know what do you mean with video->op_baz() ?
> DSI-master is not modeled in CDF, and only CDF provides video
> operations.
It was just an example of the additional complexity with regarding
locking when using two APIs.
The point is that if the panel driver has two pointers (i.e. API), one
for the control bus, one for the video bus, and ops on both buses affect
the same hardware, the locking is not easy.
If, on the other hand, the panel driver only has one API to use, it's
simple to require the caller to handle any locking.
> I guess one scenario, when two panels are connected to single DSI-master.
> In such case both can call DSI ops, but I do not know how do you want to
> prevent it in case of your CDF-T implementation.
No, that was not the case I was describing. This was about a single panel.
If we have two independent APIs, we need to define how locking is
managed for those APIs. Even if in practice both APIs are used by the
same driver, and the driver can manage the locking, that's not really a
valid requirement. It'd be almost the same as requiring that gpio API
cannot be called at the same time as i2c API.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox